mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-06-24 14:53:24 +01:00
Merge branch 'master' of https://github.com/Fordoxia/CRUNCHParadise
This commit is contained in:
@@ -113,7 +113,7 @@ jobs:
|
||||
|
||||
- name: Rebuild TGUI
|
||||
run: |
|
||||
if git diff-tree --name-only -r $(git rev-parse HEAD~2) | grep "tgui/public/"
|
||||
if git diff-tree --name-only -r $(git rev-parse HEAD~2) | grep "tgui/public/" ; then
|
||||
bash tgui/bin/tgui
|
||||
git commit -m "Rebuild TGUI"
|
||||
git push origin
|
||||
|
||||
@@ -404,8 +404,11 @@ CREATE TABLE `notes` (
|
||||
`server` varchar(50) NOT NULL,
|
||||
`crew_playtime` mediumint(8) UNSIGNED DEFAULT '0',
|
||||
`automated` TINYINT(3) UNSIGNED NULL DEFAULT '0',
|
||||
`deleted` TINYINT(4) NOT NULL DEFAULT '0',
|
||||
`deletedby` VARCHAR(32) NULL DEFAULT NULL COLLATE 'utf8mb4_general_ci',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `ckey` (`ckey`)
|
||||
KEY `ckey` (`ckey`),
|
||||
KEY `deleted` (`deleted`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# Updating DB from 55-56 ~AffectedArc07
|
||||
# Adds a new column to the notes table for tracking deleted notes
|
||||
ALTER TABLE `notes`
|
||||
ADD COLUMN `deleted` TINYINT NOT NULL DEFAULT 0 AFTER `automated`,
|
||||
ADD COLUMN `deletedby` VARCHAR(32) NULL DEFAULT NULL AFTER `deleted`,
|
||||
ADD INDEX `deleted` (`deleted`);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+1434
-1429
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -258,6 +258,10 @@
|
||||
/obj/item/target,
|
||||
/obj/item/target,
|
||||
/obj/item/target,
|
||||
/obj/item/target/syndicate,
|
||||
/obj/item/target/syndicate,
|
||||
/obj/item/target/syndicate,
|
||||
/obj/item/target/syndicate,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"acD" = (
|
||||
@@ -453,7 +457,6 @@
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Firing Range"
|
||||
},
|
||||
/obj/machinery/syndicatebomb/training,
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
@@ -466,7 +469,7 @@
|
||||
name = "east bump";
|
||||
pixel_x = 24
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"adn" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
|
||||
@@ -522,9 +525,8 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 4
|
||||
},
|
||||
/obj/item/radio/intercom/department/security{
|
||||
pixel_y = -28
|
||||
},
|
||||
/obj/machinery/nuclearbomb/training,
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"adE" = (
|
||||
@@ -537,13 +539,34 @@
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/machinery/syndicatebomb/training,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"adG" = (
|
||||
/obj/item/disk/nuclear/training{
|
||||
pixel_y = -2;
|
||||
pixel_x = -7
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 9
|
||||
},
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/structure/table/reinforced,
|
||||
/obj/item/paper/nuclear_guide_spacing{
|
||||
pixel_x = 10;
|
||||
pixel_y = 7
|
||||
},
|
||||
/obj/item/paper/nuclear_guide_defusing{
|
||||
pixel_x = 9;
|
||||
pixel_y = 4
|
||||
},
|
||||
/obj/item/disk/nuclear/training{
|
||||
pixel_x = -5
|
||||
},
|
||||
/obj/item/paper/nuclear_guide_operating{
|
||||
pixel_x = 8;
|
||||
pixel_y = 1
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"adH" = (
|
||||
@@ -1696,10 +1719,22 @@
|
||||
/area/station/command/office/hos)
|
||||
"aij" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/structure/rack,
|
||||
/obj/item/target/syndicate,
|
||||
/obj/item/target/syndicate,
|
||||
/obj/item/target/syndicate,
|
||||
/obj/item/storage/toolbox/mechanical{
|
||||
pixel_x = 3;
|
||||
pixel_y = 6
|
||||
},
|
||||
/obj/item/multitool{
|
||||
pixel_y = -5;
|
||||
pixel_x = 5
|
||||
},
|
||||
/obj/item/clothing/head/welding{
|
||||
pixel_y = -2;
|
||||
pixel_x = -6
|
||||
},
|
||||
/obj/structure/table/reinforced,
|
||||
/obj/item/radio/intercom/department/security{
|
||||
pixel_x = 28
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"aio" = (
|
||||
@@ -11923,7 +11958,6 @@
|
||||
/area/station/hallway/secondary/entry/north)
|
||||
"aMC" = (
|
||||
/obj/structure/table,
|
||||
/obj/machinery/computer/mob_healer_terminal,
|
||||
/turf/simulated/floor/carpet/arcade,
|
||||
/area/station/public/arcade)
|
||||
"aMD" = (
|
||||
@@ -14876,9 +14910,6 @@
|
||||
/area/station/medical/reception)
|
||||
"aVy" = (
|
||||
/obj/machinery/economy/vending/coffee,
|
||||
/obj/machinery/computer/mob_healer_terminal{
|
||||
pixel_x = 28
|
||||
},
|
||||
/obj/structure/sign/poster/official/random{
|
||||
pixel_y = 32
|
||||
},
|
||||
@@ -35301,13 +35332,14 @@
|
||||
/obj/machinery/door/airlock/engineering/glass{
|
||||
name = "Laser Room"
|
||||
},
|
||||
/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
|
||||
/obj/effect/mapping_helpers/airlock/access/any/engineering/general,
|
||||
/obj/structure/cable{
|
||||
d1 = 1;
|
||||
d2 = 2;
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
|
||||
/obj/effect/mapping_helpers/airlock/access/any/engineering/atmos,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/engineering/control)
|
||||
"cmd" = (
|
||||
@@ -38903,13 +38935,14 @@
|
||||
/obj/machinery/door/airlock/engineering/glass{
|
||||
name = "Laser Room"
|
||||
},
|
||||
/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
|
||||
/obj/effect/mapping_helpers/airlock/access/any/engineering/general,
|
||||
/obj/structure/cable{
|
||||
d1 = 1;
|
||||
d2 = 2;
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,
|
||||
/obj/effect/mapping_helpers/airlock/access/any/engineering/atmos,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/engineering/control)
|
||||
"cyS" = (
|
||||
@@ -52294,12 +52327,6 @@
|
||||
icon_state = "vault"
|
||||
},
|
||||
/area/station/engineering/gravitygenerator)
|
||||
"dCJ" = (
|
||||
/obj/structure/transit_tube/cap{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/turret_protected/aisat/interior)
|
||||
"dCM" = (
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 4
|
||||
@@ -55778,13 +55805,6 @@
|
||||
icon_state = "darkgreen"
|
||||
},
|
||||
/area/station/medical/medbay3)
|
||||
"fes" = (
|
||||
/obj/structure/chair{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/computer/mob_battle_terminal/red,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/public/dorms)
|
||||
"feN" = (
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/hallway/secondary/entry/north)
|
||||
@@ -57663,10 +57683,12 @@
|
||||
layer = 4;
|
||||
pixel_y = 32
|
||||
},
|
||||
/obj/structure/transit_tube/station,
|
||||
/obj/structure/transit_tube_pod{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/transit_tube/station/reverse/flipped{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
@@ -64030,9 +64052,6 @@
|
||||
name = "north bump";
|
||||
pixel_y = 24
|
||||
},
|
||||
/obj/structure/transit_tube/cap{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
@@ -65342,12 +65361,6 @@
|
||||
/obj/effect/spawner/window/reinforced,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/supply/lobby)
|
||||
"jPN" = (
|
||||
/obj/machinery/computer/mob_battle_terminal/blue{
|
||||
pixel_x = -32
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/public/dorms)
|
||||
"jPZ" = (
|
||||
/obj/structure/sign/poster/official/cleanliness{
|
||||
pixel_x = 32
|
||||
@@ -72410,11 +72423,11 @@
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/supply/storage)
|
||||
"nrh" = (
|
||||
/obj/structure/transit_tube/station,
|
||||
/obj/structure/transit_tube_pod{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/visible/yellow,
|
||||
/obj/structure/transit_tube/station/reverse,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/turret_protected/aisat/interior)
|
||||
"nrD" = (
|
||||
@@ -76992,10 +77005,6 @@
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/security/permabrig)
|
||||
"pwU" = (
|
||||
/obj/effect/landmark/battle_mob_point,
|
||||
/turf/simulated/floor/engine,
|
||||
/area/holodeck/alphadeck)
|
||||
"pxv" = (
|
||||
/obj/machinery/atmospherics/unary/outlet_injector/on{
|
||||
dir = 8;
|
||||
@@ -82089,7 +82098,7 @@
|
||||
id = "engsm";
|
||||
name = "Radiation Shutters Control";
|
||||
pixel_y = -24;
|
||||
req_access_txt = "10"
|
||||
req_access_txt = "32"
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line,
|
||||
/turf/simulated/floor/engine,
|
||||
@@ -131932,7 +131941,7 @@ aab
|
||||
aaa
|
||||
cQp
|
||||
wza
|
||||
dCJ
|
||||
dnW
|
||||
dnv
|
||||
dnW
|
||||
diz
|
||||
@@ -132341,7 +132350,7 @@ nXr
|
||||
aKQ
|
||||
fRL
|
||||
aPm
|
||||
jPN
|
||||
aPm
|
||||
lkw
|
||||
fho
|
||||
aPm
|
||||
@@ -132590,7 +132599,7 @@ awE
|
||||
ayf
|
||||
azn
|
||||
arR
|
||||
fes
|
||||
tbC
|
||||
tbC
|
||||
tbC
|
||||
aPm
|
||||
@@ -133621,10 +133630,10 @@ atG
|
||||
sHt
|
||||
sHt
|
||||
sHt
|
||||
pwU
|
||||
sHt
|
||||
sHt
|
||||
pwU
|
||||
sHt
|
||||
sHt
|
||||
sHt
|
||||
sHt
|
||||
sHt
|
||||
|
||||
@@ -2486,13 +2486,6 @@
|
||||
/obj/machinery/ai_status_display,
|
||||
/turf/simulated/wall/r_wall,
|
||||
/area/station/turret_protected/aisat/interior)
|
||||
"apu" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/effect/spawner/lootdrop/maintenance,
|
||||
/turf/simulated/floor/plating{
|
||||
icon_state = "asteroidplating"
|
||||
},
|
||||
/area/station/maintenance/fore2)
|
||||
"apw" = (
|
||||
/obj/structure/table,
|
||||
/obj/item/storage/toolbox/emergency,
|
||||
@@ -2752,37 +2745,41 @@
|
||||
/turf/simulated/floor/plating/asteroid/ancient,
|
||||
/area/station/maintenance/fpmaint)
|
||||
"ard" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/machinery/light/small,
|
||||
/turf/simulated/floor/plating{
|
||||
icon_state = "asteroidplating"
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 9
|
||||
},
|
||||
/area/station/security/permabrig)
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/syndicatebomb/training,
|
||||
/obj/machinery/light,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/defusal)
|
||||
"arh" = (
|
||||
/obj/item/vending_refill/cola,
|
||||
/obj/item/multitool,
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/effect/spawner/grouped_spawner{
|
||||
group_id = "tunnelbats";
|
||||
max_per_spawner = 1;
|
||||
name = "bat spawner";
|
||||
path_to_spawn = /mob/living/simple_animal/hostile/scarybat;
|
||||
total_amount = 20
|
||||
/obj/item/disk/nuclear/training{
|
||||
pixel_y = -2;
|
||||
pixel_x = -7
|
||||
},
|
||||
/turf/simulated/floor/plating{
|
||||
icon_state = "asteroidplating"
|
||||
/obj/structure/table/reinforced,
|
||||
/obj/item/paper/nuclear_guide_spacing{
|
||||
pixel_x = 10;
|
||||
pixel_y = 7
|
||||
},
|
||||
/area/station/maintenance/fore2)
|
||||
"ark" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/turf/simulated/floor/plating{
|
||||
icon_state = "asteroidplating"
|
||||
/obj/item/paper/nuclear_guide_defusing{
|
||||
pixel_x = 9;
|
||||
pixel_y = 4
|
||||
},
|
||||
/area/station/maintenance/fore2)
|
||||
"arl" = (
|
||||
/obj/structure/closet/emcloset,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/maintenance/fore2)
|
||||
/obj/item/disk/nuclear/training{
|
||||
pixel_x = -5
|
||||
},
|
||||
/obj/item/paper/nuclear_guide_operating{
|
||||
pixel_x = 8;
|
||||
pixel_y = 1
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "redcorner"
|
||||
},
|
||||
/area/station/security/defusal)
|
||||
"arm" = (
|
||||
/obj/machinery/door/airlock/maintenance{
|
||||
name = "Fore Asteroid Maintenance Access"
|
||||
@@ -5829,6 +5826,13 @@
|
||||
"aMC" = (
|
||||
/turf/simulated/mineral/ancient,
|
||||
/area/station/medical/break_room)
|
||||
"aME" = (
|
||||
/obj/machinery/door/airlock/maintenance,
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/turf/simulated/floor/plating{
|
||||
icon_state = "asteroidplating"
|
||||
},
|
||||
/area/station/security/permabrig)
|
||||
"aMJ" = (
|
||||
/obj/machinery/firealarm{
|
||||
dir = 1;
|
||||
@@ -11253,7 +11257,7 @@
|
||||
/obj/machinery/door/airlock/engineering/glass{
|
||||
name = "Laser Room"
|
||||
},
|
||||
/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
|
||||
/obj/effect/mapping_helpers/airlock/access/any/engineering/atmos,
|
||||
/obj/structure/cable{
|
||||
d1 = 1;
|
||||
d2 = 2;
|
||||
@@ -11261,6 +11265,7 @@
|
||||
},
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,
|
||||
/obj/effect/mapping_helpers/airlock/access/any/engineering/general,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
@@ -12062,19 +12067,21 @@
|
||||
pixel_x = -3;
|
||||
pixel_y = -2
|
||||
},
|
||||
/obj/item/clothing/glasses/sunglasses,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"bsP" = (
|
||||
/obj/item/radio/intercom{
|
||||
pixel_y = -28;
|
||||
name = "custom placement"
|
||||
},
|
||||
/obj/structure/table/reinforced,
|
||||
/obj/item/clothing/glasses/sunglasses{
|
||||
pixel_x = 3;
|
||||
pixel_y = 3
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"bsP" = (
|
||||
/obj/machinery/syndicatebomb/training,
|
||||
/obj/structure/closet/bombclosetsecurity,
|
||||
/obj/item/radio/intercom{
|
||||
pixel_y = -28;
|
||||
name = "custom placement"
|
||||
/obj/item/clothing/glasses/sunglasses,
|
||||
/obj/item/storage/box/flashbangs{
|
||||
pixel_x = -16
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
@@ -25812,13 +25819,16 @@
|
||||
/turf/simulated/floor/wood,
|
||||
/area/station/legal/magistrate)
|
||||
"cKZ" = (
|
||||
/obj/machinery/door/airlock/maintenance,
|
||||
/obj/effect/mapping_helpers/airlock/access/all/security/general,
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/turf/simulated/floor/plating{
|
||||
icon_state = "asteroidplating"
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/on,
|
||||
/obj/item/radio/intercom{
|
||||
name = "custom placement";
|
||||
pixel_y = 28
|
||||
},
|
||||
/area/station/maintenance/fore2)
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Defusal Workshop"
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/defusal)
|
||||
"cLa" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 4
|
||||
@@ -28999,6 +29009,23 @@
|
||||
icon_state = "darkyellow"
|
||||
},
|
||||
/area/station/engineering/atmos)
|
||||
"cZi" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 6
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 6
|
||||
},
|
||||
/obj/structure/cable/orange{
|
||||
d2 = 2;
|
||||
icon_state = "0-2"
|
||||
},
|
||||
/obj/machinery/power/apc/directional/west,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 8;
|
||||
icon_state = "redcorner"
|
||||
},
|
||||
/area/station/security/defusal)
|
||||
"cZr" = (
|
||||
/obj/structure/chair{
|
||||
dir = 8
|
||||
@@ -29371,13 +29398,11 @@
|
||||
/area/station/security/prison/cell_block/A)
|
||||
"ddl" = (
|
||||
/obj/effect/spawner/window/reinforced/grilled,
|
||||
/obj/structure/cable/orange{
|
||||
d1 = 1;
|
||||
d2 = 4;
|
||||
icon_state = "1-4"
|
||||
},
|
||||
/obj/structure/cable/orange,
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/structure/cable/orange{
|
||||
d2 = 4;
|
||||
icon_state = "0-4"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/security/permabrig)
|
||||
"ddn" = (
|
||||
@@ -33148,9 +33173,10 @@
|
||||
/obj/machinery/door/airlock/engineering/glass{
|
||||
name = "Laser Room"
|
||||
},
|
||||
/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
|
||||
/obj/effect/mapping_helpers/airlock/access/any/engineering/atmos,
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
|
||||
/obj/effect/mapping_helpers/airlock/access/any/engineering/general,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
@@ -33955,6 +33981,17 @@
|
||||
icon_state = "yellowcorner"
|
||||
},
|
||||
/area/station/hallway/primary/central/east)
|
||||
"dEa" = (
|
||||
/obj/machinery/light_switch{
|
||||
name = "north bump";
|
||||
pixel_y = 24
|
||||
},
|
||||
/obj/machinery/alarm/directional/west,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 1;
|
||||
icon_state = "redcorner"
|
||||
},
|
||||
/area/station/security/defusal)
|
||||
"dEi" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/item/ammo_box/shotgun/beanbag,
|
||||
@@ -34819,6 +34856,24 @@
|
||||
icon_state = "bluered"
|
||||
},
|
||||
/area/station/hallway/secondary/entry/west)
|
||||
"dQG" = (
|
||||
/obj/machinery/door/airlock/security/glass{
|
||||
name = "Defusal Workshop"
|
||||
},
|
||||
/obj/effect/mapping_helpers/airlock/access/all/security/general,
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/structure/cable/orange{
|
||||
d1 = 1;
|
||||
d2 = 2;
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 4;
|
||||
icon_state = "red"
|
||||
},
|
||||
/area/station/security/defusal)
|
||||
"dQR" = (
|
||||
/obj/machinery/door/airlock/maintenance{
|
||||
name = "Aft Asteroid Maintenance"
|
||||
@@ -36720,15 +36775,6 @@
|
||||
/obj/machinery/hologram/holopad,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/hallway/secondary/exit)
|
||||
"eAn" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/structure/closet/firecloset,
|
||||
/obj/item/crowbar/red,
|
||||
/obj/machinery/light{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/maintenance/fore2)
|
||||
"eAu" = (
|
||||
/obj/effect/turf_decal/delivery,
|
||||
/obj/machinery/recharge_station,
|
||||
@@ -41487,6 +41533,25 @@
|
||||
/obj/effect/spawner/random_spawners/dirt_often,
|
||||
/turf/simulated/floor/transparent/glass/reinforced,
|
||||
/area/station/maintenance/apmaint)
|
||||
"gmV" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 9
|
||||
},
|
||||
/obj/structure/table/reinforced,
|
||||
/obj/item/clothing/head/welding{
|
||||
pixel_x = 12;
|
||||
pixel_y = 6
|
||||
},
|
||||
/obj/item/multitool{
|
||||
pixel_x = -4;
|
||||
pixel_y = 6
|
||||
},
|
||||
/obj/item/storage/toolbox/mechanical{
|
||||
pixel_x = -3;
|
||||
pixel_y = -2
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/defusal)
|
||||
"gmZ" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 5
|
||||
@@ -42842,6 +42907,21 @@
|
||||
icon_state = "whitebluecorner"
|
||||
},
|
||||
/area/station/medical/surgery/secondary)
|
||||
"gLb" = (
|
||||
/obj/item/vending_refill/cola,
|
||||
/obj/item/multitool,
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/effect/spawner/grouped_spawner{
|
||||
group_id = "tunnelbats";
|
||||
max_per_spawner = 1;
|
||||
name = "bat spawner";
|
||||
path_to_spawn = /mob/living/simple_animal/hostile/scarybat;
|
||||
total_amount = 20
|
||||
},
|
||||
/turf/simulated/floor/plating{
|
||||
icon_state = "asteroidplating"
|
||||
},
|
||||
/area/station/security/permabrig)
|
||||
"gLj" = (
|
||||
/obj/structure/table/wood,
|
||||
/obj/effect/spawner/lootdrop/maintenance/eight,
|
||||
@@ -43849,6 +43929,15 @@
|
||||
icon_state = "red"
|
||||
},
|
||||
/area/station/security/storage)
|
||||
"hcm" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/structure/closet/firecloset,
|
||||
/obj/item/crowbar/red,
|
||||
/obj/machinery/light{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/security/permabrig)
|
||||
"hco" = (
|
||||
/obj/structure/cable/orange{
|
||||
d1 = 4;
|
||||
@@ -44431,6 +44520,14 @@
|
||||
/obj/effect/spawner/window/reinforced/grilled,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/turret_protected/aisat/interior/secondary)
|
||||
"hnL" = (
|
||||
/obj/machinery/atmospherics/unary/vent_pump/on,
|
||||
/obj/machinery/firealarm{
|
||||
name = "north bump";
|
||||
pixel_y = 24
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/defusal)
|
||||
"hoa" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 6
|
||||
@@ -50739,12 +50836,12 @@
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/hallway/primary/central/west)
|
||||
"jjh" = (
|
||||
/obj/structure/cable/orange{
|
||||
d1 = 2;
|
||||
d2 = 8;
|
||||
icon_state = "2-8"
|
||||
},
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/structure/cable/orange{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/permabrig)
|
||||
"jjp" = (
|
||||
@@ -53865,20 +53962,6 @@
|
||||
temperature = 80
|
||||
},
|
||||
/area/station/science/xenobiology)
|
||||
"khV" = (
|
||||
/obj/effect/spawner/window/reinforced/grilled,
|
||||
/obj/structure/cable/orange{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/structure/cable/orange{
|
||||
d2 = 8;
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/obj/machinery/door/firedoor,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/security/brig)
|
||||
"kic" = (
|
||||
/obj/structure/closet/wardrobe/grey,
|
||||
/turf/simulated/floor/mineral/titanium/blue,
|
||||
@@ -59525,6 +59608,15 @@
|
||||
icon_state = "cafeteria"
|
||||
},
|
||||
/area/station/service/kitchen)
|
||||
"lQa" = (
|
||||
/obj/effect/spawner/window/reinforced/grilled,
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/structure/cable/orange{
|
||||
d2 = 8;
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/security/permabrig)
|
||||
"lQy" = (
|
||||
/obj/machinery/optable,
|
||||
/obj/machinery/light{
|
||||
@@ -60954,11 +61046,6 @@
|
||||
/obj/effect/spawner/random_spawners/dirt_often,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/maintenance/disposal/external/southwest)
|
||||
"moQ" = (
|
||||
/obj/effect/spawner/lootdrop/maintenance,
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/maintenance/fore2)
|
||||
"moY" = (
|
||||
/obj/structure/closet/secure_closet/medical3,
|
||||
/obj/machinery/light,
|
||||
@@ -62522,15 +62609,6 @@
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/security/brig)
|
||||
"mSf" = (
|
||||
/obj/effect/spawner/window/reinforced/grilled,
|
||||
/obj/structure/cable/orange{
|
||||
d2 = 8;
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/obj/machinery/door/firedoor,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/security/permabrig)
|
||||
"mSh" = (
|
||||
/obj/structure/girder,
|
||||
/turf/simulated/floor/plating,
|
||||
@@ -62825,13 +62903,12 @@
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/maintenance/maintcentral)
|
||||
"mVr" = (
|
||||
/obj/item/clothing/shoes/orange,
|
||||
/obj/item/clothing/under/color/orange/prison,
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/turf/simulated/floor/plating{
|
||||
icon_state = "asteroidplating"
|
||||
/obj/machinery/nuclearbomb/training,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 4;
|
||||
icon_state = "redcorner"
|
||||
},
|
||||
/area/station/maintenance/fore2)
|
||||
/area/station/security/defusal)
|
||||
"mVs" = (
|
||||
/obj/structure/disposalpipe/segment/corner{
|
||||
dir = 8;
|
||||
@@ -63272,6 +63349,16 @@
|
||||
/obj/structure/sign/securearea,
|
||||
/turf/simulated/wall,
|
||||
/area/station/engineering/tech_storage)
|
||||
"nde" = (
|
||||
/obj/structure/cable/orange{
|
||||
d1 = 2;
|
||||
d2 = 8;
|
||||
icon_state = "2-8"
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "floorgrime"
|
||||
},
|
||||
/area/station/security/permabrig)
|
||||
"ndl" = (
|
||||
/obj/effect/spawner/window/reinforced/polarized/grilled{
|
||||
id = "rd"
|
||||
@@ -65368,6 +65455,11 @@
|
||||
icon_state = "neutralcorner"
|
||||
},
|
||||
/area/station/hallway/primary/fore/east)
|
||||
"nNB" = (
|
||||
/obj/effect/spawner/lootdrop/maintenance,
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/security/permabrig)
|
||||
"nNF" = (
|
||||
/obj/machinery/door/airlock/maintenance{
|
||||
name = "Service SMES Access"
|
||||
@@ -65403,6 +65495,10 @@
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/hallway/primary/port/north)
|
||||
"nOr" = (
|
||||
/obj/structure/closet/emcloset,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/security/permabrig)
|
||||
"nOu" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
|
||||
/obj/structure/disposalpipe/segment,
|
||||
@@ -69524,6 +69620,9 @@
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/station/turret_protected/ai)
|
||||
"peU" = (
|
||||
/turf/simulated/wall/r_wall,
|
||||
/area/station/security/defusal)
|
||||
"pfe" = (
|
||||
/obj/structure/chair/wood{
|
||||
dir = 1
|
||||
@@ -77318,6 +77417,30 @@
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/public/locker)
|
||||
"rGv" = (
|
||||
/obj/structure/cable/orange{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/disposalpipe/segment{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/cable/orange{
|
||||
d1 = 1;
|
||||
d2 = 8;
|
||||
icon_state = "1-8"
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/station/security/brig)
|
||||
"rGw" = (
|
||||
/obj/structure/disposalpipe/segment/corner,
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/cyan{
|
||||
@@ -82602,12 +82725,6 @@
|
||||
icon_state = "whitegreen"
|
||||
},
|
||||
/area/station/medical/virology)
|
||||
"tpw" = (
|
||||
/obj/effect/landmark/battle_mob_point,
|
||||
/turf/simulated/floor/engine{
|
||||
name = "Holodeck Projector Floor"
|
||||
},
|
||||
/area/holodeck/alphadeck)
|
||||
"tpA" = (
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
@@ -83579,16 +83696,18 @@
|
||||
/area/station/maintenance/port)
|
||||
"tFL" = (
|
||||
/obj/effect/spawner/window/reinforced/grilled,
|
||||
/obj/structure/cable/orange{
|
||||
d2 = 8;
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/obj/structure/cable/orange{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/structure/cable/orange{
|
||||
d1 = 1;
|
||||
d2 = 4;
|
||||
icon_state = "1-4"
|
||||
},
|
||||
/obj/structure/cable/orange{
|
||||
d1 = 1;
|
||||
d2 = 8;
|
||||
icon_state = "1-8"
|
||||
},
|
||||
/obj/structure/cable/orange,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/security/permabrig)
|
||||
"tFY" = (
|
||||
@@ -91624,6 +91743,14 @@
|
||||
icon_state = "darkyellow"
|
||||
},
|
||||
/area/station/engineering/control)
|
||||
"weh" = (
|
||||
/obj/item/clothing/shoes/orange,
|
||||
/obj/item/clothing/under/color/orange/prison,
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/turf/simulated/floor/plating{
|
||||
icon_state = "asteroidplating"
|
||||
},
|
||||
/area/station/security/permabrig)
|
||||
"weN" = (
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
@@ -92008,6 +92135,13 @@
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/hallway/primary/aft/west)
|
||||
"wiU" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/effect/spawner/lootdrop/maintenance,
|
||||
/turf/simulated/floor/plating{
|
||||
icon_state = "asteroidplating"
|
||||
},
|
||||
/area/station/security/permabrig)
|
||||
"wiV" = (
|
||||
/obj/structure/mirror{
|
||||
pixel_x = -28
|
||||
@@ -95268,7 +95402,7 @@
|
||||
id = "engsm";
|
||||
name = "Radiation Shutters Control";
|
||||
pixel_y = 24;
|
||||
req_access_txt = "10"
|
||||
req_access_txt = "32"
|
||||
},
|
||||
/obj/machinery/camera{
|
||||
c_tag = "SM South";
|
||||
@@ -98581,6 +98715,7 @@
|
||||
/obj/machinery/light/small{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/closet/bombclosetsecurity,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
@@ -116641,10 +116776,10 @@ bEM
|
||||
pDn
|
||||
pDn
|
||||
pDn
|
||||
tpw
|
||||
pDn
|
||||
pDn
|
||||
tpw
|
||||
pDn
|
||||
pDn
|
||||
pDn
|
||||
pDn
|
||||
pDn
|
||||
@@ -118894,7 +119029,7 @@ rHj
|
||||
cDb
|
||||
rHj
|
||||
aQL
|
||||
aQL
|
||||
nde
|
||||
tFL
|
||||
rNK
|
||||
rNK
|
||||
@@ -119152,10 +119287,10 @@ gLk
|
||||
cVR
|
||||
amO
|
||||
myY
|
||||
tFL
|
||||
lQa
|
||||
rNK
|
||||
rNK
|
||||
khV
|
||||
lPn
|
||||
yfX
|
||||
fOj
|
||||
awv
|
||||
@@ -119409,11 +119544,11 @@ dpC
|
||||
rHj
|
||||
adc
|
||||
rHj
|
||||
mSf
|
||||
rNK
|
||||
rNK
|
||||
lPn
|
||||
yfX
|
||||
peU
|
||||
peU
|
||||
peU
|
||||
peU
|
||||
wGz
|
||||
uaJ
|
||||
awB
|
||||
uqz
|
||||
@@ -119666,12 +119801,12 @@ rHj
|
||||
rHj
|
||||
vNP
|
||||
sFU
|
||||
afd
|
||||
afd
|
||||
afd
|
||||
afd
|
||||
wGz
|
||||
uaJ
|
||||
peU
|
||||
dEa
|
||||
cZi
|
||||
dQG
|
||||
dsy
|
||||
rGv
|
||||
dtr
|
||||
uqz
|
||||
aLp
|
||||
@@ -119923,10 +120058,10 @@ rHj
|
||||
cgX
|
||||
tkn
|
||||
dqz
|
||||
tkn
|
||||
rHj
|
||||
peU
|
||||
hnL
|
||||
ard
|
||||
afd
|
||||
peU
|
||||
daG
|
||||
sVX
|
||||
daG
|
||||
@@ -120176,13 +120311,13 @@ aTz
|
||||
afd
|
||||
aTz
|
||||
aTz
|
||||
rHj
|
||||
aTz
|
||||
aTz
|
||||
afd
|
||||
afd
|
||||
cKZ
|
||||
aME
|
||||
mYJ
|
||||
peU
|
||||
cKZ
|
||||
gmV
|
||||
fqh
|
||||
eBm
|
||||
krP
|
||||
@@ -120433,11 +120568,11 @@ afd
|
||||
afd
|
||||
aTz
|
||||
aTz
|
||||
aTz
|
||||
aTz
|
||||
aTz
|
||||
afd
|
||||
vXM
|
||||
tkn
|
||||
weh
|
||||
gLb
|
||||
peU
|
||||
mVr
|
||||
arh
|
||||
fqh
|
||||
@@ -120690,13 +120825,13 @@ abW
|
||||
abW
|
||||
afd
|
||||
aTz
|
||||
aTz
|
||||
aTz
|
||||
aTz
|
||||
afd
|
||||
eAn
|
||||
moQ
|
||||
ark
|
||||
hcm
|
||||
nNB
|
||||
adc
|
||||
peU
|
||||
peU
|
||||
peU
|
||||
fqh
|
||||
xax
|
||||
pZs
|
||||
@@ -120945,15 +121080,15 @@ rNK
|
||||
cRv
|
||||
abW
|
||||
abW
|
||||
abW
|
||||
afd
|
||||
aTz
|
||||
afd
|
||||
vNP
|
||||
wiU
|
||||
nOr
|
||||
afd
|
||||
aTz
|
||||
aTz
|
||||
aTz
|
||||
afd
|
||||
vrQ
|
||||
apu
|
||||
arl
|
||||
asu
|
||||
atc
|
||||
eZh
|
||||
@@ -121202,15 +121337,15 @@ rNK
|
||||
cRv
|
||||
cRv
|
||||
cRv
|
||||
abW
|
||||
afd
|
||||
aTz
|
||||
aTz
|
||||
aTz
|
||||
aTz
|
||||
afd
|
||||
afd
|
||||
aTz
|
||||
afd
|
||||
aTz
|
||||
aTz
|
||||
fqh
|
||||
bOR
|
||||
gyQ
|
||||
|
||||
@@ -28019,6 +28019,34 @@
|
||||
icon_state = "neutralfull"
|
||||
},
|
||||
/area/station/hallway/primary/port/north)
|
||||
"bDD" = (
|
||||
/obj/item/disk/nuclear/training{
|
||||
pixel_y = -2;
|
||||
pixel_x = -7
|
||||
},
|
||||
/obj/structure/table/reinforced,
|
||||
/obj/item/paper/nuclear_guide_spacing{
|
||||
pixel_x = 10;
|
||||
pixel_y = 7
|
||||
},
|
||||
/obj/item/paper/nuclear_guide_defusing{
|
||||
pixel_x = 9;
|
||||
pixel_y = 4
|
||||
},
|
||||
/obj/item/disk/nuclear/training{
|
||||
pixel_x = -5
|
||||
},
|
||||
/obj/item/paper/nuclear_guide_operating{
|
||||
pixel_x = 8;
|
||||
pixel_y = 1
|
||||
},
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/on{
|
||||
dir = 1
|
||||
},
|
||||
/obj/machinery/alarm/directional/south,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"bDE" = (
|
||||
/obj/item/kirbyplants,
|
||||
/obj/machinery/status_display{
|
||||
@@ -35212,7 +35240,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply,
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers,
|
||||
/obj/structure/table,
|
||||
/obj/machinery/syndicatebomb/training,
|
||||
/obj/item/toy/figure/crew/secofficer,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
@@ -40235,6 +40263,16 @@
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"cju" = (
|
||||
/obj/machinery/syndicatebomb/training,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"cjv" = (
|
||||
/obj/structure/window/reinforced{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/security/range)
|
||||
"cjw" = (
|
||||
/obj/structure/table/reinforced,
|
||||
/obj/machinery/recharger{
|
||||
pixel_x = -6;
|
||||
@@ -40247,27 +40285,8 @@
|
||||
pixel_x = 7;
|
||||
pixel_y = 3
|
||||
},
|
||||
/obj/machinery/atmospherics/unary/vent_pump/on,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"cjv" = (
|
||||
/obj/structure/window/reinforced{
|
||||
dir = 8
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/security/range)
|
||||
"cjw" = (
|
||||
/obj/structure/sign/securearea{
|
||||
pixel_y = 32
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/security/range)
|
||||
"cjx" = (
|
||||
/obj/machinery/light{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/security/range)
|
||||
"cjy" = (
|
||||
/obj/machinery/atmospherics/unary/vent_pump/on,
|
||||
/turf/simulated/floor/plating,
|
||||
@@ -40863,9 +40882,6 @@
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 8
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 4
|
||||
},
|
||||
@@ -40901,10 +40917,13 @@
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{
|
||||
dir = 1
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/manifold/hidden/supply,
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"clf" = (
|
||||
@@ -41413,7 +41432,6 @@
|
||||
icon_state = "1-2"
|
||||
},
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/effect/turf_decal/stripes/line,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"cmC" = (
|
||||
@@ -41437,18 +41455,8 @@
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/security/range)
|
||||
"cmF" = (
|
||||
/obj/structure/table/reinforced,
|
||||
/obj/machinery/alarm/directional/south,
|
||||
/obj/item/gun/energy/laser/practice,
|
||||
/obj/item/gun/energy/laser/practice,
|
||||
/obj/item/clothing/ears/earmuffs,
|
||||
/obj/item/clothing/ears/earmuffs,
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/on{
|
||||
dir = 1
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 6
|
||||
},
|
||||
/obj/machinery/nuclearbomb/training,
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"cmG" = (
|
||||
@@ -44275,13 +44283,6 @@
|
||||
icon_state = "neutralfull"
|
||||
},
|
||||
/area/station/hallway/primary/starboard/south)
|
||||
"cut" = (
|
||||
/obj/machinery/light,
|
||||
/obj/structure/sign/securearea{
|
||||
pixel_y = -32
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/security/range)
|
||||
"cuu" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 4
|
||||
@@ -59862,6 +59863,14 @@
|
||||
icon_state = "whitebluefull"
|
||||
},
|
||||
/area/station/maintenance/starboard)
|
||||
"dxV" = (
|
||||
/obj/structure/table/reinforced,
|
||||
/obj/item/gun/energy/laser/practice,
|
||||
/obj/item/gun/energy/laser/practice,
|
||||
/obj/item/clothing/ears/earmuffs,
|
||||
/obj/item/clothing/ears/earmuffs,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"dyb" = (
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/maintenance/theatre)
|
||||
@@ -67079,6 +67088,23 @@
|
||||
/obj/structure/cable,
|
||||
/turf/simulated/floor/plasteel/white,
|
||||
/area/station/science/explab)
|
||||
"eOg" = (
|
||||
/obj/structure/table/reinforced,
|
||||
/obj/machinery/atmospherics/unary/vent_pump/on,
|
||||
/obj/item/clothing/head/welding{
|
||||
pixel_x = 9;
|
||||
pixel_y = 10
|
||||
},
|
||||
/obj/item/multitool{
|
||||
pixel_x = -6;
|
||||
pixel_y = 8
|
||||
},
|
||||
/obj/item/storage/toolbox/mechanical{
|
||||
pixel_y = -2;
|
||||
pixel_x = -3
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"eOt" = (
|
||||
/obj/structure/table/glass,
|
||||
/obj/structure/cable{
|
||||
@@ -69896,6 +69922,19 @@
|
||||
dir = 5
|
||||
},
|
||||
/area/space/nearstation)
|
||||
"gAP" = (
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/manifold/hidden/supply,
|
||||
/obj/machinery/atmospherics/pipe/manifold/hidden/scrubbers{
|
||||
dir = 1
|
||||
},
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"gAR" = (
|
||||
/obj/structure/closet/wardrobe/pjs,
|
||||
/obj/structure/cable{
|
||||
@@ -80599,7 +80638,6 @@
|
||||
"ngl" = (
|
||||
/obj/structure/table,
|
||||
/obj/item/storage/fancy/donut_box,
|
||||
/obj/item/toy/figure/crew/secofficer,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "dark"
|
||||
},
|
||||
@@ -87511,9 +87549,6 @@
|
||||
/area/station/maintenance/starboard)
|
||||
"rjL" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/structure/transit_tube/cap{
|
||||
dir = 8
|
||||
},
|
||||
/obj/item/radio/intercom{
|
||||
name = "south bump";
|
||||
pixel_y = -28
|
||||
@@ -92501,7 +92536,8 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/range)
|
||||
"tVV" = (
|
||||
/turf/simulated/floor/plasteel{
|
||||
@@ -97302,9 +97338,7 @@
|
||||
/obj/machinery/ai_status_display{
|
||||
pixel_y = -32
|
||||
},
|
||||
/obj/structure/transit_tube/station{
|
||||
dir = 1
|
||||
},
|
||||
/obj/structure/transit_tube/station/reverse/flipped,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 8;
|
||||
icon_state = "vault"
|
||||
@@ -152270,9 +152304,9 @@ cgr
|
||||
hFc
|
||||
cgr
|
||||
jIs
|
||||
cjv
|
||||
iCU
|
||||
cjv
|
||||
eOg
|
||||
gAP
|
||||
bDD
|
||||
cjr
|
||||
brS
|
||||
bHF
|
||||
@@ -152529,7 +152563,7 @@ ccL
|
||||
jIs
|
||||
cjw
|
||||
tVO
|
||||
cjz
|
||||
dxV
|
||||
cjr
|
||||
eeN
|
||||
lnU
|
||||
@@ -152784,9 +152818,9 @@ ccM
|
||||
ceC
|
||||
cgo
|
||||
jIs
|
||||
cjx
|
||||
tVO
|
||||
cut
|
||||
cjv
|
||||
iCU
|
||||
cjv
|
||||
cjr
|
||||
cpa
|
||||
cqI
|
||||
|
||||
@@ -806,9 +806,6 @@
|
||||
/turf/simulated/wall,
|
||||
/area/station/public/arcade)
|
||||
"ajb" = (
|
||||
/obj/machinery/computer/mob_battle_terminal/red{
|
||||
pixel_y = 30
|
||||
},
|
||||
/obj/item/kirbyplants/plant20,
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "darkgrey"
|
||||
@@ -3389,9 +3386,6 @@
|
||||
name = "east bump";
|
||||
pixel_x = 27
|
||||
},
|
||||
/obj/machinery/computer/mob_battle_terminal/blue{
|
||||
pixel_y = -30
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "darkgrey"
|
||||
},
|
||||
@@ -8848,7 +8842,7 @@
|
||||
id = "engsm";
|
||||
name = "Radiation Shutters Control";
|
||||
pixel_x = 24;
|
||||
req_access_txt = "10"
|
||||
req_access_txt = "32"
|
||||
},
|
||||
/obj/effect/turf_decal/stripes/line{
|
||||
dir = 4
|
||||
@@ -19452,10 +19446,12 @@
|
||||
/turf/simulated/floor/wood,
|
||||
/area/station/command/office/captain/bedroom)
|
||||
"bsI" = (
|
||||
/obj/structure/transit_tube/station,
|
||||
/obj/structure/sign/securearea{
|
||||
pixel_y = 32
|
||||
},
|
||||
/obj/structure/transit_tube/station/reverse/flipped{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 4;
|
||||
icon_state = "darkbluecorners"
|
||||
@@ -47045,13 +47041,25 @@
|
||||
/turf/simulated/floor/wood,
|
||||
/area/station/service/bar)
|
||||
"exm" = (
|
||||
/obj/effect/spawner/window/reinforced/grilled,
|
||||
/obj/structure/cable{
|
||||
d2 = 8;
|
||||
icon_state = "0-8"
|
||||
/obj/machinery/door/airlock/security/glass,
|
||||
/obj/effect/mapping_helpers/airlock/autoname,
|
||||
/obj/effect/mapping_helpers/airlock/access/any/security/general,
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 4
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/security/main)
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 4
|
||||
},
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "redfull"
|
||||
},
|
||||
/area/station/security/defusal)
|
||||
"exI" = (
|
||||
/obj/structure/table/glass,
|
||||
/obj/item/hand_labeler,
|
||||
@@ -48607,6 +48615,37 @@
|
||||
},
|
||||
/turf/simulated/floor/carpet,
|
||||
/area/station/legal/lawoffice)
|
||||
"ffH" = (
|
||||
/obj/item/disk/nuclear/training{
|
||||
pixel_y = -2;
|
||||
pixel_x = -7
|
||||
},
|
||||
/obj/item/paper/nuclear_guide_spacing{
|
||||
pixel_x = 10;
|
||||
pixel_y = 7
|
||||
},
|
||||
/obj/item/paper/nuclear_guide_defusing{
|
||||
pixel_x = 9;
|
||||
pixel_y = 4
|
||||
},
|
||||
/obj/item/disk/nuclear/training{
|
||||
pixel_x = -5
|
||||
},
|
||||
/obj/item/paper/nuclear_guide_operating{
|
||||
pixel_x = 8;
|
||||
pixel_y = 1
|
||||
},
|
||||
/obj/structure/table,
|
||||
/obj/machinery/camera{
|
||||
c_tag = "Defusal Workshop"
|
||||
},
|
||||
/obj/machinery/firealarm{
|
||||
dir = 4;
|
||||
pixel_x = 24;
|
||||
name = "east bump"
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/defusal)
|
||||
"fga" = (
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/structure/disposalpipe/segment{
|
||||
@@ -49977,6 +50016,24 @@
|
||||
/obj/effect/decal/cleanable/blood,
|
||||
/turf/simulated/floor/bluegrid,
|
||||
/area/station/maintenance/starboard)
|
||||
"fFo" = (
|
||||
/obj/structure/table,
|
||||
/obj/item/radio/intercom{
|
||||
name = "south bump";
|
||||
pixel_y = -28
|
||||
},
|
||||
/obj/item/clothing/head/welding{
|
||||
pixel_x = -4;
|
||||
pixel_y = 19
|
||||
},
|
||||
/obj/item/multitool{
|
||||
pixel_x = 7;
|
||||
pixel_y = 13
|
||||
},
|
||||
/obj/item/storage/toolbox/mechanical,
|
||||
/obj/machinery/alarm/directional/east,
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/defusal)
|
||||
"fFL" = (
|
||||
/obj/machinery/atmospherics/meter,
|
||||
/obj/machinery/atmospherics/pipe/simple/visible/yellow,
|
||||
@@ -50222,12 +50279,12 @@
|
||||
/area/station/hallway/primary/central/north)
|
||||
"fJr" = (
|
||||
/obj/machinery/disposal,
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/obj/structure/disposalpipe/trunk,
|
||||
/obj/structure/cable{
|
||||
d1 = 1;
|
||||
d2 = 8;
|
||||
icon_state = "1-8"
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
icon_state = "darkred"
|
||||
},
|
||||
@@ -53400,9 +53457,6 @@
|
||||
/obj/structure/table,
|
||||
/obj/item/stack/medical/bruise_pack,
|
||||
/obj/item/stack/medical/ointment,
|
||||
/obj/machinery/computer/mob_healer_terminal{
|
||||
pixel_y = 30
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 1;
|
||||
icon_state = "whiteblue"
|
||||
@@ -53831,9 +53885,6 @@
|
||||
},
|
||||
/area/station/medical/virology)
|
||||
"hkm" = (
|
||||
/obj/structure/transit_tube/cap{
|
||||
dir = 4
|
||||
},
|
||||
/obj/machinery/status_display{
|
||||
layer = 4;
|
||||
pixel_y = 32
|
||||
@@ -59778,6 +59829,23 @@
|
||||
"jKj" = (
|
||||
/turf/simulated/wall/r_wall,
|
||||
/area/station/engineering/ai_transit_tube)
|
||||
"jKG" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 9
|
||||
},
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 10
|
||||
},
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
icon_state = "4-8"
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 8;
|
||||
icon_state = "red"
|
||||
},
|
||||
/area/station/security/defusal)
|
||||
"jKP" = (
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 4
|
||||
@@ -60579,6 +60647,14 @@
|
||||
},
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/medical/virology)
|
||||
"jXY" = (
|
||||
/obj/machinery/nuclearbomb/training,
|
||||
/obj/machinery/atmospherics/unary/vent_scrubber/on,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 8;
|
||||
icon_state = "red"
|
||||
},
|
||||
/area/station/security/defusal)
|
||||
"jYj" = (
|
||||
/obj/machinery/atmospherics/pipe/manifold/visible/cyan{
|
||||
dir = 8;
|
||||
@@ -66792,7 +66868,7 @@
|
||||
name = "Supermatter Engine Room"
|
||||
},
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
|
||||
/obj/effect/mapping_helpers/airlock/access/any/engineering/general,
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
@@ -66801,6 +66877,7 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/supply{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/mapping_helpers/airlock/access/any/engineering/atmos,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/engineering/control)
|
||||
"mCX" = (
|
||||
@@ -69551,6 +69628,9 @@
|
||||
/obj/effect/mapping_helpers/airlock/access/all/engineering/external,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/engineering/control)
|
||||
"nEV" = (
|
||||
/turf/simulated/wall/r_wall,
|
||||
/area/station/security/defusal)
|
||||
"nFf" = (
|
||||
/obj/structure/table/glass,
|
||||
/obj/item/reagent_containers/dropper,
|
||||
@@ -72815,7 +72895,6 @@
|
||||
name = "Supermatter Engine Room"
|
||||
},
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/effect/mapping_helpers/airlock/access/all/engineering/general,
|
||||
/obj/structure/cable{
|
||||
d1 = 4;
|
||||
d2 = 8;
|
||||
@@ -72824,6 +72903,8 @@
|
||||
/obj/machinery/atmospherics/pipe/simple/hidden/scrubbers{
|
||||
dir = 4
|
||||
},
|
||||
/obj/effect/mapping_helpers/airlock/access/any/engineering/general,
|
||||
/obj/effect/mapping_helpers/airlock/access/any/engineering/atmos,
|
||||
/turf/simulated/floor/plating,
|
||||
/area/station/engineering/control)
|
||||
"pgs" = (
|
||||
@@ -79389,6 +79470,21 @@
|
||||
icon_state = "dark"
|
||||
},
|
||||
/area/station/security/permabrig)
|
||||
"rOj" = (
|
||||
/obj/machinery/syndicatebomb/training,
|
||||
/obj/machinery/light_switch{
|
||||
dir = 4;
|
||||
name = "west bump";
|
||||
pixel_x = -24
|
||||
},
|
||||
/obj/machinery/atmospherics/unary/vent_pump/on{
|
||||
dir = 1
|
||||
},
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 8;
|
||||
icon_state = "red"
|
||||
},
|
||||
/area/station/security/defusal)
|
||||
"rOp" = (
|
||||
/obj/machinery/door/airlock/tranquillite{
|
||||
name = "Old Mime's Storage"
|
||||
@@ -79617,6 +79713,22 @@
|
||||
icon_state = "whitebluefull"
|
||||
},
|
||||
/area/station/medical/exam_room)
|
||||
"rUg" = (
|
||||
/obj/structure/table,
|
||||
/obj/machinery/light{
|
||||
dir = 4
|
||||
},
|
||||
/obj/item/book/manual/wiki/hacking{
|
||||
pixel_x = 3;
|
||||
pixel_y = 3
|
||||
},
|
||||
/obj/machinery/power/apc/directional/east,
|
||||
/obj/structure/cable{
|
||||
d2 = 8;
|
||||
icon_state = "0-8"
|
||||
},
|
||||
/turf/simulated/floor/plasteel,
|
||||
/area/station/security/defusal)
|
||||
"rUl" = (
|
||||
/obj/structure/lattice/catwalk,
|
||||
/obj/machinery/atmospherics/pipe/simple/heat_exchanging{
|
||||
@@ -83836,10 +83948,6 @@
|
||||
icon_state = "cafeteria"
|
||||
},
|
||||
/area/station/service/kitchen)
|
||||
"tNe" = (
|
||||
/obj/effect/spawner/random_spawners/wall_rusted_probably,
|
||||
/turf/simulated/wall/r_wall,
|
||||
/area/station/maintenance/fore)
|
||||
"tNg" = (
|
||||
/obj/machinery/door/firedoor,
|
||||
/turf/simulated/floor/plasteel{
|
||||
@@ -88708,15 +88816,6 @@
|
||||
},
|
||||
/area/station/medical/surgery/observation)
|
||||
"vVR" = (
|
||||
/obj/structure/table,
|
||||
/obj/item/screwdriver{
|
||||
pixel_x = -2;
|
||||
pixel_y = 18
|
||||
},
|
||||
/obj/item/wirecutters{
|
||||
pixel_y = 5
|
||||
},
|
||||
/obj/machinery/syndicatebomb/training,
|
||||
/turf/simulated/floor/plasteel{
|
||||
dir = 8;
|
||||
icon_state = "red"
|
||||
@@ -124925,7 +125024,7 @@ aaa
|
||||
aaa
|
||||
laH
|
||||
aaa
|
||||
apO
|
||||
sRw
|
||||
fJr
|
||||
hwP
|
||||
vgv
|
||||
@@ -125183,11 +125282,11 @@ aaa
|
||||
laH
|
||||
abq
|
||||
apO
|
||||
jSU
|
||||
apO
|
||||
nEV
|
||||
nEV
|
||||
exm
|
||||
apO
|
||||
apO
|
||||
nEV
|
||||
nEV
|
||||
xyP
|
||||
apO
|
||||
apO
|
||||
@@ -125440,11 +125539,11 @@ aaa
|
||||
aaa
|
||||
aaa
|
||||
laH
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
tNe
|
||||
nEV
|
||||
jXY
|
||||
jKG
|
||||
rOj
|
||||
nEV
|
||||
oQV
|
||||
ajg
|
||||
jiR
|
||||
@@ -125697,11 +125796,11 @@ aaa
|
||||
aaa
|
||||
aaa
|
||||
laH
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
ahH
|
||||
nEV
|
||||
ffH
|
||||
rUg
|
||||
fFo
|
||||
nEV
|
||||
alW
|
||||
akR
|
||||
aDY
|
||||
@@ -125954,11 +126053,11 @@ aaa
|
||||
aaa
|
||||
aaa
|
||||
laH
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
aaa
|
||||
ahH
|
||||
nEV
|
||||
nEV
|
||||
nEV
|
||||
nEV
|
||||
nEV
|
||||
aDY
|
||||
wLB
|
||||
cnV
|
||||
@@ -126216,8 +126315,8 @@ abq
|
||||
abq
|
||||
abq
|
||||
ajg
|
||||
ajg
|
||||
aVY
|
||||
ahH
|
||||
ahH
|
||||
ajg
|
||||
aWv
|
||||
cXu
|
||||
|
||||
@@ -141,6 +141,9 @@
|
||||
|
||||
//LAVALAND
|
||||
#define LAVALAND_EQUIPMENT_EFFECT_PRESSURE 50 //what pressure you have to be under to increase the effect of equipment meant for lavaland
|
||||
#define LAVALAND_TEMPERATURE 500
|
||||
#define LAVALAND_OXYGEN 8
|
||||
#define LAVALAND_NITROGEN 14
|
||||
|
||||
// Reactions
|
||||
#define N2O_DECOMPOSITION_MIN_ENERGY 1400
|
||||
|
||||
@@ -28,12 +28,13 @@
|
||||
#define BOT_EAT_TILE 19 // adding said tiles to inventory (floorbots)
|
||||
|
||||
//Bot types
|
||||
#define SEC_BOT (1<<0) // Secutritrons (Beepsky) and ED-209s
|
||||
#define MULE_BOT (1<<1) // MULEbots
|
||||
#define FLOOR_BOT (1<<2) // Floorbots
|
||||
#define CLEAN_BOT (1<<3) // Cleanbots
|
||||
#define MED_BOT (1<<4) // Medibots
|
||||
#define HONK_BOT (1<<5) // Honkbots
|
||||
#define SEC_BOT "Security" // Secutritrons (Beepsky) and ED-209s
|
||||
#define MULE_BOT "Mule" // MULEbots
|
||||
#define FLOOR_BOT "Floorbot" // Floorbots
|
||||
#define CLEAN_BOT "Cleanbot" // Cleanbots
|
||||
#define MED_BOT "Medibot" // Medibots
|
||||
#define HONK_BOT "Honkbot" // Honkbots
|
||||
#define GRIEF_BOT "Grief" // Griefsky
|
||||
|
||||
//Sentience types
|
||||
#define SENTIENCE_ORGANIC 1
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
//Damage things //TODO: merge these down to reduce on defines
|
||||
//Way to waste perfectly good damagetype names (BRUTE) on this... If you were really worried about case sensitivity, you could have just used lowertext(damagetype) in the proc...
|
||||
#define CUT "cut"
|
||||
#define BRUISE "bruise"
|
||||
#define BRUTE "brute"
|
||||
#define BURN "fire"
|
||||
#define TOX "tox"
|
||||
|
||||
@@ -342,6 +342,8 @@
|
||||
#define COMSIG_MIND_TRANSER_TO "mind_transfer_to"
|
||||
///called on the mob instead of the mind
|
||||
#define COMSIG_BODY_TRANSFER_TO "body_transfer_to"
|
||||
///called when the mind is initialized (called every time the mob logins)
|
||||
#define COMSIG_MIND_INITIALIZE "mind_initialize"
|
||||
|
||||
// /mob signals
|
||||
|
||||
@@ -717,9 +719,12 @@
|
||||
|
||||
// /obj/item/gun signals
|
||||
|
||||
/// called in /obj/item/gun/process_fire (user, target, params, zone_override)
|
||||
#define COMSIG_MOB_FIRED_GUN "mob_fired_gun"
|
||||
/// called in /obj/item/gun/process_fire (user, target)
|
||||
///called in /obj/item/gun/fire_gun (user, target, flag, params)
|
||||
#define COMSIG_GUN_TRY_FIRE "gun_try_fire"
|
||||
#define COMPONENT_CANCEL_GUN_FIRE (1<<0)
|
||||
///called in /obj/item/gun/afterattack (user, target, flag, params)
|
||||
#define COMSIG_MOB_TRY_FIRE "mob_fired_gun"
|
||||
///called in /obj/item/gun/process_fire (user, target)
|
||||
#define COMSIG_GUN_FIRED "gun_fired"
|
||||
/// called in /datum/component/automatic_fire/proc/on_mouse_down: (client/clicker, atom/target, turf/location, control, params)
|
||||
#define COMSIG_AUTOFIRE_ONMOUSEDOWN "autofire_onmousedown"
|
||||
|
||||
@@ -57,6 +57,8 @@
|
||||
#define EMOTE_TARGET_BHVR_RAW 4
|
||||
/// The emote target should be just a number. Anything else will be rejected.
|
||||
#define EMOTE_TARGET_BHVR_NUM 5
|
||||
/// The emote target is used elsewhere, and processing should be skipped.
|
||||
#define EMOTE_TARGET_BHVR_IGNORE 6
|
||||
|
||||
// This set determines the type of target that we want to check for.
|
||||
|
||||
@@ -75,3 +77,12 @@
|
||||
|
||||
/// List of emotes useable by ghosties
|
||||
#define USABLE_DEAD_EMOTES list("*flip", "*spin")
|
||||
|
||||
// Strings used for the rock paper scissors emote and status effect
|
||||
#define RPS_EMOTE_ROCK "rock"
|
||||
#define RPS_EMOTE_PAPER "paper"
|
||||
#define RPS_EMOTE_SCISSORS "scissors"
|
||||
|
||||
#define RPS_EMOTE_THEY_WIN "aww"
|
||||
#define RPS_EMOTE_WE_WIN "yay"
|
||||
#define RPS_EMOTE_TIE "tie"
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
// Used for secondary goals.
|
||||
/// Used for secondary goals.
|
||||
/// TOO easy, not accepted for variety goals.
|
||||
#define FOOD_GOAL_SKIP 0
|
||||
/// Easy food, ask for a lot for single goals.
|
||||
#define FOOD_GOAL_EASY 1
|
||||
/// Normal food, ask for a middling amount for single goals.
|
||||
#define FOOD_GOAL_NORMAL 2
|
||||
/// Hard reagent, ask for a little for single goals.
|
||||
#define FOOD_GOAL_HARD 3
|
||||
/// TOO hard, accepted for variety goals, but never used for single goals.
|
||||
#define FOOD_GOAL_EXCESSIVE 4
|
||||
/// Same as FOOD_GOAL_EXCESSIVE, just different name to indicate that there's another version of this food that's used in variety goals.
|
||||
#define FOOD_GOAL_DUPLICATE FOOD_GOAL_EXCESSIVE
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#define HIDES_COVERED_FULL 3
|
||||
#define PLATES_COVERED_FULL 3
|
||||
|
||||
#define DRAKE_HIDES_COVERED_SLIGHT 1
|
||||
#define DRAKE_HIDES_COVERED_MODERATE 2
|
||||
#define DRAKE_HIDES_COVERED_FULL 3
|
||||
@@ -250,6 +250,10 @@
|
||||
0.4,0.6,0.0,\
|
||||
0.2,0.2,0.6)
|
||||
|
||||
#define MATRIX_STANDARD list(1.0,0.0,0.0,\
|
||||
0.0,1.0,0.0,\
|
||||
0.0,0.0,1.0)
|
||||
|
||||
/*
|
||||
Used for wire name appearances. Replaces the color name on the left with the one on the right.
|
||||
The color on the left is the one used as the actual color of the wire, but it doesn't look good when written.
|
||||
@@ -398,7 +402,7 @@
|
||||
#define INVESTIGATE_BOMB "bombs"
|
||||
|
||||
// The SQL version required by this version of the code
|
||||
#define SQL_VERSION 55
|
||||
#define SQL_VERSION 56
|
||||
|
||||
// Vending machine stuff
|
||||
#define CAT_NORMAL (1<<0)
|
||||
|
||||
@@ -298,6 +298,7 @@
|
||||
#define HEALTH_HUD_OVERRIDE_HEALTHY 3
|
||||
// Eye protection
|
||||
#define FLASH_PROTECTION_VERYVUNERABLE -4
|
||||
#define FLASH_PROTECTION_EXTRA_SENSITIVE -2
|
||||
#define FLASH_PROTECTION_SENSITIVE -1
|
||||
#define FLASH_PROTECTION_NONE 0
|
||||
#define FLASH_PROTECTION_FLASH 1
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#define NANOMOB_TYPE_FIRE /datum/mob_type/fire
|
||||
#define NANOMOB_TYPE_WATER /datum/mob_type/water
|
||||
#define NANOMOB_TYPE_GRASS /datum/mob_type/grass
|
||||
#define NANOMOB_TYPE_ELECTRIC /datum/mob_type/electric
|
||||
#define NANOMOB_TYPE_GROUND /datum/mob_type/ground
|
||||
#define NANOMOB_TYPE_ROCK /datum/mob_type/rock
|
||||
#define NANOMOB_TYPE_BUG /datum/mob_type/bug
|
||||
#define NANOMOB_TYPE_POISON /datum/mob_type/poison
|
||||
#define NANOMOB_TYPE_NORMAL /datum/mob_type/normal
|
||||
#define NANOMOB_TYPE_FIGHTING /datum/mob_type/fighting
|
||||
#define NANOMOB_TYPE_PSYCHIC /datum/mob_type/psychic
|
||||
#define NANOMOB_TYPE_GHOST /datum/mob_type/ghost
|
||||
#define NANOMOB_TYPE_ICE /datum/mob_type/ice
|
||||
#define NANOMOB_TYPE_FLYING /datum/mob_type/flying
|
||||
#define NANOMOB_TYPE_BLUESPACE /datum/mob_type/bluespace
|
||||
#define NANOMOB_TYPE_DARK /datum/mob_type/dark
|
||||
#define NANOMOB_TYPE_STEEL /datum/mob_type/steel
|
||||
@@ -5,3 +5,16 @@
|
||||
#define DEBRIS_GLASS "glass"
|
||||
#define DEBRIS_LEAF "leaf"
|
||||
#define DEBRIS_SNOW "snow"
|
||||
|
||||
/*
|
||||
* Generator defines
|
||||
*/
|
||||
|
||||
#define GEN_NUM "num"
|
||||
#define GEN_VECTOR "vector"
|
||||
#define GEN_BOX "box"
|
||||
#define GEN_COLOR "color"
|
||||
#define GEN_CIRCLE "circle"
|
||||
#define GEN_SPHERE "sphere"
|
||||
#define GEN_SQUARE "square"
|
||||
#define GEN_CUBE "cube"
|
||||
|
||||
@@ -34,7 +34,13 @@
|
||||
#define BLOOD_TYPE_FAKE_BLOOD "Vh Null"
|
||||
|
||||
/// Used for secondary goals.
|
||||
/// TOO easy, not accepted for variety goals.
|
||||
#define REAGENT_GOAL_SKIP 0
|
||||
/// Easy reagent, ask for a lot for single goals.
|
||||
#define REAGENT_GOAL_EASY 1
|
||||
/// Normal reagent, ask for a middling amount for single goals.
|
||||
#define REAGENT_GOAL_NORMAL 2
|
||||
/// Hard reagent, ask for a little for single goals.
|
||||
#define REAGENT_GOAL_HARD 3
|
||||
/// TOO hard, accepted for variety goals, but never used for single goals.
|
||||
#define REAGENT_GOAL_EXCESSIVE 4
|
||||
|
||||
@@ -178,6 +178,7 @@
|
||||
#define STATUS_EFFECT_HIGHFIVE /datum/status_effect/high_five
|
||||
#define STATUS_EFFECT_DAP /datum/status_effect/high_five/dap
|
||||
#define STATUS_EFFECT_HANDSHAKE /datum/status_effect/high_five/handshake
|
||||
#define STATUS_EFFECT_RPS /datum/status_effect/high_five/rps
|
||||
|
||||
#define STATUS_EFFECT_CHARGING /datum/status_effect/charging
|
||||
|
||||
|
||||
@@ -91,7 +91,6 @@
|
||||
// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
|
||||
|
||||
#define FIRE_PRIORITY_PING 10
|
||||
#define FIRE_PRIORITY_NANOMOB 10
|
||||
#define FIRE_PRIORITY_NIGHTSHIFT 10
|
||||
#define FIRE_PRIORITY_IDLE_NPC 10
|
||||
#define FIRE_PRIORITY_CLEANUP 10
|
||||
|
||||
@@ -46,9 +46,11 @@
|
||||
#define WIRE_BOMB_ACTIVATE "Activate" // Will start a bombs timer if pulsed, will hint if pulsed while already active, will stop a timer a bomb on cut.
|
||||
|
||||
// Nuclear bomb
|
||||
#define WIRE_BOMB_LIGHT "Bomb Light"
|
||||
#define WIRE_BOMB_TIMING "Bomb Timing"
|
||||
#define WIRE_BOMB_SAFETY "Bomb Safety"
|
||||
#define WIRE_NUKE_SAFETY "Safety"
|
||||
#define WIRE_NUKE_DETONATOR "Detonator"
|
||||
#define WIRE_NUKE_DISARM "Disarm"
|
||||
#define WIRE_NUKE_LIGHT "Lights"
|
||||
#define WIRE_NUKE_CONTROL "Control Panel"
|
||||
|
||||
// Particle accelerator
|
||||
#define WIRE_PARTICLE_POWER "Power Toggle" // Toggles whether the PA is on or not.
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
///How the scope component is toggled.
|
||||
/// Wielding the object with both hands toggles the zoom. Requires the two-handed component to work.
|
||||
#define ZOOM_METHOD_WIELD 1
|
||||
/// Activated by clicking an item action button specified by the `item_action_type` var.
|
||||
#define ZOOM_METHOD_ITEM_ACTION 2
|
||||
@@ -223,6 +223,7 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
|
||||
#define TRAIT_CAN_VIEW_HEALTH "can_view_health" // Also used for /Stat
|
||||
#define TRAIT_MAGPULSE "magnetificent" // Used for anything that is magboot related
|
||||
#define TRAIT_NOSLIP "noslip"
|
||||
#define TRAIT_SCOPED "user_scoped"
|
||||
#define TRAIT_MEPHEDRONE_ADAPTED "mephedrone_adapted" // Trait that changes the ending effects of twitch leaving your system
|
||||
#define TRAIT_NOKNOCKDOWNSLOWDOWN "noknockdownslowdown" //If this person has this trait, they are not slowed via knockdown, but they can be hit by bullets like a self knockdown
|
||||
#define TRAIT_CAN_STRIP "can_strip" // This mob can strip other mobs.
|
||||
|
||||
@@ -35,6 +35,9 @@ GLOBAL_LIST_EMPTY(beacons)
|
||||
GLOBAL_LIST_EMPTY(shuttle_caller_list) //list of all communication consoles, comms consoles circuit and AIs, for automatic shuttle calls when there are none.
|
||||
GLOBAL_LIST_EMPTY(tracked_implants) //list of all current implants that are tracked to work out what sort of trek everyone is on. Sadly not on lavaworld not implemented...
|
||||
GLOBAL_LIST_EMPTY(pinpointer_list) //list of all pinpointers. Used to change stuff they are pointing to all at once.
|
||||
GLOBAL_LIST_EMPTY(nuke_list) //list of (real) nukes
|
||||
GLOBAL_LIST_EMPTY(syndi_nuke_list) //list of syndicate nukes
|
||||
GLOBAL_LIST_EMPTY(nad_list) //list of (real) nuclear authentication disks
|
||||
GLOBAL_LIST_EMPTY(nuclear_uplink_list) //list of all existing nuke ops uplinks
|
||||
GLOBAL_LIST_EMPTY(abductor_equipment) //list of all abductor equipment
|
||||
GLOBAL_LIST_EMPTY(global_intercoms) //list of all intercomms, across all z-levels
|
||||
|
||||
@@ -88,6 +88,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
|
||||
"TRAIT_FORCED_STANDING" = TRAIT_FORCED_STANDING,
|
||||
"TRAIT_NOSLIP" = TRAIT_NOSLIP,
|
||||
"TRAIT_MAGPULSE" = TRAIT_MAGPULSE,
|
||||
"TRAIT_SCOPED" = TRAIT_SCOPED,
|
||||
"TRAIT_MEPHEDRONE_ADAPTED" = TRAIT_MEPHEDRONE_ADAPTED,
|
||||
"TRAIT_NOKNOCKDOWNSLOWDOWN" = TRAIT_NOKNOCKDOWNSLOWDOWN,
|
||||
"TRAIT_CAN_STRIP" = TRAIT_CAN_STRIP
|
||||
|
||||
@@ -239,6 +239,8 @@ GLOBAL_LIST_EMPTY(radial_menus)
|
||||
return
|
||||
else
|
||||
next_check = world.time + check_delay
|
||||
// if you're wondering why your radial menus aren't clickable while debugging:
|
||||
// it's probably the stoplag call here, try it again without any breakpoints
|
||||
stoplag(1)
|
||||
|
||||
/datum/radial_menu/Destroy()
|
||||
|
||||
@@ -68,6 +68,7 @@ SUBSYSTEM_DEF(economy)
|
||||
var/credits_per_easy_food_goal = 300
|
||||
var/credits_per_normal_food_goal = 450
|
||||
var/credits_per_hard_food_goal = 600
|
||||
var/credits_per_variety_food_goal = 450
|
||||
var/credits_per_ripley_goal = 600
|
||||
var/credits_per_kudzu_goal = 600
|
||||
/// credits lost for sending unsecured cargo
|
||||
|
||||
@@ -1,155 +0,0 @@
|
||||
SUBSYSTEM_DEF(mob_hunt)
|
||||
name = "Nano-Mob Hunter GO Server"
|
||||
priority = FIRE_PRIORITY_NANOMOB // Low priority, no need for MC_TICK_CHECK due to extremely low performance impact.
|
||||
flags = SS_NO_INIT
|
||||
offline_implications = "Nano-Mob Hunter will no longer spawn mobs. No immediate action is needed."
|
||||
cpu_display = SS_CPUDISPLAY_LOW
|
||||
var/max_normal_spawns = 15 //change this to adjust the number of normal spawns that can exist at one time. trapped spawns (from traitors) don't count towards this
|
||||
var/list/normal_spawns = list()
|
||||
var/max_trap_spawns = 15 //change this to adjust the number of trap spawns that can exist at one time. traps spawned beyond this point clear the oldest traps
|
||||
var/list/trap_spawns = list()
|
||||
var/list/connected_clients = list()
|
||||
var/server_status = 1 //1 is online, 0 is offline
|
||||
var/reset_cooldown = 0 //number of controller cycles before the manual_reboot proc can be used again (ignored if server is offline so you can always boot back up)
|
||||
var/obj/machinery/computer/mob_battle_terminal/red_terminal
|
||||
var/obj/machinery/computer/mob_battle_terminal/blue_terminal
|
||||
var/battle_turn = null
|
||||
|
||||
/datum/controller/subsystem/mob_hunt/fire(resumed = FALSE)
|
||||
if(reset_cooldown) //if reset_cooldown is set (we are on cooldown, duh), reduce the remaining cooldown every cycle
|
||||
reset_cooldown--
|
||||
if(!server_status)
|
||||
return
|
||||
client_mob_update()
|
||||
if(length(normal_spawns) < max_normal_spawns)
|
||||
spawn_mob()
|
||||
|
||||
//leaving this here in case admins want to use it for a random mini-event or something
|
||||
/datum/controller/subsystem/mob_hunt/proc/server_crash(recover_time = 3000)
|
||||
server_status = 0
|
||||
for(var/datum/data/pda/app/mob_hunter_game/client in connected_clients)
|
||||
client.disconnect("Server Crash")
|
||||
for(var/obj/effect/nanomob/N in trap_spawns)
|
||||
N.despawn()
|
||||
for(var/obj/effect/nanomob/N in normal_spawns)
|
||||
N.despawn()
|
||||
//just in case
|
||||
normal_spawns.Cut()
|
||||
trap_spawns.Cut()
|
||||
connected_clients.Cut()
|
||||
if(!isnum(recover_time))
|
||||
recover_time = 3000
|
||||
if(recover_time > 0) //when provided with a negative or zero valued recover_time argument, the server won't auto-restart but can be manually rebooted still
|
||||
//set a timer to automatically recover after recover_time has passed (can be manually restarted if you get impatient too)
|
||||
addtimer(CALLBACK(src, PROC_REF(auto_recover)), recover_time, TIMER_UNIQUE)
|
||||
|
||||
/datum/controller/subsystem/mob_hunt/proc/client_mob_update()
|
||||
var/list/ex_players = list()
|
||||
for(var/datum/data/pda/app/mob_hunter_game/client in connected_clients)
|
||||
var/mob/living/carbon/human/H = client.get_player()
|
||||
if(connected_clients[client])
|
||||
if(!H || H != connected_clients[client])
|
||||
ex_players |= connected_clients[client]
|
||||
connected_clients[client] = H
|
||||
if(length(ex_players)) //to make sure we don't do this if we didn't lose any player since the last update
|
||||
for(var/obj/effect/nanomob/N in (normal_spawns + trap_spawns))
|
||||
N.conceal(ex_players)
|
||||
|
||||
/datum/controller/subsystem/mob_hunt/proc/auto_recover()
|
||||
if(server_status != 0)
|
||||
return
|
||||
server_status = 1
|
||||
while(length(normal_spawns) < max_normal_spawns) //repopulate the server's spawns completely if we auto-recover from crash
|
||||
spawn_mob()
|
||||
|
||||
/datum/controller/subsystem/mob_hunt/proc/manual_reboot()
|
||||
if(server_status && reset_cooldown)
|
||||
return 0
|
||||
for(var/obj/effect/nanomob/N in trap_spawns)
|
||||
N.despawn()
|
||||
for(var/obj/effect/nanomob/N in normal_spawns)
|
||||
N.despawn()
|
||||
server_status = 1
|
||||
reset_cooldown = 25 //25 controller cycle cooldown for manual restarts
|
||||
return 1
|
||||
|
||||
/datum/controller/subsystem/mob_hunt/proc/spawn_mob()
|
||||
var/list/nanomob_types = subtypesof(/datum/mob_hunt)
|
||||
var/datum/mob_hunt/mob_info = pick(nanomob_types)
|
||||
new mob_info()
|
||||
|
||||
/datum/controller/subsystem/mob_hunt/proc/register_spawn(datum/mob_hunt/mob_info)
|
||||
if(!mob_info)
|
||||
return 0
|
||||
var/obj/effect/nanomob/new_mob = new /obj/effect/nanomob(mob_info.spawn_point, mob_info)
|
||||
normal_spawns += new_mob
|
||||
new_mob.reveal()
|
||||
return 1
|
||||
|
||||
/datum/controller/subsystem/mob_hunt/proc/register_trap(datum/mob_hunt/mob_info)
|
||||
if(!mob_info)
|
||||
return 0
|
||||
if(!mob_info.is_trap)
|
||||
return register_spawn(mob_info)
|
||||
var/obj/effect/nanomob/new_mob = new /obj/effect/nanomob(mob_info.spawn_point, mob_info)
|
||||
trap_spawns += new_mob
|
||||
new_mob.reveal()
|
||||
if(length(trap_spawns) > max_trap_spawns)
|
||||
var/obj/effect/nanomob/old_trap = trap_spawns[1]
|
||||
old_trap.despawn()
|
||||
return 1
|
||||
|
||||
/datum/controller/subsystem/mob_hunt/proc/start_check()
|
||||
if(battle_turn) //somehow we got called mid-battle, so lets just stop now
|
||||
return
|
||||
if(red_terminal && red_terminal.ready && blue_terminal && blue_terminal.ready)
|
||||
battle_turn = pick("Red", "Blue")
|
||||
red_terminal.atom_say("Battle starting!")
|
||||
blue_terminal.atom_say("Battle starting!")
|
||||
if(battle_turn == "Red")
|
||||
red_terminal.atom_say("Red Player's Turn!")
|
||||
else if(battle_turn == "Blue")
|
||||
blue_terminal.atom_say("Blue Player's Turn!")
|
||||
|
||||
/datum/controller/subsystem/mob_hunt/proc/launch_attack(team, raw_damage, datum/mob_type/attack_type)
|
||||
if(!team || !raw_damage)
|
||||
return
|
||||
var/obj/machinery/computer/mob_battle_terminal/target = null
|
||||
if(team == "Red")
|
||||
target = blue_terminal
|
||||
else if(team == "Blue")
|
||||
target = red_terminal
|
||||
else
|
||||
return
|
||||
target.receive_attack(raw_damage, attack_type)
|
||||
|
||||
/datum/controller/subsystem/mob_hunt/proc/end_battle(loser, surrender = 0)
|
||||
var/obj/machinery/computer/mob_battle_terminal/winner_terminal = null
|
||||
var/obj/machinery/computer/mob_battle_terminal/loser_terminal = null
|
||||
if(loser == "Red")
|
||||
loser_terminal = red_terminal
|
||||
winner_terminal = blue_terminal
|
||||
else if(loser == "Blue")
|
||||
loser_terminal = blue_terminal
|
||||
winner_terminal = red_terminal
|
||||
battle_turn = null
|
||||
winner_terminal.ready = FALSE
|
||||
loser_terminal.ready = FALSE
|
||||
if(surrender) //surrender doesn't give exp, to avoid people just farming exp without actually doing a battle
|
||||
winner_terminal.atom_say("Your rival surrendered!")
|
||||
else
|
||||
var/progress_message = winner_terminal.mob_info.gain_exp()
|
||||
winner_terminal.atom_say("[winner_terminal.team] Player wins!")
|
||||
winner_terminal.atom_say(progress_message)
|
||||
|
||||
/datum/controller/subsystem/mob_hunt/proc/end_turn()
|
||||
red_terminal.updateUsrDialog()
|
||||
blue_terminal.updateUsrDialog()
|
||||
if(!battle_turn)
|
||||
return
|
||||
if(battle_turn == "Red")
|
||||
battle_turn = "Blue"
|
||||
blue_terminal.atom_say("Blue's turn.")
|
||||
else if(battle_turn == "Blue")
|
||||
battle_turn = "Red"
|
||||
blue_terminal.atom_say("Red's turn.")
|
||||
@@ -38,6 +38,8 @@ SUBSYSTEM_DEF(shuttle)
|
||||
var/custom_escape_shuttle_loading = FALSE
|
||||
/// Whether or not a shuttle is currently being loaded at the template landmark, if it exists.
|
||||
var/loading_shuttle_at_preview_template = FALSE
|
||||
/// Have we locked in the emergency shuttle, to prevent people from breaking things / wasting player money?
|
||||
var/emergency_locked_in = FALSE
|
||||
|
||||
/datum/controller/subsystem/shuttle/Initialize()
|
||||
if(!emergency)
|
||||
@@ -316,6 +318,8 @@ SUBSYSTEM_DEF(shuttle)
|
||||
if(loading_shuttle_at_preview_template)
|
||||
CRASH("A shuttle was already loading at the preview template when another was loaded")
|
||||
|
||||
S.preload()
|
||||
|
||||
loading_shuttle_at_preview_template = TRUE
|
||||
var/turf/landmark_turf = get_turf(locate("landmark*Shuttle Import"))
|
||||
S.load(landmark_turf, centered = TRUE)
|
||||
@@ -377,6 +381,8 @@ SUBSYSTEM_DEF(shuttle)
|
||||
timer = emergency.timer
|
||||
mode = emergency.mode
|
||||
dock = emergency.get_docked()
|
||||
if(!dock) //lance moment
|
||||
dock = getDock("emergency_away")
|
||||
else
|
||||
dock = loaded_shuttle.findRoundstartDock()
|
||||
|
||||
|
||||
@@ -78,6 +78,8 @@
|
||||
/datum/action/proc/Trigger(left_click = TRUE)
|
||||
if(!IsAvailable())
|
||||
return FALSE
|
||||
if(SEND_SIGNAL(src, COMSIG_ACTION_TRIGGER, src) & COMPONENT_ACTION_BLOCK_TRIGGER)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/action/proc/AltTrigger()
|
||||
@@ -570,7 +572,6 @@
|
||||
var/obj/item/clothing/shoes/magboots/gravity/G = target
|
||||
G.dash(usr)
|
||||
|
||||
|
||||
///prset for organ actions
|
||||
/datum/action/item_action/organ_action
|
||||
check_flags = AB_CHECK_CONSCIOUS
|
||||
|
||||
@@ -3,35 +3,6 @@
|
||||
* Originally from https://github.com/tgstation/TerraGov-Marine-Corps/pull/12752
|
||||
*/
|
||||
|
||||
/particles/debris
|
||||
icon = 'icons/effects/particles/generic_particles.dmi'
|
||||
width = 500
|
||||
height = 500
|
||||
count = 10
|
||||
spawning = 10
|
||||
lifespan = 0.5 SECONDS
|
||||
fade = 0.3 SECONDS
|
||||
drift = generator("circle", 0, 7)
|
||||
scale = 0.3
|
||||
velocity = list(50, 0)
|
||||
friction = generator("num", 0.1, 0.15)
|
||||
spin = generator("num", -20, 20)
|
||||
|
||||
/particles/impact_smoke
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "smoke"
|
||||
width = 500
|
||||
height = 500
|
||||
count = 20
|
||||
spawning = 20
|
||||
lifespan = 0.8 SECONDS
|
||||
fade = 10 SECONDS
|
||||
grow = 0.1
|
||||
scale = 0.2
|
||||
spin = generator("num", -20, 20)
|
||||
velocity = list(50, 0)
|
||||
friction = generator("num", 0.1, 0.5)
|
||||
|
||||
/datum/component/debris
|
||||
/// Icon state of debris when impacted by a projectile
|
||||
var/debris
|
||||
@@ -76,7 +47,7 @@
|
||||
|
||||
if(debris && P.damage_type == BRUTE)
|
||||
debris_visuals = new(parent, /particles/debris)
|
||||
debris_visuals.particles.position = generator("circle", position_offset, position_offset)
|
||||
debris_visuals.particles.position = generator(GEN_CIRCLE, position_offset, position_offset)
|
||||
debris_visuals.particles.velocity = list(x_component, y_component)
|
||||
debris_visuals.layer = ABOVE_OBJ_LAYER + 0.02
|
||||
debris_visuals.particles.icon_state = debris
|
||||
|
||||
@@ -262,6 +262,9 @@
|
||||
current_windup_reduction = (current_windup_reduction + round(autofire_shot_delay * windup_autofire_reduction_multiplier))
|
||||
timerid = addtimer(CALLBACK(src, PROC_REF(windup_reset), FALSE), windup_spindown, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_STOPPABLE)
|
||||
|
||||
if(shooter.next_move_modifier) //DNA vault, mephemdrone, bluespace slowness debuff.
|
||||
next_delay = round(next_delay * shooter.next_move_modifier, SSprojectiles.wait)
|
||||
|
||||
COOLDOWN_START(src, next_shot_cd, next_delay)
|
||||
|
||||
if(SEND_SIGNAL(parent, COMSIG_AUTOFIRE_SHOT, target, shooter, allow_akimbo, mouse_parameters) & COMPONENT_AUTOFIRE_SHOT_SUCCESS)
|
||||
|
||||
@@ -0,0 +1,273 @@
|
||||
///A component that allows players to use the item to zoom out. Mainly intended for firearms, but now works with other items too.
|
||||
/datum/component/scope
|
||||
/// How far the view can be moved from the player. At 1, it can be moved by the player's view distance; other values scale linearly.
|
||||
var/range_modifier = 1
|
||||
/// Fullscreen object we use for tracking.
|
||||
var/atom/movable/screen/fullscreen/stretch/cursor_catcher/scope/tracker
|
||||
/// The owner of the tracker's ckey. For comparing with the current owner mob, in case the client has left it (e.g. ghosted).
|
||||
var/tracker_owner_ckey
|
||||
/// The method which we zoom in and out
|
||||
var/zoom_method = ZOOM_METHOD_ITEM_ACTION
|
||||
/// if not null, an item action will be added. Redundant if the mode is ZOOM_METHOD_RIGHT_CLICK or ZOOM_METHOD_WIELD.
|
||||
var/item_action_type
|
||||
/// Time to scope up, if you want the scope to take time to boot up. Used by the LWAP
|
||||
var/time_to_scope
|
||||
/// Do we let the user scope and click on the middle of their screen?
|
||||
var/allow_middle_click = FALSE
|
||||
/// Do we have the scope cancel on move?
|
||||
var/movement_cancels_scope = FALSE
|
||||
|
||||
/datum/component/scope/Initialize(range_modifier = 1, zoom_method = ZOOM_METHOD_ITEM_ACTION, item_action_type = /datum/action/zoom, time_to_scope = 0, allow_middle_click = FALSE, movement_cancels_scope = FALSE)
|
||||
if(!isitem(parent))
|
||||
return COMPONENT_INCOMPATIBLE
|
||||
src.range_modifier = range_modifier
|
||||
src.zoom_method = zoom_method
|
||||
src.item_action_type = item_action_type
|
||||
src.time_to_scope = time_to_scope
|
||||
src.allow_middle_click = allow_middle_click
|
||||
src.movement_cancels_scope = movement_cancels_scope
|
||||
|
||||
|
||||
/datum/component/scope/Destroy(force)
|
||||
if(is_zoomed_in())
|
||||
stop_zooming(tracker.owner)
|
||||
return ..()
|
||||
|
||||
/datum/component/scope/RegisterWithParent()
|
||||
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, PROC_REF(on_move)) //Checks for being removed for person, not mob movement
|
||||
if(zoom_method == ZOOM_METHOD_WIELD)
|
||||
RegisterSignal(parent, SIGNAL_ADDTRAIT(TRAIT_WIELDED), PROC_REF(on_wielded))
|
||||
RegisterSignal(parent, SIGNAL_REMOVETRAIT(TRAIT_WIELDED), PROC_REF(on_unwielded))
|
||||
if(item_action_type)
|
||||
var/obj/item/parent_item = parent
|
||||
var/datum/action/scope = new item_action_type(parent)
|
||||
parent_item.actions += scope
|
||||
RegisterSignal(scope, COMSIG_ACTION_TRIGGER, PROC_REF(on_action_trigger))
|
||||
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine))
|
||||
if(istype(parent, /obj/item/gun))
|
||||
RegisterSignal(parent, COMSIG_GUN_TRY_FIRE, PROC_REF(on_gun_fire))
|
||||
|
||||
/datum/component/scope/UnregisterFromParent()
|
||||
if(item_action_type)
|
||||
var/obj/item/parent_item = parent
|
||||
var/datum/action/scope = locate(item_action_type) in parent_item.actions
|
||||
parent_item.actions -= scope
|
||||
UnregisterSignal(parent, list(
|
||||
COMSIG_MOVABLE_MOVED,
|
||||
SIGNAL_ADDTRAIT(TRAIT_WIELDED),
|
||||
SIGNAL_REMOVETRAIT(TRAIT_WIELDED),
|
||||
COMSIG_GUN_TRY_FIRE,
|
||||
COMSIG_PARENT_EXAMINE,
|
||||
))
|
||||
|
||||
/datum/component/scope/process()
|
||||
var/mob/user_mob = tracker.owner
|
||||
var/client/user_client = user_mob.client
|
||||
if(!user_client)
|
||||
stop_zooming(user_mob)
|
||||
return
|
||||
tracker.calculate_params()
|
||||
animate(user_client, world.tick_lag, pixel_x = tracker.given_x, pixel_y = tracker.given_y)
|
||||
|
||||
/datum/component/scope/proc/on_move(atom/movable/source, atom/oldloc, dir, forced)
|
||||
SIGNAL_HANDLER // COMSIG_MOVABLE_MOVED
|
||||
|
||||
if(!is_zoomed_in())
|
||||
return
|
||||
if(source.loc != tracker.owner) //Dropped.
|
||||
to_chat(tracker.owner, "<span class='warning'>[parent]'s scope is overloaded by movement and shuts down!</span>")
|
||||
stop_zooming(tracker.owner)
|
||||
|
||||
/datum/component/scope/proc/on_action_trigger(datum/action/source)
|
||||
SIGNAL_HANDLER // COMSIG_ACTION_TRIGGER
|
||||
var/obj/item/item = source.target
|
||||
var/mob/living/user = item.loc
|
||||
if(is_internal_organ(item))
|
||||
var/obj/item/organ/internal/O = item
|
||||
user = O.owner
|
||||
if(is_zoomed_in())
|
||||
stop_zooming(user)
|
||||
else
|
||||
INVOKE_ASYNC(src, PROC_REF(zoom), user)
|
||||
|
||||
/datum/component/scope/proc/on_wielded(obj/item/source, trait)
|
||||
SIGNAL_HANDLER // SIGNAL_ADDTRAIT(TRAIT_WIELDED)
|
||||
var/mob/living/user = source.loc
|
||||
INVOKE_ASYNC(src, PROC_REF(zoom), user)
|
||||
|
||||
/datum/component/scope/proc/on_unwielded(obj/item/source, trait)
|
||||
SIGNAL_HANDLER // SIGNAL_REMOVETRAIT(TRAIT_WIELDED)
|
||||
var/mob/living/user = source.loc
|
||||
stop_zooming(user)
|
||||
|
||||
/datum/component/scope/proc/on_gun_fire(obj/item/gun/source, mob/living/user, atom/target, flag, params)
|
||||
SIGNAL_HANDLER // COMSIG_GUN_TRY_FIRE
|
||||
if(!tracker?.given_turf || target == get_target(tracker.given_turf))
|
||||
return NONE
|
||||
INVOKE_ASYNC(source, TYPE_PROC_REF(/obj/item, afterattack), get_target(tracker.given_turf), user)
|
||||
return COMPONENT_CANCEL_GUN_FIRE
|
||||
|
||||
/datum/component/scope/proc/on_examine(datum/source, mob/user, list/examine_list)
|
||||
SIGNAL_HANDLER // COMSIG_PARENT_EXAMINE
|
||||
|
||||
var/scope = istype(parent, /obj/item/gun) ? "scope in" : "zoom out"
|
||||
switch(zoom_method)
|
||||
if(ZOOM_METHOD_WIELD)
|
||||
examine_list += "<span class='notice'>You can [scope] by wielding it with both hands.</span>"
|
||||
|
||||
/**
|
||||
* We find and return the best target to hit on a given turf.
|
||||
*
|
||||
* Arguments:
|
||||
* * target_turf: The turf we are looking for targets on.
|
||||
*/
|
||||
/datum/component/scope/proc/get_target(turf/target_turf)
|
||||
var/list/non_dense_targets = list()
|
||||
for(var/atom/movable/possible_target in target_turf)
|
||||
if(possible_target.layer <= PROJECTILE_HIT_THRESHHOLD_LAYER)
|
||||
continue
|
||||
if(possible_target.invisibility > tracker.owner.see_invisible)
|
||||
continue
|
||||
if(!possible_target.mouse_opacity)
|
||||
continue
|
||||
if(iseffect(possible_target))
|
||||
continue
|
||||
if(ismob(possible_target))
|
||||
if(possible_target == tracker.owner)
|
||||
continue
|
||||
return possible_target
|
||||
if(!possible_target.density)
|
||||
non_dense_targets += possible_target
|
||||
continue
|
||||
return possible_target
|
||||
if(length(non_dense_targets))
|
||||
return non_dense_targets[1]
|
||||
return target_turf
|
||||
|
||||
/**
|
||||
* We start zooming by adding our tracker overlay and starting our processing.
|
||||
*
|
||||
* Arguments:
|
||||
* * user: The mob we are starting zooming on.
|
||||
*/
|
||||
/datum/component/scope/proc/zoom(mob/user)
|
||||
if(isnull(user.client))
|
||||
return
|
||||
if(HAS_TRAIT(user, TRAIT_SCOPED))
|
||||
to_chat(user, "<span class='warning'>You are already zoomed in!</span>")
|
||||
return
|
||||
if(time_to_scope)
|
||||
if(!do_after_once(user, time_to_scope, target = parent))
|
||||
return
|
||||
user.playsound_local(parent, 'sound/weapons/scope.ogg', 75, TRUE)
|
||||
tracker = user.overlay_fullscreen("scope", /atom/movable/screen/fullscreen/stretch/cursor_catcher/scope, istype(parent, /obj/item/gun))
|
||||
tracker.assign_to_mob(user, range_modifier)
|
||||
if(movement_cancels_scope)
|
||||
RegisterSignal(user, COMSIG_MOVABLE_MOVED, PROC_REF(on_move))
|
||||
if(allow_middle_click)
|
||||
RegisterSignal(tracker, COMSIG_CLICK, PROC_REF(generic_click))
|
||||
tracker_owner_ckey = user.ckey
|
||||
if(user.is_holding(parent))
|
||||
RegisterSignals(user, list(COMSIG_CARBON_SWAP_HANDS, COMSIG_PARENT_QDELETING), PROC_REF(stop_zooming))
|
||||
else // The item is likely worn.
|
||||
RegisterSignal(user, COMSIG_PARENT_QDELETING, PROC_REF(stop_zooming))
|
||||
var/static/list/capacity_signals = list(
|
||||
COMSIG_LIVING_STATUS_PARALYSE,
|
||||
COMSIG_LIVING_STATUS_STUN,
|
||||
)
|
||||
RegisterSignals(user, capacity_signals, PROC_REF(on_incapacitated))
|
||||
START_PROCESSING(SSprojectiles, src)
|
||||
ADD_TRAIT(user, TRAIT_SCOPED, "[UID(src)]")
|
||||
if(istype(parent, /obj/item/gun))
|
||||
var/obj/item/gun/G = parent
|
||||
G.on_scope_success(user)
|
||||
return TRUE
|
||||
|
||||
/datum/component/scope/proc/on_incapacitated(mob/living/source, amount = 0, ignore_canstun = FALSE)
|
||||
SIGNAL_HANDLER // COMSIG_LIVING_STATUS_PARALYSE, COMSIG_LIVING_STATUS_STUN
|
||||
|
||||
if(amount > 0)
|
||||
stop_zooming(source)
|
||||
|
||||
/datum/component/scope/proc/generic_click(/obj/source, location, control, params)
|
||||
SIGNAL_HANDLER // COMSIG_CLICK
|
||||
INVOKE_ASYNC(tracker.owner, TYPE_PROC_REF(/mob, ClickOn), get_target(tracker.given_turf), params)
|
||||
|
||||
/**
|
||||
* We stop zooming, canceling processing, resetting stuff back to normal and deleting our tracker.
|
||||
*
|
||||
* Arguments:
|
||||
* * user: The mob we are canceling zooming on.
|
||||
*/
|
||||
/datum/component/scope/proc/stop_zooming(mob/user)
|
||||
SIGNAL_HANDLER // COMSIG_CARBON_SWAP_HANDS, COMSIG_PARENT_QDELETING
|
||||
|
||||
if(!HAS_TRAIT(user, TRAIT_SCOPED))
|
||||
return
|
||||
|
||||
STOP_PROCESSING(SSprojectiles, src)
|
||||
UnregisterSignal(user, list(
|
||||
COMSIG_LIVING_STATUS_PARALYSE,
|
||||
COMSIG_LIVING_STATUS_STUN,
|
||||
COMSIG_CARBON_SWAP_HANDS,
|
||||
COMSIG_PARENT_QDELETING,
|
||||
))
|
||||
REMOVE_TRAIT(user, TRAIT_SCOPED, "[UID(src)]")
|
||||
|
||||
user.playsound_local(parent, 'sound/weapons/scope.ogg', 75, TRUE, frequency = -1)
|
||||
user.clear_fullscreen("scope")
|
||||
|
||||
// if the client has ended up in another mob, find that mob so we can fix their cursor
|
||||
var/mob/true_user
|
||||
if(user.ckey != tracker_owner_ckey)
|
||||
true_user = get_mob_by_ckey(tracker_owner_ckey)
|
||||
|
||||
if(!isnull(true_user))
|
||||
user = true_user
|
||||
|
||||
if(user.client)
|
||||
animate(user.client, 0.2 SECONDS, pixel_x = 0, pixel_y = 0)
|
||||
UnregisterSignal(user, COMSIG_MOVABLE_MOVED)
|
||||
QDEL_NULL(tracker)
|
||||
tracker_owner_ckey = null
|
||||
if(istype(parent, /obj/item/gun))
|
||||
var/obj/item/gun/G = parent
|
||||
G.on_scope_end(user)
|
||||
|
||||
/datum/component/scope/proc/is_zoomed_in()
|
||||
return !!tracker
|
||||
|
||||
/atom/movable/screen/fullscreen/stretch/cursor_catcher/scope
|
||||
icon = 'icons/mob/screen_scope.dmi'
|
||||
icon_state = "scope"
|
||||
/// Multiplier for given_X an given_y.
|
||||
var/range_modifier = 1
|
||||
|
||||
/atom/movable/screen/fullscreen/stretch/cursor_catcher/scope/assign_to_mob(mob/new_owner, range_modifier)
|
||||
src.range_modifier = range_modifier
|
||||
return ..()
|
||||
|
||||
/atom/movable/screen/fullscreen/stretch/cursor_catcher/scope/Click(location, control, params)
|
||||
if(usr == owner)
|
||||
calculate_params()
|
||||
SEND_SIGNAL(src, COMSIG_CLICK, location, control, params)
|
||||
|
||||
return ..()
|
||||
|
||||
/atom/movable/screen/fullscreen/stretch/cursor_catcher/scope/calculate_params()
|
||||
var/list/modifiers = params2list(mouse_params)
|
||||
var/icon_x = text2num(LAZYACCESS(modifiers, "vis-x"))
|
||||
if(isnull(icon_x))
|
||||
icon_x = text2num(LAZYACCESS(modifiers, "icon-x"))
|
||||
var/icon_y = text2num(LAZYACCESS(modifiers, "vis-y"))
|
||||
if(isnull(icon_y))
|
||||
icon_y = text2num(LAZYACCESS(modifiers, "icon-y"))
|
||||
given_x = round(range_modifier * (icon_x - view_list[1] * world.icon_size / 2))
|
||||
given_y = round(range_modifier * (icon_y - view_list[2] * world.icon_size / 2))
|
||||
given_turf = locate(owner.x + round(given_x / world.icon_size, 1), owner.y + round(given_y / world.icon_size, 1), owner.z)
|
||||
|
||||
|
||||
/datum/action/zoom
|
||||
name = "Toggle Scope"
|
||||
check_flags = AB_CHECK_CONSCIOUS|AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_LYING
|
||||
button_icon_state = "sniper_zoom"
|
||||
@@ -951,6 +951,14 @@
|
||||
log_admin("[key_name(usr)] has added [amount] units of [chosen_id] to \the [A]")
|
||||
message_admins("<span class='notice'>[key_name(usr)] has added [amount] units of [chosen_id] to \the [A]</span>")
|
||||
|
||||
else if(href_list["editreagents"])
|
||||
if(!check_rights(R_DEBUG|R_ADMIN))
|
||||
return
|
||||
|
||||
var/atom/A = locateUID(href_list["editreagents"])
|
||||
|
||||
try_open_reagent_editor(A)
|
||||
|
||||
else if(href_list["explode"])
|
||||
if(!check_rights(R_DEBUG|R_EVENT)) return
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
/// Handles the actual shattering part, throwing shards of whatever is defined on the component everywhere
|
||||
/datum/element/shatters_when_thrown/proc/shatter(atom/movable/source, atom/hit_atom)
|
||||
var/generator/scatter_gen = generator("circle", 0, 48, NORMAL_RAND)
|
||||
var/generator/scatter_gen = generator(GEN_CIRCLE, 0, 48, NORMAL_RAND)
|
||||
var/scatter_turf = get_turf(hit_atom)
|
||||
|
||||
for(var/obj/item/scattered_item as anything in source.contents)
|
||||
|
||||
+21
-9
@@ -147,16 +147,16 @@
|
||||
*
|
||||
* Arguments:
|
||||
* * user - Person that is trying to send the emote.
|
||||
* * params - Parameters added after the emote.
|
||||
* * emote_arg - String parameter added after the emote.
|
||||
* * type_override - Override to the current emote_type.
|
||||
* * intentional - Bool that says whether the emote was forced (FALSE) or not (TRUE).
|
||||
*
|
||||
* Returns TRUE if it was able to run the emote, FALSE otherwise.
|
||||
*/
|
||||
/datum/emote/proc/run_emote(mob/user, params, type_override, intentional = FALSE)
|
||||
/datum/emote/proc/run_emote(mob/user, emote_arg, type_override, intentional = FALSE)
|
||||
. = TRUE
|
||||
var/msg = select_message_type(user, message, intentional)
|
||||
if(params && message_param)
|
||||
if(emote_arg && message_param)
|
||||
// In this case, we did make some changes to the message that will be used, and we want to add the postfix on with the new parameters.
|
||||
// This is applicable to things like mimes, who this lets have a target on their canned emote responses.
|
||||
// Note that we only do this if we would otherwise have a message param, meaning there should be some target by default.
|
||||
@@ -164,17 +164,17 @@
|
||||
if(message_param == EMOTE_PARAM_USE_POSTFIX || (msg != message && message_postfix))
|
||||
if(!message_postfix)
|
||||
CRASH("Emote was specified to use postfix but message_postfix is empty.")
|
||||
msg = select_param(user, params, "[remove_ending_punctuation(msg)] [message_postfix]", msg)
|
||||
msg = select_param(user, emote_arg, "[remove_ending_punctuation(msg)] [message_postfix]", msg)
|
||||
else if(msg == message)
|
||||
// In this case, we're not making any substitutions in select_message_type, but we do have some params we want to sub in.
|
||||
msg = select_param(user, params, message_param, message)
|
||||
msg = select_param(user, emote_arg, message_param, message)
|
||||
|
||||
// If this got propogated up, jump out.
|
||||
if(msg == EMOTE_ACT_STOP_EXECUTION)
|
||||
return TRUE
|
||||
|
||||
if(isnull(msg))
|
||||
to_chat(user, "<span class='warning'>'[params]' isn't a valid parameter for [key].</span>")
|
||||
to_chat(user, "<span class='warning'>'[emote_arg]' isn't a valid parameter for [key].</span>")
|
||||
return TRUE
|
||||
|
||||
msg = replace_pronoun(user, msg)
|
||||
@@ -230,13 +230,13 @@
|
||||
* Try to run an emote, checking can_run_emote once before executing the emote itself.
|
||||
*
|
||||
* * user - User of the emote
|
||||
* * params - Params of the emote to be passed to run_emote
|
||||
* * params - An optional extra argument included after the emote key.
|
||||
* * type_override - emote type to override the existing one with, if given.
|
||||
* * intentional - Whether or not the emote was triggered intentionally (if false, the emote was forced by code).
|
||||
*
|
||||
* Returns TRUE if the emote was able to be run (or failed successfully), or FALSE if the emote is unusable.
|
||||
*/
|
||||
/datum/emote/proc/try_run_emote(mob/user, params, type_override, intentional = FALSE)
|
||||
/datum/emote/proc/try_run_emote(mob/user, emote_arg, type_override, intentional = FALSE)
|
||||
// You can use this signal to block execution of emotes from components/other sources.
|
||||
var/sig_res = SEND_SIGNAL(user, COMSIG_MOB_PREEMOTE, key, intentional)
|
||||
switch(sig_res)
|
||||
@@ -245,9 +245,18 @@
|
||||
if(COMPONENT_BLOCK_EMOTE_SILENT)
|
||||
return TRUE
|
||||
|
||||
. = run_emote(user, params, type_override, intentional)
|
||||
. = run_emote(user, emote_arg, type_override, intentional)
|
||||
|
||||
// safeguard in case these get modified
|
||||
reset_emote()
|
||||
|
||||
/**
|
||||
* Reset the emote back to its original state.
|
||||
* Necessary if you've made modifications to the emote itself over the course of its
|
||||
* execution, as emotes are singletons, and changes would be reflected on every usage of the emote.
|
||||
*/
|
||||
/datum/emote/proc/reset_emote()
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
message = initial(message)
|
||||
message_param = initial(message_param)
|
||||
|
||||
@@ -421,6 +430,9 @@
|
||||
*/
|
||||
/datum/emote/proc/select_param(mob/user, params, substitution, base_message)
|
||||
|
||||
if(target_behavior == EMOTE_TARGET_BHVR_IGNORE)
|
||||
return base_message
|
||||
|
||||
if(target_behavior == EMOTE_TARGET_BHVR_RAW)
|
||||
return replacetext(substitution, "%t", params)
|
||||
|
||||
|
||||
@@ -1786,6 +1786,7 @@
|
||||
|
||||
//Initialisation procs
|
||||
/mob/proc/mind_initialize()
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
if(mind)
|
||||
mind.key = key
|
||||
else
|
||||
@@ -1797,6 +1798,7 @@
|
||||
if(!mind.name)
|
||||
mind.name = real_name
|
||||
mind.current = src
|
||||
SEND_SIGNAL(src, COMSIG_MIND_INITIALIZE)
|
||||
|
||||
//HUMAN
|
||||
/mob/living/carbon/human/mind_initialize()
|
||||
|
||||
@@ -50,7 +50,20 @@
|
||||
|
||||
/datum/outfit/proc/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
//to be overriden for toggling internals, id binding, access etc
|
||||
return
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
if(visualsOnly)
|
||||
return
|
||||
|
||||
if(H.mind)
|
||||
on_mind_initialize(H)
|
||||
return
|
||||
RegisterSignal(H, COMSIG_MIND_INITIALIZE, PROC_REF(on_mind_initialize))
|
||||
|
||||
// Guaranteed access to mind, will never be called if visualsOnly = TRUE
|
||||
/datum/outfit/proc/on_mind_initialize(mob/living/carbon/human/H)
|
||||
SIGNAL_HANDLER // COMSIG_MIND_INITIALIZE
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
UnregisterSignal(H, COMSIG_MIND_INITIALIZE) // prevent this call from being called multiple times on a human
|
||||
|
||||
/datum/outfit/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
pre_equip(H, visualsOnly)
|
||||
|
||||
@@ -3,21 +3,15 @@
|
||||
|
||||
/datum/outfit/admin/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
. = ..()
|
||||
if(!visualsOnly && H.mind)
|
||||
H.mind.assigned_role = name
|
||||
H.job = name
|
||||
|
||||
/datum/outfit/admin/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
. = ..()
|
||||
|
||||
if(visualsOnly)
|
||||
return
|
||||
|
||||
if(H.mind)
|
||||
H.mind.offstation_role = TRUE
|
||||
else
|
||||
H.RegisterSignal(H, COMSIG_HUMAN_LOGIN, TYPE_PROC_REF(/mob/living/carbon/human, apply_offstation_roles))
|
||||
H.job = name
|
||||
|
||||
/datum/outfit/admin/on_mind_initialize(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
H.mind.assigned_role = name
|
||||
H.mind.offstation_role = TRUE
|
||||
|
||||
/proc/apply_to_card(obj/item/card/id/I, mob/living/carbon/human/H, list/access = list(), rank, special_icon)
|
||||
if(!istype(I) || !istype(H))
|
||||
@@ -1250,17 +1244,17 @@
|
||||
if(istype(I))
|
||||
apply_to_card(I, H, get_all_accesses(), "Ancient One", "data")
|
||||
|
||||
if(H.mind)
|
||||
if(!H.mind.has_antag_datum(/datum/antagonist/vampire))
|
||||
H.mind.make_vampire(TRUE)
|
||||
var/datum/antagonist/vampire/V = H.mind.has_antag_datum(/datum/antagonist/vampire)
|
||||
V.bloodusable = 9999
|
||||
V.bloodtotal = 9999
|
||||
V.add_subclass(SUBCLASS_ANCIENT, FALSE)
|
||||
H.dna.SetSEState(GLOB.jumpblock, TRUE)
|
||||
singlemutcheck(H, GLOB.jumpblock, MUTCHK_FORCED)
|
||||
H.update_mutations()
|
||||
H.gene_stability = 100
|
||||
/datum/outfit/admin/ancient_vampire/on_mind_initialize(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
H.mind.make_vampire()
|
||||
var/datum/antagonist/vampire/V = H.mind.has_antag_datum(/datum/antagonist/vampire)
|
||||
V.bloodusable = 9999
|
||||
V.bloodtotal = 9999
|
||||
V.add_subclass(SUBCLASS_ANCIENT, FALSE)
|
||||
H.dna.SetSEState(GLOB.jumpblock, TRUE)
|
||||
singlemutcheck(H, GLOB.jumpblock, MUTCHK_FORCED)
|
||||
H.update_mutations()
|
||||
H.gene_stability = 100
|
||||
|
||||
/datum/outfit/admin/wizard
|
||||
name = "Blue Wizard"
|
||||
@@ -1490,10 +1484,6 @@
|
||||
|
||||
H.real_name = "Unknown" //Enforcers sacrifice their name to Oblivion for their power
|
||||
|
||||
for(var/spell_path in spell_paths)
|
||||
var/S = new spell_path
|
||||
H.mind.AddSpell(S)
|
||||
|
||||
var/obj/item/clothing/suit/hooded/oblivion/robes = H.wear_suit
|
||||
if(istype(robes))
|
||||
robes.ToggleHood()
|
||||
@@ -1502,6 +1492,12 @@
|
||||
if(istype(I))
|
||||
apply_to_card(I, H, get_all_accesses(), "Oblivion Enforcer")
|
||||
|
||||
/datum/outfit/admin/enforcer/on_mind_initialize(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
for(var/spell_path in spell_paths)
|
||||
var/S = new spell_path
|
||||
H.mind.AddSpell(S)
|
||||
|
||||
/datum/outfit/admin/viper
|
||||
name = "Solar Federation Viper Infiltrator"
|
||||
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
MARK: Impact debris + smoke
|
||||
*/
|
||||
|
||||
/particles/debris
|
||||
icon = 'icons/effects/particles/generic_particles.dmi'
|
||||
width = 500
|
||||
height = 500
|
||||
count = 10
|
||||
spawning = 10
|
||||
lifespan = 0.5 SECONDS
|
||||
fade = 0.3 SECONDS
|
||||
drift = generator(GEN_CIRCLE, 0, 7)
|
||||
scale = 0.3
|
||||
velocity = list(50, 0)
|
||||
friction = generator(GEN_NUM, 0.1, 0.15)
|
||||
spin = generator(GEN_NUM, -20, 20)
|
||||
|
||||
/particles/impact_smoke
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "smoke"
|
||||
width = 500
|
||||
height = 500
|
||||
count = 20
|
||||
spawning = 20
|
||||
lifespan = 0.8 SECONDS
|
||||
fade = 10 SECONDS
|
||||
grow = 0.1
|
||||
scale = 0.2
|
||||
spin = generator(GEN_NUM, -20, 20)
|
||||
velocity = list(50, 0)
|
||||
friction = generator(GEN_NUM, 0.1, 0.5)
|
||||
|
||||
/*
|
||||
MARK: Explosion smoke
|
||||
*/
|
||||
|
||||
/particles/explosion_smoke
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "smoke3"
|
||||
width = 1000
|
||||
height = 1000
|
||||
count = 45
|
||||
spawning = 45
|
||||
gradient = list("#FA9632", "#C3630C", "#333333", "#808080", "#FFFFFF")
|
||||
lifespan = 2.5 SECONDS
|
||||
fade = 2 SECONDS
|
||||
color = generator(GEN_NUM, 0, 0.25)
|
||||
color_change = generator(GEN_NUM, 0.04, 0.05)
|
||||
velocity = generator(GEN_CIRCLE, 15, 15)
|
||||
drift = generator(GEN_CIRCLE, 0, 1, NORMAL_RAND)
|
||||
spin = generator(GEN_NUM, -20, 20)
|
||||
friction = generator(GEN_NUM, 0.1, 0.5)
|
||||
gravity = list(1, 2)
|
||||
scale = 0.25
|
||||
grow = 0.05
|
||||
|
||||
/particles/explosion_smoke/deva
|
||||
scale = 0.5
|
||||
velocity = generator(GEN_CIRCLE, 23, 23)
|
||||
|
||||
/particles/explosion_smoke/small
|
||||
count = 15
|
||||
spawning = 15
|
||||
scale = 0.25
|
||||
velocity = generator(GEN_CIRCLE, 10, 10)
|
||||
|
||||
/particles/smoke_wave
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "smoke3"
|
||||
width = 750
|
||||
height = 750
|
||||
count = 75
|
||||
spawning = 75
|
||||
lifespan = 3 SECONDS
|
||||
fade = 6 SECONDS
|
||||
gradient = list("#BA9F6D", "#808080", "#FFFFFF")
|
||||
color = generator(GEN_NUM, 0, 0.25)
|
||||
color_change = generator(GEN_NUM, 0.08, 0.07)
|
||||
velocity = generator(GEN_CIRCLE, 15, 15)
|
||||
rotation = generator(GEN_NUM, -45, 45)
|
||||
scale = 0.15
|
||||
grow = 0.05
|
||||
friction = 0.1
|
||||
|
||||
/particles/smoke_wave/small
|
||||
count = 45
|
||||
spawning = 45
|
||||
scale = 0.05
|
||||
lifespan = 2 SECONDS
|
||||
fade = 5 SECONDS
|
||||
|
||||
/particles/sparks_outwards
|
||||
icon = 'icons/effects/64x64.dmi'
|
||||
icon_state = "flare"
|
||||
width = 750
|
||||
height = 750
|
||||
count = 40
|
||||
spawning = 20
|
||||
lifespan = 5 SECONDS
|
||||
fade = 2 SECONDS
|
||||
position = generator(GEN_SPHERE, 8, 8)
|
||||
velocity = generator(GEN_CIRCLE, 30, 30)
|
||||
scale = 0.1
|
||||
friction = 0.1
|
||||
@@ -224,3 +224,11 @@
|
||||
suffix = "lavaland_surface_watcher_grave.dmm"
|
||||
cost = 5
|
||||
allow_duplicates = FALSE
|
||||
|
||||
/datum/map_template/ruin/lavaland/shuttlecrash
|
||||
name = "Crashed Passenger Shuttle"
|
||||
id = "shuttlecrash"
|
||||
description = "A passenger shuttle crashsite of indeterminate origin."
|
||||
suffix = "lavaland_surface_shuttlecrash.dmm"
|
||||
cost = 5
|
||||
allow_duplicates = FALSE
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
var/description
|
||||
var/admin_notes
|
||||
|
||||
/datum/map_template/shuttle/proc/preload()
|
||||
return
|
||||
|
||||
/datum/map_template/shuttle/New()
|
||||
if(port_id && suffix)
|
||||
shuttle_id = "[port_id]_[suffix]"
|
||||
@@ -125,6 +128,43 @@
|
||||
description = "Guaranteed to get you somewhere FAST. With a custom-built plasma engine, this bad boy will put more distance between you and certain danger than any other!"
|
||||
admin_notes = "The aft of the ship has a plasma tank that starts ignited. May get released by crew. The plasma windows next to the engine heaters will also erupt into flame, and also risk getting released by crew."
|
||||
|
||||
/datum/map_template/shuttle/emergency/lance
|
||||
suffix = "lance"
|
||||
name = "The Lance Crew Evacuation System"
|
||||
description = "A brand new shuttle by Nanotrasen's finest in shuttle-engineering, it's designed to tactically slam into a destroyed station, \
|
||||
dispatching threats and saving crew at the same time! \
|
||||
Be careful to stay out of it's path. Comes with a beacon to choose where it docks!"
|
||||
admin_notes = "WARNING: This shuttle is designed to crash into the station. It has turrets, similar to the raven. Place down the beacon please. Once the shuttle is loaded, it cannot be unloaded."
|
||||
|
||||
/datum/map_template/shuttle/emergency/lance/preload()
|
||||
message_admins("Preloading [name]!")
|
||||
var/obj/docking_port/stationary/CCport
|
||||
CCport = SSshuttle.getDock("emergency_away")
|
||||
CCport.setDir(4)
|
||||
CCport.forceMove(locate(136, 107, 1))
|
||||
CCport.height = 50
|
||||
CCport.dheight = 0
|
||||
CCport.width = 19
|
||||
CCport.dwidth = 9
|
||||
var/obj/docking_port/stationary/CCtransit
|
||||
CCtransit = SSshuttle.getDock("emergency_transit")
|
||||
CCtransit.setDir(2)
|
||||
CCtransit.forceMove(locate(113, 68, 1))
|
||||
CCtransit.height = 50
|
||||
CCtransit.dheight = 0
|
||||
CCtransit.width = 19
|
||||
CCtransit.dwidth = 9
|
||||
var/obj/docking_port/stationary/syndicate
|
||||
syndicate = SSshuttle.getDock("emergency_syndicate")
|
||||
syndicate.setDir(8)
|
||||
syndicate.forceMove(locate(202, 199, 1))
|
||||
syndicate.height = 50
|
||||
syndicate.dheight = 0
|
||||
syndicate.width = 19
|
||||
syndicate.dwidth = 9
|
||||
qdel(SSshuttle.getDock("emergency_home"), TRUE)
|
||||
SSshuttle.emergency_locked_in = TRUE
|
||||
|
||||
/datum/map_template/shuttle/ferry/base
|
||||
suffix = "base"
|
||||
name = "transport ferry"
|
||||
|
||||
@@ -69,6 +69,20 @@
|
||||
user.remove_status_effect(type)
|
||||
highfived.remove_status_effect(type)
|
||||
|
||||
/datum/status_effect/high_five/proc/wiz_effect(mob/living/carbon/user, mob/living/carbon/highfived)
|
||||
user.status_flags |= GODMODE
|
||||
highfived.status_flags |= GODMODE
|
||||
explosion(get_turf(user), 5, 2, 1, 3, cause = id)
|
||||
// explosions have a spawn so this makes sure that we don't get gibbed
|
||||
addtimer(CALLBACK(src, PROC_REF(wiz_cleanup), user, highfived), 0.3 SECONDS) // I want to be sure this lasts long enough, with lag.
|
||||
add_attack_logs(user, highfived, "caused a wizard [id] explosion")
|
||||
|
||||
/datum/status_effect/high_five/proc/post_start()
|
||||
return
|
||||
|
||||
/datum/status_effect/high_five/proc/regular_effect(mob/living/carbon/user, mob/living/carbon/highfived)
|
||||
user.visible_message("<span class='notice'><b>[user.name]</b> and <b>[highfived.name]</b> [success]</span>")
|
||||
|
||||
/datum/status_effect/high_five/on_apply()
|
||||
if(!iscarbon(owner))
|
||||
return FALSE
|
||||
@@ -82,25 +96,23 @@
|
||||
continue
|
||||
if(is_wiz && iswizard(C))
|
||||
user.visible_message("<span class='biggerdanger'><b>[user.name]</b> and <b>[C.name]</b> [critical_success]</span>")
|
||||
user.status_flags |= GODMODE
|
||||
C.status_flags |= GODMODE
|
||||
explosion(get_turf(user), 5, 2, 1, 3, cause = id)
|
||||
// explosions have a spawn so this makes sure that we don't get gibbed
|
||||
addtimer(CALLBACK(src, PROC_REF(wiz_cleanup), user, C), 0.3 SECONDS) //I want to be sure this lasts long enough, with lag.
|
||||
add_attack_logs(user, C, "caused a wizard [id] explosion")
|
||||
wiz_effect(user, C)
|
||||
both_wiz = TRUE
|
||||
user.do_attack_animation(C, no_effect = TRUE)
|
||||
C.do_attack_animation(user, no_effect = TRUE)
|
||||
playsound(user, sound_effect, 80)
|
||||
if(!both_wiz)
|
||||
user.visible_message("<span class='notice'><b>[user.name]</b> and <b>[C.name]</b> [success]</span>")
|
||||
regular_effect(user, C)
|
||||
user.remove_status_effect(type)
|
||||
C.remove_status_effect(type)
|
||||
return FALSE
|
||||
// We can return to break out of the loop here so we don't auto-remove (which causes the timer on the wizard highfive to break)
|
||||
// This is safe because we only pass the continue if we don't have the status effect
|
||||
return TRUE // DO NOT AUTOREMOVE
|
||||
|
||||
owner.custom_emote(EMOTE_VISIBLE, request)
|
||||
owner.create_point_bubble_from_path(item_path, FALSE)
|
||||
post_start()
|
||||
|
||||
/datum/status_effect/high_five/on_timeout()
|
||||
owner.visible_message("[owner] [get_missed_message()]")
|
||||
@@ -144,6 +156,96 @@
|
||||
|
||||
return pick(missed_messages)
|
||||
|
||||
/datum/status_effect/high_five/rps
|
||||
id = "rps"
|
||||
critical_success = "both play rock -- THEY'RE GOING IN FOR THE FISTBUMP!"
|
||||
success = "play rock-paper-scissors!"
|
||||
sound_effect = 'sound/effects/glassknock.ogg'
|
||||
request = "wants to play rock-paper-scissors!"
|
||||
item_path = /obj/item/claymore // it's time to d-d-d-d-d-d-d-duel!
|
||||
/// The move that you'll be making.
|
||||
var/move
|
||||
|
||||
/datum/status_effect/high_five/rps/get_missed_message()
|
||||
var/list/missed_messages = list(
|
||||
"just seems to be practicing against [owner.p_themselves()]. [owner.p_are(TRUE)] [owner.p_they()] losing?",
|
||||
"seems more interested in a thumb war."
|
||||
)
|
||||
|
||||
return pick(missed_messages)
|
||||
|
||||
/datum/status_effect/high_five/rps/proc/get_move_status(my_move, their_move)
|
||||
if(my_move == their_move)
|
||||
return RPS_EMOTE_TIE
|
||||
switch(my_move)
|
||||
if(RPS_EMOTE_ROCK)
|
||||
return their_move == RPS_EMOTE_SCISSORS ? RPS_EMOTE_WE_WIN : RPS_EMOTE_THEY_WIN
|
||||
|
||||
if(RPS_EMOTE_PAPER)
|
||||
return their_move == RPS_EMOTE_ROCK ? RPS_EMOTE_WE_WIN : RPS_EMOTE_THEY_WIN
|
||||
|
||||
if(RPS_EMOTE_SCISSORS)
|
||||
return their_move == RPS_EMOTE_PAPER ? RPS_EMOTE_WE_WIN : RPS_EMOTE_THEY_WIN
|
||||
|
||||
else
|
||||
CRASH("Unknown emote rock type")
|
||||
|
||||
/datum/status_effect/high_five/rps/post_start()
|
||||
playsound(owner, 'sound/effects/glassknock.ogg', 50, FALSE)
|
||||
|
||||
/datum/status_effect/high_five/rps/regular_effect(mob/living/carbon/user, mob/living/carbon/highfived)
|
||||
var/datum/status_effect/high_five/rps/their_status_effect = highfived.has_status_effect(type)
|
||||
var/outcome = get_move_status(move, their_status_effect.move)
|
||||
var/outcome_msg
|
||||
switch(outcome)
|
||||
if(RPS_EMOTE_TIE)
|
||||
outcome_msg = "It's a tie!"
|
||||
if(RPS_EMOTE_WE_WIN)
|
||||
outcome_msg = "[user] wins!"
|
||||
if(RPS_EMOTE_THEY_WIN)
|
||||
outcome_msg = "[highfived] wins!"
|
||||
|
||||
user.visible_message(
|
||||
"<span class='notice'>[user] plays <b>[move]</b>, and [highfived] plays <b>[their_status_effect.move]</b>.</span>",
|
||||
"<span class='notice'>[highfived] plays <b>[their_status_effect.move]</b>.</span>",
|
||||
"<span class='notice'>It sounds like rock-paper-scissors.</span>"
|
||||
)
|
||||
|
||||
user.visible_message(
|
||||
"<span class='warning'>[outcome_msg]</span>",
|
||||
blind_message = "<span class='notice'>It sounds like [pick(user, highfived)] won!</span>" // you're blind how are you supposed to know
|
||||
)
|
||||
|
||||
/datum/status_effect/high_five/rps/on_creation(mob/living/new_owner, made_move)
|
||||
if(made_move)
|
||||
if(!(made_move in list(RPS_EMOTE_ROCK, RPS_EMOTE_PAPER, RPS_EMOTE_SCISSORS)))
|
||||
stack_trace("RPS emote was given an invalid move type on creation.")
|
||||
else
|
||||
move = made_move
|
||||
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/high_five/rps/on_apply()
|
||||
if(!isnull(move))
|
||||
to_chat(owner, "<span class='notice'>You prepare to play <b>[move]</b>.</span>")
|
||||
return ..() // we already have the move, probably from the emote passing it in
|
||||
|
||||
move = get_rock_paper_scissors_move(owner)
|
||||
if(move == null)
|
||||
return FALSE // make it auto-remove itself
|
||||
|
||||
to_chat(owner, "<span class='notice'>You prepare to play <b>[move]</b>.</span>")
|
||||
return ..()
|
||||
|
||||
|
||||
/proc/get_rock_paper_scissors_move(mob/living/carbon/user)
|
||||
var/list/move_icons = list(
|
||||
RPS_EMOTE_SCISSORS = image(icon = 'icons/obj/items.dmi', icon_state = "bscissor"),
|
||||
RPS_EMOTE_PAPER = image(icon = 'icons/obj/bureaucracy.dmi', icon_state = "paper"),
|
||||
RPS_EMOTE_ROCK = image(icon = 'icons/obj/toy.dmi', icon_state = "pet_rock")
|
||||
)
|
||||
return show_radial_menu(user, user, move_icons)
|
||||
|
||||
/// A status effect that can have a certain amount of "bonus" duration added, which extends the duration every tick,
|
||||
/// although there is a maximum amount of bonus time that can be active at any given time.
|
||||
/datum/status_effect/limited_bonus
|
||||
@@ -218,26 +320,11 @@
|
||||
tick_interval = 4
|
||||
/// The number of people the gun has locked on to. Caps at 10 for sanity.
|
||||
var/locks = 0
|
||||
/// What direction the owner was in when using the scope.
|
||||
var/owner_dir = 0
|
||||
|
||||
/datum/status_effect/lwap_scope/on_creation(mob/living/new_owner, stored_dir = 0)
|
||||
owner_dir = stored_dir
|
||||
return ..()
|
||||
|
||||
/datum/status_effect/lwap_scope/tick()
|
||||
locks = 0
|
||||
var/turf/owner_turf = get_turf(owner)
|
||||
var/scope_turf
|
||||
for(var/turf/T in RANGE_EDGE_TURFS(7, owner_turf))
|
||||
if(get_dir(owner, T) != owner_dir)
|
||||
continue
|
||||
if(T in range(owner, 6))
|
||||
continue
|
||||
scope_turf = T
|
||||
break
|
||||
if(scope_turf)
|
||||
for(var/mob/living/L in range(10, scope_turf))
|
||||
for(var/atom/movable/screen/fullscreen/stretch/cursor_catcher/scope/our_scope in owner.client.screen)
|
||||
for(var/mob/living/L in range(10, our_scope.given_turf))
|
||||
if(locks >= LWAP_LOCK_CAP)
|
||||
return
|
||||
if(L == owner || L.stat == DEAD || isslime(L) || ismonkeybasic(L)) //xenobio moment
|
||||
|
||||
@@ -133,11 +133,13 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
if(limited_stock > 0)
|
||||
limited_stock--
|
||||
log_game("[key_name(user)] purchased [name]. [name] was discounted to [cost].")
|
||||
user.create_log(MISC_LOG, "Uplink purchase: [name] was discounted to [cost]tc")
|
||||
if(!user.mind.special_role)
|
||||
message_admins("[key_name_admin(user)] purchased [name] (discounted to [cost]), as a non antagonist.")
|
||||
|
||||
else
|
||||
log_game("[key_name(user)] purchased [name].")
|
||||
user.create_log(MISC_LOG, "Uplink purchase: [name] for [cost]tc")
|
||||
if(!user.mind.special_role)
|
||||
message_admins("[key_name_admin(user)] purchased [name], as a non antagonist.")
|
||||
|
||||
@@ -603,7 +605,7 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
|
||||
/datum/uplink_item/device_tools/bonerepair
|
||||
name = "Prototype Nanite Autoinjector"
|
||||
desc = "Stolen prototype full body repair nanites. On injection it will shut down body systems as it revitilizes limbs and organs."
|
||||
desc = "Stolen prototype full body repair nanites. On injection it will shut down body systems as it revitilizes limbs and organs. Heals organics organs, cybernetic organs, and limbs to fully operational conditions."
|
||||
reference = "NCAI"
|
||||
item = /obj/item/reagent_containers/hypospray/autoinjector/nanocalcium
|
||||
cost = 10
|
||||
@@ -853,6 +855,16 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item))
|
||||
item = /obj/item/autosurgeon/organ/syndicate/razorwire
|
||||
cost = 20
|
||||
|
||||
/datum/uplink_item/cyber_implants/scope_eyes
|
||||
name = "Hardened Kaleido Optics Eyes Autoimplanter"
|
||||
desc = "These cybernetic eye implants will let you zoom in on far away objects. \
|
||||
Many users find it disorienting, and find it hard to interact with things near them when active. \
|
||||
This pair has been hardened for special operations personnel."
|
||||
reference = "KOE"
|
||||
item = /obj/item/autosurgeon/organ/syndicate/scope_eyes
|
||||
cost = 20
|
||||
|
||||
|
||||
// POINTLESS BADASSERY
|
||||
|
||||
/datum/uplink_item/badass
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
/datum/wires/nuclearbomb
|
||||
holder_type = /obj/machinery/nuclearbomb
|
||||
labelled = TRUE
|
||||
randomize = TRUE
|
||||
wire_count = 7 // 3 actual, 4 duds.
|
||||
wire_count = 5
|
||||
proper_name = "Nuclear bomb"
|
||||
|
||||
/datum/wires/nuclearbomb/New(atom/_holder)
|
||||
wires = list(WIRE_BOMB_LIGHT, WIRE_BOMB_TIMING, WIRE_BOMB_SAFETY)
|
||||
wires = list(WIRE_NUKE_SAFETY, WIRE_NUKE_DETONATOR, WIRE_NUKE_DISARM, WIRE_NUKE_LIGHT, WIRE_NUKE_CONTROL)
|
||||
return ..()
|
||||
|
||||
/datum/wires/nuclearbomb/interactable(mob/user)
|
||||
@@ -18,39 +19,64 @@
|
||||
. = ..()
|
||||
var/obj/machinery/nuclearbomb/N = holder
|
||||
. += "The device is [N.timing ? "shaking!" : "still."]"
|
||||
. += "The device is [N.safety ? "quiet" : "whirring"]."
|
||||
. += "The lights are [N.lighthack ? "static" : "functional"]."
|
||||
. += "The control panel is [is_cut(WIRE_NUKE_CONTROL) ? "turned off" : "functional"]."
|
||||
. += "The disarm controls are [is_cut(WIRE_NUKE_DISARM) || is_cut(WIRE_NUKE_CONTROL) ? "disabled" : "functional"]."
|
||||
. += "The safety controls are [is_cut(WIRE_NUKE_SAFETY) || is_cut(WIRE_NUKE_CONTROL) ? "disabled" : "functional"]."
|
||||
. += "The lights are [is_cut(WIRE_NUKE_LIGHT) ? "static" : "functional"]."
|
||||
|
||||
/datum/wires/nuclearbomb/on_pulse(wire)
|
||||
var/obj/machinery/nuclearbomb/N = holder
|
||||
switch(wire)
|
||||
if(WIRE_BOMB_LIGHT)
|
||||
N.lighthack = !N.lighthack
|
||||
addtimer(CALLBACK(N, TYPE_PROC_REF(/obj/machinery/nuclearbomb, reset_lighthack_callback)), 10 SECONDS)
|
||||
if(WIRE_NUKE_SAFETY)
|
||||
if(!is_cut(WIRE_NUKE_CONTROL))
|
||||
N.audible_message("<span class='notice'>The safety controls flicker.</span>", hearing_distance = 1)
|
||||
|
||||
if(WIRE_BOMB_TIMING)
|
||||
if(WIRE_NUKE_DETONATOR)
|
||||
if(N.timing)
|
||||
message_admins("[key_name_admin(usr)] pulsed a nuclear bomb's detonation wire, causing it to explode (<A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[holder.x];Y=[holder.y];Z=[holder.z]'>JMP</a>)")
|
||||
if(!N.training)
|
||||
message_admins("[key_name_admin(usr)] pulsed a nuclear bomb's detonator wire, causing it to explode (<a href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[holder.x];Y=[holder.y];Z=[holder.z]'>JMP</a>)")
|
||||
N.explode()
|
||||
else
|
||||
N.audible_message("<span class='warning'>[N] whirrs ominously.</span>", hearing_distance = 1)
|
||||
|
||||
if(WIRE_BOMB_SAFETY)
|
||||
N.safety = !N.safety
|
||||
addtimer(CALLBACK(N, TYPE_PROC_REF(/obj/machinery/nuclearbomb, reset_safety_callback)), 10 SECONDS)
|
||||
if(WIRE_NUKE_DISARM)
|
||||
if(N.timing && is_cut(WIRE_NUKE_CONTROL))
|
||||
if(!is_cut(WIRE_NUKE_LIGHT))
|
||||
N.icon_state = N.sprite_prefix + "nuclearbomb1"
|
||||
N.timing = FALSE
|
||||
N.audible_message("<span class='boldnotice'>The timer on [N] stops!</span>", hearing_distance = 1)
|
||||
N.update_icon(UPDATE_OVERLAYS)
|
||||
if(!N.training)
|
||||
GLOB.bomb_set = FALSE
|
||||
if(!N.is_syndicate && !N.training)
|
||||
SSsecurity_level.set_level(N.previous_level)
|
||||
else if(N.timing && !is_cut(WIRE_NUKE_CONTROL))
|
||||
N.audible_message("<span class='boldnotice'>The disarm controls flash with an error. You need to disable the control panel first!</span>", hearing_distance = 1)
|
||||
else if(!is_cut(WIRE_NUKE_CONTROL))
|
||||
N.audible_message("<span class='notice'>The disarm controls flicker.</span>", hearing_distance = 1)
|
||||
|
||||
if(WIRE_NUKE_LIGHT)
|
||||
N.audible_message("<span class='notice'>The lights on [N] flicker.</span>", hearing_distance = 1)
|
||||
flick(N.sprite_prefix + "nuclearbombc", N)
|
||||
|
||||
if(WIRE_NUKE_CONTROL)
|
||||
N.audible_message("<span class='notice'>[N]'s control panel flickers.</span>", hearing_distance = 1)
|
||||
|
||||
/datum/wires/nuclearbomb/on_cut(wire, mend)
|
||||
var/obj/machinery/nuclearbomb/N = holder
|
||||
switch(wire)
|
||||
if(WIRE_BOMB_SAFETY)
|
||||
if(N.timing)
|
||||
message_admins("[key_name_admin(usr)] cut a nuclear bomb's timing wire, causing it to explode (<A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[holder.x];Y=[holder.y];Z=[holder.z]'>JMP</a>)")
|
||||
if(WIRE_NUKE_DETONATOR)
|
||||
if(N.timing && !mend)
|
||||
if(!N.training)
|
||||
message_admins("[key_name_admin(usr)] cut a nuclear bomb's detonator wire, causing it to explode (<a href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[holder.x];Y=[holder.y];Z=[holder.z]'>JMP</a>)")
|
||||
N.explode()
|
||||
|
||||
if(WIRE_BOMB_TIMING)
|
||||
if(!N.lighthack)
|
||||
if(N.icon_state == "nuclearbomb2")
|
||||
N.icon_state = "nuclearbomb1"
|
||||
N.timing = FALSE
|
||||
GLOB.bomb_set = FALSE
|
||||
|
||||
if(WIRE_BOMB_LIGHT)
|
||||
N.lighthack = !N.lighthack
|
||||
if(WIRE_NUKE_LIGHT)
|
||||
if(!mend)
|
||||
N.icon_state = N.sprite_prefix + "nuclearbomb0"
|
||||
if(mend)
|
||||
if(N.timing)
|
||||
N.icon_state = N.sprite_prefix + "nuclearbomb2"
|
||||
else
|
||||
N.icon_state = N.sprite_prefix + "nuclearbomb1"
|
||||
N.update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
/datum/wires
|
||||
/// TRUE if the wires will be different every time a new wire datum is created.
|
||||
var/randomize = FALSE
|
||||
/// TRUE if the wires are labelled for every user
|
||||
var/labelled = FALSE
|
||||
/// The atom the wires belong too. For example: an airlock.
|
||||
var/atom/holder
|
||||
/// The holder type; used to make sure that the holder is the correct type.
|
||||
@@ -104,7 +106,8 @@
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/obj/item/organ/internal/eyes/eyes = H.get_int_organ(/obj/item/organ/internal/eyes)
|
||||
if(eyes && HAS_TRAIT(H, TRAIT_COLORBLIND)) // Check if the human has colorblindness.
|
||||
var/obj/item/clothing/glasses/glasses = H.get_item_by_slot(SLOT_HUD_GLASSES)
|
||||
if(eyes && HAS_TRAIT(H, TRAIT_COLORBLIND) && (!glasses || !glasses.correct_wires)) // Check if the human has colorblindness.
|
||||
replace_colors = eyes.replace_colours // Get the colorblind replacement colors list.
|
||||
|
||||
var/list/wires_list = list()
|
||||
@@ -281,6 +284,8 @@
|
||||
var/can_probably_see_wires = FALSE
|
||||
var/obj/item/held_item = user.get_active_hand()
|
||||
var/obj/item/offhand = user.get_inactive_hand()
|
||||
if(labelled)
|
||||
can_probably_see_wires = TRUE
|
||||
if(istype(held_item) && HAS_TRAIT(held_item, TRAIT_SHOW_WIRE_INFO))
|
||||
can_probably_see_wires = TRUE
|
||||
if(istype(offhand) && HAS_TRAIT(offhand, TRAIT_SHOW_WIRE_INFO))
|
||||
|
||||
@@ -106,6 +106,10 @@
|
||||
name = "\improper Firing Range"
|
||||
icon_state = "firingrange"
|
||||
|
||||
/area/station/security/defusal
|
||||
name = "\improper Defusal Workshop"
|
||||
icon_state = "defusal"
|
||||
|
||||
// Checkpoints
|
||||
|
||||
/area/station/security/checkpoint
|
||||
|
||||
@@ -1164,6 +1164,7 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
if(curturf)
|
||||
.["Jump to turf"] = "?_src_=holder;adminplayerobservecoodjump=1;X=[curturf.x];Y=[curturf.y];Z=[curturf.z]"
|
||||
.["Add reagent"] = "?_src_=vars;addreagent=[UID()]"
|
||||
.["Edit reagents"] = "?_src_=vars;editreagents=[UID()]"
|
||||
.["Trigger explosion"] = "?_src_=vars;explode=[UID()]"
|
||||
.["Trigger EM pulse"] = "?_src_=vars;emp=[UID()]"
|
||||
|
||||
|
||||
+17
-16
@@ -199,7 +199,8 @@
|
||||
Moved(old_loc, direction, TRUE)
|
||||
|
||||
/atom/movable/Move(atom/newloc, direct = 0, movetime)
|
||||
if(!loc || !newloc) return 0
|
||||
if(!loc || !newloc)
|
||||
return FALSE
|
||||
var/atom/oldloc = loc
|
||||
|
||||
if(loc != newloc)
|
||||
@@ -321,7 +322,7 @@
|
||||
|
||||
Moved(old_loc, NONE)
|
||||
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/atom/movable/proc/onTransitZ(old_z,new_z)
|
||||
for(var/item in src) // Notify contents of Z-transition. This can be overridden if we know the items contents do not care.
|
||||
@@ -348,36 +349,36 @@
|
||||
|
||||
//Called whenever an object moves and by mobs when they attempt to move themselves through space
|
||||
//And when an object or action applies a force on src, see newtonian_move() below
|
||||
//Return 0 to have src start/keep drifting in a no-grav area and 1 to stop/not start drifting
|
||||
//Mobs should return 1 if they should be able to move of their own volition, see client/Move() in mob_movement.dm
|
||||
//return FALSE to have src start/keep drifting in a no-grav area and TRUE to stop/not start drifting
|
||||
//Mobs should return TRUE if they should be able to move of their own volition, see client/Move() in mob_movement.dm
|
||||
//movement_dir == 0 when stopping or any dir when trying to move
|
||||
/atom/movable/proc/Process_Spacemove(movement_dir = 0)
|
||||
if(has_gravity(src))
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
if(pulledby && !pulledby.pulling)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
if(throwing)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
if(locate(/obj/structure/lattice) in range(1, get_turf(src))) //Not realistic but makes pushing things in space easier
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
/atom/movable/proc/newtonian_move(direction) //Only moves the object if it's under no gravity
|
||||
if(!loc || Process_Spacemove(0))
|
||||
inertia_dir = 0
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
inertia_dir = direction
|
||||
if(!direction)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
inertia_last_loc = loc
|
||||
SSspacedrift.processing[src] = src
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
//called when src is thrown into hit_atom
|
||||
/atom/movable/proc/throw_impact(atom/hit_atom, throwingdatum)
|
||||
@@ -397,7 +398,7 @@
|
||||
|
||||
/atom/movable/proc/throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, diagonals_first = FALSE, datum/callback/callback, force = INFINITY, dodgeable = TRUE, block_movement = TRUE)
|
||||
if(!target || (flags & NODROP) || speed <= 0)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(pulledby)
|
||||
pulledby.stop_pulling()
|
||||
@@ -500,8 +501,8 @@
|
||||
last_move = buckled_mob.last_move
|
||||
inertia_dir = last_move
|
||||
buckled_mob.inertia_dir = last_move
|
||||
return 0
|
||||
return 1
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/atom/movable/proc/force_pushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
|
||||
return FALSE
|
||||
@@ -521,7 +522,7 @@
|
||||
|
||||
/atom/movable/CanPass(atom/movable/mover, turf/target, height=1.5)
|
||||
if(mover in buckled_mobs)
|
||||
return 1
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/atom/movable/proc/get_spacemove_backup()
|
||||
|
||||
@@ -339,8 +339,6 @@
|
||||
~~~~~~~~~~~~~~~~~~~~~*/
|
||||
/obj/mecha/proc/diag_hud_set_mechhealth()
|
||||
var/image/holder = hud_list[DIAG_MECH_HUD]
|
||||
var/icon/I = icon(icon, icon_state, dir)
|
||||
holder.pixel_y = I.Height() - world.icon_size
|
||||
holder.icon_state = "huddiag[RoundDiagBar(obj_integrity/max_integrity)]"
|
||||
|
||||
/obj/mecha/proc/diag_hud_set_mechcell()
|
||||
|
||||
@@ -29,18 +29,17 @@
|
||||
H.set_species(has_primitive_form, keep_missing_bodyparts = TRUE)
|
||||
|
||||
new /obj/effect/temp_visual/monkeyify(H.loc)
|
||||
sleep(22)
|
||||
addtimer(CALLBACK(src, PROC_REF(finish_monkeyize), H, !has_primitive_form), 2.2 SECONDS)
|
||||
|
||||
/datum/mutation/monkey/proc/finish_monkeyize(mob/living/carbon/human/H, should_gib)
|
||||
H.invisibility = initial(H.invisibility)
|
||||
|
||||
if(!has_primitive_form) //If the pre-change mob in question has no primitive set, this is going to be messy.
|
||||
if(should_gib) //If the pre-change mob in question has no primitive set, this is going to be messy.
|
||||
H.gib()
|
||||
return
|
||||
REMOVE_TRAITS_IN(H, TRANSFORMING_TRAIT)
|
||||
to_chat(H, "<B>You are now a [H.dna.species.name].</B>")
|
||||
|
||||
return H
|
||||
|
||||
/datum/mutation/monkey/deactivate(mob/living/carbon/human/H)
|
||||
..()
|
||||
if(!istype(H))
|
||||
@@ -63,11 +62,13 @@
|
||||
H.set_species(has_greater_form, keep_missing_bodyparts = TRUE)
|
||||
|
||||
new /obj/effect/temp_visual/monkeyify/humanify(H.loc)
|
||||
sleep(22)
|
||||
addtimer(CALLBACK(src, PROC_REF(finish_unmonkeyize), H, !has_greater_form), 2.2 SECONDS)
|
||||
|
||||
/datum/mutation/monkey/proc/finish_unmonkeyize(mob/living/carbon/human/H, should_gib)
|
||||
REMOVE_TRAITS_IN(H, TRANSFORMING_TRAIT)
|
||||
H.invisibility = initial(H.invisibility)
|
||||
|
||||
if(!has_greater_form) //If the pre-change mob in question has no primitive set, this is going to be messy.
|
||||
if(should_gib) //If the pre-change mob in question has no primitive set, this is going to be messy.
|
||||
H.gib()
|
||||
return
|
||||
|
||||
@@ -76,4 +77,3 @@
|
||||
|
||||
to_chat(H, "<B>You are now a [H.dna.species.name].</B>")
|
||||
|
||||
return H
|
||||
|
||||
@@ -394,6 +394,9 @@
|
||||
return
|
||||
|
||||
var/atom/movable/the_item = targets[1]
|
||||
if(!user.Adjacent(the_item))
|
||||
to_chat(user, "<span class='danger'>You need to be next to [the_item] for this!</span>")
|
||||
return FALSE
|
||||
if(ishuman(the_item))
|
||||
var/mob/living/carbon/human/H = the_item
|
||||
var/obj/item/organ/external/limb = H.get_organ(user.zone_selected)
|
||||
@@ -412,15 +415,14 @@
|
||||
revert_cast()
|
||||
return FALSE
|
||||
user.visible_message("<span class='danger'>[user] begins stuffing [the_item]'s [limb.name] into [user.p_their()] gaping maw!</span>")
|
||||
var/oldloc = H.loc
|
||||
if(!do_mob(user,H,EAT_MOB_DELAY))
|
||||
if(!do_mob(user, H, EAT_MOB_DELAY))
|
||||
to_chat(user, "<span class='danger'>You were interrupted before you could eat [the_item]!</span>")
|
||||
else
|
||||
if(!limb || !H)
|
||||
return
|
||||
if(H.loc != oldloc)
|
||||
to_chat(user, "<span class='danger'>\The [limb] moved away from your mouth!</span>")
|
||||
return
|
||||
if(!user.Adjacent(the_item))
|
||||
to_chat(user, "<span class='danger'>You need to be next to [the_item] for this!</span>")
|
||||
return FALSE
|
||||
user.visible_message("<span class='danger'>[user] [pick("chomps","bites")] off [the_item]'s [limb]!</span>")
|
||||
playsound(user.loc, 'sound/items/eatfood.ogg', 50, 0)
|
||||
|
||||
@@ -476,6 +478,7 @@
|
||||
invocation_type = "none"
|
||||
|
||||
action_icon_state = "genetic_jump"
|
||||
var/leap_distance = 10
|
||||
|
||||
/datum/spell/leap/create_new_targeting()
|
||||
return new /datum/spell_targeting/self
|
||||
@@ -508,15 +511,25 @@
|
||||
user.layer = 9
|
||||
|
||||
user.flying = TRUE
|
||||
for(var/i=0, i<10, i++)
|
||||
for(var/i in 1 to leap_distance)
|
||||
var/turf/hit_turf = get_step(user, user.dir)
|
||||
var/atom/hit_atom = get_blocking_atom(hit_turf)
|
||||
if(hit_atom)
|
||||
hit_atom.hit_by_thrown_mob(user, damage = 10)
|
||||
break
|
||||
|
||||
step(user, user.dir)
|
||||
if(i < 5) user.pixel_y += 8
|
||||
else user.pixel_y -= 8
|
||||
if(i < 6)
|
||||
user.pixel_y += 8
|
||||
else
|
||||
user.pixel_y -= 8
|
||||
sleep(1)
|
||||
|
||||
user.flying = prevFlying
|
||||
user.pixel_y = 0 // In case leap was varedited to be longer or shorter
|
||||
|
||||
if(HAS_TRAIT(user, TRAIT_FAT) && prob(66))
|
||||
user.visible_message("<span class='danger'>[user.name]</b> crashes due to [user.p_their()] heavy weight!</span>")
|
||||
user.visible_message("<span class='danger'><b>[user.name]</b> crashes due to [user.p_their()] heavy weight!</span>")
|
||||
//playsound(user.loc, 'zhit.wav', 50, 1)
|
||||
user.AdjustWeakened(20 SECONDS)
|
||||
user.AdjustStunned(10 SECONDS)
|
||||
@@ -539,6 +552,24 @@
|
||||
container.pixel_x = 0
|
||||
container.pixel_y = 0
|
||||
|
||||
/datum/spell/leap/proc/get_blocking_atom(turf/turf_to_check)
|
||||
if(!turf_to_check)
|
||||
return FALSE
|
||||
|
||||
if(turf_to_check.density)
|
||||
return turf_to_check
|
||||
|
||||
for(var/atom/movable/hit_thing in turf_to_check)
|
||||
if(isliving(hit_thing))
|
||||
var/mob/living/hit_mob = hit_thing
|
||||
return hit_mob.density
|
||||
|
||||
if(isobj(hit_thing))
|
||||
var/obj/hit_obj = hit_thing
|
||||
return hit_obj.density
|
||||
|
||||
return FALSE
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// WAS: /datum/bioEffect/polymorphism
|
||||
|
||||
@@ -438,14 +438,14 @@
|
||||
|
||||
/proc/get_nuke_code()
|
||||
var/nukecode = "ERROR"
|
||||
for(var/obj/machinery/nuclearbomb/bomb in GLOB.machines)
|
||||
for(var/obj/machinery/nuclearbomb/bomb in GLOB.nuke_list)
|
||||
if(bomb && bomb.r_code && is_station_level(bomb.z))
|
||||
nukecode = bomb.r_code
|
||||
return nukecode
|
||||
|
||||
/proc/get_nuke_status()
|
||||
var/nuke_status = NUKE_MISSING
|
||||
for(var/obj/machinery/nuclearbomb/bomb in GLOB.machines)
|
||||
for(var/obj/machinery/nuclearbomb/bomb in GLOB.nuke_list)
|
||||
if(is_station_level(bomb.z))
|
||||
nuke_status = NUKE_CORE_MISSING
|
||||
if(bomb.core)
|
||||
|
||||
@@ -3,7 +3,62 @@
|
||||
#define MIND_DEVICE_MESSAGE 1
|
||||
#define MIND_DEVICE_CONTROL 2
|
||||
|
||||
//AGENT VEST
|
||||
#define BATON_STUN 0
|
||||
#define BATON_SLEEP 1
|
||||
#define BATON_CUFF 2
|
||||
#define BATON_PROBE 3
|
||||
#define BATON_MODES 4
|
||||
|
||||
/*
|
||||
CONTENTS:
|
||||
1. AGENT GEAR
|
||||
2. SCIENTIST GEAR
|
||||
3. ENGINEERING TOOLS
|
||||
4. MEDICAL TOOLS
|
||||
5. JANITORIAL TOOLS
|
||||
6. STRUCTURES
|
||||
*/
|
||||
|
||||
// Setting up abductor exclusivity.
|
||||
/obj/item/abductor
|
||||
name = "generic abductor item"
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
desc = "You are not supposed to be able to see this. If you can see this, please make an issue report on GitHub."
|
||||
|
||||
/obj/item/abductor/proc/AbductorCheck(user)
|
||||
if(isabductor(user))
|
||||
return TRUE
|
||||
to_chat(user, "<span class='warning'>You can't figure how this works!</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/item/abductor/proc/ScientistCheck(user)
|
||||
if(!AbductorCheck(user))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/datum/species/abductor/S = H.dna.species
|
||||
if(S.scientist)
|
||||
return TRUE
|
||||
to_chat(user, "<span class='warning'>You're not trained to use this!</span>")
|
||||
return FALSE
|
||||
|
||||
/////////////////////////////////////////
|
||||
/////////////// AGENT GEAR //////////////
|
||||
/////////////////////////////////////////
|
||||
/obj/item/clothing/head/helmet/abductor
|
||||
name = "agent headgear"
|
||||
desc = "Abduct with style - spiky style. Prevents digital tracking."
|
||||
icon_state = "alienhelmet"
|
||||
item_state = "alienhelmet"
|
||||
blockTracking = 1
|
||||
origin_tech = "materials=7;magnets=4;abductor=3"
|
||||
flags = BLOCKHAIR
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
|
||||
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/clothing/species/vox/head.dmi'
|
||||
)
|
||||
|
||||
/obj/item/clothing/suit/armor/abductor/vest
|
||||
name = "agent vest"
|
||||
desc = "A vest outfitted with advanced stealth technology. It has two modes - combat and stealth."
|
||||
@@ -129,113 +184,6 @@
|
||||
break
|
||||
return ..()
|
||||
|
||||
/obj/item/abductor
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
|
||||
/obj/item/abductor/proc/AbductorCheck(user)
|
||||
if(isabductor(user))
|
||||
return TRUE
|
||||
to_chat(user, "<span class='warning'>You can't figure how this works!</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/item/abductor/proc/ScientistCheck(user)
|
||||
if(!AbductorCheck(user))
|
||||
return FALSE
|
||||
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/datum/species/abductor/S = H.dna.species
|
||||
if(S.scientist)
|
||||
return TRUE
|
||||
to_chat(user, "<span class='warning'>You're not trained to use this!</span>")
|
||||
return FALSE
|
||||
|
||||
/obj/item/abductor/gizmo
|
||||
name = "science tool"
|
||||
desc = "A dual-mode tool for retrieving specimens and scanning appearances. Scanning can be done through cameras."
|
||||
icon_state = "gizmo_scan"
|
||||
item_state = "gizmo"
|
||||
origin_tech = "engineering=7;magnets=4;bluespace=4;abductor=3"
|
||||
var/mode = GIZMO_SCAN
|
||||
var/mob/living/marked = null
|
||||
var/obj/machinery/abductor/console/console
|
||||
|
||||
/obj/item/abductor/gizmo/attack_self(mob/user)
|
||||
if(!ScientistCheck(user))
|
||||
return
|
||||
if(!console)
|
||||
to_chat(user, "<span class='warning'>The device is not linked to a console!</span>")
|
||||
return
|
||||
|
||||
if(mode == GIZMO_SCAN)
|
||||
mode = GIZMO_MARK
|
||||
icon_state = "gizmo_mark"
|
||||
else
|
||||
mode = GIZMO_SCAN
|
||||
icon_state = "gizmo_scan"
|
||||
to_chat(user, "<span class='notice'>You switch the device to [mode==GIZMO_SCAN? "SCAN": "MARK"] MODE</span>")
|
||||
|
||||
/obj/item/abductor/gizmo/attack(mob/living/M, mob/user)
|
||||
if(!ScientistCheck(user))
|
||||
return
|
||||
if(!console)
|
||||
to_chat(user, "<span class='warning'>The device is not linked to console!</span>")
|
||||
return
|
||||
|
||||
switch(mode)
|
||||
if(GIZMO_SCAN)
|
||||
scan(M, user)
|
||||
if(GIZMO_MARK)
|
||||
mark(M, user)
|
||||
|
||||
|
||||
/obj/item/abductor/gizmo/afterattack(atom/target, mob/living/user, flag, params)
|
||||
if(flag)
|
||||
return
|
||||
if(!ScientistCheck(user))
|
||||
return
|
||||
if(!console)
|
||||
to_chat(user, "<span class='warning'>The device is not linked to console!</span>")
|
||||
return
|
||||
|
||||
switch(mode)
|
||||
if(GIZMO_SCAN)
|
||||
scan(target, user)
|
||||
if(GIZMO_MARK)
|
||||
mark(target, user)
|
||||
|
||||
/obj/item/abductor/gizmo/proc/scan(atom/target, mob/living/user)
|
||||
if(ishuman(target))
|
||||
console.AddSnapshot(target)
|
||||
to_chat(user, "<span class='notice'>You scan [target] and add [target.p_them()] to the database.</span>")
|
||||
|
||||
/obj/item/abductor/gizmo/proc/mark(atom/target, mob/living/user)
|
||||
if(marked == target)
|
||||
to_chat(user, "<span class='warning'>This specimen is already marked!</span>")
|
||||
return
|
||||
if(ishuman(target))
|
||||
if(isabductor(target))
|
||||
marked = target
|
||||
to_chat(user, "<span class='notice'>You mark [target] for future retrieval.</span>")
|
||||
else
|
||||
prepare(target,user)
|
||||
else
|
||||
prepare(target,user)
|
||||
|
||||
/obj/item/abductor/gizmo/proc/prepare(atom/target, mob/living/user)
|
||||
if(get_dist(target,user)>1)
|
||||
to_chat(user, "<span class='warning'>You need to be next to the specimen to prepare it for transport!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You begin preparing [target] for transport...</span>")
|
||||
if(do_after(user, 100, target = target))
|
||||
marked = target
|
||||
to_chat(user, "<span class='notice'>You finish preparing [target] for transport.</span>")
|
||||
|
||||
/obj/item/abductor/gizmo/Destroy()
|
||||
if(console)
|
||||
console.gizmo = null
|
||||
return ..()
|
||||
|
||||
|
||||
/obj/item/abductor/silencer
|
||||
name = "abductor silencer"
|
||||
desc = "A compact device used to shut down communications equipment."
|
||||
@@ -277,75 +225,6 @@
|
||||
R.listening = FALSE // Prevents the radio from buzzing due to the EMP, preserving possible stealthiness.
|
||||
R.emp_act(1)
|
||||
|
||||
/obj/item/abductor/mind_device
|
||||
name = "mental interface device"
|
||||
desc = "A dual-mode tool for directly communicating with sentient brains. It can be used to send a direct message to a target, or to send a command to a test subject with a charged gland."
|
||||
icon_state = "mind_device_message"
|
||||
item_state = "silencer"
|
||||
var/mode = MIND_DEVICE_MESSAGE
|
||||
|
||||
/obj/item/abductor/mind_device/attack_self(mob/user)
|
||||
if(!ScientistCheck(user))
|
||||
return
|
||||
|
||||
if(mode == MIND_DEVICE_MESSAGE)
|
||||
mode = MIND_DEVICE_CONTROL
|
||||
icon_state = "mind_device_control"
|
||||
else
|
||||
mode = MIND_DEVICE_MESSAGE
|
||||
icon_state = "mind_device_message"
|
||||
to_chat(user, "<span class='notice'>You switch the device to [mode == MIND_DEVICE_MESSAGE ? "TRANSMISSION" : "COMMAND"] MODE</span>")
|
||||
|
||||
/obj/item/abductor/mind_device/afterattack(atom/target, mob/living/user, flag, params)
|
||||
if(!ScientistCheck(user))
|
||||
return
|
||||
|
||||
switch(mode)
|
||||
if(MIND_DEVICE_CONTROL)
|
||||
mind_control(target, user)
|
||||
if(MIND_DEVICE_MESSAGE)
|
||||
mind_message(target, user)
|
||||
|
||||
/obj/item/abductor/mind_device/proc/mind_control(atom/target, mob/living/user)
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
var/obj/item/organ/internal/heart/gland/G = C.get_organ_slot("heart")
|
||||
if(!istype(G))
|
||||
to_chat(user, "<span class='warning'>Your target does not have an experimental gland!</span>")
|
||||
return
|
||||
if(!G.mind_control_uses)
|
||||
to_chat(user, "<span class='warning'>Your target's gland is spent!</span>")
|
||||
return
|
||||
if(G.active_mind_control)
|
||||
to_chat(user, "<span class='warning'>Your target is already under a mind-controlling influence!</span>")
|
||||
return
|
||||
|
||||
var/command = tgui_input_text(user, "Enter the command for your target to follow. Uses Left: [G.mind_control_uses], Duration: [DisplayTimeText(G.mind_control_duration)]", "Enter command")
|
||||
if(!command)
|
||||
return
|
||||
if(QDELETED(user) || user.get_active_hand() != src || loc != user)
|
||||
return
|
||||
if(QDELETED(G))
|
||||
return
|
||||
G.mind_control(command, user)
|
||||
to_chat(user, "<span class='notice'>You send the command to your target.</span>")
|
||||
|
||||
/obj/item/abductor/mind_device/proc/mind_message(atom/target, mob/living/user)
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.stat == DEAD)
|
||||
to_chat(user, "<span class='warning'>Your target is dead!</span>")
|
||||
return
|
||||
var/message = tgui_input_text(user, "Write a message to send to your target's brain.", "Enter message")
|
||||
if(!message)
|
||||
return
|
||||
if(QDELETED(L) || L.stat == DEAD)
|
||||
return
|
||||
|
||||
to_chat(L, "<span class='italics'>You hear a voice in your head saying: </span><span class='abductor'>[message]</span>")
|
||||
to_chat(user, "<span class='notice'>You send the message to your target.</span>")
|
||||
log_say("[key_name(user)] sent an abductor mind message to [key_name(L)]: '[message]'", user)
|
||||
|
||||
/obj/item/gun/energy/alien
|
||||
name = "alien pistol"
|
||||
desc = "A complicated gun that fires bursts of high-intensity radiation."
|
||||
@@ -357,41 +236,6 @@
|
||||
trigger_guard = TRIGGER_GUARD_ALLOW_ALL
|
||||
can_holster = TRUE
|
||||
|
||||
/obj/item/paper/abductor
|
||||
name = "Dissection Guide"
|
||||
icon_state = "alienpaper_words"
|
||||
info = {"<b>Dissection for Dummies</b><br>
|
||||
<br>
|
||||
1.Acquire fresh specimen.<br>
|
||||
2.Put the specimen on operating table.<br>
|
||||
3.Apply scalpel to the chest, preparing for experimental dissection.<br>
|
||||
4.Apply scalpel to specimen's torso.<br>
|
||||
5.Clamp bleeders on specimen's torso with a hemostat.<br>
|
||||
6.Retract skin of specimen's torso with a retractor.<br>
|
||||
7.Saw through the specimen's torso with a saw.<br>
|
||||
8.Apply retractor again to specimen's torso.<br>
|
||||
9.Search through the specimen's torso with your hands to remove any superfluous organs.<br>
|
||||
10.Insert replacement gland (Retrieve one from gland storage).<br>
|
||||
11.Cauterize the patient's torso with a cautery.<br>
|
||||
12.Consider dressing the specimen back to not disturb the habitat. <br>
|
||||
13.Put the specimen in the experiment machinery.<br>
|
||||
14.Choose one of the machine options. The target will be analyzed and teleported to the selected drop-off point.<br>
|
||||
15.You will receive one supply credit, and the subject will be counted towards your quota.<br>
|
||||
<br>
|
||||
Congratulations! You are now trained for invasive xenobiology research!"}
|
||||
|
||||
/obj/item/paper/abductor/update_icon_state()
|
||||
return
|
||||
|
||||
/obj/item/paper/abductor/AltClick()
|
||||
return
|
||||
|
||||
#define BATON_STUN 0
|
||||
#define BATON_SLEEP 1
|
||||
#define BATON_CUFF 2
|
||||
#define BATON_PROBE 3
|
||||
#define BATON_MODES 4
|
||||
|
||||
/obj/item/abductor_baton
|
||||
name = "advanced baton"
|
||||
desc = "A quad-mode baton used for incapacitation and restraining of specimens."
|
||||
@@ -590,6 +434,281 @@ Congratulations! You are now trained for invasive xenobiology research!"}
|
||||
/obj/item/radio/headset/abductor/screwdriver_act()
|
||||
return// Stops humans from disassembling abductor headsets.
|
||||
|
||||
/////////////////////////////////////////
|
||||
///////////// SCIENTIST GEAR ////////////
|
||||
/////////////////////////////////////////
|
||||
/obj/item/abductor/gizmo
|
||||
name = "science tool"
|
||||
desc = "A dual-mode tool for retrieving specimens and scanning appearances. Scanning can be done through cameras."
|
||||
icon_state = "gizmo_scan"
|
||||
item_state = "gizmo"
|
||||
origin_tech = "engineering=7;magnets=4;bluespace=4;abductor=3"
|
||||
var/mode = GIZMO_SCAN
|
||||
var/mob/living/marked = null
|
||||
var/obj/machinery/abductor/console/console
|
||||
|
||||
/obj/item/abductor/gizmo/attack_self(mob/user)
|
||||
if(!ScientistCheck(user))
|
||||
return
|
||||
if(!console)
|
||||
to_chat(user, "<span class='warning'>The device is not linked to a console!</span>")
|
||||
return
|
||||
|
||||
if(mode == GIZMO_SCAN)
|
||||
mode = GIZMO_MARK
|
||||
icon_state = "gizmo_mark"
|
||||
else
|
||||
mode = GIZMO_SCAN
|
||||
icon_state = "gizmo_scan"
|
||||
to_chat(user, "<span class='notice'>You switch the device to [mode==GIZMO_SCAN? "SCAN": "MARK"] MODE</span>")
|
||||
|
||||
/obj/item/abductor/gizmo/attack(mob/living/M, mob/user)
|
||||
if(!ScientistCheck(user))
|
||||
return
|
||||
if(!console)
|
||||
to_chat(user, "<span class='warning'>The device is not linked to console!</span>")
|
||||
return
|
||||
|
||||
switch(mode)
|
||||
if(GIZMO_SCAN)
|
||||
scan(M, user)
|
||||
if(GIZMO_MARK)
|
||||
mark(M, user)
|
||||
|
||||
/obj/item/abductor/gizmo/afterattack(atom/target, mob/living/user, flag, params)
|
||||
if(flag)
|
||||
return
|
||||
if(!ScientistCheck(user))
|
||||
return
|
||||
if(!console)
|
||||
to_chat(user, "<span class='warning'>The device is not linked to console!</span>")
|
||||
return
|
||||
|
||||
switch(mode)
|
||||
if(GIZMO_SCAN)
|
||||
scan(target, user)
|
||||
if(GIZMO_MARK)
|
||||
mark(target, user)
|
||||
|
||||
/obj/item/abductor/gizmo/proc/scan(atom/target, mob/living/user)
|
||||
if(ishuman(target))
|
||||
console.AddSnapshot(target)
|
||||
to_chat(user, "<span class='notice'>You scan [target] and add [target.p_them()] to the database.</span>")
|
||||
|
||||
/obj/item/abductor/gizmo/proc/mark(atom/target, mob/living/user)
|
||||
if(marked == target)
|
||||
to_chat(user, "<span class='warning'>This specimen is already marked!</span>")
|
||||
return
|
||||
if(ishuman(target))
|
||||
if(isabductor(target))
|
||||
marked = target
|
||||
to_chat(user, "<span class='notice'>You mark [target] for future retrieval.</span>")
|
||||
else
|
||||
prepare(target,user)
|
||||
else
|
||||
prepare(target,user)
|
||||
|
||||
/obj/item/abductor/gizmo/proc/prepare(atom/target, mob/living/user)
|
||||
if(get_dist(target,user)>1)
|
||||
to_chat(user, "<span class='warning'>You need to be next to the specimen to prepare it for transport!</span>")
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You begin preparing [target] for transport...</span>")
|
||||
if(do_after(user, 100, target = target))
|
||||
marked = target
|
||||
to_chat(user, "<span class='notice'>You finish preparing [target] for transport.</span>")
|
||||
|
||||
/obj/item/abductor/gizmo/Destroy()
|
||||
if(console)
|
||||
console.gizmo = null
|
||||
return ..()
|
||||
|
||||
/obj/item/abductor/mind_device
|
||||
name = "mental interface device"
|
||||
desc = "A dual-mode tool for directly communicating with sentient brains. It can be used to send a direct message to a target, or to send a command to a test subject with a charged gland."
|
||||
icon_state = "mind_device_message"
|
||||
item_state = "silencer"
|
||||
var/mode = MIND_DEVICE_MESSAGE
|
||||
|
||||
/obj/item/abductor/mind_device/attack_self(mob/user)
|
||||
if(!ScientistCheck(user))
|
||||
return
|
||||
|
||||
if(mode == MIND_DEVICE_MESSAGE)
|
||||
mode = MIND_DEVICE_CONTROL
|
||||
icon_state = "mind_device_control"
|
||||
else
|
||||
mode = MIND_DEVICE_MESSAGE
|
||||
icon_state = "mind_device_message"
|
||||
to_chat(user, "<span class='notice'>You switch the device to [mode == MIND_DEVICE_MESSAGE ? "TRANSMISSION" : "COMMAND"] MODE</span>")
|
||||
|
||||
/obj/item/abductor/mind_device/afterattack(atom/target, mob/living/user, flag, params)
|
||||
if(!ScientistCheck(user))
|
||||
return
|
||||
|
||||
switch(mode)
|
||||
if(MIND_DEVICE_CONTROL)
|
||||
mind_control(target, user)
|
||||
if(MIND_DEVICE_MESSAGE)
|
||||
mind_message(target, user)
|
||||
|
||||
/obj/item/abductor/mind_device/proc/mind_control(atom/target, mob/living/user)
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
var/obj/item/organ/internal/heart/gland/G = C.get_organ_slot("heart")
|
||||
if(!istype(G))
|
||||
to_chat(user, "<span class='warning'>Your target does not have an experimental gland!</span>")
|
||||
return
|
||||
if(!G.mind_control_uses)
|
||||
to_chat(user, "<span class='warning'>Your target's gland is spent!</span>")
|
||||
return
|
||||
if(G.active_mind_control)
|
||||
to_chat(user, "<span class='warning'>Your target is already under a mind-controlling influence!</span>")
|
||||
return
|
||||
|
||||
var/command = tgui_input_text(user, "Enter the command for your target to follow. Uses Left: [G.mind_control_uses], Duration: [DisplayTimeText(G.mind_control_duration)]", "Enter command")
|
||||
if(!command)
|
||||
return
|
||||
if(QDELETED(user) || user.get_active_hand() != src || loc != user)
|
||||
return
|
||||
if(QDELETED(G))
|
||||
return
|
||||
G.mind_control(command, user)
|
||||
to_chat(user, "<span class='notice'>You send the command to your target.</span>")
|
||||
|
||||
/obj/item/abductor/mind_device/proc/mind_message(atom/target, mob/living/user)
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.stat == DEAD)
|
||||
to_chat(user, "<span class='warning'>Your target is dead!</span>")
|
||||
return
|
||||
var/message = tgui_input_text(user, "Write a message to send to your target's brain.", "Enter message")
|
||||
if(!message)
|
||||
return
|
||||
if(QDELETED(L) || L.stat == DEAD)
|
||||
return
|
||||
|
||||
to_chat(L, "<span class='italics'>You hear a voice in your head saying: </span><span class='abductor'>[message]</span>")
|
||||
to_chat(user, "<span class='notice'>You send the message to your target.</span>")
|
||||
log_say("[key_name(user)] sent an abductor mind message to [key_name(L)]: '[message]'", user)
|
||||
|
||||
/obj/item/paper/abductor
|
||||
name = "Dissection Guide"
|
||||
icon_state = "alienpaper_words"
|
||||
info = {"<b>Dissection for Dummies</b><br>
|
||||
<br>
|
||||
1.Acquire fresh specimen.<br>
|
||||
2.Put the specimen on operating table.<br>
|
||||
3.Apply scalpel to the chest, preparing for experimental dissection.<br>
|
||||
4.Apply scalpel to specimen's torso.<br>
|
||||
5.Clamp bleeders on specimen's torso with a hemostat.<br>
|
||||
6.Retract skin of specimen's torso with a retractor.<br>
|
||||
7.Saw through the specimen's torso with a saw.<br>
|
||||
8.Apply retractor again to specimen's torso.<br>
|
||||
9.Search through the specimen's torso with your hands to remove any superfluous organs.<br>
|
||||
10.Insert replacement gland (Retrieve one from gland storage).<br>
|
||||
11.Cauterize the patient's torso with a cautery.<br>
|
||||
12.Consider dressing the specimen back to not disturb the habitat. <br>
|
||||
13.Put the specimen in the experiment machinery.<br>
|
||||
14.Choose one of the machine options. The target will be analyzed and teleported to the selected drop-off point.<br>
|
||||
15.You will receive one supply credit, and the subject will be counted towards your quota.<br>
|
||||
<br>
|
||||
Congratulations! You are now trained for invasive xenobiology research!"}
|
||||
|
||||
/obj/item/paper/abductor/update_icon_state()
|
||||
return
|
||||
|
||||
/obj/item/paper/abductor/AltClick()
|
||||
return
|
||||
|
||||
/////////////////////////////////////////
|
||||
/////////// ENGINEERING TOOLS ///////////
|
||||
/////////////////////////////////////////
|
||||
/obj/item/screwdriver/abductor
|
||||
name = "alien screwdriver"
|
||||
desc = "An ultrasonic screwdriver."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "screwdriver"
|
||||
usesound = 'sound/items/pshoom.ogg'
|
||||
toolspeed = 0.1
|
||||
random_color = FALSE
|
||||
|
||||
/obj/item/wrench/abductor
|
||||
name = "alien wrench"
|
||||
desc = "A polarized wrench. It causes anything placed between the jaws to turn."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "wrench"
|
||||
usesound = 'sound/effects/empulse.ogg'
|
||||
toolspeed = 0.1
|
||||
origin_tech = "materials=5;engineering=5;abductor=3"
|
||||
|
||||
/obj/item/weldingtool/abductor
|
||||
name = "alien welding tool"
|
||||
desc = "An alien welding tool. Whatever fuel it uses, it never runs out."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "welder"
|
||||
toolspeed = 0.1
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
light_intensity = 0
|
||||
origin_tech = "plasmatech=5;engineering=5;abductor=3"
|
||||
requires_fuel = FALSE
|
||||
refills_over_time = TRUE
|
||||
low_fuel_changes_icon = FALSE
|
||||
|
||||
/obj/item/crowbar/abductor
|
||||
name = "alien crowbar"
|
||||
desc = "A hard-light crowbar. It appears to pry by itself, without any effort required."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "crowbar"
|
||||
usesound = 'sound/weapons/sonic_jackhammer.ogg'
|
||||
toolspeed = 0.1
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
origin_tech = "combat=4;engineering=4;abductor=3"
|
||||
|
||||
/obj/item/wirecutters/abductor
|
||||
name = "alien wirecutters"
|
||||
desc = "Extremely sharp wirecutters, made out of a silvery-green metal."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "cutters"
|
||||
toolspeed = 0.1
|
||||
origin_tech = "materials=5;engineering=4;abductor=3"
|
||||
random_color = FALSE
|
||||
|
||||
/obj/item/wirecutters/abductor/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_SHOW_WIRE_INFO, ROUNDSTART_TRAIT)
|
||||
|
||||
/obj/item/multitool/abductor
|
||||
name = "alien multitool"
|
||||
desc = "An omni-technological interface."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "multitool"
|
||||
toolspeed = 0.1
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
origin_tech = "magnets=5;engineering=5;abductor=3"
|
||||
|
||||
/obj/item/multitool/abductor/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_SHOW_WIRE_INFO, ROUNDSTART_TRAIT)
|
||||
|
||||
/obj/item/storage/belt/military/abductor
|
||||
name = "agent belt"
|
||||
desc = "A belt used by abductor agents."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "belt"
|
||||
item_state = "security"
|
||||
|
||||
/obj/item/storage/belt/military/abductor/full/populate_contents()
|
||||
new /obj/item/screwdriver/abductor(src)
|
||||
new /obj/item/wrench/abductor(src)
|
||||
new /obj/item/weldingtool/abductor(src)
|
||||
new /obj/item/crowbar/abductor(src)
|
||||
new /obj/item/wirecutters/abductor(src)
|
||||
new /obj/item/multitool/abductor(src)
|
||||
new /obj/item/stack/cable_coil(src, 30, COLOR_WHITE)
|
||||
|
||||
/////////////////////////////////////////
|
||||
/////////// MEDICAL TOOLS ///////////////
|
||||
/////////////////////////////////////////
|
||||
/obj/item/scalpel/alien
|
||||
name = "alien scalpel"
|
||||
desc = "It's a gleaming sharp knife made out of silvery-green metal."
|
||||
@@ -641,7 +760,7 @@ Congratulations! You are now trained for invasive xenobiology research!"}
|
||||
|
||||
/obj/item/FixOVein/alien
|
||||
name = "alien FixOVein"
|
||||
desc = "Bloodless aliens would totally know how to stop internal bleeding...right?"
|
||||
desc = "Bloodless aliens would totally know how to stop internal bleeding... Right?"
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
origin_tech = "materials=2;biotech=2;abductor=2"
|
||||
toolspeed = 0.25
|
||||
@@ -653,21 +772,89 @@ Congratulations! You are now trained for invasive xenobiology research!"}
|
||||
origin_tech = "materials=2;biotech=2;abductor=2"
|
||||
toolspeed = 0.25
|
||||
|
||||
/obj/item/clothing/head/helmet/abductor
|
||||
name = "agent headgear"
|
||||
desc = "Abduct with style - spiky style. Prevents digital tracking."
|
||||
icon_state = "alienhelmet"
|
||||
item_state = "alienhelmet"
|
||||
blockTracking = 1
|
||||
origin_tech = "materials=7;magnets=4;abductor=3"
|
||||
flags = BLOCKHAIR
|
||||
flags_inv = HIDEMASK|HIDEEARS|HIDEEYES|HIDEFACE
|
||||
/////////////////////////////////////////
|
||||
//////////// JANITORIAL TOOLS ///////////
|
||||
/////////////////////////////////////////
|
||||
/obj/item/mop/advanced/abductor
|
||||
name = "alien mop"
|
||||
desc = "A collapsible mop clearly used by aliens to clean up any evidence of a close encounter. The head produces a constant supply of water when run over a surface, seemingly out of nowhere."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "mop_abductor"
|
||||
mopcap = 100
|
||||
origin_tech = "materials=3;engineering=3;abductor=3"
|
||||
refill_rate = 50
|
||||
refill_reagent = "water"
|
||||
mopspeed = 10
|
||||
|
||||
sprite_sheets = list(
|
||||
"Vox" = 'icons/mob/clothing/species/vox/head.dmi'
|
||||
/obj/item/soap/syndie/abductor
|
||||
name = "alien soap"
|
||||
desc = "Even bloodless aliens need to wash the grime off. Smells like gunpowder."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "soap_abductor"
|
||||
|
||||
/obj/item/lightreplacer/bluespace/abductor
|
||||
name = "alien light replacer"
|
||||
desc = "It's important to keep all the mysterious lights on a UFO functional when flying over backwater country."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "lightreplacer_abductor"
|
||||
origin_tech = "magnets=3;engineering=4;abductor=3"
|
||||
max_uses = 40
|
||||
uses = 20
|
||||
|
||||
/obj/item/melee/flyswatter/abductor
|
||||
name = "alien flyswatter"
|
||||
desc = "For killing alien insects, obviously."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "flyswatter_abductor"
|
||||
item_state = "flyswatter_abductor"
|
||||
origin_tech = "abductor=1"
|
||||
force = 2 // Twice as powerful thanks to alien technology!
|
||||
throwforce = 2
|
||||
|
||||
/obj/item/reagent_containers/spray/cleaner/safety/abductor // Essentially an Advanced Space Cleaner, but abductor-themed. For the implant.
|
||||
name = "alien space cleaner"
|
||||
desc = "An alien spray bottle contaning alien-brand non-foaming space cleaner! It only accepts space cleaner."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "cleaner_abductor"
|
||||
item_state = "cleaner_abductor"
|
||||
volume = 500
|
||||
spray_maxrange = 3
|
||||
spray_currentrange = 3
|
||||
list_reagents = list("cleaner" = 500)
|
||||
|
||||
/obj/item/storage/belt/janitor/abductor
|
||||
name = "alien janibelt"
|
||||
desc = "A belt used to hold out-of-this-world cleaning supplies! Used by abductors to keep their ships clean."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "janibelt_abductor"
|
||||
item_state = "security"
|
||||
storage_slots = 7
|
||||
can_hold = list(
|
||||
/obj/item/grenade/chem_grenade/cleaner,
|
||||
/obj/item/lightreplacer,
|
||||
/obj/item/flashlight,
|
||||
/obj/item/reagent_containers/spray,
|
||||
/obj/item/soap,
|
||||
/obj/item/holosign_creator/janitor,
|
||||
/obj/item/melee/flyswatter,
|
||||
/obj/item/storage/bag/trash,
|
||||
/obj/item/push_broom,
|
||||
/obj/item/door_remote/janikeyring,
|
||||
/obj/item/mop/advanced/abductor
|
||||
)
|
||||
// Operating Table / Beds / Lockers
|
||||
|
||||
/obj/item/storage/belt/janitor/abductor/full/populate_contents()
|
||||
new /obj/item/mop/advanced/abductor(src)
|
||||
new /obj/item/soap/syndie/abductor(src)
|
||||
new /obj/item/lightreplacer/bluespace/abductor(src)
|
||||
new /obj/item/storage/bag/trash/bluespace(src)
|
||||
new /obj/item/melee/flyswatter/abductor(src)
|
||||
new /obj/item/reagent_containers/spray/cleaner/safety/abductor(src)
|
||||
new /obj/item/holosign_creator/janitor(src)
|
||||
|
||||
/////////////////////////////////////////
|
||||
/////////////// STRUCTURES //////////////
|
||||
/////////////////////////////////////////
|
||||
/obj/structure/bed/abductor
|
||||
name = "resting contraption"
|
||||
desc = "This looks similar to contraptions from earth. Could aliens be stealing our technology?"
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
|
||||
/datum/outfit/abductor/scientist
|
||||
name = "Abductor Scientist"
|
||||
|
||||
backpack_contents = list(
|
||||
/obj/item/abductor/gizmo = 1
|
||||
)
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
if(declaring_war)
|
||||
to_chat(user, "You are already in the process of declaring war! Make your mind up.")
|
||||
return FALSE
|
||||
if(length(GLOB.player_list) < CHALLENGE_MIN_PLAYERS)
|
||||
if(length(get_living_players(exclude_nonhuman = FALSE, exclude_offstation = TRUE)) < CHALLENGE_MIN_PLAYERS)
|
||||
to_chat(user, "The enemy crew is too small to be worth declaring war on.")
|
||||
return FALSE
|
||||
if(!is_admin_level(user.z))
|
||||
|
||||
@@ -15,7 +15,7 @@ GLOBAL_VAR(bomb_set)
|
||||
name = "\improper Nuclear Fission Explosive"
|
||||
desc = "Uh oh. RUN!!!!"
|
||||
icon = 'icons/obj/nuclearbomb.dmi'
|
||||
icon_state = "nuclearbomb0"
|
||||
icon_state = "nuclearbomb1"
|
||||
density = TRUE
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
flags_2 = NO_MALF_EFFECT_2 | CRITICAL_ATOM_2
|
||||
@@ -25,8 +25,6 @@ GLOBAL_VAR(bomb_set)
|
||||
|
||||
/// Are our bolts *supposed* to be in the floor, may not actually cause anchoring if the bolts are cut
|
||||
var/extended = TRUE
|
||||
/// If true, prevents the lights on the nuke
|
||||
var/lighthack = FALSE
|
||||
/// Countdown to boom
|
||||
var/timeleft = 120
|
||||
/// Are we counting down?
|
||||
@@ -55,6 +53,10 @@ GLOBAL_VAR(bomb_set)
|
||||
var/core_stage = NUKE_CORE_EVERYTHING_FINE
|
||||
///How many sheets of various metals we need to fix it
|
||||
var/sheets_to_fix = 5
|
||||
/// Is this a training bomb?
|
||||
var/training = FALSE
|
||||
/// Prefix to add, if any, on icon states for this bomb
|
||||
var/sprite_prefix = ""
|
||||
///Bombs Internal Radio
|
||||
var/obj/item/radio/radio
|
||||
|
||||
@@ -70,9 +72,10 @@ GLOBAL_VAR(bomb_set)
|
||||
. = ..()
|
||||
r_code = rand(10000, 99999) // Creates a random code upon object spawn.
|
||||
wires = new/datum/wires/nuclearbomb(src)
|
||||
ADD_TRAIT(src, TRAIT_OBSCURED_WIRES, ROUNDSTART_TRAIT)
|
||||
previous_level = SSsecurity_level.get_current_level_as_text()
|
||||
GLOB.poi_list |= src
|
||||
if(!training)
|
||||
GLOB.poi_list |= src
|
||||
GLOB.nuke_list |= src
|
||||
core = new /obj/item/nuke_core/plutonium(src)
|
||||
STOP_PROCESSING(SSobj, core) //Let us not irradiate the vault by default.
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
@@ -81,14 +84,26 @@ GLOBAL_VAR(bomb_set)
|
||||
radio.follow_target = src
|
||||
radio.config(list("Special Ops" = 0))
|
||||
|
||||
/obj/machinery/nuclearbomb/syndicate/Initialize()
|
||||
. = ..()
|
||||
wires.labelled = FALSE
|
||||
ADD_TRAIT(src, TRAIT_OBSCURED_WIRES, ROUNDSTART_TRAIT)
|
||||
GLOB.syndi_nuke_list |= src
|
||||
|
||||
/obj/machinery/nuclearbomb/Destroy()
|
||||
SStgui.close_uis(wires)
|
||||
QDEL_NULL(wires)
|
||||
QDEL_NULL(core)
|
||||
QDEL_NULL(radio)
|
||||
GLOB.poi_list.Remove(src)
|
||||
if(!training)
|
||||
GLOB.poi_list.Remove(src)
|
||||
GLOB.nuke_list.Remove(src)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/nuclearbomb/syndicate/Destroy()
|
||||
GLOB.syndi_nuke_list.Remove(src)
|
||||
. = ..()
|
||||
|
||||
/obj/machinery/nuclearbomb/process()
|
||||
if(timing)
|
||||
GLOB.bomb_set = TRUE // So long as there is one nuke timing, it means one nuke is armed.
|
||||
@@ -99,6 +114,8 @@ GLOBAL_VAR(bomb_set)
|
||||
|
||||
/obj/machinery/nuclearbomb/examine(mob/user)
|
||||
. = ..()
|
||||
if(training)
|
||||
. += "<span class='notice'><b>Alt-Click</b> to reset the bomb.</span>"
|
||||
if(!panel_open)
|
||||
. += "<span class='notice'>The outer panel is <b>screwed shut</b>.</span>"
|
||||
switch(removal_stage)
|
||||
@@ -126,15 +143,15 @@ GLOBAL_VAR(bomb_set)
|
||||
underlays.Cut()
|
||||
set_light(0)
|
||||
|
||||
if(!lighthack)
|
||||
underlays += emissive_appearance(icon, "nuclearbomb_lightmask")
|
||||
if(!wires.is_cut(WIRE_NUKE_LIGHT))
|
||||
underlays += emissive_appearance(icon, sprite_prefix + "nukelights_lightmask")
|
||||
set_light(1, LIGHTING_MINIMUM_POWER)
|
||||
|
||||
if(panel_open)
|
||||
. += "hackpanel_open"
|
||||
. += sprite_prefix + "hackpanel_open"
|
||||
|
||||
if(anchored) // Using anchored due to removal_stage deanchoring having multiple steps
|
||||
. += "nukebolts"
|
||||
. += sprite_prefix + "nukebolts"
|
||||
|
||||
// Selected stage lets us show the open core, even if the front panel is closed
|
||||
var/selected_stage = removal_stage
|
||||
@@ -151,6 +168,12 @@ GLOBAL_VAR(bomb_set)
|
||||
/obj/machinery/nuclearbomb/attackby(obj/item/O as obj, mob/user as mob, params)
|
||||
if(istype(O, /obj/item/disk/nuclear))
|
||||
if(extended)
|
||||
if(auth)
|
||||
to_chat(user, "<span class='warning'>There's already a disk in the slot!</span>")
|
||||
return
|
||||
if((istype(O, /obj/item/disk/nuclear/training) && !training) || (training && !istype(O, /obj/item/disk/nuclear/training)))
|
||||
to_chat(user, "<span class='warning'>[O] doesn't fit into [src]!</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
to_chat(user, "<span class='notice'>[O] is stuck to your hand!</span>")
|
||||
return
|
||||
@@ -212,12 +235,15 @@ GLOBAL_VAR(bomb_set)
|
||||
if(!I.tool_use_check(user, 0))
|
||||
return
|
||||
if(removal_stage == NUKE_COVER_OFF)
|
||||
user.visible_message("[user] starts forcing open the bolt covers on [src].", "You start forcing open the anchoring bolt covers with [I]...")
|
||||
user.visible_message("<span class='notice'>[user] starts forcing open the bolt covers on [src].</span>", "<span class='notice'>You start forcing open the anchoring bolt covers with [I]...</span>")
|
||||
if(!I.use_tool(src, user, 15, volume = I.tool_volume) || removal_stage != NUKE_COVER_OFF)
|
||||
return
|
||||
user.visible_message("[user] forces open the bolt covers on [src].", "You force open the bolt covers.")
|
||||
user.visible_message("<span class='notice'>[user] forces open the bolt covers on [src].</span>", "<span class='notice'>You force open the bolt covers.</span>")
|
||||
removal_stage = NUKE_COVER_OPEN
|
||||
if(removal_stage == NUKE_CORE_EVERYTHING_FINE)
|
||||
if(training)
|
||||
to_chat(user, "<span class='notice'>This is where you'd take off the plate to access the internal core, but this training bomb doesn't have one.</span>")
|
||||
return
|
||||
user.visible_message("<span class='notice'>[user] starts removing [src]'s outer core plate...</span>", "<span class='notice'>You start removing [src]'s outer core plate...</span>")
|
||||
if(!I.use_tool(src, user, 4 SECONDS, volume = I.tool_volume) || removal_stage != NUKE_CORE_EVERYTHING_FINE)
|
||||
return
|
||||
@@ -235,10 +261,10 @@ GLOBAL_VAR(bomb_set)
|
||||
if(core)
|
||||
START_PROCESSING(SSobj, core)
|
||||
if(removal_stage == NUKE_UNWRENCHED)
|
||||
user.visible_message("[user] begins lifting [src] off of the anchors.", "You begin lifting the device off the anchors...")
|
||||
user.visible_message("<span class='notice'>[user] begins lifting [src] off of the anchors.</span>", "<span class='notice'>You begin lifting the device off the anchors...</span>")
|
||||
if(!I.use_tool(src, user, 8 SECONDS, volume = I.tool_volume) || removal_stage != NUKE_UNWRENCHED)
|
||||
return
|
||||
user.visible_message("[user] crowbars [src] off of the anchors. It can now be moved.", "You jam the crowbar under the nuclear device and lift it off its anchors. You can now move it!")
|
||||
user.visible_message("<span class='notice'>[user] crowbars [src] off of the anchors. It can now be moved.</span>", "<span class='notice'>You jam the crowbar under the nuclear device and lift it off its anchors. You can now move it!</span>")
|
||||
anchored = FALSE
|
||||
removal_stage = NUKE_MOBILE
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
@@ -251,10 +277,10 @@ GLOBAL_VAR(bomb_set)
|
||||
. = TRUE
|
||||
if(!I.tool_use_check(user, 0))
|
||||
return
|
||||
user.visible_message("[user] begins unwrenching the anchoring bolts on [src].", "You begin unwrenching the anchoring bolts...")
|
||||
user.visible_message("<span class='notice'>[user] begins unwrenching the anchoring bolts on [src].</span>", "<span class='notice'>You begin unwrenching the anchoring bolts...</span>")
|
||||
if(!I.use_tool(src, user, 50, volume = I.tool_volume) || removal_stage != NUKE_SEALANT_OPEN)
|
||||
return
|
||||
user.visible_message("[user] unwrenches the anchoring bolts on [src].", "You unwrench the anchoring bolts.")
|
||||
user.visible_message("<span class='notice'>[user] unwrenches the anchoring bolts on [src].</span>", "<span class='notice'>You unwrench the anchoring bolts.</span>")
|
||||
removal_stage = NUKE_UNWRENCHED
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
@@ -273,23 +299,23 @@ GLOBAL_VAR(bomb_set)
|
||||
if(auth || (istype(I, /obj/item/screwdriver/nuke) && !is_syndicate))
|
||||
if(!panel_open)
|
||||
panel_open = TRUE
|
||||
to_chat(user, "You unscrew the control panel of [src].")
|
||||
to_chat(user, "<span class='notice'>You unscrew the control panel of [src].</span>")
|
||||
anchor_stage = removal_stage
|
||||
removal_stage = core_stage
|
||||
else
|
||||
panel_open = FALSE
|
||||
to_chat(user, "You screw the control panel of [src] back on.")
|
||||
to_chat(user, "<span class='notice'>You screw the control panel of [src] back on.</span>")
|
||||
core_stage = removal_stage
|
||||
removal_stage = anchor_stage
|
||||
else
|
||||
if(!panel_open)
|
||||
to_chat(user, "[src] emits a buzzing noise, the panel staying locked in.")
|
||||
to_chat(user, "<span class='warning'>[src] emits a buzzing noise, the panel staying locked in.</span>")
|
||||
if(panel_open)
|
||||
panel_open = FALSE
|
||||
to_chat(user, "You screw the control panel of [src] back on.")
|
||||
to_chat(user, "<span class='notice'>You screw the control panel of [src] back on.</span>")
|
||||
core_stage = removal_stage
|
||||
removal_stage = anchor_stage
|
||||
flick("nuclearbombc", src)
|
||||
flick(sprite_prefix + "nuclearbombc", src)
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
/obj/machinery/nuclearbomb/wirecutter_act(mob/user, obj/item/I)
|
||||
@@ -397,6 +423,8 @@ GLOBAL_VAR(bomb_set)
|
||||
|
||||
/obj/machinery/nuclearbomb/proc/is_auth(mob/user)
|
||||
if(auth)
|
||||
if(istype(auth, /obj/item/disk/nuclear/training) && !training)
|
||||
return FALSE
|
||||
return TRUE
|
||||
else if(user.can_admin_interact())
|
||||
return TRUE
|
||||
@@ -409,6 +437,9 @@ GLOBAL_VAR(bomb_set)
|
||||
. = TRUE
|
||||
if(exploded)
|
||||
return
|
||||
if(wires.is_cut(WIRE_NUKE_CONTROL))
|
||||
to_chat(usr, "<span class='warning'>The control panel isn't responding! Something must be wrong with its wiring!</span>")
|
||||
return FALSE
|
||||
switch(action)
|
||||
if("deploy")
|
||||
if(removal_stage != NUKE_MOBILE)
|
||||
@@ -416,9 +447,9 @@ GLOBAL_VAR(bomb_set)
|
||||
visible_message("<span class='warning'>With a steely snap, bolts slide out of [src] and anchor it to the flooring!</span>")
|
||||
else
|
||||
visible_message("<span class='warning'>[src] makes a highly unpleasant crunching noise. It looks like the anchoring bolts have been cut.</span>")
|
||||
if(!lighthack)
|
||||
flick("nuclearbombc", src)
|
||||
icon_state = "nuclearbomb1"
|
||||
if(!wires.is_cut(WIRE_NUKE_LIGHT))
|
||||
flick(sprite_prefix + "nuclearbombc", src)
|
||||
icon_state = sprite_prefix + "nuclearbomb1"
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
extended = TRUE
|
||||
return
|
||||
@@ -433,6 +464,8 @@ GLOBAL_VAR(bomb_set)
|
||||
else
|
||||
var/obj/item/I = usr.get_active_hand()
|
||||
if(istype(I, /obj/item/disk/nuclear))
|
||||
if((istype(I, /obj/item/disk/nuclear/training) && !training) || (training && !istype(I, /obj/item/disk/nuclear/training)))
|
||||
return
|
||||
usr.drop_item()
|
||||
I.forceMove(src)
|
||||
auth = I
|
||||
@@ -491,43 +524,57 @@ GLOBAL_VAR(bomb_set)
|
||||
return
|
||||
timeleft = time
|
||||
if("toggle_safety")
|
||||
if(wires.is_cut(WIRE_NUKE_SAFETY))
|
||||
to_chat(usr, "<span class='warning'>The safety isn't responding! Something must be wrong with its wiring!</span>")
|
||||
return FALSE
|
||||
safety = !(safety)
|
||||
if(safety)
|
||||
if(!is_syndicate)
|
||||
if(!is_syndicate && !training)
|
||||
SSsecurity_level.set_level(previous_level)
|
||||
timing = FALSE
|
||||
GLOB.bomb_set = FALSE
|
||||
if(!training)
|
||||
GLOB.bomb_set = FALSE
|
||||
if("toggle_armed")
|
||||
if(safety)
|
||||
to_chat(usr, "<span class='notice'>The safety is still on.</span>")
|
||||
return
|
||||
if(!core)
|
||||
if(!core && !training)
|
||||
to_chat(usr, "<span class='danger'>[src]'s screen blinks red! There is no plutonium core in [src]!</span>")
|
||||
return
|
||||
timing = !(timing)
|
||||
if(timing)
|
||||
if(!lighthack)
|
||||
icon_state = "nuclearbomb2"
|
||||
if(!timing)
|
||||
if(wires.is_cut(WIRE_NUKE_DETONATOR))
|
||||
to_chat(usr, "<span class='warning'>[src] isn't arming! Something must be wrong with its wiring!</span>")
|
||||
return FALSE
|
||||
timing = TRUE
|
||||
if(!wires.is_cut(WIRE_NUKE_LIGHT))
|
||||
icon_state = sprite_prefix + "nuclearbomb2"
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
if(!safety)
|
||||
if(!safety && !training)
|
||||
message_admins("[key_name_admin(usr)] engaged a nuclear bomb [ADMIN_JMP(src)]")
|
||||
if(!is_syndicate && SSsecurity_level.get_current_level_as_number() != SEC_LEVEL_EPSILON)
|
||||
SSsecurity_level.set_level(SEC_LEVEL_DELTA)
|
||||
GLOB.bomb_set = TRUE // There can still be issues with this resetting when there are multiple bombs. Not a big deal though for Nuke
|
||||
if(SSsecurity_level.get_current_level_as_number() == SEC_LEVEL_EPSILON)
|
||||
radio.autosay("<span class='reallybig'>The Nuclear Bomb has been armed, retreat from the station immediately!</span>", name, "Special Ops")
|
||||
else
|
||||
else if(!training)
|
||||
GLOB.bomb_set = TRUE
|
||||
else
|
||||
if(!is_syndicate)
|
||||
if(wires.is_cut(WIRE_NUKE_DISARM))
|
||||
to_chat(usr, "<span class='warning'>[src] isn't disarming! Something must be wrong with its wiring!</span>")
|
||||
return FALSE
|
||||
timing = FALSE
|
||||
if(!is_syndicate && !training)
|
||||
SSsecurity_level.set_level(previous_level)
|
||||
GLOB.bomb_set = FALSE
|
||||
if(!lighthack)
|
||||
icon_state = "nuclearbomb1"
|
||||
if(!training)
|
||||
GLOB.bomb_set = FALSE
|
||||
if(!wires.is_cut(WIRE_NUKE_LIGHT))
|
||||
icon_state = sprite_prefix + "nuclearbomb1"
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
|
||||
/obj/machinery/nuclearbomb/blob_act(obj/structure/blob/B)
|
||||
if(training)
|
||||
qdel(src)
|
||||
return
|
||||
if(exploded)
|
||||
return
|
||||
if(timing) //boom
|
||||
@@ -567,16 +614,19 @@ GLOBAL_VAR(bomb_set)
|
||||
|
||||
|
||||
/obj/machinery/nuclearbomb/proc/explode()
|
||||
if(training)
|
||||
atom_say("You've triggered the detonate wire. You are dead.")
|
||||
return
|
||||
if(safety)
|
||||
timing = FALSE
|
||||
return
|
||||
exploded = TRUE
|
||||
yes_code = FALSE
|
||||
safety = TRUE
|
||||
if(!lighthack)
|
||||
icon_state = "nuclearbomb3"
|
||||
if(!wires.is_cut(WIRE_NUKE_LIGHT))
|
||||
icon_state = sprite_prefix + "nuclearbomb3"
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
playsound(src,'sound/machines/alarm.ogg',100,0,5)
|
||||
playsound(src, 'sound/machines/alarm.ogg', 100, FALSE, 5)
|
||||
if(SSticker && SSticker.mode)
|
||||
SSticker.mode.explosion_in_progress = TRUE
|
||||
SSticker.event_blackbox(outcome = ROUND_END_NUCLEAR)
|
||||
@@ -618,23 +668,6 @@ GLOBAL_VAR(bomb_set)
|
||||
return
|
||||
return
|
||||
|
||||
/obj/machinery/nuclearbomb/proc/reset_lighthack_callback()
|
||||
lighthack = !lighthack
|
||||
|
||||
/obj/machinery/nuclearbomb/proc/reset_safety_callback()
|
||||
safety = !safety
|
||||
if(safety == 1)
|
||||
if(!is_syndicate)
|
||||
SSsecurity_level.set_level(previous_level)
|
||||
visible_message("<span class='notice'>[src] quiets down.</span>")
|
||||
if(!lighthack)
|
||||
if(icon_state == "nuclearbomb2")
|
||||
icon_state = "nuclearbomb1"
|
||||
update_icon(UPDATE_OVERLAYS)
|
||||
|
||||
else
|
||||
visible_message("<span class='notice'>[src] emits a quiet whirling noise!</span>")
|
||||
|
||||
//==========DAT FUKKEN DISK===============
|
||||
/obj/item/disk/nuclear
|
||||
name = "nuclear authentication disk"
|
||||
@@ -645,6 +678,8 @@ GLOBAL_VAR(bomb_set)
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
/// Is the disk restricted to the station? If true, also respawns the disk when deleted
|
||||
var/restricted_to_station = TRUE
|
||||
/// Is this a training disk?
|
||||
var/training = FALSE
|
||||
|
||||
/obj/item/disk/nuclear/unrestricted
|
||||
name = "unrestricted nuclear authentication disk"
|
||||
@@ -655,7 +690,9 @@ GLOBAL_VAR(bomb_set)
|
||||
..()
|
||||
if(restricted_to_station)
|
||||
START_PROCESSING(SSobj, src)
|
||||
GLOB.poi_list |= src
|
||||
if(!training)
|
||||
GLOB.poi_list |= src
|
||||
GLOB.nad_list |= src
|
||||
|
||||
/obj/item/disk/nuclear/process()
|
||||
if(!restricted_to_station)
|
||||
@@ -682,26 +719,32 @@ GLOBAL_VAR(bomb_set)
|
||||
/obj/item/disk/nuclear/Destroy(force)
|
||||
var/turf/diskturf = get_turf(src)
|
||||
|
||||
if(training)
|
||||
return ..()
|
||||
|
||||
if(force)
|
||||
message_admins("[src] has been !!force deleted!! in ([diskturf ? "[diskturf.x], [diskturf.y] ,[diskturf.z] - <A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[diskturf.x];Y=[diskturf.y];Z=[diskturf.z]'>JMP</a>":"nonexistent location"]).")
|
||||
message_admins("[src] has been !!force deleted!! in ([diskturf ? "[diskturf.x], [diskturf.y] ,[diskturf.z] - <a href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[diskturf.x];Y=[diskturf.y];Z=[diskturf.z]'>JMP</a>":"nonexistent location"]).")
|
||||
log_game("[src] has been !!force deleted!! in ([diskturf ? "[diskturf.x], [diskturf.y] ,[diskturf.z]":"nonexistent location"]).")
|
||||
GLOB.poi_list.Remove(src)
|
||||
GLOB.nad_list.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
if(!restricted_to_station) // Non-restricted NADs should be allowed to be deleted, otherwise it becomes a restricted NAD when teleported
|
||||
message_admins("[src] (unrestricted) has been deleted in ([diskturf ? "[diskturf.x], [diskturf.y] ,[diskturf.z] - <A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[diskturf.x];Y=[diskturf.y];Z=[diskturf.z]'>JMP</a>":"nonexistent location"]). It will not respawn.")
|
||||
message_admins("[src] (unrestricted) has been deleted in ([diskturf ? "[diskturf.x], [diskturf.y] ,[diskturf.z] - <a href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[diskturf.x];Y=[diskturf.y];Z=[diskturf.z]'>JMP</a>":"nonexistent location"]). It will not respawn.")
|
||||
log_game("[src] (unrestricted) has been deleted in ([diskturf ? "[diskturf.x], [diskturf.y] ,[diskturf.z]":"nonexistent location"]). It will not respawn.")
|
||||
GLOB.poi_list.Remove(src)
|
||||
GLOB.nad_list.Remove(src)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
return ..()
|
||||
|
||||
var/turf/new_spawn = find_respawn()
|
||||
if(new_spawn)
|
||||
GLOB.poi_list.Remove(src)
|
||||
GLOB.nad_list.Remove(src)
|
||||
var/obj/item/disk/nuclear/NEWDISK = new(new_spawn)
|
||||
transfer_fingerprints_to(NEWDISK)
|
||||
message_admins("[src] has been destroyed at ([diskturf.x], [diskturf.y], [diskturf.z] - <A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[diskturf.x];Y=[diskturf.y];Z=[diskturf.z]'>JMP</a>). Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z] - <A href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[NEWDISK.x];Y=[NEWDISK.y];Z=[NEWDISK.z]'>JMP</a>).")
|
||||
message_admins("[src] has been destroyed at ([diskturf.x], [diskturf.y], [diskturf.z] - <a href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[diskturf.x];Y=[diskturf.y];Z=[diskturf.z]'>JMP</a>). Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z] - <a href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[NEWDISK.x];Y=[NEWDISK.y];Z=[NEWDISK.z]'>JMP</a>).")
|
||||
log_game("[src] has been destroyed in ([diskturf.x], [diskturf.y], [diskturf.z]). Moving it to ([NEWDISK.x], [NEWDISK.y], [NEWDISK.z]).")
|
||||
..()
|
||||
return QDEL_HINT_HARDDEL_NOW // We want this to be deleted ASAP, but we want refs properly cleared too
|
||||
@@ -720,6 +763,54 @@ GLOBAL_VAR(bomb_set)
|
||||
if(length(open_turfs))
|
||||
return pick(open_turfs)
|
||||
|
||||
/// MARK: TRAINING NUKE
|
||||
|
||||
/obj/machinery/nuclearbomb/training
|
||||
name = "training nuclear bomb"
|
||||
desc = "A fake nuke used to practice nuclear device operations. \
|
||||
The '1' key on the keypad appears to be significantly more worn than the other keys."
|
||||
icon_state = "t_nuclearbomb1"
|
||||
resistance_flags = null
|
||||
training = TRUE
|
||||
sprite_prefix = "t_"
|
||||
|
||||
/obj/machinery/nuclearbomb/training/Initialize()
|
||||
. = ..()
|
||||
r_code = 11111 //Uuh.. one!
|
||||
qdel(core)
|
||||
|
||||
/obj/machinery/nuclearbomb/training/process()
|
||||
if(timing)
|
||||
timeleft = max(timeleft - 2, 0) // 2 seconds per process()
|
||||
if(timeleft <= 0)
|
||||
INVOKE_ASYNC(src, PROC_REF(training_detonation))
|
||||
|
||||
/obj/machinery/nuclearbomb/training/blob_act(obj/structure/blob/B)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/nuclearbomb/training/AltClick(mob/user)
|
||||
. = ..()
|
||||
to_chat(user, "<span class='notice'>You hit the reset button on [src].</span>")
|
||||
training_reset()
|
||||
|
||||
/obj/machinery/nuclearbomb/training/proc/training_detonation()
|
||||
atom_say("Nuclear device detonated. Resetting...")
|
||||
training_reset()
|
||||
|
||||
/obj/machinery/nuclearbomb/training/proc/training_reset()
|
||||
if(auth)
|
||||
auth.forceMove(get_turf(src))
|
||||
new /obj/machinery/nuclearbomb/training(get_turf(src))
|
||||
qdel(src)
|
||||
|
||||
/obj/item/disk/nuclear/training
|
||||
name = "training authentication disk"
|
||||
desc = "The code is 11111."
|
||||
icon_state = "trainingdisk"
|
||||
resistance_flags = null
|
||||
restricted_to_station = FALSE
|
||||
training = TRUE
|
||||
|
||||
#undef NUKE_INTACT
|
||||
#undef NUKE_COVER_OFF
|
||||
#undef NUKE_COVER_OPEN
|
||||
|
||||
@@ -96,15 +96,15 @@
|
||||
|
||||
/obj/item/pinpointer/proc/scandisk()
|
||||
if(!the_disk)
|
||||
the_disk = locate() in GLOB.poi_list
|
||||
the_disk = locate() in GLOB.nad_list
|
||||
|
||||
/obj/item/pinpointer/proc/scanbomb()
|
||||
if(!syndicate)
|
||||
if(!the_bomb)
|
||||
the_bomb = locate() in GLOB.poi_list
|
||||
the_bomb = locate() in GLOB.nuke_list
|
||||
else
|
||||
if(!the_s_bomb)
|
||||
the_s_bomb = locate() in GLOB.poi_list
|
||||
the_s_bomb = locate() in GLOB.syndi_nuke_list
|
||||
|
||||
/obj/item/pinpointer/proc/point_at_target(atom/target)
|
||||
if(!target)
|
||||
|
||||
@@ -106,6 +106,11 @@
|
||||
protected_jobs = list("Captain")
|
||||
location_override = "the Captain's Office"
|
||||
|
||||
/datum/theft_objective/nukedisc/check_special_completion(obj/item/I)
|
||||
if(istype(I, /obj/item/disk/nuclear/training)) //Haha no
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/theft_objective/reactive
|
||||
name = "any type of reactive armor"
|
||||
typepath = /obj/item/clothing/suit/armor/reactive
|
||||
|
||||
@@ -389,11 +389,9 @@
|
||||
card_icon = "wheel_of_fortune"
|
||||
|
||||
/datum/tarot/wheel_of_fortune/activate(mob/living/target)
|
||||
var/list/static/bad_vendors = list(
|
||||
/obj/machinery/economy/vending/liberationstation,
|
||||
/obj/machinery/economy/vending/toyliberationstation,
|
||||
/obj/machinery/economy/vending/wallmed
|
||||
)
|
||||
var/list/static/bad_vendors = typesof(/obj/machinery/economy/vending/liberationstation)\
|
||||
+ typesof(/obj/machinery/economy/vending/toyliberationstation)\
|
||||
+ typesof(/obj/machinery/economy/vending/wallmed) // Future proofing in case we add more subtypes of disallowed vendors
|
||||
var/turf/target_turf = get_turf(target)
|
||||
var/vendorpath = pick(subtypesof(/obj/machinery/economy/vending) - bad_vendors)
|
||||
new vendorpath(target_turf)
|
||||
|
||||
@@ -41,10 +41,8 @@
|
||||
/obj/item/organ/internal/cyberimp/arm/combat/centcom
|
||||
)
|
||||
|
||||
/datum/outfit/job/ntnavyofficer/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
/datum/outfit/job/ntnavyofficer/on_mind_initialize(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
if(visualsOnly)
|
||||
return
|
||||
H.mind.offstation_role = TRUE
|
||||
|
||||
// CC Officials who lead ERTs, Death Squads, etc.
|
||||
@@ -97,10 +95,8 @@
|
||||
/obj/item/organ/internal/cyberimp/arm/combat/centcom
|
||||
)
|
||||
|
||||
/datum/outfit/job/ntspecops/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
/datum/outfit/job/ntspecops/on_mind_initialize(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
if(visualsOnly)
|
||||
return
|
||||
H.mind.offstation_role = TRUE
|
||||
|
||||
/datum/job/ntspecops/solgovspecops
|
||||
@@ -121,4 +117,7 @@
|
||||
if(istype(I))
|
||||
apply_to_card(I, H, get_centcom_access(name), name, "lifetimeid")
|
||||
H.sec_hud_set_ID()
|
||||
|
||||
/datum/outfit/job/ntspecops/solgovspecops/on_mind_initialize(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
H.mind.offstation_role = TRUE
|
||||
|
||||
@@ -216,6 +216,7 @@
|
||||
gear_leftovers += G
|
||||
|
||||
/datum/outfit/job/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
. = ..()
|
||||
if(visualsOnly)
|
||||
return
|
||||
|
||||
@@ -280,3 +281,16 @@
|
||||
PDA.ownjob = C.assignment
|
||||
PDA.ownrank = C.rank
|
||||
PDA.name = "PDA-[H.real_name] ([PDA.ownjob])"
|
||||
|
||||
/datum/outfit/job/on_mind_initialize(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
var/obj/item/card/id/id = H.wear_id
|
||||
if(!id)
|
||||
return
|
||||
var/datum/job/J = SSjobs.GetJobType(jobtype)
|
||||
if(!J)
|
||||
J = SSjobs.GetJob(H.job)
|
||||
id.assignment = H.mind.role_alt_title ? H.mind.role_alt_title : J.title
|
||||
if(!H.mind.initial_account)
|
||||
return
|
||||
id.associated_account_number = H.mind.initial_account.account_number
|
||||
|
||||
@@ -202,6 +202,9 @@
|
||||
singlemutcheck(H, GLOB.soberblock, MUTCHK_FORCED)
|
||||
H.dna.default_blocks.Add(GLOB.soberblock)
|
||||
H.check_mutations = 1
|
||||
|
||||
/datum/outfit/job/bartender/on_mind_initialize(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
ADD_TRAIT(H.mind, TRAIT_TABLE_LEAP, ROUNDSTART_TRAIT)
|
||||
ADD_TRAIT(H.mind, TRAIT_SLEIGHT_OF_HAND, ROUNDSTART_TRAIT)
|
||||
|
||||
@@ -236,12 +239,10 @@
|
||||
/obj/item/paper/chef=1,\
|
||||
/obj/item/book/manual/wiki/chef_recipes=1)
|
||||
|
||||
/datum/outfit/job/chef/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
..()
|
||||
if(visualsOnly)
|
||||
return
|
||||
/datum/outfit/job/chef/on_mind_initialize(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
var/datum/martial_art/cqc/under_siege/justacook = new
|
||||
justacook.teach(H)
|
||||
justacook.teach(H) // requires mind
|
||||
ADD_TRAIT(H.mind, TRAIT_TABLE_LEAP, ROUNDSTART_TRAIT)
|
||||
|
||||
|
||||
@@ -419,12 +420,14 @@
|
||||
if(visualsOnly)
|
||||
return
|
||||
|
||||
if(H.mind)
|
||||
H.mind.AddSpell(new /datum/spell/aoe/conjure/build/mime_wall(null))
|
||||
H.mind.AddSpell(new /datum/spell/mime/speak(null))
|
||||
H.mind.miming = 1
|
||||
qdel(H.GetComponent(/datum/component/footstep))
|
||||
|
||||
/datum/outfit/job/mime/on_mind_initialize(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
H.mind.AddSpell(new /datum/spell/aoe/conjure/build/mime_wall(null))
|
||||
H.mind.AddSpell(new /datum/spell/mime/speak(null))
|
||||
H.mind.miming = TRUE
|
||||
|
||||
/datum/job/janitor
|
||||
title = "Janitor"
|
||||
flag = JOB_JANITOR
|
||||
@@ -488,7 +491,7 @@
|
||||
|
||||
/datum/outfit/job/librarian/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
..()
|
||||
if(!H.mind)
|
||||
if(visualsOnly)
|
||||
return
|
||||
for(var/la in GLOB.all_languages)
|
||||
var/datum/language/new_language = GLOB.all_languages[la]
|
||||
|
||||
@@ -32,11 +32,12 @@
|
||||
if(visualsOnly)
|
||||
return
|
||||
|
||||
if(istype(H.mind))
|
||||
ADD_TRAIT(H.mind, TRAIT_HOLY, ROUNDSTART_TRAIT)
|
||||
|
||||
INVOKE_ASYNC(src, PROC_REF(religion_pick), H)
|
||||
|
||||
/datum/outfit/job/chaplain/on_mind_initialize(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
ADD_TRAIT(H.mind, TRAIT_HOLY, ROUNDSTART_TRAIT)
|
||||
|
||||
/datum/outfit/job/chaplain/proc/religion_pick(mob/living/carbon/human/user)
|
||||
var/obj/item/storage/bible/B = new /obj/item/storage/bible(get_turf(user))
|
||||
B.customisable = TRUE // Only the initial bible is customisable
|
||||
|
||||
@@ -55,8 +55,11 @@
|
||||
U.implant(H)
|
||||
U.hidden_uplink.uses = 2500
|
||||
H.faction += "syndicate"
|
||||
|
||||
/datum/outfit/job/syndicateofficer/on_mind_initialize(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
var/datum/atom_hud/antag/opshud = GLOB.huds[ANTAG_HUD_OPS]
|
||||
opshud.join_hud(H.mind.current)
|
||||
H.mind.offstation_role = TRUE
|
||||
set_antag_hud(H.mind.current, "hudoperative")
|
||||
H.regenerate_icons()
|
||||
INVOKE_ASYNC(H, TYPE_PROC_REF(/mob/living/carbon/human, regenerate_icons))
|
||||
|
||||
@@ -300,20 +300,7 @@
|
||||
emagged = FALSE
|
||||
setMenuState(ui.user, COMM_SCREEN_MAIN)
|
||||
|
||||
if("RestartNanoMob")
|
||||
if(SSmob_hunt)
|
||||
if(SSmob_hunt.manual_reboot())
|
||||
var/loading_msg = pick("Respawning spawns", "Reticulating splines", "Flipping hat",
|
||||
"Capturing all of them", "Fixing minor text issues", "Being the very best",
|
||||
"Nerfing this", "Not communicating with playerbase", "Coding a ripoff in a 2D spaceman game")
|
||||
to_chat(ui.user, "<span class='notice'>Restarting Nano-Mob Hunter GO! game server. [loading_msg]...</span>")
|
||||
else
|
||||
to_chat(ui.user, "<span class='warning'>Nano-Mob Hunter GO! game server reboot failed due to recent restart. Please wait before re-attempting.</span>")
|
||||
else
|
||||
to_chat(ui.user, "<span class='danger'>Nano-Mob Hunter GO! game server is offline for extended maintenance. Contact your Central Command administrators for more info if desired.</span>")
|
||||
|
||||
// ADMIN CENTCOMM ONLY STUFF
|
||||
|
||||
if("send_to_cc_announcement_page")
|
||||
if(!ADMIN_CHECK(ui.user))
|
||||
return
|
||||
|
||||
@@ -301,8 +301,9 @@
|
||||
if(occupant_typecache)
|
||||
occupant_typecache = typecacheof(occupant_typecache)
|
||||
|
||||
/obj/machinery/suit_storage_unit/Destroy()
|
||||
dump_contents()
|
||||
/obj/machinery/suit_storage_unit/Destroy(force)
|
||||
if(!force)
|
||||
dump_contents()
|
||||
SStgui.close_uis(wires)
|
||||
QDEL_NULL(wires)
|
||||
return ..()
|
||||
|
||||
@@ -1301,7 +1301,6 @@
|
||||
icon_panel = "wide_vendor"
|
||||
category = VENDOR_TYPE_SUPPLIES
|
||||
products = list(/obj/item/pda =10,
|
||||
/obj/item/cartridge/mob_hunt_game = 25,
|
||||
/obj/item/cartridge/medical = 10,
|
||||
/obj/item/cartridge/chemistry = 10,
|
||||
/obj/item/cartridge/engineering = 10,
|
||||
@@ -1314,7 +1313,6 @@
|
||||
/obj/item/cartridge/mime = 1)
|
||||
|
||||
prices = list(/obj/item/pda = 300,
|
||||
/obj/item/cartridge/mob_hunt_game = 50,
|
||||
/obj/item/cartridge/medical = 200,
|
||||
/obj/item/cartridge/chemistry = 150,
|
||||
/obj/item/cartridge/engineering = 100,
|
||||
|
||||
@@ -16,8 +16,16 @@
|
||||
wreckage = /obj/structure/mecha_wreckage/ripley
|
||||
var/list/cargo = new
|
||||
var/cargo_capacity = 15
|
||||
|
||||
/// How many goliath hides does the Ripley have? Does not stack with other armor
|
||||
var/hides = 0
|
||||
|
||||
/// How many drake hides does the Ripley have? Does not stack with other armor
|
||||
var/drake_hides = 0
|
||||
|
||||
/// How many plates does the Ripley have? Does not stack with other armor
|
||||
var/plates = 0
|
||||
|
||||
/obj/mecha/working/ripley/Move()
|
||||
. = ..()
|
||||
if(.)
|
||||
@@ -33,10 +41,14 @@
|
||||
ore.forceMove(ore_box)
|
||||
|
||||
/obj/mecha/working/ripley/Destroy()
|
||||
for(var/i=1, i <= hides, i++)
|
||||
new /obj/item/stack/sheet/animalhide/goliath_hide(loc) //If a goliath-plated ripley gets killed, all the plates drop
|
||||
for(var/i in 1 to hides)
|
||||
new /obj/item/stack/sheet/animalhide/goliath_hide(get_turf(src)) //If a armor-plated ripley gets killed, all the armor drop
|
||||
for(var/i in 1 to plates)
|
||||
new /obj/item/stack/sheet/animalhide/armor_plate(get_turf(src))
|
||||
for(var/i in 1 to drake_hides)
|
||||
new /obj/item/stack/sheet/animalhide/ashdrake(get_turf(src))
|
||||
for(var/atom/movable/A in cargo)
|
||||
A.forceMove(loc)
|
||||
A.forceMove(get_turf(src))
|
||||
step_rand(A)
|
||||
cargo.Cut()
|
||||
return ..()
|
||||
@@ -55,22 +67,58 @@
|
||||
|
||||
/obj/mecha/working/ripley/update_desc()
|
||||
. = ..()
|
||||
if(!hides) // Just in case if hides are somehow removed
|
||||
if(!hides && !plates && !drake_hides) // Just in case if armor is removed
|
||||
desc = initial(desc)
|
||||
return
|
||||
if(hides == 3)
|
||||
desc = "Autonomous Power Loader Unit. It's wearing a fearsome carapace entirely composed of goliath hide plates - its pilot must be an experienced monster hunter."
|
||||
else
|
||||
desc = "Autonomous Power Loader Unit. Its armour is enhanced with some goliath hide plates."
|
||||
|
||||
// Goliath hides
|
||||
if(hides)
|
||||
if(hides == HIDES_COVERED_FULL)
|
||||
desc = "Autonomous Power Loader Unit. It's wearing a fearsome carapace entirely composed of goliath hide plates - its pilot must be an experienced monster hunter."
|
||||
else
|
||||
desc = "Autonomous Power Loader Unit. Its armour is enhanced with some goliath hide plates."
|
||||
return
|
||||
|
||||
// Metal plates
|
||||
if(plates)
|
||||
if(plates == PLATES_COVERED_FULL)
|
||||
desc = "Autonomous Power Loader Unit. Its armor is completely lined with metal plating."
|
||||
else
|
||||
desc = "Autonomous Power Loader Unit. Its armor is reinforced with some metal plating."
|
||||
return
|
||||
|
||||
// Drake hides
|
||||
if(drake_hides)
|
||||
if(drake_hides == DRAKE_HIDES_COVERED_FULL)
|
||||
desc = "Autonomous Power Loader Unit. Its every corner is covered in ancient hide, creating a powerful shield. The pilot of this exosuit must be prepared for battles on the level of legend."
|
||||
if(drake_hides == DRAKE_HIDES_COVERED_MODERATE)
|
||||
desc = "Autonomous Power Loader Unit. Its armor is adorned with dragon hide plates, instilling fear in its enemies and guarding its pilot."
|
||||
if(drake_hides == DRAKE_HIDES_COVERED_SLIGHT)
|
||||
desc = "Autonomous Power Loader Unit. The armor of this exosuit only touches the mythical: a few plates of dragon hide adorn its plating like rare warrior trophies."
|
||||
return
|
||||
|
||||
/obj/mecha/working/ripley/update_overlays()
|
||||
. = ..()
|
||||
if(!hides)
|
||||
return
|
||||
if(hides == 3)
|
||||
. += occupant ? "ripley-g-full" : "ripley-g-full-open"
|
||||
else
|
||||
. += occupant ? "ripley-g" : "ripley-g-open"
|
||||
// hides
|
||||
if(hides)
|
||||
if(hides == HIDES_COVERED_FULL)
|
||||
. += occupant ? "ripley-g-full" : "ripley-g-full-open"
|
||||
else
|
||||
. += occupant ? "ripley-g" : "ripley-g-open"
|
||||
//plates
|
||||
if(plates)
|
||||
if(plates == PLATES_COVERED_FULL)
|
||||
. += occupant ? "ripley-m-full" : "ripley-m-full-open"
|
||||
else
|
||||
. += occupant ? "ripley-m" : "ripley-m-open"
|
||||
//drake hides
|
||||
if(drake_hides)
|
||||
if(drake_hides == DRAKE_HIDES_COVERED_FULL)
|
||||
. += occupant ? "ripley-d-full" : "ripley-d-full-open"
|
||||
else if(drake_hides == DRAKE_HIDES_COVERED_MODERATE)
|
||||
. += occupant ? "ripley-d-2" : "ripley-d-2-open"
|
||||
else if(drake_hides == DRAKE_HIDES_COVERED_SLIGHT)
|
||||
. += occupant ? "ripley-d" : "ripley-d-open"
|
||||
|
||||
/obj/mecha/working/ripley/firefighter
|
||||
desc = "A standard APLU chassis that was refitted with additional thermal protection and a cistern."
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
/obj/mecha/working
|
||||
internal_damage_threshold = 60
|
||||
|
||||
|
||||
@@ -228,3 +228,6 @@
|
||||
|
||||
/obj/effect/turf_decal/raven/nine
|
||||
icon_state = "RAVEN9"
|
||||
|
||||
/obj/effect/turf_decal/blue_corner
|
||||
icon_state = "darkbluecorners"
|
||||
|
||||
@@ -19,41 +19,3 @@
|
||||
for(var/j in 1 to steps_amt)
|
||||
sleep(1)
|
||||
step(expl,direct)
|
||||
|
||||
/obj/effect/explosion
|
||||
name = "explosive particles"
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "explosion"
|
||||
opacity = TRUE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
|
||||
/obj/effect/explosion/New()
|
||||
..()
|
||||
QDEL_IN(src, 10)
|
||||
|
||||
/datum/effect_system/explosion
|
||||
|
||||
/datum/effect_system/explosion/set_up(loca)
|
||||
if(isturf(loca))
|
||||
location = loca
|
||||
else
|
||||
location = get_turf(loca)
|
||||
|
||||
/datum/effect_system/explosion/start()
|
||||
new/obj/effect/explosion(location)
|
||||
var/datum/effect_system/expl_particles/P = new/datum/effect_system/expl_particles()
|
||||
P.set_up(10, 0, location)
|
||||
P.start()
|
||||
|
||||
/datum/effect_system/explosion/smoke
|
||||
|
||||
/datum/effect_system/explosion/smoke/proc/create_smoke()
|
||||
var/datum/effect_system/smoke_spread/S = new
|
||||
S.set_up(5, FALSE, location, null)
|
||||
S.start()
|
||||
|
||||
/datum/effect_system/explosion/smoke/start()
|
||||
..()
|
||||
addtimer(CALLBACK(src, PROC_REF(create_smoke)), 5)
|
||||
|
||||
@@ -678,8 +678,5 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/newplayer_start) //Without this you sp
|
||||
var/turf/simulated/T = get_turf(src)
|
||||
T.burn_tile()
|
||||
|
||||
/obj/effect/landmark/battle_mob_point
|
||||
name = "Nanomob Battle Avatar Spawn Point"
|
||||
|
||||
/obj/effect/landmark/free_golem_spawn
|
||||
name = "Free Golem Spawn Point"
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/obj/effect/temp_visual/explosion
|
||||
name = "boom"
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "explosion2"
|
||||
duration = 6 SECONDS
|
||||
/// Smoke wave particle holder
|
||||
var/obj/effect/abstract/particle_holder/smoke_wave
|
||||
/// Explosion smoke particle holder
|
||||
var/obj/effect/abstract/particle_holder/explosion_smoke
|
||||
/// Sparks particle holder
|
||||
var/obj/effect/abstract/particle_holder/sparks
|
||||
|
||||
/obj/effect/temp_visual/explosion/Initialize(mapload, radius, color, small = FALSE, large = FALSE)
|
||||
. = ..()
|
||||
set_light(radius, radius, LIGHT_COLOR_ORANGE)
|
||||
generate_particles(radius, small, large)
|
||||
var/image/I = image(icon, src, icon_state, 10, -32, -32)
|
||||
var/matrix/rotate = matrix()
|
||||
rotate.Turn(rand(0, 359))
|
||||
I.transform = rotate
|
||||
overlays += I // We use an overlay so the explosion and light source are both in the correct location plus so the particles don't rotate with the explosion
|
||||
icon_state = null
|
||||
|
||||
/// Generate the particles
|
||||
/obj/effect/temp_visual/explosion/proc/generate_particles(radius, small = FALSE, large = FALSE)
|
||||
if(small)
|
||||
smoke_wave = new(src, /particles/smoke_wave/small)
|
||||
else
|
||||
smoke_wave = new(src, /particles/smoke_wave)
|
||||
|
||||
if(large)
|
||||
explosion_smoke = new(src, /particles/explosion_smoke/deva)
|
||||
else if(small)
|
||||
explosion_smoke = new(src, /particles/explosion_smoke/small)
|
||||
else
|
||||
explosion_smoke = new(src, /particles/explosion_smoke)
|
||||
|
||||
sparks = new(src, /particles/sparks_outwards)
|
||||
|
||||
if(large)
|
||||
smoke_wave.particles.velocity = generator(GEN_CIRCLE, 6 * radius, 6 * radius)
|
||||
else if(small)
|
||||
smoke_wave.particles.velocity = generator(GEN_CIRCLE, 3 * radius, 3 * radius)
|
||||
else
|
||||
smoke_wave.particles.velocity = generator(GEN_CIRCLE, 5 * radius, 5 * radius)
|
||||
|
||||
explosion_smoke.layer = layer + 0.1
|
||||
sparks.particles.velocity = generator(GEN_CIRCLE, 8 * radius, 8 * radius)
|
||||
|
||||
// The reason for these timers is to set the count to 0
|
||||
// This causes any particle systems to not spawn in new particles, but not delete the currently existing ones
|
||||
addtimer(CALLBACK(src, PROC_REF(set_count_short)), 1 SECONDS)
|
||||
|
||||
/obj/effect/temp_visual/explosion/proc/set_count_short()
|
||||
remove_light()
|
||||
explosion_smoke.particles.count = 0
|
||||
sparks.particles.count = 0
|
||||
smoke_wave.particles.count = 0
|
||||
|
||||
/obj/effect/temp_visual/explosion/Destroy()
|
||||
QDEL_NULL(smoke_wave)
|
||||
QDEL_NULL(explosion_smoke)
|
||||
QDEL_NULL(sparks)
|
||||
return ..()
|
||||
@@ -231,16 +231,12 @@
|
||||
layer = ABOVE_MOB_LAYER
|
||||
duration = 4
|
||||
|
||||
/obj/effect/temp_visual/explosion
|
||||
/obj/effect/temp_visual/pka_explosion
|
||||
name = "explosion"
|
||||
icon = 'icons/effects/96x96.dmi'
|
||||
icon_state = "explosion"
|
||||
icon_state = "explosionfast"
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
duration = 8
|
||||
|
||||
/obj/effect/temp_visual/explosion/fast
|
||||
icon_state = "explosionfast"
|
||||
duration = 4
|
||||
|
||||
/obj/effect/temp_visual/heart
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
//TODO: Flash range does nothing currently
|
||||
|
||||
#define CREAK_DELAY 5 SECONDS //Time taken for the creak to play after explosion, if applicable.
|
||||
#define DEVASTATION_PROB 30 //The probability modifier for devistation, maths!
|
||||
#define HEAVY_IMPACT_PROB 5 //ditto
|
||||
@@ -74,6 +72,10 @@
|
||||
var/turf/M_turf = get_turf(M)
|
||||
if(M_turf && M_turf.z == z0)
|
||||
var/dist = get_dist(M_turf, epicenter)
|
||||
if(isliving(M) && dist <= flash_range)
|
||||
var/mob/living/to_flash = M
|
||||
var/is_very_close_to_the_explosion = flash_range > (dist * 2)
|
||||
to_flash.flash_eyes(is_very_close_to_the_explosion * 2, is_very_close_to_the_explosion, is_very_close_to_the_explosion) // Gets past sunglasses
|
||||
var/baseshakeamount
|
||||
if(orig_max_distance - dist > 0)
|
||||
baseshakeamount = sqrt((orig_max_distance - dist) * 0.1)
|
||||
@@ -107,14 +109,12 @@
|
||||
if(creaking_explosion) // 5 seconds after the bang, the station begins to creak
|
||||
addtimer(CALLBACK(M, TYPE_PROC_REF(/mob, playsound_local), epicenter, null, rand(FREQ_LOWER, FREQ_UPPER), 1, frequency, null, null, FALSE, hull_creaking_sound, 0), CREAK_DELAY)
|
||||
|
||||
if(heavy_impact_range > 1)
|
||||
var/datum/effect_system/explosion/E
|
||||
if(smoke)
|
||||
E = new /datum/effect_system/explosion/smoke
|
||||
else
|
||||
E = new
|
||||
E.set_up(epicenter)
|
||||
E.start()
|
||||
if(devastation_range > 0)
|
||||
new /obj/effect/temp_visual/explosion(epicenter, max_range, FALSE, TRUE)
|
||||
else if(heavy_impact_range > 0)
|
||||
new /obj/effect/temp_visual/explosion(epicenter, max_range, FALSE, FALSE)
|
||||
else if(light_impact_range > 0)
|
||||
new /obj/effect/temp_visual/explosion(epicenter, max_range, TRUE, FALSE)
|
||||
|
||||
var/list/affected_turfs = spiral_range_turfs(max_range, epicenter)
|
||||
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
/* CONTENTS:
|
||||
0. generic define gripper
|
||||
1. UNIVERSAL GRIPPER
|
||||
2. MEDICAL GRIPPER
|
||||
3. SERVICE GRIPPER
|
||||
4. ENGINEERING GRIPPER
|
||||
*/
|
||||
|
||||
// Generic gripper. This should never appear anywhere.
|
||||
/obj/item/gripper
|
||||
name = "generic gripper item"
|
||||
desc = "If you can see this, make an issue report to Github. Something has gone wrong!"
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "gripper"
|
||||
actions_types = list(/datum/action/item_action/drop_gripped_item)
|
||||
/// Set to TRUE to allow interaction with light fixtures and cell-containing machinery.
|
||||
var/engineering_machine_interaction = FALSE
|
||||
/// Set to TRUE to allow the gripper to shake people awake/help them up.
|
||||
var/can_help_up = FALSE
|
||||
/// Defines what items the gripper can carry.
|
||||
var/list/can_hold = list()
|
||||
/// Set to TRUE to allow ANY item to be held, bypassing can_hold checks.
|
||||
var/can_hold_all_items = FALSE
|
||||
/// The item currently being held.
|
||||
var/obj/item/gripped_item
|
||||
|
||||
/obj/item/gripper/examine(mob/user)
|
||||
. = ..()
|
||||
if(!gripped_item)
|
||||
. += "<span class='notice'>[src] is empty.</span>"
|
||||
return
|
||||
. += "<span class='notice'>[src] is currently holding [gripped_item].</span>"
|
||||
|
||||
/obj/item/gripper/examine_more(mob/user)
|
||||
. = ..()
|
||||
. += {"Cyborg grippers are well-developed, and despite some anatomical differences that manifest in some models, they can be used just as effectively as a regular hand with enough practice.
|
||||
|
||||
Companies like Nanotrasen use software to limit the items that a cyborg can manipulate to a specific pre-defined list, \
|
||||
as part of their multi-layered protections to try and eliminate the chance of a hypothetical synthetic uprising, not wishing to see a repeat of the IPC uprising in 2525."}
|
||||
|
||||
|
||||
/obj/item/gripper/Initialize(mapload)
|
||||
. = ..()
|
||||
can_hold = typecacheof(can_hold)
|
||||
|
||||
/obj/item/gripper/ui_action_click(mob/user)
|
||||
drop_gripped_item(user)
|
||||
|
||||
/obj/item/gripper/proc/drop_gripped_item(mob/user, silent = FALSE)
|
||||
if(!gripped_item)
|
||||
to_chat(user, "<span class='warning'>[src] is empty.</span>")
|
||||
return
|
||||
if(!silent)
|
||||
to_chat(user, "<span class='warning'>You drop [gripped_item].</span>")
|
||||
gripped_item.forceMove(get_turf(src))
|
||||
gripped_item = null
|
||||
|
||||
/obj/item/gripper/attack_self(mob/user)
|
||||
if(!gripped_item)
|
||||
to_chat(user, "<span class='warning'>[src] is empty.</span>")
|
||||
return
|
||||
gripped_item.attack_self(user)
|
||||
|
||||
/obj/item/gripper/attack(mob/living/carbon/M, mob/living/carbon/user)
|
||||
return
|
||||
|
||||
// This is required to ensure that the forceMove checks on some objects don't rip the gripper out of the borg's inventory and toss it on the floor. That would hurt, a lot!
|
||||
/obj/item/gripper/forceMove(atom/destination)
|
||||
return
|
||||
|
||||
/obj/item/gripper/afterattack(atom/target, mob/living/user, proximity, params)
|
||||
//Target is invalid or we are not adjacent.
|
||||
if(!target || !proximity)
|
||||
return FALSE
|
||||
// Shake people awake, get them on their feet.
|
||||
if(ishuman(target) && can_help_up)
|
||||
var/mob/living/carbon/human/pickup_target = target
|
||||
if(!IS_HORIZONTAL(pickup_target))
|
||||
return
|
||||
pickup_target.AdjustSleeping(-10 SECONDS)
|
||||
pickup_target.AdjustParalysis(-6 SECONDS)
|
||||
pickup_target.AdjustStunned(-6 SECONDS)
|
||||
pickup_target.AdjustWeakened(-6 SECONDS)
|
||||
pickup_target.AdjustKnockDown(-6 SECONDS)
|
||||
pickup_target.adjustStaminaLoss(-10)
|
||||
pickup_target.resting = FALSE
|
||||
pickup_target.stand_up()
|
||||
playsound(user.loc, 'sound/weapons/thudswoosh.ogg', 50, TRUE, -1)
|
||||
user.visible_message(
|
||||
"<span class='notice'>[user] shakes [pickup_target] trying to wake [pickup_target.p_them()] up!</span>",
|
||||
"<span class='notice'>You shake [pickup_target] trying to wake [pickup_target.p_them()] up!</span>"
|
||||
)
|
||||
return FALSE
|
||||
//Already have an item.
|
||||
if(gripped_item)
|
||||
|
||||
//Pass the attack on to the target. This might delete/relocate gripped_item.
|
||||
if(!target.attackby(gripped_item, user, params))
|
||||
// If the attackby didn't resolve or delete the target or gripped_item, afterattack
|
||||
// (Certain things, such as mountable frames, rely on afterattack)
|
||||
gripped_item?.afterattack(target, user, 1, params)
|
||||
|
||||
//If gripped_item either didn't get deleted, or it failed to be transfered to its target
|
||||
if(!gripped_item && length(contents))
|
||||
gripped_item = contents[1]
|
||||
return FALSE
|
||||
else if(gripped_item && !contents.len)
|
||||
gripped_item = null
|
||||
|
||||
//Check that we're not pocketing a mob.
|
||||
else if(isitem(target))
|
||||
var/obj/item/I = target
|
||||
// Make sure the item is something the gripper can hold
|
||||
if(can_hold_all_items || is_type_in_typecache(I, can_hold))
|
||||
to_chat(user, "<span class='notice'>You collect [I].</span>")
|
||||
I.forceMove(src)
|
||||
gripped_item = I
|
||||
return TRUE
|
||||
|
||||
to_chat(user, "<span class='warning'>You hold your gripper over [target], but no matter how hard you try, you cannot make yourself grab it.</span>")
|
||||
return FALSE
|
||||
|
||||
// Everything past this point requires being able to engineer.
|
||||
if(!engineering_machine_interaction)
|
||||
return
|
||||
// APC cells.
|
||||
if(istype(target, /obj/machinery/power/apc))
|
||||
var/obj/machinery/power/apc/A = target
|
||||
if(A.opened && A.cell)
|
||||
gripped_item = A.cell
|
||||
|
||||
A.cell.add_fingerprint(user)
|
||||
A.cell.update_icon()
|
||||
A.cell.forceMove(src)
|
||||
A.cell = null
|
||||
|
||||
A.charging = APC_NOT_CHARGING
|
||||
A.update_icon()
|
||||
|
||||
user.visible_message("<span class='warning'>[user] removes the power cell from [A]!</span>", "<span class='warning'>You remove the power cell.</span>")
|
||||
// Cell Chargers
|
||||
else if(istype(target, /obj/machinery/cell_charger))
|
||||
var/obj/machinery/cell_charger/cell_charger = target
|
||||
if(cell_charger.charging)
|
||||
gripped_item = cell_charger.charging
|
||||
cell_charger.charging.add_fingerprint(user)
|
||||
cell_charger.charging.forceMove(src)
|
||||
cell_charger.removecell()
|
||||
// Putting lights in fixtures.
|
||||
else if(istype(target, /obj/machinery/light))
|
||||
var/obj/machinery/light/light = target
|
||||
var/obj/item/light/L = light.drop_light_tube()
|
||||
L.forceMove(src)
|
||||
gripped_item = L
|
||||
user.visible_message("<span class='notice'>[user] removes the light from the fixture.</span>", "<span class='notice'>You dislodge the light from the fixture.</span>")
|
||||
|
||||
return TRUE
|
||||
|
||||
////////////////////////////////
|
||||
// MARK: UNIVERSAL GRIPPER
|
||||
////////////////////////////////
|
||||
/// Universal gripper. Not supplied to any cyborg by default. Could be varedited onto a borg for event stuff. Functions almost like a real hand!
|
||||
/obj/item/gripper/universal
|
||||
name = "cyborg gripper"
|
||||
desc = "A grasping tool for cyborgs. This one is not restricted by any restraining software, allowing it to handle any object the user wishes."
|
||||
// It's UNIVERSAL so it has all functions enabled.
|
||||
engineering_machine_interaction = TRUE
|
||||
can_help_up = TRUE
|
||||
can_hold_all_items = TRUE
|
||||
|
||||
////////////////////////////////
|
||||
// MARK: MEDICAL GRIPPER
|
||||
////////////////////////////////
|
||||
// For medical borgs, for doing medical stuff!
|
||||
// Not giving this anything to hold yet, but stuff may be added in the future. Organs/implants are currently viewed as too strong to hold.
|
||||
/obj/item/gripper/medical
|
||||
name = "medical gripper"
|
||||
desc = "A grasping tool for cyborgs. This one is covered with hygenic medical-grade silicone rubber. \
|
||||
Use it to help patients up once surgery is complete, or to substitute for hands in surgical operations."
|
||||
can_help_up = TRUE
|
||||
// REMOVE actions_types from here if you add a can_hold list for this gripper!
|
||||
actions_types = list()
|
||||
|
||||
////////////////////////////////
|
||||
// MARK: SERVICE GRIPPER
|
||||
////////////////////////////////
|
||||
// For service borgs. To make them slightly better at their job.
|
||||
/obj/item/gripper/service
|
||||
name = "service gripper"
|
||||
desc = "A grasping tool for cyborgs. This version is made from hygenic easy-clean material. Maybe some day you'll be able to grab food with it..."
|
||||
// For waking up drunkards.
|
||||
can_help_up = TRUE
|
||||
// Everything in this list is currently for either playing games or otherwise assisting the crew in mundane, non-impactful ways.
|
||||
can_hold = list(
|
||||
/obj/item/deck,
|
||||
/obj/item/cardhand,
|
||||
/obj/item/coin,
|
||||
/obj/item/paper,
|
||||
/obj/item/photo,
|
||||
/obj/item/toy/plushie
|
||||
)
|
||||
|
||||
////////////////////////////////
|
||||
// MARK: ENGINEERING GRIPPER
|
||||
////////////////////////////////
|
||||
// For engineering and sabotage borgs, and drones.
|
||||
/obj/item/gripper/engineering
|
||||
name = "engineering gripper"
|
||||
desc = "A grasping tool for cyborgs. This version can hold a wide variety of constructon components for use in engineering work."
|
||||
engineering_machine_interaction = TRUE
|
||||
can_hold = list(
|
||||
/obj/item/firealarm_electronics,
|
||||
/obj/item/airalarm_electronics,
|
||||
/obj/item/airlock_electronics,
|
||||
/obj/item/firelock_electronics,
|
||||
/obj/item/intercom_electronics,
|
||||
/obj/item/apc_electronics,
|
||||
/obj/item/tracker_electronics,
|
||||
/obj/item/stock_parts,
|
||||
/obj/item/vending_refill,
|
||||
/obj/item/mounted/frame,
|
||||
/obj/item/assembly/prox_sensor,
|
||||
/obj/item/assembly/igniter,
|
||||
/obj/item/rack_parts,
|
||||
/obj/item/camera_assembly,
|
||||
/obj/item/tank,
|
||||
/obj/item/circuitboard,
|
||||
/obj/item/stack/ore/bluespace_crystal,
|
||||
/obj/item/stack/tile/light,
|
||||
/obj/item/light
|
||||
)
|
||||
@@ -486,3 +486,24 @@
|
||||
return
|
||||
for(var/obj/item/reagent_containers/borghypo/F in R.module.modules)
|
||||
F.emag_act()
|
||||
|
||||
/obj/item/borg/upgrade/abductor_jani
|
||||
name = "janitorial cyborg abductor upgrade"
|
||||
desc = "An experimental upgrade that replaces a janitorial cyborg's tools with the abductor versions."
|
||||
icon_state = "abductor_mod"
|
||||
origin_tech = "biotech=6;materials=6;abductor=3"
|
||||
require_module = TRUE
|
||||
module_type = /obj/item/robot_module/janitor
|
||||
items_to_replace = list(
|
||||
/obj/item/mop/advanced/cyborg = /obj/item/mop/advanced/abductor,
|
||||
/obj/item/soap = /obj/item/soap/syndie/abductor,
|
||||
/obj/item/lightreplacer/cyborg = /obj/item/lightreplacer/bluespace/abductor,
|
||||
/obj/item/melee/flyswatter = /obj/item/melee/flyswatter/abductor
|
||||
)
|
||||
items_to_add = list(
|
||||
/obj/item/reagent_containers/spray/cleaner/safety/abductor
|
||||
)
|
||||
special_rechargables = list(
|
||||
/obj/item/reagent_containers/spray/cleaner/safety/abductor,
|
||||
/obj/item/lightreplacer/bluespace/abductor
|
||||
)
|
||||
|
||||
@@ -178,7 +178,7 @@ GLOBAL_LIST_INIT(sinew_recipes, list (
|
||||
|
||||
/obj/item/stack/sheet/animalhide/goliath_hide
|
||||
name = "goliath hide plates"
|
||||
desc = "Pieces of a goliath's rocky hide, these might be able to make your suit a bit more durable to attack from the local fauna."
|
||||
desc = "Pieces of a goliath's rocky hide, these might be able to make your miner equipment such as suits, plasmaman helmets, borgs and Ripley class exosuits a bit more durable to attack from the local fauna."
|
||||
icon = 'icons/obj/stacks/organic.dmi'
|
||||
icon_state = "goliath_hide"
|
||||
item_state = "goliath_hide"
|
||||
@@ -198,41 +198,80 @@ GLOBAL_LIST_INIT(sinew_recipes, list (
|
||||
if(is_type_in_typecache(target, goliath_platable_armor_typecache))
|
||||
var/obj/item/clothing/C = target
|
||||
var/datum/armor/current_armor = C.armor
|
||||
if(current_armor.getRating(MELEE) < 60)
|
||||
C.armor = current_armor.setRating(melee_value = min(current_armor.getRating(MELEE) + 10, 60))
|
||||
if(current_armor.getRating(MELEE) < 75)
|
||||
if(!use(1))
|
||||
to_chat(user, "<span class='notice'>You dont have enough [src] for this!</span>")
|
||||
return
|
||||
C.armor = current_armor.setRating(melee_value = min(current_armor.getRating(MELEE) + 15, 75))
|
||||
to_chat(user, "<span class='info'>You strengthen [target], improving its resistance against melee attacks.</span>")
|
||||
use(1)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't improve [C] any further!</span>")
|
||||
else if(istype(target, /obj/mecha/working/ripley))
|
||||
var/obj/mecha/working/ripley/D = target
|
||||
if(D.hides < 3)
|
||||
if(D.hides < HIDES_COVERED_FULL && !D.plates && !D.drake_hides)
|
||||
if(!use(1))
|
||||
to_chat(user, "<span class='notice'>You dont have enough [src] for this!</span>")
|
||||
return
|
||||
D.hides++
|
||||
D.armor = D.armor.setRating(melee_value = min(D.armor.getRating(MELEE) + 10, 70))
|
||||
D.armor = D.armor.setRating(bullet_value = min(D.armor.getRating(BULLET) + 5, 50))
|
||||
D.armor = D.armor.setRating(laser_value = min(D.armor.getRating(LASER) + 5, 50))
|
||||
to_chat(user, "<span class='info'>You strengthen [target], improving its resistance against melee attacks.</span>")
|
||||
D.armor = D.armor.setRating(melee_value = min(D.armor.getRating(MELEE) + 25, 115))
|
||||
D.armor = D.armor.setRating(bullet_value = min(D.armor.getRating(BULLET) + 7, 60))
|
||||
D.armor = D.armor.setRating(laser_value = min(D.armor.getRating(LASER) + 7, 60))
|
||||
to_chat(user, "<span class='info'>You strengthen [target], improving its resistance against attacks.</span>")
|
||||
D.update_appearance(UPDATE_DESC|UPDATE_OVERLAYS)
|
||||
use(1)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't improve [D] any further!</span>")
|
||||
else if(isrobot(target))
|
||||
var/mob/living/silicon/robot/R = target
|
||||
if(istype(R.module, /obj/item/robot_module/miner))
|
||||
var/datum/armor/current_armor = R.armor
|
||||
if(current_armor.getRating(MELEE) < 60)
|
||||
R.armor = current_armor.setRating(melee_value = min(current_armor.getRating(MELEE) + 10, 60))
|
||||
if(current_armor.getRating(MELEE) < 75)
|
||||
if(!use(1))
|
||||
to_chat(user, "<span class='notice'>You dont have enough [src] for this!</span>")
|
||||
return
|
||||
R.armor = current_armor.setRating(melee_value = min(current_armor.getRating(MELEE) + 15, 75))
|
||||
to_chat(user, "<span class='info'>You strengthen [target], improving its resistance against melee attacks.</span>")
|
||||
use(1)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't improve [R] any further!</span>")
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[R]'s armor can not be improved!</span>")
|
||||
|
||||
/obj/item/stack/sheet/animalhide/armor_plate
|
||||
name = "armor plate"
|
||||
desc = "This piece of metal can be attached to the mech itself, enhancing its protective characteristics. Unfortunately, only working class exosuits have notches for such armor."
|
||||
icon = 'icons/mecha/mecha_equipment.dmi'
|
||||
icon_state = "armor_plate"
|
||||
item_state = "armor_plate"
|
||||
singular_name = "armor plate"
|
||||
flags = NOBLUDGEON
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
layer = MOB_LAYER
|
||||
|
||||
/obj/item/stack/sheet/animalhide/armor_plate/afterattack(atom/target, mob/user, proximity_flag)
|
||||
if(!proximity_flag)
|
||||
return
|
||||
if(istype(target, /obj/mecha/working/ripley))
|
||||
var/obj/mecha/working/ripley/D = target
|
||||
if(D.plates < PLATES_COVERED_FULL && !D.hides && !D.drake_hides)
|
||||
if(!use(1))
|
||||
to_chat(user, "<span class='notice'>You dont have enough [src] for this!</span>")
|
||||
return
|
||||
use(1)
|
||||
D.plates++
|
||||
D.armor = D.armor.setRating(melee_value = min(D.armor.getRating(MELEE) + 10, 70))
|
||||
D.armor = D.armor.setRating(bullet_value = min(D.armor.getRating(BULLET) + 4, 50))
|
||||
D.armor = D.armor.setRating(laser_value = min(D.armor.getRating(LASER) + 4, 50))
|
||||
to_chat(user, "<span class='info'>You strengthen [target], improving its resistance against attacks.</span>")
|
||||
D.update_appearance(UPDATE_DESC|UPDATE_OVERLAYS)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't improve [D] any further!</span>")
|
||||
|
||||
/obj/item/stack/sheet/animalhide/armor_plate/attackby(obj/item/W, mob/user, params)
|
||||
return // no steel leather for ya
|
||||
|
||||
/obj/item/stack/sheet/animalhide/ashdrake
|
||||
name = "ash drake hide"
|
||||
desc = "The strong, scaled hide of an ash drake."
|
||||
desc = "The strong, scaled hide of an ash drake. Can be attached to the mech itself, greatly enhancing its protective characteristics. Unfortunately, only working class exosuits have notches for such armor."
|
||||
icon = 'icons/obj/stacks/organic.dmi'
|
||||
icon_state = "dragon_hide"
|
||||
item_state = "dragon_hide"
|
||||
@@ -242,9 +281,30 @@ GLOBAL_LIST_INIT(sinew_recipes, list (
|
||||
layer = MOB_LAYER
|
||||
dynamic_icon_state = TRUE
|
||||
|
||||
/obj/item/stack/sheet/animalhide/ashdrake/afterattack(atom/target, mob/user, proximity_flag)
|
||||
if(!proximity_flag)
|
||||
return
|
||||
if(istype(target, /obj/mecha/working/ripley))
|
||||
var/obj/mecha/working/ripley/D = target
|
||||
if(D.drake_hides < DRAKE_HIDES_COVERED_FULL && !D.hides && !D.plates)
|
||||
if(!use(1))
|
||||
to_chat(user, "<span class='notice'>You dont have enough [src] for this!</span>")
|
||||
return
|
||||
use(1)
|
||||
D.drake_hides++
|
||||
D.max_integrity += 50
|
||||
D.obj_integrity += 50
|
||||
D.armor = D.armor.setRating(melee_value = min(D.armor.getRating(MELEE) + 45, 175)) // 77.7% melee armor maximum
|
||||
D.armor = D.armor.setRating(bullet_value = min(D.armor.getRating(BULLET) + 7, 60))
|
||||
D.armor = D.armor.setRating(laser_value = min(D.armor.getRating(LASER) + 7, 60))
|
||||
to_chat(user, "<span class='info'>You strengthen [target], improving its resistance against attacks.</span>")
|
||||
D.update_appearance(UPDATE_DESC|UPDATE_OVERLAYS)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You can't improve [D] any further!</span>")
|
||||
|
||||
//Step one - dehairing.
|
||||
|
||||
/obj/item/stack/sheet/animalhide/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
/obj/item/stack/sheet/animalhide/attackby(obj/item/W, mob/user, params)
|
||||
if(W.sharp)
|
||||
user.visible_message("[user] starts cutting hair off \the [src].", "<span class='notice'>You start cutting the hair off \the [src]...</span>", "<span class='italics'>You hear the sound of a knife rubbing against flesh.</span>")
|
||||
if(do_after(user, 50 * W.toolspeed, target = src))
|
||||
|
||||
@@ -215,6 +215,7 @@ GLOBAL_LIST_INIT(wood_recipes, list(
|
||||
new /datum/stack_recipe("rake", /obj/item/cultivator/rake, 5, time = 1 SECONDS),
|
||||
new /datum/stack_recipe("wooden bucket", /obj/item/reagent_containers/glass/bucket/wooden, 3, time = 1 SECONDS),
|
||||
new /datum/stack_recipe("firebrand", /obj/item/match/firebrand, 2, time = 10 SECONDS),
|
||||
new /datum/stack_recipe("notice board", /obj/item/mounted/noticeboard, 5, time = 5 SECONDS),
|
||||
null,
|
||||
new /datum/stack_recipe("wood floor tile", /obj/item/stack/tile/wood, 1, 4, 20),
|
||||
new /datum/stack_recipe_list("wood structures", list(
|
||||
|
||||
@@ -35,16 +35,6 @@
|
||||
toolspeed = 0.5
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
|
||||
/obj/item/crowbar/abductor
|
||||
name = "alien crowbar"
|
||||
desc = "A hard-light crowbar. It appears to pry by itself, without any effort required."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
usesound = 'sound/weapons/sonic_jackhammer.ogg'
|
||||
icon_state = "crowbar"
|
||||
toolspeed = 0.1
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
origin_tech = "combat=4;engineering=4;abductor=3"
|
||||
|
||||
/obj/item/crowbar/small
|
||||
name = "miniature titanium crowbar"
|
||||
desc = "A tiny, lightweight titanium crowbar. It fits handily in your pocket."
|
||||
|
||||
@@ -171,19 +171,6 @@
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_SHOW_WIRE_INFO, ROUNDSTART_TRAIT) // Drones are linked to the station
|
||||
|
||||
/obj/item/multitool/abductor
|
||||
name = "alien multitool"
|
||||
desc = "An omni-technological interface."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "multitool"
|
||||
toolspeed = 0.1
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
origin_tech = "magnets=5;engineering=5;abductor=3"
|
||||
|
||||
/obj/item/multitool/abductor/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_SHOW_WIRE_INFO, ROUNDSTART_TRAIT)
|
||||
|
||||
#undef PROXIMITY_NONE
|
||||
#undef PROXIMITY_ON_SCREEN
|
||||
#undef PROXIMITY_NEAR
|
||||
|
||||
@@ -90,15 +90,6 @@
|
||||
|
||||
return BRUTELOSS
|
||||
|
||||
/obj/item/screwdriver/abductor
|
||||
name = "alien screwdriver"
|
||||
desc = "An ultrasonic screwdriver."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "screwdriver"
|
||||
usesound = 'sound/items/pshoom.ogg'
|
||||
toolspeed = 0.1
|
||||
random_color = FALSE
|
||||
|
||||
/obj/item/screwdriver/power
|
||||
name = "hand drill"
|
||||
desc = "A simple hand drill with a screwdriver bit attached."
|
||||
|
||||
@@ -275,19 +275,6 @@
|
||||
materials = list(MAT_METAL = 200, MAT_GLASS = 50)
|
||||
low_fuel_changes_icon = FALSE
|
||||
|
||||
/obj/item/weldingtool/abductor
|
||||
name = "alien welding tool"
|
||||
desc = "An alien welding tool. Whatever fuel it uses, it never runs out."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "welder"
|
||||
toolspeed = 0.1
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
light_intensity = 0
|
||||
origin_tech = "plasmatech=5;engineering=5;abductor=3"
|
||||
requires_fuel = FALSE
|
||||
refills_over_time = TRUE
|
||||
low_fuel_changes_icon = FALSE
|
||||
|
||||
/obj/item/weldingtool/hugetank
|
||||
name = "upgraded welding tool"
|
||||
desc = "An upgraded welder based off the industrial welder."
|
||||
|
||||
@@ -98,19 +98,6 @@
|
||||
random_color = FALSE
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
|
||||
/obj/item/wirecutters/abductor
|
||||
name = "alien wirecutters"
|
||||
desc = "Extremely sharp wirecutters, made out of a silvery-green metal."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "cutters"
|
||||
toolspeed = 0.1
|
||||
origin_tech = "materials=5;engineering=4;abductor=3"
|
||||
random_color = FALSE
|
||||
|
||||
/obj/item/wirecutters/abductor/Initialize(mapload)
|
||||
. = ..()
|
||||
ADD_TRAIT(src, TRAIT_SHOW_WIRE_INFO, ROUNDSTART_TRAIT)
|
||||
|
||||
/obj/item/wirecutters/cyborg
|
||||
name = "wirecutters"
|
||||
desc = "This cuts wires."
|
||||
|
||||
@@ -54,15 +54,6 @@
|
||||
toolspeed = 0.5
|
||||
resistance_flags = FIRE_PROOF | ACID_PROOF
|
||||
|
||||
/obj/item/wrench/abductor
|
||||
name = "alien wrench"
|
||||
desc = "A polarized wrench. It causes anything placed between the jaws to turn."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "wrench"
|
||||
usesound = 'sound/effects/empulse.ogg'
|
||||
toolspeed = 0.1
|
||||
origin_tech = "materials=5;engineering=5;abductor=3"
|
||||
|
||||
/obj/item/wrench/power
|
||||
name = "hand drill"
|
||||
desc = "A simple powered drill with a bolt bit."
|
||||
|
||||
@@ -13,14 +13,19 @@
|
||||
var/obj/item/assembly/nadeassembly = null
|
||||
var/assemblyattacher
|
||||
var/notify_admins = TRUE
|
||||
/// C4 overlay to put on target
|
||||
var/mutable_appearance/plastic_overlay
|
||||
/// Target of the overlay, not neccicarly the thing the C4 is attached to!
|
||||
var/atom/plastic_overlay_target
|
||||
|
||||
/obj/item/grenade/plastic/Initialize(mapload)
|
||||
. = ..()
|
||||
image_overlay = image('icons/obj/grenade.dmi', "[item_state]2")
|
||||
plastic_overlay = mutable_appearance(icon, "[item_state]2", HIGH_OBJ_LAYER)
|
||||
|
||||
/obj/item/grenade/plastic/Destroy()
|
||||
QDEL_NULL(nadeassembly)
|
||||
target = null
|
||||
plastic_overlay_target = null
|
||||
return ..()
|
||||
|
||||
/obj/item/grenade/plastic/attackby(obj/item/I, mob/user, params)
|
||||
@@ -74,7 +79,7 @@
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You start planting [src].[isnull(nadeassembly) ? " The timer is set to [det_time]..." : ""]</span>")
|
||||
|
||||
if(do_after(user, 5 SECONDS * toolspeed, target = AM))
|
||||
if(do_after(user, 1.5 SECONDS * toolspeed, target = AM))
|
||||
if(!user.unEquip(src))
|
||||
return
|
||||
target = AM
|
||||
@@ -84,7 +89,26 @@
|
||||
message_admins("[ADMIN_LOOKUPFLW(user)] planted [name] on [target.name] at ([target.x],[target.y],[target.z] - <a href='byond://?_src_=holder;adminplayerobservecoodjump=1;X=[target.x];Y=[target.y];Z=[target.z]'>JMP</a>) with [det_time] second fuse", 0, 1)
|
||||
log_game("[key_name(user)] planted [name] on [target.name] at ([target.x],[target.y],[target.z]) with [det_time] second fuse")
|
||||
|
||||
AddComponent(/datum/component/persistent_overlay, image_overlay, target)
|
||||
plastic_overlay.layer = HIGH_OBJ_LAYER
|
||||
if(isturf(target) || istype(target, /obj/machinery/door))
|
||||
plastic_overlay_target = new /obj/effect/plastic(get_turf(user))
|
||||
else
|
||||
plastic_overlay_target = target
|
||||
if(isliving(target))
|
||||
plastic_overlay.layer = ABOVE_ALL_MOB_LAYER
|
||||
if(plastic_overlay_target != target)
|
||||
switch(plastic_overlay_target.x - target.x)
|
||||
if(-1)
|
||||
plastic_overlay.pixel_x += 32
|
||||
if(1)
|
||||
plastic_overlay.pixel_x -= 32
|
||||
switch(plastic_overlay_target.y - target.y)
|
||||
if(-1)
|
||||
plastic_overlay.pixel_y += 32
|
||||
if(1)
|
||||
plastic_overlay.pixel_y -= 32
|
||||
plastic_overlay_target.add_overlay(plastic_overlay)
|
||||
|
||||
if(!nadeassembly)
|
||||
to_chat(user, "<span class='notice'>You plant the bomb. Timer counting down from [det_time].</span>")
|
||||
addtimer(CALLBACK(src, PROC_REF(prime)), det_time SECONDS)
|
||||
@@ -146,6 +170,10 @@
|
||||
|
||||
/obj/item/grenade/plastic/c4/prime()
|
||||
var/turf/location
|
||||
if(plastic_overlay_target && !QDELETED(plastic_overlay_target))
|
||||
plastic_overlay_target.cut_overlay(plastic_overlay, TRUE)
|
||||
if(istype(plastic_overlay_target, /obj/effect/plastic))
|
||||
qdel(plastic_overlay_target)
|
||||
if(target)
|
||||
if(!QDELETED(target))
|
||||
location = get_turf(target)
|
||||
@@ -211,6 +239,10 @@
|
||||
|
||||
/obj/item/grenade/plastic/c4/thermite/prime()
|
||||
var/turf/location
|
||||
if(plastic_overlay_target && !QDELETED(plastic_overlay_target))
|
||||
plastic_overlay_target.cut_overlay(plastic_overlay, TRUE)
|
||||
if(istype(plastic_overlay_target, /obj/effect/plastic))
|
||||
qdel(plastic_overlay_target)
|
||||
if(target)
|
||||
if(!QDELETED(target))
|
||||
location = get_turf(target)
|
||||
@@ -235,3 +267,7 @@
|
||||
M.adjust_fire_stacks(2)
|
||||
M.IgniteMob()
|
||||
qdel(src)
|
||||
|
||||
//Used so the effect is visable for overlay purposes, but not show on right click with a broken sprite
|
||||
/obj/effect/plastic
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
|
||||
@@ -457,22 +457,6 @@
|
||||
new /obj/item/grenade/empgrenade(src) // Two of each
|
||||
new /obj/item/grenade/syndieminibomb(src) // One minibomb
|
||||
|
||||
/obj/item/storage/belt/military/abductor
|
||||
name = "agent belt"
|
||||
desc = "A belt used by abductor agents."
|
||||
icon = 'icons/obj/abductor.dmi'
|
||||
icon_state = "belt"
|
||||
item_state = "security"
|
||||
|
||||
/obj/item/storage/belt/military/abductor/full/populate_contents()
|
||||
new /obj/item/screwdriver/abductor(src)
|
||||
new /obj/item/wrench/abductor(src)
|
||||
new /obj/item/weldingtool/abductor(src)
|
||||
new /obj/item/crowbar/abductor(src)
|
||||
new /obj/item/wirecutters/abductor(src)
|
||||
new /obj/item/multitool/abductor(src)
|
||||
new /obj/item/stack/cable_coil(src, 30, COLOR_WHITE)
|
||||
|
||||
/obj/item/storage/belt/military/assault
|
||||
name = "assault belt"
|
||||
desc = "A tactical assault belt."
|
||||
|
||||
@@ -242,6 +242,8 @@
|
||||
origin_tech = "magnets=1"
|
||||
/// The reference to the envelope that is currently stored in the mail scanner. It will be cleared upon confirming a correct delivery
|
||||
var/obj/item/envelope/saved
|
||||
/// How far away can the scanner scan mail or people
|
||||
var/scanner_range = 7
|
||||
|
||||
/obj/item/mail_scanner/examine(mob/user)
|
||||
. = ..()
|
||||
@@ -251,6 +253,9 @@
|
||||
return
|
||||
|
||||
/obj/item/mail_scanner/afterattack(atom/A, mob/user)
|
||||
if(get_dist(A, user) > scanner_range)
|
||||
to_chat(user, "<span class='warning'>The scanner doesn't reach that far!</span>")
|
||||
return
|
||||
if(istype(A, /obj/item/envelope))
|
||||
var/obj/item/envelope/envelope = A
|
||||
if(envelope.has_been_scanned)
|
||||
|
||||
@@ -57,8 +57,9 @@
|
||||
break
|
||||
|
||||
// Fix for #383 - C4 deleting fridges with corpses
|
||||
/obj/structure/closet/Destroy()
|
||||
dump_contents()
|
||||
/obj/structure/closet/Destroy(force)
|
||||
if(!force)
|
||||
dump_contents()
|
||||
return ..()
|
||||
|
||||
/obj/structure/closet/CanPass(atom/movable/mover, turf/target, height=0)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
L.unbuckle_mob()
|
||||
L.forceMove(src)
|
||||
ADD_TRAIT(L, TRAIT_MUTE, STATUE_MUTE)
|
||||
ADD_TRAIT(L, TRAIT_EMOTE_MUTE, STATUE_MUTE)
|
||||
max_integrity = max(L.health + 100, 100) //stoning damaged mobs will result in easier to shatter statues
|
||||
intialTox = L.getToxLoss()
|
||||
intialFire = L.getFireLoss()
|
||||
@@ -50,6 +51,7 @@
|
||||
M.adjustFireLoss(intialFire - M.getFireLoss())
|
||||
M.adjustBruteLoss(intialBrute - M.getBruteLoss())
|
||||
M.setOxyLoss(intialOxy)
|
||||
M.Stun(2.5 SECONDS) // No using items inside a statue
|
||||
if(timer <= 0)
|
||||
dump_contents()
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
@@ -69,6 +71,7 @@
|
||||
for(var/mob/living/M in src)
|
||||
M.forceMove(loc)
|
||||
REMOVE_TRAIT(M, TRAIT_MUTE, STATUE_MUTE)
|
||||
REMOVE_TRAIT(M, TRAIT_EMOTE_MUTE, STATUE_MUTE)
|
||||
M.take_overall_damage((M.health - obj_integrity - 100),0) //any new damage the statue incurred is transfered to the mob
|
||||
|
||||
..()
|
||||
@@ -120,7 +123,7 @@
|
||||
|
||||
/obj/structure/closet/statue/indestructible
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
timer = 240 SECONDS_TO_LIFE_CYCLES
|
||||
timer = 120 SECONDS_TO_LIFE_CYCLES
|
||||
|
||||
/obj/structure/closet/statue/indestructible/ex_act(severity)
|
||||
return //No delimbing them
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
M.gib()
|
||||
for(var/obj/mecha/E in range(30, T))
|
||||
E.take_damage(E.max_integrity)
|
||||
explosion(get_turf(src), 25, 35, 45, 55, 1, 1, 60, 0, 0)
|
||||
explosion(get_turf(src), 25, 35, 45, 55, 1, 1, 60, 0)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
else if(mybag)
|
||||
mybag.attackby(I, user, params)
|
||||
else
|
||||
to_chat(usr, "<span class='warning'>You cannot interface your modules [src]!</span>")
|
||||
to_chat(usr, "<span class='warning'>You cannot interface your modules with [src]!</span>")
|
||||
|
||||
/obj/structure/janitorialcart/crowbar_act(mob/living/user, obj/item/I)
|
||||
. = TRUE
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
return ..()
|
||||
|
||||
/obj/structure/mopbucket/attackby(obj/item/W as obj, mob/user as mob, params)
|
||||
if(W.is_robot_module())
|
||||
to_chat(user, "<span class='warning'>You cannot interface your modules with [src]!</span>")
|
||||
return
|
||||
if(istype(W, /obj/item/mop))
|
||||
var/obj/item/mop/M = W
|
||||
if(M.reagents.total_volume < M.reagents.maximum_volume)
|
||||
|
||||
@@ -1,82 +1,143 @@
|
||||
#define MAX_NOTICES 5
|
||||
|
||||
/obj/item/mounted/noticeboard
|
||||
name = "notice board"
|
||||
desc = "A board for pinning important notices upon."
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "noticeboard"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
/obj/item/mounted/noticeboard/do_build(turf/on_wall, mob/user)
|
||||
new /obj/structure/noticeboard(get_turf(user), get_dir(on_wall, user), building = TRUE)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/noticeboard
|
||||
name = "notice board"
|
||||
desc = "A board for pinning important notices upon."
|
||||
icon = 'icons/obj/stationobjs.dmi'
|
||||
icon_state = "nboard00"
|
||||
icon_state = "noticeboard-5"
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
max_integrity = 150
|
||||
var/notices = 0
|
||||
|
||||
/obj/structure/noticeboard/Initialize()
|
||||
..()
|
||||
for(var/obj/item/I in loc)
|
||||
if(notices > 4) break
|
||||
if(istype(I, /obj/item/paper))
|
||||
I.loc = src
|
||||
notices++
|
||||
icon_state = "nboard0[notices]"
|
||||
/obj/structure/noticeboard/New(turf/loc, direction, building = FALSE)
|
||||
. = ..()
|
||||
if(building)
|
||||
setDir(direction)
|
||||
set_pixel_offsets_from_dir(-32, 32, -30, 30)
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
|
||||
//attaching papers!!
|
||||
/obj/structure/noticeboard/attackby(obj/item/O as obj, mob/user as mob, params)
|
||||
if(istype(O, /obj/item/paper))
|
||||
if(notices < 5)
|
||||
O.add_fingerprint(user)
|
||||
add_fingerprint(user)
|
||||
user.drop_item()
|
||||
O.loc = src
|
||||
/obj/structure/noticeboard/Initialize()
|
||||
. = ..()
|
||||
for(var/obj/item/paper in loc)
|
||||
if(notices >= MAX_NOTICES)
|
||||
break
|
||||
if(istype(paper, /obj/item/paper))
|
||||
paper.loc = src
|
||||
notices++
|
||||
icon_state = "nboard0[notices]" //update sprite
|
||||
to_chat(user, "<span class='notice'>You pin the paper to the noticeboard.</span>")
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You reach to pin your paper to the board but hesitate. You are certain your paper will not be seen among the many others already attached.</span>")
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
|
||||
/obj/structure/noticeboard/update_icon_state()
|
||||
if(notices)
|
||||
icon_state = "noticeboard-[notices]"
|
||||
return
|
||||
icon_state = "noticeboard"
|
||||
|
||||
/obj/structure/noticeboard/attack_hand(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/structure/noticeboard/attack_ghost(mob/user)
|
||||
ui_interact(user)
|
||||
|
||||
/obj/structure/noticeboard/ui_state(mob/user)
|
||||
return GLOB.default_state
|
||||
|
||||
/obj/structure/noticeboard/ui_interact(mob/user, datum/tgui/ui)
|
||||
ui = SStgui.try_update_ui(user, src, ui)
|
||||
if(!ui)
|
||||
ui = new(user, src, "Noticeboard", name)
|
||||
ui.set_autoupdate(FALSE)
|
||||
ui.open()
|
||||
|
||||
/obj/structure/noticeboard/ui_data(mob/user)
|
||||
var/list/data = list()
|
||||
|
||||
var/list/pinned_papers = list()
|
||||
for(var/obj/item/paper/paper in src)
|
||||
pinned_papers += list(list(
|
||||
"name" = paper.name,
|
||||
"contents" = paper.info,
|
||||
"ref" = paper.UID(),
|
||||
))
|
||||
data["papers"] = pinned_papers
|
||||
|
||||
return data
|
||||
|
||||
/obj/structure/noticeboard/ui_act(action, params, datum/tgui/ui)
|
||||
if(..())
|
||||
return
|
||||
. = TRUE
|
||||
|
||||
add_fingerprint(usr)
|
||||
switch(action)
|
||||
if("interact")
|
||||
if(usr.stat || usr.restrained())
|
||||
return
|
||||
var/obj/item/paper/paper = locate(params["paper"])
|
||||
if(!paper && paper.loc != src)
|
||||
return
|
||||
var/obj/item/held_item = usr.get_active_hand()
|
||||
if(is_pen(held_item))
|
||||
paper.attackby(held_item, usr)
|
||||
return
|
||||
else
|
||||
usr.put_in_hands(paper)
|
||||
paper.add_fingerprint(usr)
|
||||
notices--
|
||||
to_chat(usr, "<span class='notice'>You take a [paper.name] out of [src].</span>")
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
if("showFull")
|
||||
var/obj/item/paper/paper = locate(params["paper"])
|
||||
if(!paper && paper.loc != src)
|
||||
return
|
||||
paper.show_content(usr)
|
||||
return
|
||||
|
||||
/obj/structure/noticeboard/attackby(obj/item/I, mob/user, params)
|
||||
if(istype(I, /obj/item/paper))
|
||||
if(notices >= MAX_NOTICES)
|
||||
to_chat(user, "<span class='notice'>You reach to pin your paper to the board but hesitate. You are certain your paper will not be seen among the many others already attached.</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
I.forceMove(src)
|
||||
notices++
|
||||
to_chat(user, "<span class='notice'>You pin the paper to the noticeboard.</span>")
|
||||
update_icon(UPDATE_ICON_STATE)
|
||||
add_fingerprint(user)
|
||||
SStgui.update_uis(src)
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/structure/noticeboard/attack_hand(user as mob)
|
||||
var/dat = "<b>Noticeboard</b><br>"
|
||||
for(var/obj/item/paper/P in src)
|
||||
dat += "<a href='byond://?src=[UID()];read=\ref[P]'>[P.name]</a> <a href='byond://?src=[UID()];write=\ref[P]'>Write</a> <a href='byond://?src=[UID()];remove=\ref[P]'>Remove</a><br>"
|
||||
user << browse("<!DOCTYPE html><meta charset='utf-8'><head><title>Notices</title></head>[dat]","window=noticeboard")
|
||||
onclose(user, "noticeboard")
|
||||
/obj/structure/noticeboard/wrench_act(mob/living/user, obj/item/I)
|
||||
if(user.a_intent != INTENT_HELP)
|
||||
return
|
||||
. = TRUE
|
||||
if(!(flags & NODECONSTRUCT))
|
||||
WRENCH_UNANCHOR_WALL_MESSAGE
|
||||
I.play_tool_sound(user, I.tool_volume)
|
||||
deconstruct(TRUE)
|
||||
|
||||
/obj/structure/noticeboard/deconstruct(disassembled = TRUE)
|
||||
if(!(flags & NODECONSTRUCT))
|
||||
new /obj/item/stack/sheet/metal (loc, 1)
|
||||
if(flags & NODECONSTRUCT)
|
||||
return
|
||||
if(notices)
|
||||
for(var/I in contents)
|
||||
var/obj/item/paper/notice = I
|
||||
notice.forceMove(loc)
|
||||
new /obj/item/mounted/noticeboard(loc)
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/noticeboard/Topic(href, href_list)
|
||||
..()
|
||||
usr.set_machine(src)
|
||||
if(href_list["remove"])
|
||||
if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open
|
||||
return
|
||||
var/obj/item/P = locate(href_list["remove"])
|
||||
if(P && P.loc == src)
|
||||
P.loc = get_turf(src) //dump paper on the floor because you're a clumsy fuck
|
||||
P.add_fingerprint(usr)
|
||||
add_fingerprint(usr)
|
||||
notices--
|
||||
icon_state = "nboard0[notices]"
|
||||
|
||||
if(href_list["write"])
|
||||
if((usr.stat || usr.restrained())) //For when a player is handcuffed while they have the notice window open
|
||||
return
|
||||
var/obj/item/P = locate(href_list["write"])
|
||||
|
||||
if((P && P.loc == src)) //ifthe paper's on the board
|
||||
if(is_pen(usr.r_hand)) //and you're holding a pen
|
||||
add_fingerprint(usr)
|
||||
P.attackby(usr.r_hand, usr) //then do ittttt
|
||||
else
|
||||
if(is_pen(usr.l_hand)) //check other hand for pen
|
||||
add_fingerprint(usr)
|
||||
P.attackby(usr.l_hand, usr)
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>You'll need something to write with!</span>")
|
||||
|
||||
if(href_list["read"])
|
||||
var/obj/item/paper/P = locate(href_list["read"])
|
||||
if(P && P.loc == src)
|
||||
P.show_content(usr)
|
||||
return
|
||||
#undef MAX_NOTICES
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user