Arconomy Adjacent Content: Newscaster Refactor Omega (#65038)

This PR moves the in-game Newscaster over to TGUI, which is one the most bothersome html to tgui projects on the codebase being that it's gone untouched for like... over 4 years now after the introduction of tgui. Newscasters are widely used in-game by players wanting to be deranged whistleblowers, noir detectives, and journalists. They're flavorful, fun, and we still use an html window to make them run so it looks like it's from 2003.
This commit is contained in:
ArcaneMusic
2022-03-26 02:42:42 -04:00
committed by GitHub
parent f0494e70fd
commit 6a461dff81
36 changed files with 13986 additions and 13194 deletions
File diff suppressed because it is too large Load Diff
+159 -159
View File
@@ -1890,25 +1890,6 @@
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/central)
"ex" = (
/obj/structure/table/reinforced,
/obj/machinery/door/firedoor,
/obj/item/paper_bin{
pixel_x = 1;
pixel_y = 9
},
/obj/item/pen,
/obj/machinery/door/window/left/directional/south{
base_state = "right";
dir = 8;
icon_state = "right";
name = "Security Checkpoint";
req_access_txt = "201"
},
/turf/open/floor/iron{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/central)
"ey" = (
/obj/effect/turf_decal/tile/red{
dir = 1
@@ -1997,26 +1978,6 @@
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/central)
"eK" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
/obj/structure/table,
/obj/machinery/recharger{
pixel_y = 4
},
/obj/machinery/newscaster/security_unit{
pixel_x = -30
},
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/tile/red{
dir = 1
},
/obj/effect/turf_decal/tile/red{
dir = 8
},
/turf/open/floor/iron{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/central)
"eL" = (
/obj/structure/chair/office{
dir = 4
@@ -2029,19 +1990,6 @@
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/central)
"eM" = (
/obj/structure/table/reinforced,
/obj/machinery/door/firedoor,
/obj/item/folder/red,
/obj/machinery/door/window/left/directional/south{
dir = 8;
name = "Security Checkpoint";
req_access_txt = "201"
},
/turf/open/floor/iron{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/central)
"eN" = (
/obj/structure/chair{
dir = 4
@@ -2069,18 +2017,6 @@
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/central)
"eQ" = (
/obj/structure/table/reinforced,
/obj/machinery/door/firedoor,
/obj/machinery/door/window/left/directional/south{
dir = 4;
name = "Hydroponics Desk";
req_access_txt = "201"
},
/turf/open/floor/iron{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/central)
"eR" = (
/obj/structure/chair/stool/directional/west,
/turf/open/floor/iron{
@@ -2200,20 +2136,6 @@
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/central)
"fd" = (
/obj/structure/table/reinforced,
/obj/machinery/door/firedoor,
/obj/machinery/door/window/left/directional/south{
base_state = "right";
dir = 4;
icon_state = "right";
name = "Hydroponics Desk";
req_access_txt = "201"
},
/turf/open/floor/iron{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/central)
"fe" = (
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/tile/green,
@@ -2516,18 +2438,6 @@
/obj/machinery/smartfridge,
/turf/closed/wall,
/area/awaymission/undergroundoutpost45/crew_quarters)
"fM" = (
/obj/structure/table/reinforced,
/obj/machinery/door/firedoor,
/obj/machinery/door/window/left/directional/east{
dir = 1;
name = "Hydroponics Desk";
req_access_txt = "201"
},
/turf/open/floor/iron/dark{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/crew_quarters)
"fN" = (
/turf/closed/wall/rust,
/area/awaymission/undergroundoutpost45/crew_quarters)
@@ -3007,6 +2917,19 @@
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/crew_quarters)
"hh" = (
/obj/structure/table/reinforced,
/obj/machinery/door/firedoor,
/obj/item/folder/red,
/obj/machinery/door/window/left/directional/south{
dir = 8;
name = "Security Checkpoint";
req_access_txt = "201"
},
/turf/open/floor/iron{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/central)
"hi" = (
/obj/machinery/vending/cigarette,
/obj/effect/turf_decal/tile/bar,
@@ -3407,6 +3330,20 @@
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/central)
"hZ" = (
/obj/structure/table/reinforced,
/obj/machinery/door/firedoor,
/obj/machinery/door/window/left/directional/south{
base_state = "right";
dir = 4;
icon_state = "right";
name = "Hydroponics Desk";
req_access_txt = "201"
},
/turf/open/floor/iron{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/central)
"ib" = (
/obj/structure/chair{
dir = 8
@@ -4120,20 +4057,6 @@
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/crew_quarters)
"jy" = (
/obj/machinery/door/window/right/directional/south{
name = "Bar Door";
req_access_txt = "201"
},
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/tile/bar,
/obj/effect/turf_decal/tile/bar{
dir = 1
},
/turf/open/floor/iron{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/crew_quarters)
"jz" = (
/obj/machinery/camera/directional/east{
c_tag = "Bar";
@@ -8815,30 +8738,6 @@
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/engineering)
"sc" = (
/obj/structure/table/reinforced,
/obj/machinery/door/firedoor,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
dir = 4
},
/obj/machinery/door/poddoor/shutters/preopen{
id = "UO45_EngineeringOffice";
name = "Privacy Shutters"
},
/obj/machinery/door/window/left/directional/south{
dir = 4;
name = "Engineering Reception";
req_access_txt = "201"
},
/obj/item/paper_bin{
pixel_x = 1;
pixel_y = 9
},
/obj/item/pen,
/turf/open/floor/iron{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/engineering)
"sd" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
dir = 1
@@ -9225,28 +9124,6 @@
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/engineering)
"sP" = (
/obj/structure/table/reinforced,
/obj/machinery/door/firedoor,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden{
dir = 4
},
/obj/machinery/door/poddoor/shutters/preopen{
id = "UO45_EngineeringOffice";
name = "Privacy Shutters"
},
/obj/machinery/door/window/left/directional/south{
base_state = "right";
dir = 4;
icon_state = "right";
name = "Engineering Reception";
req_access_txt = "201"
},
/obj/item/folder/red,
/turf/open/floor/iron{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/engineering)
"sQ" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden{
dir = 4
@@ -11664,6 +11541,26 @@
temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"zG" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
/obj/structure/table,
/obj/machinery/recharger{
pixel_y = 4
},
/obj/machinery/newscaster{
pixel_x = -30
},
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/tile/red{
dir = 1
},
/obj/effect/turf_decal/tile/red{
dir = 8
},
/turf/open/floor/iron{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/central)
"zK" = (
/obj/structure/alien/weeds,
/obj/structure/bed/nest,
@@ -11871,6 +11768,18 @@
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/engineering)
"Ed" = (
/obj/structure/table/reinforced,
/obj/machinery/door/firedoor,
/obj/machinery/door/window/left/directional/south{
dir = 4;
name = "Hydroponics Desk";
req_access_txt = "201"
},
/turf/open/floor/iron{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/central)
"Fd" = (
/obj/structure/disposalpipe/segment,
/obj/machinery/door/airlock/command/glass{
@@ -12087,6 +11996,20 @@
temperature = 363.9
},
/area/awaymission/undergroundoutpost45/gateway)
"Mu" = (
/obj/machinery/door/window/right/directional/south{
name = "Bar Door";
req_access_txt = "201"
},
/obj/effect/decal/cleanable/dirt,
/obj/effect/turf_decal/tile/bar,
/obj/effect/turf_decal/tile/bar{
dir = 1
},
/turf/open/floor/iron{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/crew_quarters)
"Mx" = (
/obj/machinery/light/small/directional/east,
/turf/open/misc/asteroid{
@@ -12123,6 +12046,25 @@
temperature = 363.9
},
/area/awaymission/undergroundoutpost45/central)
"NA" = (
/obj/structure/table/reinforced,
/obj/machinery/door/firedoor,
/obj/item/paper_bin{
pixel_x = 1;
pixel_y = 9
},
/obj/item/pen,
/obj/machinery/door/window/left/directional/south{
base_state = "right";
dir = 8;
icon_state = "right";
name = "Security Checkpoint";
req_access_txt = "201"
},
/turf/open/floor/iron{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/central)
"NK" = (
/obj/structure/bookcase/manuals/engineering,
/obj/effect/turf_decal/tile/neutral/fourcorners,
@@ -12225,6 +12167,30 @@
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/central)
"Qm" = (
/obj/structure/table/reinforced,
/obj/machinery/door/firedoor,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden{
dir = 4
},
/obj/machinery/door/poddoor/shutters/preopen{
id = "UO45_EngineeringOffice";
name = "Privacy Shutters"
},
/obj/machinery/door/window/left/directional/south{
dir = 4;
name = "Engineering Reception";
req_access_txt = "201"
},
/obj/item/paper_bin{
pixel_x = 1;
pixel_y = 9
},
/obj/item/pen,
/turf/open/floor/iron{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/engineering)
"Qo" = (
/obj/structure/disposalpipe/segment{
dir = 9
@@ -12391,6 +12357,18 @@
temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"Wo" = (
/obj/structure/table/reinforced,
/obj/machinery/door/firedoor,
/obj/machinery/door/window/left/directional/east{
dir = 1;
name = "Hydroponics Desk";
req_access_txt = "201"
},
/turf/open/floor/iron/dark{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/crew_quarters)
"WE" = (
/obj/structure/glowshroom/single,
/turf/open/misc/asteroid{
@@ -12409,6 +12387,28 @@
temperature = 363.9
},
/area/awaymission/undergroundoutpost45/caves)
"XJ" = (
/obj/structure/table/reinforced,
/obj/machinery/door/firedoor,
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden{
dir = 4
},
/obj/machinery/door/poddoor/shutters/preopen{
id = "UO45_EngineeringOffice";
name = "Privacy Shutters"
},
/obj/machinery/door/window/left/directional/south{
base_state = "right";
dir = 4;
icon_state = "right";
name = "Engineering Reception";
req_access_txt = "201"
},
/obj/item/folder/red,
/turf/open/floor/iron{
heat_capacity = 1e+006
},
/area/awaymission/undergroundoutpost45/engineering)
"XQ" = (
/obj/structure/glowshroom/single,
/turf/open/misc/asteroid{
@@ -41391,7 +41391,7 @@ ae
bf
eg
cz
eK
zG
eW
fo
fA
@@ -42161,8 +42161,8 @@ br
an
dR
aP
ex
eM
NA
hh
aP
ae
fD
@@ -45246,8 +45246,8 @@ bd
dZ
aS
aP
eQ
fd
Ed
hZ
ae
ad
ad
@@ -46803,7 +46803,7 @@ hO
hK
hK
hK
jy
Mu
hK
kr
li
@@ -47819,7 +47819,7 @@ eD
en
fk
Bh
fM
Wo
fZ
fZ
fZ
@@ -51700,8 +51700,8 @@ Ai
zq
ni
ni
sc
sP
Qm
XJ
ln
ln
uE
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+27 -27
View File
@@ -1826,6 +1826,13 @@
},
/turf/open/lava/smooth/lava_land_surface,
/area/lavaland/surface/outdoors)
"lN" = (
/obj/machinery/door/window/right/directional/south,
/obj/machinery/shower{
pixel_y = 22
},
/turf/open/floor/iron/freezer,
/area/mine/living_quarters)
"lO" = (
/obj/effect/turf_decal/tile/brown{
dir = 4
@@ -2279,16 +2286,6 @@
},
/turf/open/misc/asteroid/basalt/lava_land_surface,
/area/lavaland/surface/outdoors)
"pH" = (
/obj/effect/turf_decal/tile/brown{
dir = 1
},
/obj/effect/turf_decal/tile/brown{
dir = 8
},
/obj/machinery/bounty_board/directional/west,
/turf/open/floor/iron,
/area/mine/production)
"pR" = (
/obj/effect/turf_decal/bot,
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
@@ -2564,13 +2561,6 @@
/obj/effect/turf_decal/tile/red,
/turf/open/floor/iron,
/area/mine/laborcamp/security)
"vb" = (
/obj/machinery/door/window/left/directional/south,
/obj/machinery/shower{
pixel_y = 22
},
/turf/open/floor/iron/freezer,
/area/mine/living_quarters)
"vg" = (
/obj/effect/turf_decal/delivery,
/obj/effect/decal/cleanable/dirt,
@@ -3189,13 +3179,6 @@
/obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2,
/turf/open/floor/iron,
/area/mine/laborcamp)
"Es" = (
/obj/machinery/door/window/right/directional/south,
/obj/machinery/shower{
pixel_y = 22
},
/turf/open/floor/iron/freezer,
/area/mine/living_quarters)
"EB" = (
/obj/structure/stone_tile/cracked,
/obj/structure/stone_tile/cracked{
@@ -3561,6 +3544,16 @@
},
/turf/open/floor/iron,
/area/mine/living_quarters)
"Ja" = (
/obj/effect/turf_decal/tile/brown{
dir = 1
},
/obj/effect/turf_decal/tile/brown{
dir = 8
},
/obj/machinery/newscaster/directional/west,
/turf/open/floor/iron,
/area/mine/production)
"Jd" = (
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/dark,
@@ -3832,6 +3825,13 @@
},
/turf/open/floor/iron,
/area/mine/living_quarters)
"Po" = (
/obj/machinery/door/window/left/directional/south,
/obj/machinery/shower{
pixel_y = 22
},
/turf/open/floor/iron/freezer,
/area/mine/living_quarters)
"Pr" = (
/obj/structure/chair/stool/directional/west,
/obj/effect/decal/cleanable/dirt,
@@ -15127,7 +15127,7 @@ fk
Pt
fI
cM
vb
Po
Zr
cM
ai
@@ -15384,7 +15384,7 @@ fk
TL
fk
cM
Es
lN
uC
cM
Hm
@@ -19741,7 +19741,7 @@ cl
cH
cO
Qj
pH
Ja
dJ
ia
cn
+30 -30
View File
@@ -111,10 +111,6 @@
"aA" = (
/turf/open/floor/iron,
/area/engineering/main)
"aB" = (
/obj/machinery/newscaster/security_unit,
/turf/closed/wall/r_wall,
/area/engineering/main)
"aC" = (
/obj/effect/mapping_helpers/airlock/cyclelink_helper{
dir = 4
@@ -1053,6 +1049,13 @@
/obj/structure/table,
/turf/open/floor/iron,
/area/commons/storage/primary)
"dO" = (
/obj/structure/table,
/obj/machinery/light/directional/south,
/obj/item/storage/medkit/regular,
/obj/item/healthanalyzer/advanced,
/turf/open/floor/iron,
/area/commons/storage/primary)
"dP" = (
/obj/effect/turf_decal/stripes/line{
dir = 1
@@ -2026,11 +2029,6 @@
/obj/machinery/chem_mass_spec,
/turf/open/floor/iron,
/area/medical/chemistry)
"mO" = (
/obj/machinery/gravity_generator/main/station,
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/engineering/gravity_generator)
"nn" = (
/obj/machinery/atmospherics/components/unary/vent_pump/on{
dir = 8
@@ -2048,6 +2046,10 @@
/obj/item/storage/toolbox/syndicate,
/turf/open/floor/iron,
/area/commons/storage/primary)
"nU" = (
/obj/machinery/newscaster,
/turf/closed/wall/r_wall,
/area/engineering/main)
"od" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -2230,10 +2232,6 @@
"wU" = (
/turf/closed/wall/r_wall,
/area/science/misc_lab)
"xy" = (
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/engineering/gravity_generator)
"yK" = (
/obj/structure/fans/tiny/invisible,
/obj/effect/turf_decal/stripes/line{
@@ -2246,13 +2244,6 @@
/obj/structure/cable,
/turf/open/floor/iron,
/area/engineering/atmos)
"AA" = (
/obj/structure/table,
/obj/machinery/light/directional/south,
/obj/item/storage/medkit/regular,
/obj/item/healthanalyzer/advanced,
/turf/open/floor/iron,
/area/commons/storage/primary)
"AE" = (
/obj/machinery/airalarm/unlocked{
dir = 1;
@@ -2379,6 +2370,11 @@
},
/turf/open/floor/iron,
/area/command/bridge)
"IE" = (
/obj/machinery/gravity_generator/main/station,
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/engineering/gravity_generator)
"II" = (
/obj/effect/turf_decal/stripes/line{
dir = 8
@@ -2436,6 +2432,10 @@
},
/turf/open/floor/iron,
/area/cargo/miningoffice)
"MN" = (
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/engineering/gravity_generator)
"MY" = (
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden,
/obj/structure/cable,
@@ -7189,7 +7189,7 @@ aa
aj
al
aA
aB
nU
WT
aj
aj
@@ -7582,7 +7582,7 @@ dJ
dJ
dJ
dJ
AA
dO
cS
gz
fO
@@ -8018,9 +8018,9 @@ ad
af
ak
av
xy
xy
xy
MN
MN
MN
av
by
bU
@@ -8110,9 +8110,9 @@ ad
af
ak
dT
xy
MN
av
mO
IE
av
by
bV
@@ -8202,9 +8202,9 @@ ad
af
ak
av
xy
xy
xy
MN
MN
MN
av
by
bW
+177 -177
View File
@@ -1231,6 +1231,18 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/centcom/control)
"en" = (
/obj/item/storage/box/ids{
pixel_x = 3;
pixel_y = 3
},
/obj/item/storage/box/silver_ids,
/obj/structure/table/reinforced,
/obj/machinery/newscaster/directional/north,
/obj/structure/reagent_dispensers/wall/peppertank/directional/east,
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/centcom/control)
"eo" = (
/obj/structure/toilet/greyscale{
dir = 4
@@ -1396,6 +1408,18 @@
},
/turf/open/floor/iron/grimy,
/area/tdome/observation)
"eO" = (
/obj/structure/table/wood,
/obj/item/clipboard,
/obj/item/folder/blue,
/obj/item/melee/chainofcommand,
/obj/item/stamp/captain,
/obj/machinery/newscaster{
pixel_y = 32
},
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/centcom/admin)
"eP" = (
/obj/structure/chair/office{
dir = 4
@@ -1404,6 +1428,16 @@
/obj/effect/decal/cleanable/dirt,
/turf/open/floor/iron/dark,
/area/centcom/control)
"eQ" = (
/obj/machinery/newscaster{
pixel_x = -32
},
/obj/effect/turf_decal/stripes/line{
dir = 8
},
/obj/machinery/light/directional/west,
/turf/open/floor/iron,
/area/centcom/prison)
"eS" = (
/obj/structure/table/wood,
/obj/item/folder,
@@ -1685,18 +1719,6 @@
/obj/structure/chair/stool/directional/south,
/turf/open/floor/wood/parquet,
/area/centcom/holding)
"fL" = (
/obj/item/storage/box/ids{
pixel_x = 3;
pixel_y = 3
},
/obj/item/storage/box/silver_ids,
/obj/structure/table/reinforced,
/obj/machinery/newscaster/security_unit/directional/north,
/obj/structure/reagent_dispensers/wall/peppertank/directional/east,
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/centcom/control)
"fM" = (
/turf/closed/indestructible/fakedoor{
name = "Guest House Back Entrance"
@@ -2121,19 +2143,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/centcom/briefing)
"hq" = (
/obj/structure/table/wood,
/obj/item/storage/secure/briefcase{
pixel_x = 5;
pixel_y = 5
},
/obj/item/storage/lockbox/medal,
/obj/machinery/newscaster/security_unit{
pixel_x = 32
},
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/centcom/admin)
"hs" = (
/turf/open/misc/asteroid/basalt/wasteland{
initial_gas_mix = "TEMP=2.7"
@@ -3039,16 +3048,6 @@
/obj/effect/turf_decal/bot,
/turf/open/floor/iron,
/area/centcom/supply)
"jR" = (
/obj/machinery/newscaster/security_unit{
pixel_x = -32
},
/obj/effect/turf_decal/stripes/line{
dir = 8
},
/obj/machinery/light/directional/west,
/turf/open/floor/iron,
/area/centcom/prison)
"jS" = (
/obj/machinery/computer/prisoner/management,
/obj/effect/turf_decal/stripes/line,
@@ -3644,17 +3643,6 @@
},
/turf/open/floor/iron,
/area/centcom/supply)
"mh" = (
/obj/structure/chair,
/obj/effect/turf_decal/tile/green{
dir = 1
},
/obj/effect/turf_decal/tile/green{
dir = 4
},
/obj/machinery/newscaster/security_unit/directional/north,
/turf/open/floor/iron,
/area/centcom/control)
"mi" = (
/obj/effect/turf_decal/tile/brown{
dir = 1
@@ -4055,18 +4043,6 @@
},
/turf/open/floor/iron,
/area/centcom/fore)
"nv" = (
/obj/machinery/newscaster/security_unit{
pixel_x = -32
},
/obj/effect/turf_decal/tile/red{
dir = 1
},
/obj/effect/turf_decal/tile/red{
dir = 8
},
/turf/open/floor/iron/dark,
/area/centcom/courtroom)
"ny" = (
/obj/machinery/light/directional/west,
/turf/open/floor/plating,
@@ -4093,18 +4069,6 @@
/obj/effect/mapping_helpers/airlock/cyclelink_helper,
/turf/open/floor/iron,
/area/tdome/observation)
"nF" = (
/obj/machinery/newscaster/security_unit{
pixel_y = -32
},
/obj/machinery/computer/cargo{
dir = 1
},
/obj/effect/turf_decal/stripes/line{
dir = 9
},
/turf/open/floor/iron,
/area/centcom/supply)
"nG" = (
/obj/machinery/computer/security/mining{
dir = 1
@@ -4499,6 +4463,19 @@
/obj/machinery/status_display/evac/directional/south,
/turf/open/floor/iron,
/area/centcom/ferry)
"oV" = (
/obj/structure/table/wood,
/obj/item/storage/secure/briefcase{
pixel_x = 5;
pixel_y = 5
},
/obj/item/storage/lockbox/medal,
/obj/machinery/newscaster{
pixel_x = 32
},
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/centcom/admin)
"oX" = (
/obj/structure/chair/comfy/brown{
color = "#596479"
@@ -4617,6 +4594,17 @@
/obj/machinery/status_display/evac/directional/south,
/turf/open/floor/iron,
/area/centcom/prison)
"pr" = (
/obj/structure/chair,
/obj/effect/turf_decal/tile/green{
dir = 1
},
/obj/effect/turf_decal/tile/green{
dir = 4
},
/obj/machinery/newscaster/directional/north,
/turf/open/floor/iron,
/area/centcom/control)
"ps" = (
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
@@ -4805,14 +4793,6 @@
},
/turf/open/floor/iron,
/area/syndicate_mothership/control)
"qb" = (
/obj/structure/table/wood,
/obj/item/folder/red,
/obj/item/lighter,
/obj/machinery/newscaster/security_unit/directional/south,
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/tdome/administration)
"qc" = (
/obj/item/book/manual/wiki/security_space_law,
/obj/item/taperecorder,
@@ -5278,6 +5258,18 @@
"rM" = (
/turf/open/floor/iron/grimy,
/area/centcom/courtroom)
"rN" = (
/obj/machinery/newscaster{
pixel_x = -32
},
/obj/effect/turf_decal/tile/red{
dir = 1
},
/obj/effect/turf_decal/tile/red{
dir = 8
},
/turf/open/floor/iron/dark,
/area/centcom/courtroom)
"rS" = (
/obj/effect/turf_decal/stripes/line{
dir = 4
@@ -5714,6 +5706,17 @@
},
/turf/open/floor/iron,
/area/syndicate_mothership/control)
"tg" = (
/obj/structure/chair{
dir = 1
},
/obj/effect/turf_decal/tile/green,
/obj/effect/turf_decal/tile/green{
dir = 8
},
/obj/machinery/newscaster/directional/south,
/turf/open/floor/iron,
/area/centcom/control)
"th" = (
/obj/structure/closet/cardboard,
/obj/effect/turf_decal/stripes/corner,
@@ -6035,18 +6038,6 @@
/obj/structure/flora/ausbushes/genericbush,
/turf/open/floor/grass,
/area/centcom/prison)
"ul" = (
/obj/machinery/computer/emergency_shuttle{
dir = 1
},
/obj/machinery/newscaster/security_unit{
pixel_y = -32
},
/obj/effect/turf_decal/stripes/line{
dir = 9
},
/turf/open/floor/iron,
/area/centcom/ferry)
"um" = (
/obj/machinery/computer/communications{
dir = 1
@@ -6261,17 +6252,6 @@
/obj/structure/flora/ausbushes/pointybush,
/turf/open/floor/grass,
/area/centcom/ferry)
"vc" = (
/obj/structure/chair{
dir = 1
},
/obj/effect/turf_decal/tile/green,
/obj/effect/turf_decal/tile/green{
dir = 8
},
/obj/machinery/newscaster/security_unit/directional/south,
/turf/open/floor/iron,
/area/centcom/control)
"vd" = (
/obj/structure/table/reinforced,
/obj/machinery/door/firedoor,
@@ -6346,6 +6326,21 @@
},
/turf/open/floor/carpet,
/area/wizard_station)
"vo" = (
/obj/structure/window/reinforced{
dir = 8
},
/obj/machinery/shower{
pixel_y = 16
},
/obj/structure/curtain,
/obj/machinery/door/window/brigdoor/left/directional/south{
name = "Shower"
},
/obj/item/soap/deluxe,
/obj/machinery/atmospherics/components/unary/vent_pump/on,
/turf/open/floor/iron/white,
/area/centcom/admin)
"vp" = (
/obj/machinery/light/directional/south,
/turf/open/floor/carpet/black,
@@ -7188,6 +7183,13 @@
},
/turf/open/floor/wood,
/area/centcom/control)
"xX" = (
/obj/machinery/newscaster{
pixel_x = 32
},
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/centcom/courtroom)
"xY" = (
/obj/effect/turf_decal/tile/blue{
dir = 1
@@ -7404,6 +7406,18 @@
/obj/machinery/status_display/evac/directional/north,
/turf/open/floor/iron/grimy,
/area/centcom/admin)
"yP" = (
/obj/machinery/newscaster{
pixel_y = -32
},
/obj/machinery/computer/cargo{
dir = 1
},
/obj/effect/turf_decal/stripes/line{
dir = 9
},
/turf/open/floor/iron,
/area/centcom/supply)
"yQ" = (
/obj/effect/turf_decal/siding/wood{
dir = 1
@@ -9320,6 +9334,10 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/centcom/courtroom)
"Hd" = (
/obj/machinery/newscaster,
/turf/closed/indestructible/riveted,
/area/centcom/admin)
"Hi" = (
/obj/structure/flora/rock/pile,
/obj/structure/flora/ausbushes/grassybush,
@@ -9404,6 +9422,18 @@
},
/turf/open/floor/vault/rock,
/area/centcom/holding)
"Ir" = (
/obj/machinery/computer/emergency_shuttle{
dir = 1
},
/obj/machinery/newscaster{
pixel_y = -32
},
/obj/effect/turf_decal/stripes/line{
dir = 9
},
/turf/open/floor/iron,
/area/centcom/ferry)
"Is" = (
/obj/machinery/igniter/on,
/obj/effect/turf_decal/delivery,
@@ -10033,14 +10063,6 @@
/obj/item/storage/box/handcuffs,
/turf/open/floor/mineral/plastitanium/red,
/area/centcom/evacuation/ship)
"Lr" = (
/obj/machinery/door/window/right/directional/north{
dir = 4;
name = "Security Desk";
req_access_txt = "103"
},
/turf/open/floor/mineral/plastitanium/red,
/area/centcom/evacuation/ship)
"Ls" = (
/obj/docking_port/stationary{
dir = 4;
@@ -10317,6 +10339,14 @@
},
/turf/open/floor/carpet/black,
/area/centcom/holding)
"MD" = (
/obj/machinery/door/window/right/directional/north{
dir = 4;
name = "Security Desk";
req_access_txt = "103"
},
/turf/open/floor/mineral/plastitanium/red,
/area/centcom/evacuation/ship)
"ME" = (
/obj/machinery/computer/camera_advanced{
dir = 4
@@ -11205,6 +11235,13 @@
dir = 1
},
/area/centcom/holding)
"PE" = (
/obj/machinery/newscaster{
pixel_x = 32
},
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/centcom/armory)
"PF" = (
/obj/structure/sign/nanotrasen,
/turf/closed/indestructible/riveted,
@@ -11590,18 +11627,6 @@
"QV" = (
/turf/open/floor/iron/grimy,
/area/centcom/admin)
"QW" = (
/obj/structure/table/wood,
/obj/item/clipboard,
/obj/item/folder/blue,
/obj/item/melee/chainofcommand,
/obj/item/stamp/captain,
/obj/machinery/newscaster/security_unit{
pixel_y = 32
},
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/centcom/admin)
"QY" = (
/obj/item/storage/box/handcuffs,
/obj/item/ammo_box/a357,
@@ -12020,10 +12045,6 @@
},
/turf/open/floor/iron,
/area/centcom/armory)
"Sr" = (
/obj/machinery/newscaster/security_unit,
/turf/closed/indestructible/riveted,
/area/centcom/admin)
"Ss" = (
/obj/item/kirbyplants{
icon_state = "plant-22"
@@ -12068,13 +12089,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/centcom/courtroom)
"SC" = (
/obj/machinery/newscaster/security_unit{
pixel_x = 32
},
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/centcom/armory)
"SD" = (
/obj/effect/turf_decal/siding/wood{
dir = 6
@@ -12122,21 +12136,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/centcom/briefing)
"SN" = (
/obj/structure/window/reinforced{
dir = 8
},
/obj/machinery/shower{
pixel_y = 16
},
/obj/structure/curtain,
/obj/machinery/door/window/brigdoor/left/directional/south{
name = "Shower"
},
/obj/item/soap/deluxe,
/obj/machinery/atmospherics/components/unary/vent_pump/on,
/turf/open/floor/iron/white,
/area/centcom/admin)
"SO" = (
/obj/machinery/computer/secure_data{
dir = 8
@@ -12325,13 +12324,6 @@
/obj/machinery/status_display/evac/directional/south,
/turf/open/floor/iron/dark,
/area/centcom/supply)
"Tr" = (
/obj/structure/table/wood,
/obj/structure/reagent_dispensers/beerkeg,
/obj/machinery/newscaster/security_unit/directional/north,
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/tdome/observation)
"Ts" = (
/obj/structure/table/reinforced,
/obj/item/restraints/handcuffs/cable/zipties,
@@ -12767,6 +12759,14 @@
/obj/machinery/light/small/directional/north,
/turf/open/floor/carpet/black,
/area/centcom/holding)
"UV" = (
/obj/structure/table/wood,
/obj/item/folder/red,
/obj/item/lighter,
/obj/machinery/newscaster/directional/south,
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/tdome/administration)
"UW" = (
/obj/effect/turf_decal/stripes/line{
dir = 10
@@ -13881,6 +13881,13 @@
"YC" = (
/turf/open/floor/wood/large,
/area/centcom/holding)
"YD" = (
/obj/structure/table/wood,
/obj/structure/reagent_dispensers/beerkeg,
/obj/machinery/newscaster/directional/north,
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/tdome/observation)
"YF" = (
/obj/machinery/gibber,
/turf/open/floor/catwalk_floor,
@@ -14211,13 +14218,6 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/centcom/ferry)
"ZO" = (
/obj/machinery/newscaster/security_unit{
pixel_x = 32
},
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/centcom/courtroom)
"ZP" = (
/obj/machinery/light/directional/east,
/obj/effect/turf_decal/tile/green{
@@ -40749,7 +40749,7 @@ KV
Lg
Lm
Lg
Lr
MD
Lt
KH
KH
@@ -49162,7 +49162,7 @@ oe
rm
ss
tq
ul
Ir
mD
vA
oe
@@ -51977,7 +51977,7 @@ aa
aa
aa
On
Sr
Hd
YI
On
gI
@@ -52491,7 +52491,7 @@ aa
aa
aa
On
SN
vo
fP
On
Qg
@@ -53012,7 +53012,7 @@ yO
To
ye
ri
hq
oV
On
Wq
Vz
@@ -53779,7 +53779,7 @@ mG
nl
pd
On
QW
eO
by
QV
QV
@@ -54291,7 +54291,7 @@ iX
md
iR
nn
nF
yP
On
On
On
@@ -55084,7 +55084,7 @@ wg
oL
fj
RM
SC
PE
oL
VM
Ya
@@ -58459,7 +58459,7 @@ Pj
Pr
Xw
Sz
qb
UV
uf
Wn
uf
@@ -59422,7 +59422,7 @@ iT
jz
iT
iT
jR
eQ
iT
iT
kS
@@ -59981,7 +59981,7 @@ QC
Qi
cZ
QC
Tr
YD
cS
cS
AE
@@ -60472,11 +60472,11 @@ sK
Ts
em
io
mh
pr
Ab
Ab
Ab
vc
tg
io
zI
Ab
@@ -61752,7 +61752,7 @@ RI
io
io
io
fL
en
uc
SO
bG
@@ -63542,7 +63542,7 @@ hP
lR
ml
mW
nv
rN
bP
ps
ps
@@ -66619,7 +66619,7 @@ aa
aa
Hv
Wp
ZO
xX
zo
pc
Xc
File diff suppressed because it is too large Load Diff
+57 -57
View File
@@ -11,14 +11,6 @@
/obj/structure/sign/nanotrasen,
/turf/closed/wall/mineral/titanium,
/area/shuttle/escape)
"ad" = (
/obj/structure/chair/comfy/shuttle{
dir = 4
},
/obj/machinery/newscaster/security_unit/directional/north,
/obj/structure/reagent_dispensers/wall/peppertank/directional/west,
/turf/open/floor/mineral/plastitanium/red/brig,
/area/shuttle/escape/brig)
"ae" = (
/obj/structure/chair/comfy/shuttle,
/turf/open/floor/mineral/plastitanium/red/brig,
@@ -41,59 +33,15 @@
"al" = (
/turf/open/floor/mineral/plastitanium/red/brig,
/area/shuttle/escape/brig)
"am" = (
/obj/machinery/door/airlock/command{
name = "Emergency Recovery Airlock"
},
/obj/effect/turf_decal/stripes/line{
dir = 8
},
/obj/effect/turf_decal/stripes/line{
dir = 4
},
/obj/effect/mapping_helpers/airlock/access/all/command/general,
/turf/open/floor/iron,
/area/shuttle/escape/brig)
"aq" = (
/obj/machinery/door/airlock/shuttle{
name = "Emergency Shuttle Airlock"
},
/obj/effect/turf_decal/stripes/line{
dir = 8
},
/obj/effect/turf_decal/stripes/line{
dir = 4
},
/obj/effect/mapping_helpers/airlock/access/all/security/brig,
/turf/open/floor/iron/white,
/area/shuttle/escape/brig)
"ar" = (
/obj/structure/table/reinforced,
/obj/machinery/recharger,
/turf/open/floor/mineral/plastitanium/red/brig,
/area/shuttle/escape/brig)
"av" = (
/obj/machinery/door/airlock/security/glass{
name = "Holding Area"
},
/obj/effect/mapping_helpers/airlock/access/all/security/brig,
/turf/open/floor/mineral/plastitanium/red/brig,
/area/shuttle/escape/brig)
"aw" = (
/obj/machinery/status_display/ai,
/turf/closed/wall/mineral/titanium/nodiagonal,
/area/shuttle/escape)
"ax" = (
/obj/machinery/door/airlock/command/glass{
name = "Cockpit"
},
/obj/effect/turf_decal/stripes/line,
/obj/effect/turf_decal/stripes/line{
dir = 1
},
/obj/effect/mapping_helpers/airlock/access/all/command/general,
/turf/open/floor/iron,
/area/shuttle/escape)
"ay" = (
/obj/machinery/door/airlock/shuttle{
name = "Emergency Shuttle Airlock"
@@ -591,6 +539,14 @@
},
/turf/open/floor/iron/white,
/area/shuttle/escape)
"dW" = (
/obj/structure/chair/comfy/shuttle{
dir = 4
},
/obj/machinery/newscaster/directional/north,
/obj/structure/reagent_dispensers/wall/peppertank/directional/west,
/turf/open/floor/mineral/plastitanium/red/brig,
/area/shuttle/escape/brig)
"eA" = (
/obj/structure/chair/comfy/shuttle{
dir = 4
@@ -646,10 +602,34 @@
},
/turf/open/floor/iron,
/area/shuttle/escape)
"qX" = (
/obj/machinery/door/airlock/shuttle{
name = "Emergency Shuttle Airlock"
},
/obj/effect/turf_decal/stripes/line{
dir = 8
},
/obj/effect/turf_decal/stripes/line{
dir = 4
},
/obj/effect/mapping_helpers/airlock/access/all/security/brig,
/turf/open/floor/iron/white,
/area/shuttle/escape/brig)
"sY" = (
/obj/effect/spawner/structure/window/reinforced/shuttle,
/turf/open/floor/plating,
/area/shuttle/escape)
"vu" = (
/obj/machinery/door/airlock/command/glass{
name = "Cockpit"
},
/obj/effect/turf_decal/stripes/line,
/obj/effect/turf_decal/stripes/line{
dir = 1
},
/obj/effect/mapping_helpers/airlock/access/all/command/general,
/turf/open/floor/iron,
/area/shuttle/escape)
"wF" = (
/obj/structure/closet/crate/medical,
/obj/item/storage/medkit/regular,
@@ -695,6 +675,19 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/shuttle/escape)
"IX" = (
/obj/machinery/door/airlock/command{
name = "Emergency Recovery Airlock"
},
/obj/effect/turf_decal/stripes/line{
dir = 8
},
/obj/effect/turf_decal/stripes/line{
dir = 4
},
/obj/effect/mapping_helpers/airlock/access/all/command/general,
/turf/open/floor/iron,
/area/shuttle/escape/brig)
"Kj" = (
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
@@ -707,6 +700,13 @@
/obj/effect/turf_decal/tile/neutral/fourcorners,
/turf/open/floor/iron/dark,
/area/shuttle/escape)
"TB" = (
/obj/machinery/door/airlock/security/glass{
name = "Holding Area"
},
/obj/effect/mapping_helpers/airlock/access/all/security/brig,
/turf/open/floor/mineral/plastitanium/red/brig,
/area/shuttle/escape/brig)
"UY" = (
/obj/item/storage/medkit/fire,
/obj/item/storage/medkit/regular{
@@ -729,7 +729,7 @@
aa
aa
aa
aq
qX
ac
ay
aa
@@ -748,7 +748,7 @@ bu
"}
(2,1,1) = {"
aa
ad
dW
ak
al
sY
@@ -772,7 +772,7 @@ sY
ae
al
al
av
TB
aA
UZ
UZ
@@ -833,7 +833,7 @@ bv
(6,1,1) = {"
ac
ab
am
IX
sY
aw
aB
@@ -877,7 +877,7 @@ sY
Dr
Ou
Kj
ax
vu
aA
aJ
aN
+1 -1
View File
@@ -104,7 +104,7 @@ GLOBAL_LIST_INIT(WALLITEMS_INTERIOR, typecacheof(list(
/obj/item/storage/secure/safe,
/obj/machinery/airalarm,
/obj/machinery/bluespace_vendor,
/obj/machinery/bounty_board,
/obj/machinery/newscaster,
/obj/machinery/button,
/obj/machinery/computer/security/telescreen,
/obj/machinery/computer/security/telescreen/entertainment,
+3 -3
View File
@@ -14,7 +14,7 @@
announcement += "<br><h2 class='alert'>[html_encode(title)]</h2>"
else if(type == "Captain")
announcement += "<h1 class='alert'>Captain Announces</h1>"
GLOB.news_network.SubmitArticle(html_encode(text), "Captain's Announcement", "Station Announcements", null)
GLOB.news_network.submit_article(html_encode(text), "Captain's Announcement", "Station Announcements", null)
else if(type == "Syndicate Captain")
announcement += "<h1 class='alert'>Syndicate Captain Announces</h1>"
@@ -28,9 +28,9 @@
if(!sender_override)
if(title == "")
GLOB.news_network.SubmitArticle(text, "Central Command Update", "Station Announcements", null)
GLOB.news_network.submit_article(text, "Central Command Update", "Station Announcements", null)
else
GLOB.news_network.SubmitArticle(title + "<br><br>" + text, "Central Command", "Station Announcements", null)
GLOB.news_network.submit_article(title + "<br><br>" + text, "Central Command", "Station Announcements", null)
///If the announcer overrides alert messages, use that message.
if(SSstation.announcer.custom_alert_message && !has_important_message)
+6 -6
View File
@@ -157,27 +157,27 @@
var/list/file_data = list()
var/pos = 1
for(var/V in GLOB.news_network.network_channels)
var/datum/newscaster/feed_channel/channel = V
var/datum/feed_channel/channel = V
if(!istype(channel))
stack_trace("Non-channel in newscaster channel list")
continue
file_data["[pos]"] = list("channel name" = "[channel.channel_name]", "author" = "[channel.author]", "censored" = channel.censored ? 1 : 0, "author censored" = channel.authorCensor ? 1 : 0, "messages" = list())
file_data["[pos]"] = list("channel name" = "[channel.channel_name]", "author" = "[channel.author]", "censored" = channel.censored ? 1 : 0, "author censored" = channel.author_censor ? 1 : 0, "messages" = list())
for(var/M in channel.messages)
var/datum/newscaster/feed_message/message = M
var/datum/feed_message/message = M
if(!istype(message))
stack_trace("Non-message in newscaster channel messages list")
continue
var/list/comment_data = list()
for(var/C in message.comments)
var/datum/newscaster/feed_comment/comment = C
var/datum/feed_comment/comment = C
if(!istype(comment))
stack_trace("Non-message in newscaster message comments list")
continue
comment_data += list(list("author" = "[comment.author]", "time stamp" = "[comment.time_stamp]", "body" = "[comment.body]"))
file_data["[pos]"]["messages"] += list(list("author" = "[message.author]", "time stamp" = "[message.time_stamp]", "censored" = message.bodyCensor ? 1 : 0, "author censored" = message.authorCensor ? 1 : 0, "photo file" = "[message.photo_file]", "photo caption" = "[message.caption]", "body" = "[message.body]", "comments" = comment_data))
file_data["[pos]"]["messages"] += list(list("author" = "[message.author]", "time stamp" = "[message.time_stamp]", "censored" = message.body_censor ? 1 : 0, "author censored" = message.author_censor ? 1 : 0, "photo file" = "[message.photo_file]", "photo caption" = "[message.caption]", "body" = "[message.body]", "comments" = comment_data))
pos++
if(GLOB.news_network.wanted_issue.active)
file_data["wanted"] = list("author" = "[GLOB.news_network.wanted_issue.scannedUser]", "criminal" = "[GLOB.news_network.wanted_issue.criminal]", "description" = "[GLOB.news_network.wanted_issue.body]", "photo file" = "[GLOB.news_network.wanted_issue.photo_file]")
file_data["wanted"] = list("author" = "[GLOB.news_network.wanted_issue.scanned_user]", "criminal" = "[GLOB.news_network.wanted_issue.criminal]", "description" = "[GLOB.news_network.wanted_issue.body]", "photo file" = "[GLOB.news_network.wanted_issue.photo_file]")
WRITE_FILE(json_file, json_encode(file_data))
///Handles random hardcore point rewarding if it applies.
+2 -2
View File
@@ -121,8 +121,8 @@ SUBSYSTEM_DEF(economy)
if(!is_station_level(V.z))
continue
V.reset_prices(V.product_records, V.coin_records)
earning_report = "Sector Economic Report<br /> Sector vendor prices is currently at [SSeconomy.inflation_value()*100]%.<br /> The station spending power is currently <b>[station_total] Credits</b>, and the crew's targeted allowance is at <b>[station_target] Credits</b>.<br /> That's all from the <i>Nanotrasen Economist Division</i>."
GLOB.news_network.SubmitArticle(earning_report, "Station Earnings Report", "Station Announcements", null, update_alert = FALSE)
earning_report = "<b>Sector Economic Report</b><br><br> Sector vendor prices is currently at <b>[SSeconomy.inflation_value()*100]%</b>.<br><br> The station spending power is currently <b>[station_total] Credits</b>, and the crew's targeted allowance is at <b>[station_target] Credits</b>.<br><br> That's all from the <i>Nanotrasen Economist Division</i>."
GLOB.news_network.submit_article(earning_report, "Station Earnings Report", "Station Announcements", null, update_alert = FALSE)
/**
* Proc that returns a value meant to shift inflation values in vendors, based on how much money exists on the station.
-192
View File
@@ -1,192 +0,0 @@
GLOBAL_LIST_EMPTY(allbountyboards)
GLOBAL_LIST_EMPTY(request_list)
/**
* A machine that acts basically like a quest board.
* Enables crew to create requests, crew can sign up to perform the request, and the requester can chose who to pay-out.
*/
/obj/machinery/bounty_board
name = "bounty board"
desc = "Allows you to place requests for goods and services across the station, as well as pay those who actually did it."
icon = 'icons/obj/terminals.dmi'
icon_state = "request_kiosk"
light_color = LIGHT_COLOR_GREEN
///Reference to the currently logged in user.
var/datum/bank_account/current_user
///The station request datum being affected by UI actions.
var/datum/station_request/active_request
///Value of the currently bounty input
var/bounty_value = 1
///Text of the currently written bounty
var/bounty_text = ""
MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/bounty_board, 32)
/obj/machinery/bounty_board/Initialize(mapload, ndir, building)
. = ..()
GLOB.allbountyboards += src
/obj/machinery/bounty_board/Destroy()
GLOB.allbountyboards -= src
. = ..()
/obj/machinery/bounty_board/attackby(obj/item/I, mob/living/user, params)
. = ..()
if(istype(I,/obj/item/card/id))
var/obj/item/card/id/current_card = I
if(current_card.registered_account)
current_user = current_card.registered_account
return TRUE
say("Requesting ID has no registered account.")
return TRUE
if(I.tool_behaviour == TOOL_WRENCH)
to_chat(user, span_notice("You start [anchored ? "un" : ""]securing [name]..."))
I.play_tool_sound(src)
if(I.use_tool(src, user, 30))
playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE)
if(machine_stat & BROKEN)
to_chat(user, span_warning("The broken remains of [src] fall on the ground."))
new /obj/item/stack/sheet/iron(loc, 3)
new /obj/item/shard(loc)
else
to_chat(user, span_notice("You [anchored ? "un" : ""]secure [name]."))
new /obj/item/wallframe/bounty_board(loc)
qdel(src)
/obj/machinery/bounty_board/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "RequestKiosk", name)
ui.open()
/obj/machinery/bounty_board/ui_data(mob/user)
var/list/data = list()
var/list/formatted_requests = list()
var/list/formatted_applicants = list()
for(var/i in GLOB.request_list)
if(!i)
continue
var/datum/station_request/request = i
formatted_requests += list(list("owner" = request.owner, "value" = request.value, "description" = request.description, "acc_number" = request.req_number))
if(request.applicants)
for(var/datum/bank_account/j in request.applicants)
formatted_applicants += list(list("name" = j.account_holder, "request_id" = request.owner_account.account_id, "requestee_id" = j.account_id))
var/obj/item/card/id/id_card
if(isliving(user))
var/mob/living/L = user
id_card = L.get_idcard()
if(id_card?.registered_account)
current_user = id_card.registered_account
if(current_user)
data["accountName"] = current_user.account_holder
data["requests"] = formatted_requests
data["applicants"] = formatted_applicants
data["bountyValue"] = bounty_value
data["bountyText"] = bounty_text
return data
/obj/machinery/bounty_board/ui_act(action, list/params)
. = ..()
if(.)
return
var/current_ref_num = params["request"]
var/current_app_num = params["applicant"]
var/datum/bank_account/request_target
if(current_ref_num)
for(var/datum/station_request/i in GLOB.request_list)
if("[i.req_number]" == "[current_ref_num]")
active_request = i
break
if(active_request)
for(var/datum/bank_account/j in active_request.applicants)
if("[j.account_id]" == "[current_app_num]")
request_target = j
break
switch(action)
if("createBounty")
if(!current_user || !bounty_text)
playsound(src, 'sound/machines/buzz-sigh.ogg', 20, TRUE)
return TRUE
for(var/datum/station_request/i in GLOB.request_list)
if("[i.req_number]" == "[current_user.account_id]")
say("Account already has active bounty.")
return
var/datum/station_request/curr_request = new /datum/station_request(current_user.account_holder, bounty_value,bounty_text,current_user.account_id, current_user)
GLOB.request_list += list(curr_request)
for(var/obj/i in GLOB.allbountyboards)
i.say("New bounty has been added!")
playsound(i.loc, 'sound/effects/cashregister.ogg', 30, TRUE)
if("apply")
if(!current_user)
say("Please swipe a valid ID first.")
return TRUE
if(current_user.account_holder == active_request.owner)
playsound(src, 'sound/machines/buzz-sigh.ogg', 20, TRUE)
return TRUE
active_request.applicants += list(current_user)
if("payApplicant")
if(!current_user)
return
if(!current_user.has_money(active_request.value) || (current_user.account_holder != active_request.owner))
playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE)
return
request_target.transfer_money(current_user, active_request.value)
say("Paid out [active_request.value] credits.")
return TRUE
if("clear")
if(current_user)
current_user = null
say("Account Reset.")
return TRUE
if("deleteRequest")
if(!active_request || !current_user)
playsound(src, 'sound/machines/buzz-sigh.ogg', 20, TRUE)
return FALSE
if(active_request?.owner != current_user?.account_holder)
playsound(src, 'sound/machines/buzz-sigh.ogg', 20, TRUE)
return TRUE
say("Deleted current request.")
GLOB.request_list.Remove(active_request)
return TRUE
if("bountyVal")
bounty_value = text2num(params["bountyval"])
if(!bounty_value)
bounty_value = 1
if("bountyText")
bounty_text = (params["bountytext"])
. = TRUE
/obj/item/wallframe/bounty_board
name = "disassembled bounty board"
desc = "Used to build a new bounty board, just secure to the wall."
icon_state = "request_kiosk"
custom_materials = list(/datum/material/iron=14000, /datum/material/glass=8000)
result_path = /obj/machinery/bounty_board
pixel_shift = 32
/**
* A combined all in one datum that stores everything about the request, the requester's account, as well as the requestee's account
* All of this is passed to the Request Console UI in order to present in organized way.
*/
/datum/station_request
///Name of the Request Owner.
var/owner
///Value of the request.
var/value
///Text description of the request to be shown within the UI.
var/description
///Internal number of the request for organizing. Id card number.
var/req_number
///The account of the request owner.
var/datum/bank_account/owner_account
///the account of the request fulfiller.
var/list/applicants = list()
/datum/station_request/New(owned, newvalue, newdescription, reqnum, own_account)
. = ..()
owner = owned
value = newvalue
description = newdescription
req_number = reqnum
if(istype(own_account, /datum/bank_account))
owner_account = own_account
+1 -1
View File
@@ -82,7 +82,7 @@
if(!is_operational)
icon_state = "[base_icon_state]_off"
return ..()
icon_state = "[base_icon_state][scan_active ? "active" : null]"
icon_state = "[base_icon_state][scan_active ? "_active" : null]"
return ..()
/obj/machinery/medical_kiosk/wrench_act(mob/living/user, obj/item/I) //Allows for wrenching/unwrenching the machine.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,283 @@
GLOBAL_DATUM_INIT(news_network, /datum/feed_network, new)
GLOBAL_LIST_EMPTY(allCasters)
GLOBAL_LIST_EMPTY(allbountyboards)
GLOBAL_LIST_EMPTY(request_list)
/datum/feed_comment
///The author of the comment, as seen on a newscaster feed.
var/author = ""
///Body of the aforementioned comment.
var/body = ""
///At what time was the feed comment sent? Time is in station time.
var/time_stamp = ""
/datum/feed_message
///Who is the author of the full-size article to the feed channel?
var/author =""
///Body of the full-size article to the feed channel.
var/body =""
///In station time, at what time was the author's messages censored and blocked from viewing.
var/list/author_censor_time = list()
///In station time, at what time was this message censored and blocked from viewing.
var/list/body_censor_time = list()
///Did an admin send this message?
var/is_admin_message = FALSE
///Is there an image tied to the feed message?
var/icon/img = null
///At what time was the full-size article sent? Time is in station time.
var/time_stamp = ""
///List consisting of the articles feed comments for this full-size article.
var/list/datum/feed_comment/comments = list()
///Can comments be placed on that feed message?
var/locked = FALSE
///If the message has an image, what is that image's caption?
var/caption = ""
///At what time was the feed message created?
var/creation_time
///Has the author been blocked from making new feed messages?
var/author_censor
///Has the body of the message been censored?
var/body_censor
///Referece to the photo used in picture messages.
var/photo_file
///What is the channel ID of the parent channel?
var/parent_ID
///What number message is this? IE: The first message sent in a round including automated messages is message 1.
var/message_ID
/datum/feed_message/proc/return_author(censor)
if(censor == -1)
censor = author_censor
var/txt = "[GLOB.news_network.redacted_text]"
if(!censor)
txt = author
return txt
/datum/feed_message/proc/return_body(censor)
if(censor == -1)
censor = body_censor
var/txt = "[GLOB.news_network.redacted_text]"
if(!censor)
txt = body
return txt
/datum/feed_message/proc/toggle_censor_author()
if(author_censor)
author_censor_time.Add(GLOB.news_network.last_action*-1)
else
author_censor_time.Add(GLOB.news_network.last_action)
author_censor = !author_censor
GLOB.news_network.last_action ++
/datum/feed_message/proc/toggle_censor_body()
if(body_censor)
body_censor_time.Add(GLOB.news_network.last_action*-1)
else
body_censor_time.Add(GLOB.news_network.last_action)
body_censor = !body_censor
GLOB.news_network.last_action ++
/datum/feed_channel
/// The name of the channel, players see this on the channel selection list
var/channel_name = ""
/// The description of the channel, players see this upon clicking on the channel before seeing messages.
var/channel_desc = ""
/// Datum list of all feed_messages.
var/list/datum/feed_message/messages = list()
/// Is the channel locked? Locked channels cannot be commented on.
var/locked = FALSE
/// Who is the author of this channel? Taken from the user's ID card.
var/author = ""
/// Has this channel been censored? Where Locked channels cannot be commented on, Censored channels cannot be viewed at all.
var/censored = FALSE
/// At what times has the author been censored?
var/list/author_censor_time = list()
/// At what times has the author been D-Class censored.
var/list/D_class_censor_time = list()
/// Has the author of the channel been censored, as opposed to the message itself?
var/author_censor
/// Is this an admin channel? Allows for actions to be taken by the admin only.
var/is_admin_channel = FALSE
/// Channel ID is a random number sequence similar to account ID number that allows for us to link messages to the proper channels through the UI backend.
var/channel_ID
/datum/feed_channel/New()
. = ..()
channel_ID = random_channel_id_setup()
/**
* This proc assigns each feed_channel a random integer, from 1-999 as a unique identifer.
* Using this value, the TGUI window has a unique identifier to attach to messages that can be used to reattach them
* to their parent channels back in dreammaker.
* Based on implementation, we're limiting outselves to only 998 player made channels maximum. How we'd use all of them, I don't know.
*/
/datum/feed_channel/proc/random_channel_id_setup()
if(!GLOB.news_network)
return //Should only apply to channels made before setup is finished, use hardset_channel for these
if(!GLOB.news_network.channel_IDs)
GLOB.news_network.channel_IDs += rand(1,999)
return //This will almost always be the station annoucements channel here.
var/channel_id
for(var/i in 1 to 10000)
channel_id = rand(1, 999)
if(!GLOB.news_network.channel_IDs["[channel_ID]"])
break
channel_ID = channel_id
return channel_ID
/datum/feed_channel/proc/return_author(censor)
if(censor == -1)
censor = author_censor
var/txt = "[GLOB.news_network.redacted_text]"
if(!censor)
txt = author
return txt
/datum/feed_channel/proc/toggle_censor_D_class()
if(censored)
D_class_censor_time.Add(GLOB.news_network.last_action*-1)
else
D_class_censor_time.Add(GLOB.news_network.last_action)
censored = !censored
GLOB.news_network.last_action ++
/datum/feed_channel/proc/toggle_censor_author()
if(author_censor)
author_censor_time.Add(GLOB.news_network.last_action*-1)
else
author_censor_time.Add(GLOB.news_network.last_action)
author_censor = !author_censor
GLOB.news_network.last_action ++
/datum/wanted_message
/// Is this criminal alert still active?
var/active
/// What is the criminal in question's name? Not a mob reference as this is a text field.
var/criminal
/// Message body used to describe what crime has been comitted.
var/body
/// Who was it that created this wanted message?
var/scanned_user
/// Is this an admin message? Prevents editing unless performed by an admin rank.
var/is_admin_msg
/// Icon image to be attached to the newscaster message.
var/icon/img
/// Reference to the photo file used by wanted message on creation.
var/photo_file
/datum/feed_network
/// All the feed channels that have been made on the feed network.
var/list/datum/feed_channel/network_channels = list()
/// What is the wanted issue being sent out to all newscasters.
var/datum/wanted_message/wanted_issue
/// What time was the last action taken on the feed_network?
var/last_action
/// What does this feed network say when a message/author is redacted?
var/redacted_text = "\[REDACTED\]"
/// List of all the network_channels Channel Id numbers, kept in a global easy to find place.
var/list/channel_IDs = list()
/// How many messages currently exist on this feed_network? Increments as new messages are written.
var/message_count = 0
/datum/feed_network/New()
create_feed_channel("Station Announcements", "SS13", "Company news, staff annoucements, and all the latest information. Have a secure shift!", locked = TRUE, hardset_channel = 1000)
wanted_issue = new /datum/wanted_message
/datum/feed_network/proc/create_feed_channel(channel_name, author, desc, locked, adminChannel = FALSE, hardset_channel)
var/datum/feed_channel/newChannel = new /datum/feed_channel
newChannel.channel_name = channel_name
newChannel.author = author
newChannel.channel_desc = desc
newChannel.locked = locked
newChannel.is_admin_channel = adminChannel
if(hardset_channel)
newChannel.channel_ID = hardset_channel
network_channels += newChannel
/datum/feed_network/proc/submit_article(msg, author, channel_name, datum/picture/picture, adminMessage = FALSE, allow_comments = TRUE, update_alert = TRUE)
var/datum/feed_message/newMsg = new /datum/feed_message
newMsg.author = author
newMsg.body = msg
newMsg.time_stamp = "[station_time_timestamp()]"
newMsg.is_admin_message = adminMessage
newMsg.locked = !allow_comments
if(picture)
newMsg.img = picture.picture_image
newMsg.caption = picture.caption
newMsg.photo_file = save_photo(picture.picture_image)
for(var/datum/feed_channel/FC in network_channels)
if(FC.channel_name == channel_name)
FC.messages += newMsg
newMsg.parent_ID = FC.channel_ID
break
for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allCasters)
NEWSCASTER.news_alert(channel_name, update_alert)
last_action ++
newMsg.creation_time = last_action
message_count ++
newMsg.message_ID = message_count
/datum/feed_network/proc/submit_wanted(criminal, body, scanned_user, datum/picture/picture, adminMsg = FALSE, newMessage = FALSE)
wanted_issue.active = TRUE
wanted_issue.criminal = criminal
wanted_issue.body = body
wanted_issue.scanned_user = scanned_user
wanted_issue.is_admin_msg = adminMsg
if(picture)
wanted_issue.img = picture.picture_image
wanted_issue.photo_file = save_photo(picture.picture_image)
if(newMessage)
for(var/obj/machinery/newscaster/N in GLOB.allCasters)
N.news_alert()
N.update_appearance()
/datum/feed_network/proc/delete_wanted()
wanted_issue.active = FALSE
wanted_issue.criminal = null
wanted_issue.body = null
wanted_issue.scanned_user = null
wanted_issue.img = null
for(var/obj/machinery/newscaster/updated_newscaster in GLOB.allCasters)
updated_newscaster.update_appearance()
/datum/feed_network/proc/save_photo(icon/photo)
var/photo_file = copytext_char(md5("\icon[photo]"), 1, 6)
if(!fexists("[GLOB.log_directory]/photos/[photo_file].png"))
//Clean up repeated frames
var/icon/clean = new /icon()
clean.Insert(photo, "", SOUTH, 1, 0)
fcopy(clean, "[GLOB.log_directory]/photos/[photo_file].png")
return photo_file
//**************************
// Bounty Board Datums
//**************************
/**
* A combined all in one datum that stores everything about the request, the requester's account, as well as the requestee's account
* All of this is passed to the Request Console UI in order to present in organized way.
*/
/datum/station_request
///Name of the Request Owner.
var/owner
///Value of the request.
var/value
///Text description of the request to be shown within the UI.
var/description
///Internal number of the request for organizing. Id card number.
var/req_number
///The account of the request owner.
var/datum/bank_account/owner_account
///the account of the request fulfiller.
var/list/applicants = list()
/datum/station_request/New(owned, newvalue, newdescription, reqnum, own_account)
. = ..()
owner = owned
value = newvalue
description = newdescription
req_number = reqnum
if(istype(own_account, /datum/bank_account))
owner_account = own_account
@@ -0,0 +1,780 @@
#define ALERT_DELAY 50 SECONDS
/obj/machinery/newscaster
name = "newscaster"
desc = "A standard Nanotrasen-licensed newsfeed handler for use in commercial space stations. All the news you absolutely have no use for, in one place!"
icon = 'icons/obj/terminals.dmi'
icon_state = "newscaster_off"
base_icon_state = "newscaster"
verb_say = "beeps"
verb_ask = "beeps"
verb_exclaim = "beeps"
armor = list(MELEE = 50, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, BIO = 0, FIRE = 50, ACID = 30)
max_integrity = 200
integrity_failure = 0.25
///Reference to the currently logged in user.
var/datum/bank_account/current_user
///How much paper is contained within the newscaster?
var/paper_remaining = 0
///What newscaster channel is currently being viewed by the player?
var/datum/feed_channel/current_channel
///What newscaster feed_message is currently having a comment written for it?
var/datum/feed_message/current_message
///The message that's currently being written for a feed story.
var/feed_channel_message
///The current image that will be submitted with the newscaster story.
var/datum/picture/current_image
///Is there currently an alert on this newscaster that hasn't been seen yet?
var/alert = FALSE
///Is the current user editing or viewing a new wanted issue at the moment?
var/viewing_wanted = FALSE
///Is the current user creating a new channel at the moment?
var/creating_channel = FALSE
///Is the current user creating a new comment at the moment?
var/creating_comment = FALSE
///What is the user submitted, criminal name for the new wanted issue?
var/criminal_name
///What is the user submitted, crime description for the new wanted issue?
var/crime_description
///What is the current, in-creation channel's name going to be?
var/channel_name
///What is the current, in-creation channel's description going to be?
var/channel_desc
///What is the current, in-creation comment's body going to be?
var/comment_text
///The station request datum being affected by UI actions.
var/datum/station_request/active_request
///Value of the currently bounty input
var/bounty_value = 1
///Text of the currently written bounty
var/bounty_text = ""
MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30)
/obj/machinery/newscaster/Initialize(mapload, ndir, building)
. = ..()
GLOB.allCasters += src
GLOB.allbountyboards += src
update_appearance()
/obj/machinery/newscaster/Destroy()
GLOB.allCasters -= src
GLOB.allbountyboards -= src
current_channel = null
current_image = null
active_request = null
current_user = null
return ..()
/obj/machinery/newscaster/update_appearance(updates=ALL)
. = ..()
if(machine_stat & (NOPOWER|BROKEN))
set_light(0)
return
set_light(1.4,0.7,"#34D352") // green light
/obj/machinery/newscaster/update_overlays()
. = ..()
if(!(machine_stat & (NOPOWER|BROKEN)))
var/state = "[base_icon_state]_[GLOB.news_network.wanted_issue.active ? "wanted" : "normal"]"
. += mutable_appearance(icon, state)
. += emissive_appearance(icon, state, alpha = src.alpha)
if(GLOB.news_network.wanted_issue.active && alert)
. += mutable_appearance(icon, "[base_icon_state]_alert")
. += emissive_appearance(icon, "[base_icon_state]_alert", alpha = src.alpha)
var/hp_percent = atom_integrity * 100 / max_integrity
switch(hp_percent)
if(75 to 100)
return
if(50 to 75)
. += "crack1"
. += emissive_blocker(icon, "crack1", alpha = src.alpha)
if(25 to 50)
. += "crack2"
. += emissive_blocker(icon, "crack2", alpha = src.alpha)
else
. += "crack3"
. += emissive_blocker(icon, "crack3", alpha = src.alpha)
/obj/machinery/newscaster/ui_interact(mob/user, datum/tgui/ui)
. = ..()
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Newscaster", name)
ui.open()
alert = FALSE //We're checking our messages!
update_icon()
/obj/machinery/newscaster/ui_data(mob/user)
var/list/data = list()
var/list/message_list = list()
//Code displaying name and Job Information, taken from the player mob's ID card if one exists.
var/obj/item/card/id/card
if(isliving(user))
var/mob/living/living_user = user
card = living_user.get_idcard(hand_first = TRUE)
if(card?.registered_account)
current_user = card.registered_account
data["user"] = list()
data["user"]["name"] = card.registered_account.account_holder
if(card?.registered_account.account_job)
data["user"]["job"] = card.registered_account.account_job.title
data["user"]["department"] = card.registered_account.account_job.paycheck_department
else
data["user"]["job"] = "No Job"
data["user"]["department"] = "No Department"
else
data["user"] = list()
data["user"]["name"] = user.name
data["user"]["job"] = "N/A"
data["user"]["department"] = "N/A"
data["security_mode"] = (ACCESS_ARMORY in card?.GetAccess())
data["photo_data"] = !isnull(current_image)
data["creating_channel"] = creating_channel
data["creating_comment"] = creating_comment
data["viewing_wanted"] = viewing_wanted
//Here is all the UI_data sent about the current wanted issue, as well as making a new one in the UI.
data["making_wanted_issue"] = !(GLOB.news_network.wanted_issue?.active)
data["criminal_name"] = criminal_name
data["crime_description"] = crime_description
var/list/wanted_info = list()
if(GLOB.news_network.wanted_issue)
if(GLOB.news_network.wanted_issue.img)
user << browse_rsc(GLOB.news_network.wanted_issue.img, "wanted_photo.png")
wanted_info = list(list(
"active" = GLOB.news_network.wanted_issue.active,
"criminal" = GLOB.news_network.wanted_issue.criminal,
"crime" = GLOB.news_network.wanted_issue.body,
"author" = GLOB.news_network.wanted_issue.scanned_user,
"image" = "wanted_photo.png"
))
//Code breaking down the channels that have been made on-station thus far. ha
//Then, breaks down the messages that have been made on those channels.
if(current_channel)
for(var/datum/feed_message/feed_message as anything in current_channel.messages)
var/photo_ID = null
var/list/comment_list
if(feed_message.img)
user << browse_rsc(feed_message.img, "tmp_photo[feed_message.message_ID].png")
photo_ID = "tmp_photo[feed_message.message_ID].png"
for(var/datum/feed_comment/comment_message as anything in feed_message.comments)
comment_list += list(list(
"auth" = comment_message.author,
"body" = comment_message.body,
"time" = comment_message.time_stamp,
))
message_list += list(list(
"auth" = feed_message.author,
"body" = feed_message.body,
"time" = feed_message.time_stamp,
"channel_num" = feed_message.parent_ID,
"censored_message" = feed_message.body_censor,
"censored_author" = feed_message.author_censor,
"ID" = feed_message.message_ID,
"photo" = photo_ID,
"comments" = comment_list
))
data["viewing_channel"] = current_channel?.channel_ID
data["paper"] = paper_remaining
//Here we display all the information about the current channel.
data["channelName"] = current_channel?.channel_name
data["channelAuthor"] = current_channel?.author
if(!current_channel)
data["channelAuthor"] = "Nanotrasen Inc"
data["channelDesc"] = "Welcome to Newscaster Net. Interface & News networks Operational."
data["channelLocked"] = TRUE
else
data["channelDesc"] = current_channel.channel_desc
data["channelLocked"] = current_channel.locked
data["channelCensored"] = current_channel.censored
//We send all the information about all messages in existance.
data["messages"] = message_list
data["wanted"] = wanted_info
var/list/formatted_requests = list()
var/list/formatted_applicants = list()
for (var/datum/station_request/request as anything in GLOB.request_list)
formatted_requests += list(list("owner" = request.owner, "value" = request.value, "description" = request.description, "acc_number" = request.req_number))
if(request.applicants)
for(var/datum/bank_account/applicant_bank_account as anything in request.applicants)
formatted_applicants += list(list("name" = applicant_bank_account.account_holder, "request_id" = request.owner_account.account_id, "requestee_id" = applicant_bank_account.account_id))
data["requests"] = formatted_requests
data["applicants"] = formatted_applicants
data["bountyValue"] = bounty_value
data["bountyText"] = bounty_text
return data
/obj/machinery/newscaster/ui_static_data(mob/user)
var/list/data = list()
var/list/channel_list = list()
for(var/datum/feed_channel/channel as anything in GLOB.news_network.network_channels)
channel_list += list(list(
"name" = channel.channel_name,
"author" = channel.author,
"censored" = channel.censored,
"locked" = channel.locked,
"ID" = channel.channel_ID,
))
data["channels"] = channel_list
return data
/obj/machinery/newscaster/ui_act(action, params)
. = ..()
if(.)
return
var/current_ref_num = params["request"]
var/current_app_num = params["applicant"]
var/datum/bank_account/request_target
if(current_ref_num)
for(var/datum/station_request/iterated_station_request as anything in GLOB.request_list)
if(iterated_station_request.req_number == current_ref_num)
active_request = iterated_station_request
break
if(active_request)
for(var/datum/bank_account/iterated_bank_account as anything in active_request.applicants)
if(iterated_bank_account.account_id == current_app_num)
request_target = iterated_bank_account
break
switch(action)
if("setChannel")
var/prototype_channel = params["channel"]
if(isnull(prototype_channel))
return TRUE
for(var/datum/feed_channel/potential_channel as anything in GLOB.news_network.network_channels)
if(prototype_channel == potential_channel.channel_ID)
current_channel = potential_channel
if("createStory")
if(!current_channel)
balloon_alert(usr, "select a channel first!")
return TRUE
var/prototype_channel = params["current"]
create_story(channel_name = prototype_channel)
if("togglePhoto")
toggle_photo()
return TRUE
if("startCreateChannel")
start_create_channel()
return TRUE
if("setChannelName")
var/pre_channel_name = params["channeltext"]
if(!pre_channel_name)
return TRUE
channel_name = pre_channel_name
if("setChannelDesc")
var/pre_channel_desc = params["channeldesc"]
if(!pre_channel_desc)
return TRUE
channel_desc = pre_channel_desc
if("createChannel")
var/locked = params["lockedmode"]
create_channel(locked)
return TRUE
if("cancelCreation")
creating_channel = FALSE
creating_comment = FALSE
viewing_wanted = FALSE
criminal_name = null
crime_description = null
return TRUE
if("storyCensor")
var/obj/item/card/id/id_card
if(isliving(usr))
var/mob/living/living_user = usr
id_card = living_user.get_idcard(hand_first = TRUE)
if(!(ACCESS_ARMORY in id_card?.GetAccess()))
say("Clearance not found.")
return TRUE
var/questionable_message = params["messageID"]
for(var/datum/feed_message/iterated_feed_message as anything in current_channel.messages)
if(iterated_feed_message.message_ID == questionable_message)
iterated_feed_message.toggle_censor_body()
break
if("authorCensor")
var/obj/item/card/id/id_card
if(isliving(usr))
var/mob/living/living_user = usr
id_card = living_user.get_idcard(hand_first = TRUE)
if(!(ACCESS_ARMORY in id_card?.GetAccess()))
say("Clearance not found.")
return TRUE
var/questionable_message = params["messageID"]
for(var/datum/feed_message/iterated_feed_message in current_channel.messages)
if(iterated_feed_message.message_ID == questionable_message)
iterated_feed_message.toggle_censor_author()
break
if("channelDNotice")
var/obj/item/card/id/id_card
if(isliving(usr))
var/mob/living/living_user = usr
id_card = living_user.get_idcard(hand_first = TRUE)
if(!(ACCESS_ARMORY in id_card?.GetAccess()))
say("Clearance not found.")
return TRUE
var/prototype_channel = (params["channel"])
for(var/datum/feed_channel/potential_channel in GLOB.news_network.network_channels)
if(prototype_channel == potential_channel.channel_ID)
current_channel = potential_channel
break
current_channel.toggle_censor_D_class()
if("startComment")
if(!current_user)
creating_comment = FALSE
return TRUE
creating_comment = TRUE
var/commentable_message = params["messageID"]
if(!commentable_message)
return TRUE
for(var/datum/feed_message/iterated_feed_message as anything in current_channel.messages)
if(iterated_feed_message.message_ID == commentable_message)
current_message = iterated_feed_message
return TRUE
if("setCommentBody")
var/pre_comment_text = params["commenttext"]
if(!pre_comment_text)
return TRUE
comment_text = pre_comment_text
return TRUE
if("createComment")
create_comment()
return TRUE
if("toggleWanted")
alert = FALSE
viewing_wanted = TRUE
update_overlays()
return TRUE
if("setCriminalName")
var/temp_name = tgui_input_text(usr, "Write the Criminal's Name", "Warrent Alert Handler", "John Doe", MAX_NAME_LEN, multiline = FALSE)
if(!temp_name)
return TRUE
criminal_name = temp_name
return TRUE
if("setCrimeData")
var/temp_desc = tgui_input_text(usr, "Write the Criminal's Crimes", "Warrent Alert Handler", "Unknown", MAX_BROADCAST_LEN, multiline = TRUE)
if(!temp_desc)
return TRUE
crime_description = temp_desc
return TRUE
if("submitWantedIssue")
if(!crime_description || !criminal_name)
return TRUE
GLOB.news_network.submit_wanted(criminal_name, crime_description, current_user?.account_holder, current_image, adminMsg = FALSE, newMessage = TRUE)
current_image = null
return TRUE
if("clearWantedIssue")
clear_wanted_issue(user = usr)
for(var/obj/machinery/newscaster/other_newscaster in GLOB.allCasters)
other_newscaster.update_appearance()
return TRUE
if("printNewspaper")
print_paper()
return TRUE
if("createBounty")
create_bounty()
return TRUE
if("apply")
apply_to_bounty()
return TRUE
if("payApplicant")
pay_applicant(payment_target = request_target)
return TRUE
if("clear")
if(current_user)
current_user = null
say("Account Reset.")
return TRUE
if("deleteRequest")
delete_bounty_request()
return TRUE
if("bountyVal")
bounty_value = text2num(params["bountyval"])
if(!bounty_value)
bounty_value = 1
if("bountyText")
var/pre_bounty_text = params["bountytext"]
if(!pre_bounty_text)
return
bounty_text = pre_bounty_text
return TRUE
/obj/machinery/newscaster/attackby(obj/item/I, mob/living/user, params)
if(I.tool_behaviour == TOOL_WRENCH)
to_chat(user, span_notice("You start [anchored ? "un" : ""]securing [name]..."))
I.play_tool_sound(src)
if(I.use_tool(src, user, 60))
playsound(loc, 'sound/items/deconstruct.ogg', 50, TRUE)
if(machine_stat & BROKEN)
to_chat(user, span_warning("The broken remains of [src] fall on the ground."))
new /obj/item/stack/sheet/iron(loc, 5)
new /obj/item/shard(loc)
new /obj/item/shard(loc)
else
to_chat(user, span_notice("You [anchored ? "un" : ""]secure [name]."))
new /obj/item/wallframe/newscaster(loc)
qdel(src)
else if(I.tool_behaviour == TOOL_WELDER && !user.combat_mode)
if(machine_stat & BROKEN)
if(!I.tool_start_check(user, amount=0))
return
user.visible_message(span_notice("[user] is repairing [src]."), \
span_notice("You begin repairing [src]..."), \
span_hear("You hear welding."))
if(I.use_tool(src, user, 40, volume=50))
if(!(machine_stat & BROKEN))
return
to_chat(user, span_notice("You repair [src]."))
atom_integrity = max_integrity
set_machine_stat(machine_stat & ~BROKEN)
update_appearance()
else
to_chat(user, span_notice("[src] does not need repairs."))
else if(istype(I, /obj/item/paper))
if(!user.temporarilyRemoveItemFromInventory(I))
return
else
paper_remaining ++
to_chat(user, span_notice("You insert the [I] into \the [src]! It now holds [paper_remaining] sheets of paper."))
qdel(I)
return
return ..()
/obj/machinery/newscaster/play_attack_sound(damage, damage_type = BRUTE, damage_flag = 0)
switch(damage_type)
if(BRUTE)
if(machine_stat & BROKEN)
playsound(loc, 'sound/effects/hit_on_shattered_glass.ogg', 100, TRUE)
else
playsound(loc, 'sound/effects/glasshit.ogg', 90, TRUE)
if(BURN)
playsound(src.loc, 'sound/items/welder.ogg', 100, TRUE)
/obj/machinery/newscaster/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
new /obj/item/stack/sheet/iron(loc, 2)
new /obj/item/shard(loc)
new /obj/item/shard(loc)
qdel(src)
/obj/machinery/newscaster/atom_break(damage_flag)
. = ..()
if(.)
playsound(loc, 'sound/effects/glassbr3.ogg', 100, TRUE)
/obj/machinery/newscaster/attack_paw(mob/living/user, list/modifiers)
if(!user.combat_mode)
to_chat(user, span_warning("The newscaster controls are far too complicated for your tiny brain!"))
else
take_damage(5, BRUTE, MELEE)
/obj/machinery/newscaster/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
update_appearance()
/**
* Sends photo data to build the newscaster article.
*/
/obj/machinery/newscaster/proc/send_photo_data()
if(!current_image)
return null
return current_image
/**
* This takes a held photograph, and updates the current_image variable with that of the held photograph's image.
* *user: The mob who is being checked for a held photo object.
*/
/obj/machinery/newscaster/proc/attach_photo(mob/user)
var/obj/item/photo/photo = user.is_holding_item_of_type(/obj/item/photo)
if(photo)
current_image = photo.picture
if(issilicon(user))
var/obj/item/camera/siliconcam/targetcam
if(isAI(user))
var/mob/living/silicon/ai/R = user
targetcam = R.aicamera
else if(ispAI(user))
var/mob/living/silicon/pai/R = user
targetcam = R.aicamera
else if(iscyborg(user))
var/mob/living/silicon/robot/R = user
if(R.connected_ai)
targetcam = R.connected_ai.aicamera
else
targetcam = R.aicamera
else
to_chat(user, span_warning("You cannot interface with silicon photo uploading!"))
if(!targetcam.stored.len)
to_chat(usr, span_boldannounce("No images saved."))
return
var/datum/picture/selection = targetcam.selectpicture(user)
if(selection)
current_image = selection
/**
* This takes all current feed stories and messages, and prints them onto a newspaper, after checking that the newscaster has been loaded with paper.
* The newscaster then prints the paper to the floor.
*/
/obj/machinery/newscaster/proc/print_paper()
if(paper_remaining <= 0)
balloon_alert_to_viewers("out of paper!")
return TRUE
SSblackbox.record_feedback("amount", "newspapers_printed", 1)
var/obj/item/newspaper/new_newspaper = new /obj/item/newspaper
for(var/datum/feed_channel/iterated_feed_channel in GLOB.news_network.network_channels)
new_newspaper.news_content += iterated_feed_channel
if(GLOB.news_network.wanted_issue.active)
new_newspaper.wantedAuthor = GLOB.news_network.wanted_issue.scanned_user
new_newspaper.wantedCriminal = GLOB.news_network.wanted_issue.criminal
new_newspaper.wantedBody = GLOB.news_network.wanted_issue.body
if(GLOB.news_network.wanted_issue.img)
new_newspaper.wantedPhoto = GLOB.news_network.wanted_issue.img
new_newspaper.forceMove(drop_location())
new_newspaper.creation_time = GLOB.news_network.last_action
paper_remaining--
/**
* This clears alerts on the newscaster from a new message being published and updates the newscaster's appearance.
*/
/obj/machinery/newscaster/proc/remove_alert()
alert = FALSE
update_overlays()
/**
* When a new feed message is made that will alert all newscasters, this causes the newscasters to sent out a spoken message as well as create a sound.
*/
/obj/machinery/newscaster/proc/news_alert(channel, update_alert = TRUE)
if(channel)
if(update_alert)
say("Breaking news from [channel]!")
playsound(loc, 'sound/machines/twobeep_high.ogg', 75, TRUE)
alert = TRUE
update_appearance()
addtimer(CALLBACK(src, .proc/remove_alert), ALERT_DELAY, TIMER_UNIQUE|TIMER_OVERRIDE)
else if(!channel && update_alert)
say("Attention! Wanted issue distributed!")
playsound(loc, 'sound/machines/warning-buzzer.ogg', 75, TRUE)
/**
* Performs a series of sanity checks before giving the user confirmation to create a new feed_channel using channel_name, and channel_desc.
* *channel_locked: This variable determines if other users than the author can make comments and new feed_stories on this channel.
*/
/obj/machinery/newscaster/proc/create_channel(channel_locked)
if(!channel_name)
return
for(var/datum/feed_channel/iterated_feed_channel as anything in GLOB.news_network.network_channels)
if(iterated_feed_channel.channel_name == channel_name)
tgui_alert(usr, "ERROR: Feed channel with that name already exists on the Network.", list("Okay"))
return TRUE
if(!channel_desc)
return TRUE
if(isnull(channel_locked))
return TRUE
var/choice = tgui_alert(usr, "Please confirm feed channel creation","Network Channel Handler", list("Confirm","Cancel"))
if(choice == "Confirm")
GLOB.news_network.create_feed_channel(channel_name, current_user.account_holder, channel_desc, locked = channel_locked)
SSblackbox.record_feedback("text", "newscaster_channels", 1, "[channel_name]")
creating_channel = FALSE
update_static_data(usr)
/**
* Constructs a comment to attach to the currently selected feed_message of choice, assuming that a user can be found and that a message body has been written.
*/
/obj/machinery/newscaster/proc/create_comment()
if(!comment_text)
creating_comment = FALSE
return TRUE
if(!current_user)
creating_comment = FALSE
return TRUE
var/datum/feed_comment/new_feed_comment = new/datum/feed_comment
new_feed_comment.author = current_user.account_holder
new_feed_comment.body = comment_text
new_feed_comment.time_stamp = station_time_timestamp()
current_message.comments += new_feed_comment
usr.log_message("(as [current_user.account_holder]) commented on message [current_message.return_body(-1)] -- [current_message.body]", LOG_COMMENT)
creating_comment = FALSE
/**
* This proc performs checks before enabling the creating_channel var on the newscaster, such as preventing a user from having multiple channels,
* preventing an un-ID'd user from making a channel, and preventing censored authors from making a channel.
* Otherwise, sets creating_channel to TRUE.
*/
/obj/machinery/newscaster/proc/start_create_channel()
//This first block checks for pre-existing reasons to prevent you from making a new channel, like being censored, or if you have a channel already.
var/list/existing_authors = list()
for(var/datum/feed_channel/iterated_feed_channel as anything in GLOB.news_network.network_channels)
if(iterated_feed_channel.author_censor)
existing_authors += GLOB.news_network.redacted_text
else
existing_authors += iterated_feed_channel.author
if((current_user?.account_holder == "Unknown") || (current_user.account_holder in existing_authors) || isnull(current_user?.account_holder))
creating_channel = FALSE
tgui_alert(usr, "ERROR: User cannot be found or already has an owned feed channel.", list("Okay"))
return TRUE
creating_channel = TRUE
return TRUE
/**
* Creates a new feed story to the global newscaster network.
* Verifies that the message is being written to a real feed_channel, then provides a text input for the feed story to be written into.
* Finally, it submits the message to the network, is logged globally, and clears all message-specific variables from the machine.
*/
/obj/machinery/newscaster/proc/create_story(channel_name)
for(var/datum/feed_channel/potential_channel as anything in GLOB.news_network.network_channels)
if(channel_name == potential_channel.channel_ID)
current_channel = potential_channel
break
var/temp_message = tgui_input_text(usr, "Write your Feed story", "Network Channel Handler", feed_channel_message, multiline = TRUE)
if(length(temp_message) <= 1)
return TRUE
if(temp_message)
feed_channel_message = temp_message
GLOB.news_network.submit_article("<font face=\"[PEN_FONT]\">[parsemarkdown(feed_channel_message, usr)]</font>", current_user?.account_holder, current_channel.channel_name, send_photo_data(), adminMessage = FALSE, allow_comments = TRUE)
SSblackbox.record_feedback("amount", "newscaster_stories", 1)
feed_channel_message = ""
current_image = null
/**
* Selects a currently held photo from the user's hand and makes it the current_image held by the newscaster.
* If a photo is still held in the newscaster, it will otherwise clear it from the machine.
*/
/obj/machinery/newscaster/proc/toggle_photo()
if(current_image)
balloon_alert(usr, "current photo cleared.")
current_image = null
return TRUE
else
attach_photo(usr)
if(current_image)
balloon_alert(usr, "photo selected.")
else
balloon_alert(usr, "no photo identified.")
/obj/machinery/newscaster/proc/clear_wanted_issue(user)
var/obj/item/card/id/id_card
if(isliving(usr))
var/mob/living/living_user = usr
id_card = living_user.get_idcard(hand_first = TRUE)
if(!(ACCESS_ARMORY in id_card?.GetAccess()))
say("Clearance not found.")
return TRUE
GLOB.news_network.wanted_issue.active = FALSE
return TRUE
/**
* This proc removes a station_request from the global list of requests, after checking that the owner of that request is the one who is trying to remove it.
*/
/obj/machinery/newscaster/proc/delete_bounty_request()
if(!active_request || !current_user)
playsound(src, 'sound/machines/buzz-sigh.ogg', 20, TRUE)
return TRUE
if(active_request?.owner != current_user?.account_holder)
playsound(src, 'sound/machines/buzz-sigh.ogg', 20, TRUE)
return TRUE
say("Deleted current request.")
GLOB.request_list.Remove(active_request)
/**
* This creates a new bounty to the global list of bounty requests, alongisde the provided value of the request, and the owner of the request.
* For more info, see datum/station_request.
*/
/obj/machinery/newscaster/proc/create_bounty()
if(!current_user || !bounty_text)
playsound(src, 'sound/machines/buzz-sigh.ogg', 20, TRUE)
return TRUE
for(var/datum/station_request/iterated_station_request as anything in GLOB.request_list)
if(iterated_station_request.req_number == current_user.account_id)
say("Account already has active bounty.")
return TRUE
var/datum/station_request/curr_request = new /datum/station_request(current_user.account_holder, bounty_value,bounty_text,current_user.account_id, current_user)
GLOB.request_list += list(curr_request)
for(var/obj/iterated_bounty_board as anything in GLOB.allbountyboards)
iterated_bounty_board.say("New bounty added!")
playsound(iterated_bounty_board.loc, 'sound/effects/cashregister.ogg', 30, TRUE)
/**
* This sorts through the current list of bounties, and confirms that the intended request found is correct.
* Then, adds the current user to the list of applicants to that bounty.
*/
/obj/machinery/newscaster/proc/apply_to_bounty()
if(!current_user)
say("Please equip a valid ID first.")
return TRUE
if(current_user.account_holder == active_request.owner)
playsound(src, 'sound/machines/buzz-sigh.ogg', 20, TRUE)
return TRUE
for(var/new_apply in active_request?.applicants)
if(current_user.account_holder == active_request?.applicants[new_apply])
playsound(src, 'sound/machines/buzz-sigh.ogg', 20, TRUE)
return TRUE
active_request.applicants += list(current_user)
/**
* This pays out the current request_target the amount held by the active request's assigned value, and then clears the active request from the global list.
*/
/obj/machinery/newscaster/proc/pay_applicant(datum/bank_account/payment_target)
if(!current_user)
return TRUE
if(!current_user.has_money(active_request.value) || (current_user.account_holder != active_request.owner))
playsound(src, 'sound/machines/buzz-sigh.ogg', 30, TRUE)
return TRUE
payment_target.transfer_money(current_user, active_request.value)
say("Paid out [active_request.value] credits.")
GLOB.request_list.Remove(active_request)
qdel(active_request)
/obj/item/wallframe/newscaster
name = "newscaster frame"
desc = "Used to build newscasters, just secure to the wall."
icon_state = "newscaster"
custom_materials = list(/datum/material/iron=14000, /datum/material/glass=8000)
result_path = /obj/machinery/newscaster
pixel_shift = 30
#undef ALERT_DELAY
+179
View File
@@ -0,0 +1,179 @@
/obj/item/newspaper
name = "newspaper"
desc = "An issue of The Griffon, the newspaper circulating aboard Nanotrasen Space Stations."
icon = 'icons/obj/bureaucracy.dmi'
icon_state = "newspaper"
lefthand_file = 'icons/mob/inhands/misc/books_lefthand.dmi'
righthand_file = 'icons/mob/inhands/misc/books_righthand.dmi'
w_class = WEIGHT_CLASS_SMALL
attack_verb_continuous = list("baps")
attack_verb_simple = list("bap")
resistance_flags = FLAMMABLE
var/screen = 0
var/pages = 0
var/curr_page = 0
var/list/datum/feed_channel/news_content = list()
var/scribble=""
var/scribble_page = null
var/wantedAuthor
var/wantedCriminal
var/wantedBody
var/wantedPhoto
var/creation_time
/obj/item/newspaper/suicide_act(mob/user)
user.visible_message(span_suicide("[user] is focusing intently on [src]! It looks like [user.p_theyre()] trying to commit sudoku... until [user.p_their()] eyes light up with realization!"))
user.say(";JOURNALISM IS MY CALLING! EVERYBODY APPRECIATES UNBIASED REPORTI-GLORF", forced="newspaper suicide")
var/mob/living/carbon/human/H = user
var/obj/W = new /obj/item/reagent_containers/food/drinks/bottle/whiskey(H.loc)
playsound(H.loc, 'sound/items/drink.ogg', rand(10,50), TRUE)
W.reagents.trans_to(H, W.reagents.total_volume, transfered_by = user)
user.visible_message(span_suicide("[user] downs the contents of [W.name] in one gulp! Shoulda stuck to sudoku!"))
return(TOXLOSS)
/obj/item/newspaper/attack_self(mob/user)
if(!ishuman(user))
to_chat(user, span_warning("The paper is full of unintelligible symbols!"))
return
var/mob/living/carbon/human/human_user = user
var/dat
pages = 0
switch(screen)
if(0) //Cover
dat+="<DIV ALIGN='center'><B><FONT SIZE=6>The Griffon</FONT></B></div>"
dat+="<DIV ALIGN='center'><FONT SIZE=2>Nanotrasen-standard newspaper, for use on Nanotrasen? Space Facilities</FONT></div><HR>"
if(!length(news_content))
if(wantedAuthor)
dat+="Contents:<BR><ul><B><FONT COLOR='red'>**</FONT>Important Security Announcement<FONT COLOR='red'>**</FONT></B> <FONT SIZE=2>\[page [pages+2]\]</FONT><BR></ul>"
else
dat+="<I>Other than the title, the rest of the newspaper is unprinted...</I>"
else
dat+="Contents:<BR><ul>"
for(var/datum/feed_channel/NP in news_content)
pages++
if(wantedAuthor)
dat+="<B><FONT COLOR='red'>**</FONT>Important Security Announcement<FONT COLOR='red'>**</FONT></B> <FONT SIZE=2>\[page [pages+2]\]</FONT><BR>"
var/temp_page=0
for(var/datum/feed_channel/NP in news_content)
temp_page++
dat+="<B>[NP.channel_name]</B> <FONT SIZE=2>\[page [temp_page+1]\]</FONT><BR>"
dat+="</ul>"
if(scribble_page==curr_page)
dat+="<BR><I>There is a small scribble near the end of this page... It reads: \"[scribble]\"</I>"
dat+= "<HR><DIV STYLE='float:right;'><A href='?src=[REF(src)];next_page=1'>Next Page</A></DIV> <div style='float:left;'><A href='?src=[REF(human_user)];mach_close=newspaper_main'>Done reading</A></DIV>"
if(1) // X channel pages inbetween.
for(var/datum/feed_channel/NP in news_content)
pages++
var/datum/feed_channel/C = news_content[curr_page]
dat += "<FONT SIZE=4><B>[C.channel_name]</B></FONT><FONT SIZE=1> \[created by: <FONT COLOR='maroon'>[C.return_author(notContent(C.author_censor_time))]</FONT>\]</FONT><BR><BR>"
if(notContent(C.D_class_censor_time))
dat+="This channel was deemed dangerous to the general welfare of the station and therefore marked with a <B><FONT COLOR='red'>D-Notice</B></FONT>. Its contents were not transferred to the newspaper at the time of printing."
else
if(!length(C.messages))
dat+="No Feed stories stem from this channel..."
else
var/i = 0
for(var/datum/feed_message/MESSAGE in C.messages)
if(MESSAGE.creation_time > creation_time)
if(i == 0)
dat+="No Feed stories stem from this channel..."
break
if(i == 0)
dat+="<ul>"
i++
dat+="-[MESSAGE.return_body(notContent(MESSAGE.body_censor_time))] <BR>"
if(MESSAGE.img)
user << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
dat+="<img src='tmp_photo[i].png' width = '180'><BR>"
dat+="<FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[MESSAGE.return_author(notContent(MESSAGE.author_censor_time))]</FONT>\]</FONT><BR><BR>"
dat+="</ul>"
if(scribble_page==curr_page)
dat+="<BR><I>There is a small scribble near the end of this page... It reads: \"[scribble]\"</I>"
dat+= "<BR><HR><DIV STYLE='float:left;'><A href='?src=[REF(src)];prev_page=1'>Previous Page</A></DIV> <DIV STYLE='float:right;'><A href='?src=[REF(src)];next_page=1'>Next Page</A></DIV>"
if(2) //Last page
for(var/datum/feed_channel/NP in news_content)
pages++
if(wantedAuthor!=null)
dat+="<DIV STYLE='float:center;'><FONT SIZE=4><B>Wanted Issue:</B></FONT SIZE></DIV><BR><BR>"
dat+="<B>Criminal name</B>: <FONT COLOR='maroon'>[wantedCriminal]</FONT><BR>"
dat+="<B>Description</B>: [wantedBody]<BR>"
dat+="<B>Photo:</B>: "
if(wantedPhoto)
user << browse_rsc(wantedPhoto, "tmp_photow.png")
dat+="<BR><img src='tmp_photow.png' width = '180'>"
else
dat+="None"
else
dat+="<I>Apart from some uninteresting classified ads, there's nothing on this page...</I>"
if(scribble_page==curr_page)
dat+="<BR><I>There is a small scribble near the end of this page... It reads: \"[scribble]\"</I>"
dat+= "<HR><DIV STYLE='float:left;'><A href='?src=[REF(src)];prev_page=1'>Previous Page</A></DIV>"
dat+="<BR><HR><div align='center'>[curr_page+1]</div>"
human_user << browse(dat, "window=newspaper_main;size=300x400")
onclose(human_user, "newspaper_main")
/obj/item/newspaper/proc/notContent(list/L)
if(!L.len)
return FALSE
for(var/i=L.len;i>0;i--)
var/num = abs(L[i])
if(creation_time <= num)
continue
else
if(L[i] > 0)
return TRUE
else
return FALSE
return FALSE
/obj/item/newspaper/Topic(href, href_list)
var/mob/living/U = usr
..()
if((src in U.contents) || (isturf(loc) && in_range(src, U)))
U.set_machine(src)
if(href_list["next_page"])
if(curr_page == pages+1)
return //Don't need that at all, but anyway.
if(curr_page == pages) //We're at the middle, get to the end
screen = 2
else
if(curr_page == 0) //We're at the start, get to the middle
screen=1
curr_page++
playsound(loc, SFX_PAGE_TURN, 50, TRUE)
else if(href_list["prev_page"])
if(curr_page == 0)
return
if(curr_page == 1)
screen = 0
else
if(curr_page == pages+1) //we're at the end, let's go back to the middle.
screen = 1
curr_page--
playsound(loc, SFX_PAGE_TURN, 50, TRUE)
if(ismob(loc))
attack_self(loc)
/obj/item/newspaper/attackby(obj/item/W, mob/living/user, params)
if(burn_paper_product_attackby_check(W, user))
return
if(istype(W, /obj/item/pen))
if(!user.is_literate())
to_chat(user, span_notice("You scribble illegibly on [src]!"))
return
if(scribble_page == curr_page)
to_chat(user, span_warning("There's already a scribble in this page... You wouldn't want to make things too cluttered, would you?"))
else
var/s = tgui_input_text(user, "Write something", "Newspaper")
if (!s)
return
if(!user.canUseTopic(src, BE_CLOSE))
return
scribble_page = curr_page
scribble = s
attack_self(user)
add_fingerprint(user)
else
return ..()
+1 -1
View File
@@ -279,7 +279,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/requests_console, 30)
var/mob/living/L = usr
message = L.treat_message(message)
minor_announce(message, "[department] Announcement:", html_encode = FALSE)
GLOB.news_network.SubmitArticle(message, department, "Station Announcements", null)
GLOB.news_network.submit_article(message, department, "Station Announcements", null)
usr.log_talk(message, LOG_SAY, tag="station announcement from [src]")
message_admins("[ADMIN_LOOKUPFLW(usr)] has made a station announcement from [src] at [AREACOORD(usr)].")
deadchat_broadcast(" made a station announcement from [span_name("[get_area_name(usr, TRUE)]")].", span_name("[usr.real_name]"), usr, message_type=DEADCHAT_ANNOUNCEMENT)
+9 -9
View File
@@ -550,22 +550,22 @@
if (PDA_UI_NEWSCASTER)
menu = "<h4>[PDAIMG(notes)] Newscaster Access</h4>"
menu += "<br> Current Newsfeed: <A href='byond://?src=[REF(src)];choice=Newscaster Switch Channel'>[current_channel ? current_channel : "None"]</a> <br>"
var/datum/newscaster/feed_channel/current
for(var/datum/newscaster/feed_channel/chan in GLOB.news_network.network_channels)
var/datum/feed_channel/current
for(var/datum/feed_channel/chan in GLOB.news_network.network_channels)
if (chan.channel_name == current_channel)
current = chan
if(!current)
menu += "<h5> ERROR : NO CHANNEL FOUND </h5>"
return menu
var/i = 1
for(var/datum/newscaster/feed_message/msg in current.messages)
menu +="-[msg.returnBody(-1)] <BR><FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[msg.returnAuthor(-1)]</FONT>\]</FONT><BR>"
for(var/datum/feed_message/msg in current.messages)
menu +="-[msg.return_body(-1)] <BR><FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[msg.return_author(-1)]</FONT>\]</FONT><BR>"
menu +="<b><font size=1>[msg.comments.len] comment[msg.comments.len > 1 ? "s" : ""]</font></b><br>"
if(msg.img)
user << browse_rsc(msg.img, "tmp_photo[i].png")
menu +="<img src='tmp_photo[i].png' width = '180'><BR>"
i++
for(var/datum/newscaster/feed_comment/comment in msg.comments)
for(var/datum/feed_comment/comment in msg.comments)
menu +="<font size=1><small>[comment.body]</font><br><font size=1><small><small><small>[comment.author] [comment.time_stamp]</small></small></small></small></font><br>"
menu += "<br> <A href='byond://?src=[REF(src)];choice=Newscaster Message'>Post Message</a>"
@@ -659,15 +659,15 @@
if("Newscaster Message")
var/host_pda_owner_name = host_pda.id ? "[host_pda.id.registered_name] ([host_pda.id.assignment])" : "Unknown"
var/message = host_pda.msg_input()
var/datum/newscaster/feed_channel/current
for(var/datum/newscaster/feed_channel/chan in GLOB.news_network.network_channels)
var/datum/feed_channel/current
for(var/datum/feed_channel/chan in GLOB.news_network.network_channels)
if (chan.channel_name == current_channel)
current = chan
if(current.locked && current.author != host_pda_owner_name)
host_pda.ui_mode = PDA_UI_NEWSCASTER_ERROR
host_pda.Topic(null,list("choice"="Refresh"))
return
GLOB.news_network.SubmitArticle(message,host_pda.owner,current_channel)
GLOB.news_network.submit_article(message,host_pda.owner,current_channel)
host_pda.Topic(null,list("choice"=num2text(host_pda.ui_mode)))
return
@@ -760,7 +760,7 @@
menu += "Keep an ID inserted to upload access codes upon summoning."
menu += "<HR><A href='byond://?src=[REF(src)];op=botlist'>[PDAIMG(back)]Return to bot list</A>"
return menu
//If the cartridge adds a special line to the top of the messaging app
+3 -3
View File
@@ -22,9 +22,9 @@ GLOBAL_PROTECT(href_token)
var/spamcooldown = 0
var/admincaster_screen = 0 //TODO: remove all these 5 variables, they are completly unacceptable
var/datum/newscaster/feed_message/admincaster_feed_message = new /datum/newscaster/feed_message
var/datum/newscaster/wanted_message/admincaster_wanted_message = new /datum/newscaster/wanted_message
var/datum/newscaster/feed_channel/admincaster_feed_channel = new /datum/newscaster/feed_channel
var/datum/feed_message/admincaster_feed_message = new /datum/feed_message
var/datum/wanted_message/admincaster_wanted_message = new /datum/wanted_message
var/datum/feed_channel/admincaster_feed_channel = new /datum/feed_channel
var/admin_signature
var/href_token
+26 -26
View File
@@ -1303,7 +1303,7 @@
if(!check_rights(R_ADMIN))
return
var/check = 0
for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
for(var/datum/feed_channel/FC in GLOB.news_network.network_channels)
if(FC.channel_name == src.admincaster_feed_channel.channel_name)
check = 1
break
@@ -1312,7 +1312,7 @@
else
var/choice = tgui_alert(usr,"Please confirm Feed channel creation.","Network Channel Handler",list("Confirm","Cancel"))
if(choice=="Confirm")
GLOB.news_network.CreateFeedChannel(src.admincaster_feed_channel.channel_name, src.admin_signature, src.admincaster_feed_channel.locked, 1)
GLOB.news_network.create_feed_channel(src.admincaster_feed_channel.channel_name, src.admin_signature, "New information from on high." , src.admincaster_feed_channel.locked, 1)
SSblackbox.record_feedback("tally", "newscaster_channels", 1, src.admincaster_feed_channel.channel_name)
log_admin("[key_name(usr)] created command feed channel: [src.admincaster_feed_channel.channel_name]!")
src.admincaster_screen=5
@@ -1322,7 +1322,7 @@
if(!check_rights(R_ADMIN))
return
var/list/available_channels = list()
for(var/datum/newscaster/feed_channel/F in GLOB.news_network.network_channels)
for(var/datum/feed_channel/F in GLOB.news_network.network_channels)
available_channels += F.channel_name
src.admincaster_feed_channel.channel_name = adminscrub(input(usr, "Choose receiving Feed Channel.", "Network Channel Handler") in sort_list(available_channels) )
src.access_news_network()
@@ -1336,15 +1336,15 @@
else if(href_list["ac_submit_new_message"])
if(!check_rights(R_ADMIN))
return
if(src.admincaster_feed_message.returnBody(-1) =="" || src.admincaster_feed_message.returnBody(-1) =="\[REDACTED\]" || src.admincaster_feed_channel.channel_name == "" )
if(src.admincaster_feed_message.return_body(-1) =="" || src.admincaster_feed_message.return_body(-1) =="\[REDACTED\]" || src.admincaster_feed_channel.channel_name == "" )
src.admincaster_screen = 6
else
GLOB.news_network.SubmitArticle(src.admincaster_feed_message.returnBody(-1), src.admin_signature, src.admincaster_feed_channel.channel_name, null, 1)
GLOB.news_network.submit_article(src.admincaster_feed_message.return_body(-1), src.admin_signature, src.admincaster_feed_channel.channel_name, null, 1)
SSblackbox.record_feedback("amount", "newscaster_stories", 1)
src.admincaster_screen=4
for(var/obj/machinery/newscaster/NEWSCASTER in GLOB.allCasters)
NEWSCASTER.newsAlert(src.admincaster_feed_channel.channel_name)
NEWSCASTER.news_alert(src.admincaster_feed_channel.channel_name)
log_admin("[key_name(usr)] submitted a feed story to channel: [src.admincaster_feed_channel.channel_name]!")
src.access_news_network()
@@ -1408,10 +1408,10 @@
var/choice = tgui_alert(usr,"Please confirm Wanted Issue [(input_param==1) ? ("creation.") : ("edit.")]","Network Security Handler",list("Confirm","Cancel"))
if(choice=="Confirm")
if(input_param==1) //If input_param == 1 we're submitting a new wanted issue. At 2 we're just editing an existing one. See the else below
GLOB.news_network.submitWanted(admincaster_wanted_message.criminal, admincaster_wanted_message.body, admin_signature, null, 1, 1)
GLOB.news_network.submit_wanted(admincaster_wanted_message.criminal, admincaster_wanted_message.body, admin_signature, null, 1, 1)
src.admincaster_screen = 15
else
GLOB.news_network.submitWanted(admincaster_wanted_message.criminal, admincaster_wanted_message.body, admin_signature)
GLOB.news_network.submit_wanted(admincaster_wanted_message.criminal, admincaster_wanted_message.body, admin_signature)
src.admincaster_screen = 19
log_admin("[key_name(usr)] issued a Station-wide Wanted Notification for [src.admincaster_wanted_message.criminal]!")
src.access_news_network()
@@ -1421,35 +1421,35 @@
return
var/choice = tgui_alert(usr,"Please confirm Wanted Issue removal.","Network Security Handler",list("Confirm","Cancel"))
if(choice=="Confirm")
GLOB.news_network.deleteWanted()
GLOB.news_network.delete_wanted()
src.admincaster_screen=17
src.access_news_network()
else if(href_list["ac_censor_channel_author"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/feed_channel/FC = locate(href_list["ac_censor_channel_author"])
FC.toggleCensorAuthor()
var/datum/feed_channel/FC = locate(href_list["ac_censor_channel_author"])
FC.toggle_censor_author()
src.access_news_network()
else if(href_list["ac_censor_channel_story_author"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/feed_message/MSG = locate(href_list["ac_censor_channel_story_author"])
MSG.toggleCensorAuthor()
var/datum/feed_message/MSG = locate(href_list["ac_censor_channel_story_author"])
MSG.toggle_censor_author()
src.access_news_network()
else if(href_list["ac_censor_channel_story_body"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/feed_message/MSG = locate(href_list["ac_censor_channel_story_body"])
MSG.toggleCensorBody()
var/datum/feed_message/MSG = locate(href_list["ac_censor_channel_story_body"])
MSG.toggle_censor_body()
src.access_news_network()
else if(href_list["ac_pick_d_notice"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/feed_channel/FC = locate(href_list["ac_pick_d_notice"])
var/datum/feed_channel/FC = locate(href_list["ac_pick_d_notice"])
src.admincaster_feed_channel = FC
src.admincaster_screen=13
src.access_news_network()
@@ -1457,8 +1457,8 @@
else if(href_list["ac_toggle_d_notice"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/feed_channel/FC = locate(href_list["ac_toggle_d_notice"])
FC.toggleCensorDclass()
var/datum/feed_channel/FC = locate(href_list["ac_toggle_d_notice"])
FC.toggle_censor_D_class()
src.access_news_network()
else if(href_list["ac_view"])
@@ -1473,17 +1473,17 @@
src.admincaster_screen = text2num(href_list["ac_setScreen"])
if (src.admincaster_screen == 0)
if(src.admincaster_feed_channel)
src.admincaster_feed_channel = new /datum/newscaster/feed_channel
src.admincaster_feed_channel = new /datum/feed_channel
if(src.admincaster_feed_message)
src.admincaster_feed_message = new /datum/newscaster/feed_message
src.admincaster_feed_message = new /datum/feed_message
if(admincaster_wanted_message)
admincaster_wanted_message = new /datum/newscaster/wanted_message
admincaster_wanted_message = new /datum/wanted_message
src.access_news_network()
else if(href_list["ac_show_channel"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/feed_channel/FC = locate(href_list["ac_show_channel"])
var/datum/feed_channel/FC = locate(href_list["ac_show_channel"])
src.admincaster_feed_channel = FC
src.admincaster_screen = 9
src.access_news_network()
@@ -1491,7 +1491,7 @@
else if(href_list["ac_pick_censor_channel"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/feed_channel/FC = locate(href_list["ac_pick_censor_channel"])
var/datum/feed_channel/FC = locate(href_list["ac_pick_censor_channel"])
src.admincaster_feed_channel = FC
src.admincaster_screen = 12
src.access_news_network()
@@ -1510,8 +1510,8 @@
else if(href_list["ac_del_comment"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/feed_comment/FC = locate(href_list["ac_del_comment"])
var/datum/newscaster/feed_message/FM = locate(href_list["ac_del_comment_msg"])
var/datum/feed_comment/FC = locate(href_list["ac_del_comment"])
var/datum/feed_message/FM = locate(href_list["ac_del_comment_msg"])
FM.comments -= FC
qdel(FC)
src.access_news_network()
@@ -1519,7 +1519,7 @@
else if(href_list["ac_lock_comment"])
if(!check_rights(R_ADMIN))
return
var/datum/newscaster/feed_message/FM = locate(href_list["ac_lock_comment"])
var/datum/feed_message/FM = locate(href_list["ac_lock_comment"])
FM.locked ^= 1
src.access_news_network()
@@ -0,0 +1,374 @@
/datum/admins/proc/access_news_network() //MARKER
set category = "Admin.Events"
set name = "Access Newscaster Network"
set desc = "Allows you to view, add and edit news feeds."
if (!istype(src, /datum/admins))
src = usr.client.holder
if (!istype(src, /datum/admins))
to_chat(usr, "Error: you are not an admin!", confidential = TRUE)
return
var/datum/newspanel/new_newspanel = new
new_newspanel.ui_interact(usr)
/datum/newspanel
///What newscaster channel is currently being viewed by the player?
var/datum/feed_channel/current_channel
///What newscaster feed_message is currently having a comment written for it?
var/datum/feed_message/current_message
///The message that's currently being written for a feed story.
var/feed_channel_message
///The current image that will be submitted with the newscaster story.
var/datum/picture/current_image
///Is the current user creating a new channel at the moment?
var/creating_channel = FALSE
///Is the current user creating a new comment at the moment?
var/creating_comment = FALSE
///Is the current user editing or viewing a new wanted issue at the moment?
var/viewing_wanted = FALSE
///What is the user submitted, criminal name for the new wanted issue?
var/criminal_name
///What is the user submitted, crime description for the new wanted issue?
var/crime_description
///What is the current, in-creation channel's name going to be?
var/channel_name
///What is the current, in-creation channel's description going to be?
var/channel_desc
///What is the current, in-creation comment's body going to be?
var/comment_text
/datum/newspanel/ui_state(mob/user)
return GLOB.admin_state
/datum/newspanel/ui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "Newscaster")
ui.open()
/datum/newspanel/ui_static_data(mob/user)
. = ..()
if (!is_admin(user))
to_chat(usr, "Error: you are not an admin!", confidential = TRUE)
return
/datum/newspanel/ui_data(mob/user)
. = list()
var/list/data = list()
var/list/channel_list = list()
var/list/message_list = list()
data["user"] = list()
data["user"]["name"] = "Centcom Official"
data["user"]["job"] = "Official"
data["user"]["department"] = "Department of News"
data["security_mode"] = TRUE
data["photo_data"] = !isnull(current_image)
data["creating_channel"] = creating_channel
data["creating_comment"] = creating_comment
//Here is all the UI_data sent about the current wanted issue, as well as making a new one in the UI.
data["viewing_wanted"] = viewing_wanted
data["making_wanted_issue"] = !(GLOB.news_network.wanted_issue?.active)
data["criminal_name"] = criminal_name
data["crime_description"] = crime_description
var/list/wanted_info = list()
if(GLOB.news_network.wanted_issue)
if(GLOB.news_network.wanted_issue.img)
user << browse_rsc(GLOB.news_network.wanted_issue.img, "wanted_photo.png")
wanted_info = list(list(
"active" = GLOB.news_network.wanted_issue.active,
"criminal" = GLOB.news_network.wanted_issue.criminal,
"crime" = GLOB.news_network.wanted_issue.body,
"author" = GLOB.news_network.wanted_issue.scanned_user,
"image" = "wanted_photo.png"
))
//Code breaking down the channels that have been made on-station thus far. ha
//Then, breaks down the messages that have been made on those channels.
for(var/datum/feed_channel/channel as anything in GLOB.news_network.network_channels)
channel_list += list(list(
"name" = channel.channel_name,
"author" = channel.author,
"censored" = channel.censored,
"locked" = channel.locked,
"ID" = channel.channel_ID,
))
if(current_channel)
for(var/datum/feed_message/feed_message as anything in current_channel.messages)
var/photo_ID = null
var/list/comment_list
if(feed_message.img)
user << browse_rsc(feed_message.img, "tmp_photo[feed_message.message_ID].png")
photo_ID = "tmp_photo[feed_message.message_ID].png"
for(var/datum/feed_comment/comment_message as anything in feed_message.comments)
comment_list += list(list(
"auth" = comment_message.author,
"body" = comment_message.body,
"time" = comment_message.time_stamp,
))
message_list += list(list(
"auth" = feed_message.author,
"body" = feed_message.body,
"time" = feed_message.time_stamp,
"channel_num" = feed_message.parent_ID,
"censored_message" = feed_message.body_censor,
"censored_author" = feed_message.author_censor,
"ID" = feed_message.message_ID,
"photo" = photo_ID,
"comments" = comment_list
))
data["viewing_channel"] = current_channel?.channel_ID
//Here we display all the information about the current channel.
data["channelName"] = current_channel?.channel_name
data["channelAuthor"] = current_channel?.author
if(!current_channel)
data["channelAuthor"] = "Nanotrasen Inc"
data["channelDesc"] = "Welcome to Newscaster Net. Interface & News networks Operational."
data["channelLocked"] = TRUE
else
data["channelDesc"] = current_channel.channel_desc
data["channelLocked"] = current_channel.locked
data["channelCensored"] = current_channel.censored
//We send all the information about all channels and all messages in existance.
data["channels"] = channel_list
data["messages"] = message_list
data["wanted"] = wanted_info
return data
/datum/newspanel/ui_act(action, params)
. = ..()
if(.)
return
switch(action)
if("setChannel")
var/prototype_channel = params["channel"]
if(isnull(prototype_channel))
return TRUE
for(var/datum/feed_channel/potential_channel as anything in GLOB.news_network.network_channels)
if(prototype_channel == potential_channel.channel_ID)
current_channel = potential_channel
if("createStory")
if(!current_channel)
to_chat(usr, "select a channel first!")
return TRUE
var/prototype_channel = params["current"]
create_story(channel_name = prototype_channel)
if("togglePhoto")
toggle_photo()
return TRUE
if("startCreateChannel")
start_creating_channel()
return TRUE
if("setChannelName")
var/pre_channel_name = params["channeltext"]
if(!pre_channel_name)
return TRUE
channel_name = pre_channel_name
if("setChannelDesc")
var/pre_channel_desc = params["channeldesc"]
if(!pre_channel_desc)
return TRUE
channel_desc = pre_channel_desc
if("createChannel")
var/locked = params["lockedmode"]
create_channel(locked)
return TRUE
if("cancelCreation")
creating_channel = FALSE
creating_comment = FALSE
viewing_wanted = FALSE
return TRUE
if("storyCensor")
var/questionable_message = params["messageID"]
for(var/datum/feed_message/iterated_feed_message as anything in current_channel.messages)
if(iterated_feed_message.message_ID == questionable_message)
iterated_feed_message.toggle_censor_body()
break
if("author_censor")
var/questionable_message = params["messageID"]
for(var/datum/feed_message/iterated_feed_message in current_channel.messages)
if(iterated_feed_message.message_ID == questionable_message)
iterated_feed_message.toggle_censor_author()
break
if("channelDNotice")
var/prototype_channel = (params["channel"])
for(var/datum/feed_channel/potential_channel in GLOB.news_network.network_channels)
if(prototype_channel == potential_channel.channel_ID)
current_channel = potential_channel
break
current_channel.toggle_censor_D_class()
if("startComment")
creating_comment = TRUE
var/commentable_message = params["messageID"]
if(!commentable_message)
return TRUE
for(var/datum/feed_message/iterated_feed_message as anything in current_channel.messages)
if(iterated_feed_message.message_ID == commentable_message)
current_message = iterated_feed_message
return TRUE
if("setCommentBody")
var/pre_comment_text = params["commenttext"]
if(!pre_comment_text)
return TRUE
comment_text = pre_comment_text
return TRUE
if("createComment")
create_comment()
return TRUE
if("toggleWanted")
viewing_wanted = TRUE
return TRUE
if("setCriminalName")
var/temp_name = tgui_input_text(usr, "Write the Criminal's Name", "Warrent Alert Handler", "John Doe", MAX_NAME_LEN, multiline = FALSE)
if(!temp_name)
return TRUE
criminal_name = temp_name
return TRUE
if("setCrimeData")
var/temp_desc = tgui_input_text(usr, "Write the Criminal's Crimes", "Warrent Alert Handler", "Unknown", MAX_BROADCAST_LEN, multiline = TRUE)
if(!temp_desc)
return TRUE
crime_description = temp_desc
return TRUE
if("submitWantedIssue")
if(!crime_description || !criminal_name)
return TRUE
GLOB.news_network.submit_wanted(criminal_name, crime_description, "Centcom Official", current_image, adminMsg = TRUE, newMessage = TRUE)
current_image = null
return TRUE
if("clearWantedIssue")
clear_wanted_issue(user = usr)
return TRUE
return TRUE
/**
* Sends photo data to build the newscaster article.
*/
/datum/newspanel/proc/send_photo_data()
if(!current_image)
return null
return current_image
/**
* This takes a held photograph, and updates the current_image variable with that of the held photograph's image.
* *user: The mob who is being checked for a held photo object.
*/
/datum/newspanel/proc/attach_photo(mob/user)
to_chat(user, "I didn't add this!")
return
/**
* Performs a series of sanity checks before giving the user confirmation to create a new feed_channel using channel_name, and channel_desc.
* *channel_locked: This variable determines if other users than the author can make comments and new feed_stories on this channel.
*/
/datum/newspanel/proc/create_channel(channel_locked)
if(!channel_name)
return
for(var/datum/feed_channel/iterated_feed_channel as anything in GLOB.news_network.network_channels)
if(iterated_feed_channel.channel_name == channel_name)
tgui_alert(usr, "ERROR: Feed channel with that name already exists on the Network.", list("Okay"))
return TRUE
if(!channel_desc)
return TRUE
if(isnull(channel_locked))
return TRUE
var/choice = tgui_alert(usr, "Please confirm feed channel creation","Network Channel Handler", list("Confirm","Cancel"))
if(choice == "Confirm")
GLOB.news_network.create_feed_channel(channel_name, "Centcom Offical", channel_desc, locked = channel_locked)
SSblackbox.record_feedback("text", "newscaster_channels", 1, "[channel_name]")
creating_channel = FALSE
/**
* Constructs a comment to attach to the currently selected feed_message of choice, assuming that a user can be found and that a message body has been written.
*/
/datum/newspanel/proc/create_comment()
if(!comment_text)
creating_comment = FALSE
return TRUE
var/datum/feed_comment/new_feed_comment = new /datum/feed_comment
new_feed_comment.author = "Centcom Offical"
new_feed_comment.body = comment_text
new_feed_comment.time_stamp = station_time_timestamp()
current_message.comments += new_feed_comment
usr.log_message("(as an admin) commented on message [current_message.return_body(-1)] -- [current_message.body]", LOG_COMMENT)
creating_comment = FALSE
/**
* This proc performs checks before enabling the creating_channel var on the newscaster, such as preventing a user from having multiple channels,
* preventing an un-ID'd user from making a channel, and preventing censored authors from making a channel.
* Otherwise, sets creating_channel to TRUE.
*/
/datum/newspanel/proc/start_creating_channel()
//This first block checks for pre-existing reasons to prevent you from making a new channel, like being censored, or if you have a channel already.
var/list/existing_authors = list()
for(var/datum/feed_channel/iterated_feed_channel as anything in GLOB.news_network.network_channels)
if(iterated_feed_channel.author_censor)
existing_authors += GLOB.news_network.redacted_text
else
existing_authors += iterated_feed_channel.author
creating_channel = TRUE
/**
* Creates a new feed story to the global newscaster network.
* Verifies that the message is being written to a real feed_channel, then provides a text input for the feed story to be written into.
* Finally, it submits the message to the network, is logged globally, and clears all message-specific variables from the machine.
*/
/datum/newspanel/proc/create_story(channel_name)
for(var/datum/feed_channel/potential_channel as anything in GLOB.news_network.network_channels)
if(channel_name == potential_channel.channel_ID)
current_channel = potential_channel
break
var/temp_message = tgui_input_text(usr, "Write your Feed story", "Network Channel Handler", feed_channel_message, multiline = TRUE)
if(length(temp_message) <= 1)
return TRUE
if(temp_message)
feed_channel_message = temp_message
GLOB.news_network.submit_article("<font face=\"[PEN_FONT]\">[parsemarkdown(feed_channel_message, usr)]</font>", "Centcom Official", current_channel.channel_name, send_photo_data(), adminMessage = TRUE, allow_comments = TRUE)
SSblackbox.record_feedback("amount", "newscaster_stories", 1)
feed_channel_message = ""
current_image = null
/**
* Selects a currently held photo from the user's hand and makes it the current_image held by the newscaster.
* If a photo is still held in the newscaster, it will otherwise clear it from the machine.
*/
/datum/newspanel/proc/toggle_photo()
if(current_image)
current_image = null
return TRUE
else
attach_photo(usr)
return TRUE
/datum/newspanel/proc/clear_wanted_issue(user)
GLOB.news_network.wanted_issue.active = FALSE
return
-207
View File
@@ -260,213 +260,6 @@
message_admins("[ADMIN_LOOKUPFLW(usr)] [N.timing ? "activated" : "deactivated"] a nuke at [ADMIN_VERBOSEJMP(N)].")
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Nuke", "[N.timing]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/datum/admins/proc/access_news_network() //MARKER
set category = "Admin.Events"
set name = "Access Newscaster Network"
set desc = "Allows you to view, add and edit news feeds."
if (!istype(src, /datum/admins))
src = usr.client.holder
if (!istype(src, /datum/admins))
to_chat(usr, "Error: you are not an admin!", confidential = TRUE)
return
var/dat
dat = text("<HEAD><TITLE>Admin Newscaster</TITLE></HEAD><H3>Admin Newscaster Unit</H3>")
switch(admincaster_screen)
if(0)
dat += "Welcome to the admin newscaster.<BR> Here you can add, edit and censor every newspiece on the network."
dat += "<BR>Feed channels and stories entered through here will be uneditable and handled as official news by the rest of the units."
dat += "<BR>Note that this panel allows full freedom over the news network, there are no constrictions except the few basic ones. Don't break things!</FONT>"
if(GLOB.news_network.wanted_issue.active)
dat+= "<HR><A href='?src=[REF(src)];[HrefToken()];ac_view_wanted=1'>Read Wanted Issue</A>"
dat+= "<HR><BR><A href='?src=[REF(src)];[HrefToken()];ac_create_channel=1'>Create Feed Channel</A>"
dat+= "<BR><A href='?src=[REF(src)];[HrefToken()];ac_view=1'>View Feed Channels</A>"
dat+= "<BR><A href='?src=[REF(src)];[HrefToken()];ac_create_feed_story=1'>Submit new Feed story</A>"
dat+= "<BR><BR><A href='?src=[REF(usr)];[HrefToken()];mach_close=newscaster_main'>Exit</A>"
var/wanted_already = 0
if(GLOB.news_network.wanted_issue.active)
wanted_already = 1
dat+="<HR><B>Feed Security functions:</B><BR>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_menu_wanted=1'>[(wanted_already) ? ("Manage") : ("Publish")] \"Wanted\" Issue</A>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_menu_censor_story=1'>Censor Feed Stories</A>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_menu_censor_channel=1'>Mark Feed Channel with Nanotrasen D-Notice (disables and locks the channel).</A>"
dat+="<BR><HR><A href='?src=[REF(src)];[HrefToken()];ac_set_signature=1'>The newscaster recognises you as:<BR> <FONT COLOR='green'>[src.admin_signature]</FONT></A>"
if(1)
dat+= "Station Feed Channels<HR>"
if( !length(GLOB.news_network.network_channels) )
dat+="<I>No active channels found...</I>"
else
for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
if(CHANNEL.is_admin_channel)
dat+="<B><FONT style='BACKGROUND-COLOR: LightGreen'><A href='?src=[REF(src)];ac_show_channel=[REF(CHANNEL)]'>[CHANNEL.channel_name]</A></FONT></B><BR>"
else
dat+="<B><A href='?src=[REF(src)];[HrefToken()];ac_show_channel=[REF(CHANNEL)]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ""]<BR></B>"
dat+="<BR><HR><A href='?src=[REF(src)];[HrefToken()];ac_refresh=1'>Refresh</A>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[0]'>Back</A>"
if(2)
dat+="Creating new Feed Channel..."
dat+="<HR><B><A href='?src=[REF(src)];[HrefToken()];ac_set_channel_name=1'>Channel Name</A>:</B> [src.admincaster_feed_channel.channel_name]<BR>"
dat+="<B><A href='?src=[REF(src)];[HrefToken()];ac_set_signature=1'>Channel Author</A>:</B> <FONT COLOR='green'>[src.admin_signature]</FONT><BR>"
dat+="<B><A href='?src=[REF(src)];[HrefToken()];ac_set_channel_lock=1'>Will Accept Public Feeds</A>:</B> [(src.admincaster_feed_channel.locked) ? ("NO") : ("YES")]<BR><BR>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_submit_new_channel=1'>Submit</A><BR><BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[0]'>Cancel</A><BR>"
if(3)
dat+="Creating new Feed Message..."
dat+="<HR><B><A href='?src=[REF(src)];[HrefToken()];ac_set_channel_receiving=1'>Receiving Channel</A>:</B> [src.admincaster_feed_channel.channel_name]<BR>" //MARK
dat+="<B>Message Author:</B> <FONT COLOR='green'>[src.admin_signature]</FONT><BR>"
dat+="<B><A href='?src=[REF(src)];[HrefToken()];ac_set_new_message=1'>Message Body</A>:</B> [src.admincaster_feed_message.returnBody(-1)] <BR>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_submit_new_message=1'>Submit</A><BR><BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[0]'>Cancel</A><BR>"
if(4)
dat+="Feed story successfully submitted to [src.admincaster_feed_channel.channel_name].<BR><BR>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[0]'>Return</A><BR>"
if(5)
dat+="Feed Channel [src.admincaster_feed_channel.channel_name] created successfully.<BR><BR>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[0]'>Return</A><BR>"
if(6)
dat+="<B><FONT COLOR='maroon'>ERROR: Could not submit Feed story to Network.</B></FONT><HR><BR>"
if(src.admincaster_feed_channel.channel_name=="")
dat+="<FONT COLOR='maroon'>•Invalid receiving channel name.</FONT><BR>"
if(src.admincaster_feed_message.returnBody(-1) == "" || src.admincaster_feed_message.returnBody(-1) == "\[REDACTED\]")
dat+="<FONT COLOR='maroon'>•Invalid message body.</FONT><BR>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[3]'>Return</A><BR>"
if(7)
dat+="<B><FONT COLOR='maroon'>ERROR: Could not submit Feed Channel to Network.</B></FONT><HR><BR>"
if(src.admincaster_feed_channel.channel_name =="" || src.admincaster_feed_channel.channel_name == "\[REDACTED\]")
dat+="<FONT COLOR='maroon'>•Invalid channel name.</FONT><BR>"
var/check = 0
for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
if(FC.channel_name == src.admincaster_feed_channel.channel_name)
check = 1
break
if(check)
dat+="<FONT COLOR='maroon'>•Channel name already in use.</FONT><BR>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[2]'>Return</A><BR>"
if(9)
dat+="<B>[admincaster_feed_channel.channel_name]: </B><FONT SIZE=1>\[created by: <FONT COLOR='maroon'>[admincaster_feed_channel.returnAuthor(-1)]</FONT>\]</FONT><HR>"
if(src.admincaster_feed_channel.censored)
dat+="<FONT COLOR='red'><B>ATTENTION: </B></FONT>This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.<BR>"
dat+="No further feed story additions are allowed while the D-Notice is in effect.</FONT><BR><BR>"
else
if( !length(src.admincaster_feed_channel.messages) )
dat+="<I>No feed messages found in channel...</I><BR>"
else
var/i = 0
for(var/datum/newscaster/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
i++
dat+="-[MESSAGE.returnBody(-1)] <BR>"
if(MESSAGE.img)
usr << browse_rsc(MESSAGE.img, "tmp_photo[i].png")
dat+="<img src='tmp_photo[i].png' width = '180'><BR><BR>"
dat+="<FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[MESSAGE.returnAuthor(-1)]</FONT>\]</FONT><BR>"
dat+="[MESSAGE.comments.len] comment[MESSAGE.comments.len > 1 ? "s" : ""]:<br>"
for(var/datum/newscaster/feed_comment/comment in MESSAGE.comments)
dat+="[comment.body]<br><font size=1>[comment.author] [comment.time_stamp]</font><br>"
dat+="<br>"
dat+="<BR><HR><A href='?src=[REF(src)];[HrefToken()];ac_refresh=1'>Refresh</A>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[1]'>Back</A>"
if(10)
dat+="<B>Nanotrasen Feed Censorship Tool</B><BR>"
dat+="<FONT SIZE=1>NOTE: Due to the nature of news Feeds, total deletion of a Feed Story is not possible.<BR>"
dat+="Keep in mind that users attempting to view a censored feed will instead see the \[REDACTED\] tag above it.</FONT>"
dat+="<HR>Select Feed channel to get Stories from:<BR>"
if(!length(GLOB.news_network.network_channels))
dat+="<I>No feed channels found active...</I><BR>"
else
for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
dat+="<A href='?src=[REF(src)];[HrefToken()];ac_pick_censor_channel=[REF(CHANNEL)]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ""]<BR>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[0]'>Cancel</A>"
if(11)
dat+="<B>Nanotrasen D-Notice Handler</B><HR>"
dat+="<FONT SIZE=1>A D-Notice is to be bestowed upon the channel if the handling Authority deems it as harmful for the station's"
dat+="morale, integrity or disciplinary behaviour. A D-Notice will render a channel unable to be updated by anyone, without deleting any feed"
dat+="stories it might contain at the time. You can lift a D-Notice if you have the required access at any time.</FONT><HR>"
if(!length(GLOB.news_network.network_channels))
dat+="<I>No feed channels found active...</I><BR>"
else
for(var/datum/newscaster/feed_channel/CHANNEL in GLOB.news_network.network_channels)
dat+="<A href='?src=[REF(src)];[HrefToken()];ac_pick_d_notice=[REF(CHANNEL)]'>[CHANNEL.channel_name]</A> [(CHANNEL.censored) ? ("<FONT COLOR='red'>***</FONT>") : ""]<BR>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[0]'>Back</A>"
if(12)
dat+="<B>[src.admincaster_feed_channel.channel_name]: </B><FONT SIZE=1>\[ created by: <FONT COLOR='maroon'>[src.admincaster_feed_channel.returnAuthor(-1)]</FONT> \]</FONT><BR>"
dat+="<FONT SIZE=2><A href='?src=[REF(src)];[HrefToken()];ac_censor_channel_author=[REF(src.admincaster_feed_channel)]'>[(src.admincaster_feed_channel.authorCensor) ? ("Undo Author censorship") : ("Censor channel Author")]</A></FONT><HR>"
if( !length(src.admincaster_feed_channel.messages) )
dat+="<I>No feed messages found in channel...</I><BR>"
else
for(var/datum/newscaster/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
dat+="-[MESSAGE.returnBody(-1)] <BR><FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[MESSAGE.returnAuthor(-1)]</FONT>\]</FONT><BR>"
dat+="<FONT SIZE=2><A href='?src=[REF(src)];[HrefToken()];ac_censor_channel_story_body=[REF(MESSAGE)]'>[(MESSAGE.bodyCensor) ? ("Undo story censorship") : ("Censor story")]</A> - <A href='?src=[REF(src)];[HrefToken()];ac_censor_channel_story_author=[REF(MESSAGE)]'>[(MESSAGE.authorCensor) ? ("Undo Author Censorship") : ("Censor message Author")]</A></FONT><BR>"
dat+="[MESSAGE.comments.len] comment[MESSAGE.comments.len > 1 ? "s" : ""]: <a href='?src=[REF(src)];[HrefToken()];ac_lock_comment=[REF(MESSAGE)]'>[MESSAGE.locked ? "Unlock" : "Lock"]</a><br>"
for(var/datum/newscaster/feed_comment/comment in MESSAGE.comments)
dat+="[comment.body] <a href='?src=[REF(src)];[HrefToken()];ac_del_comment=[REF(comment)];ac_del_comment_msg=[REF(MESSAGE)]'>X</a><br><font size=1>[comment.author] [comment.time_stamp]</font><br>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[10]'>Back</A>"
if(13)
dat+="<B>[src.admincaster_feed_channel.channel_name]: </B><FONT SIZE=1>\[ created by: <FONT COLOR='maroon'>[src.admincaster_feed_channel.returnAuthor(-1)]</FONT> \]</FONT><BR>"
dat+="Channel messages listed below. If you deem them dangerous to the station, you can <A href='?src=[REF(src)];[HrefToken()];ac_toggle_d_notice=[REF(src.admincaster_feed_channel)]'>Bestow a D-Notice upon the channel</A>.<HR>"
if(src.admincaster_feed_channel.censored)
dat+="<FONT COLOR='red'><B>ATTENTION: </B></FONT>This channel has been deemed as threatening to the welfare of the station, and marked with a Nanotrasen D-Notice.<BR>"
dat+="No further feed story additions are allowed while the D-Notice is in effect.</FONT><BR><BR>"
else
if( !length(src.admincaster_feed_channel.messages) )
dat+="<I>No feed messages found in channel...</I><BR>"
else
for(var/datum/newscaster/feed_message/MESSAGE in src.admincaster_feed_channel.messages)
dat+="-[MESSAGE.returnBody(-1)] <BR><FONT SIZE=1>\[Story by <FONT COLOR='maroon'>[MESSAGE.returnAuthor(-1)]</FONT>\]</FONT><BR>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[11]'>Back</A>"
if(14)
dat+="<B>Wanted Issue Handler:</B>"
var/wanted_already = 0
var/end_param = 1
if(GLOB.news_network.wanted_issue.active)
wanted_already = 1
end_param = 2
if(wanted_already)
dat+="<FONT SIZE=2><BR><I>A wanted issue is already in Feed Circulation. You can edit or cancel it below.</FONT></I>"
dat+="<HR>"
dat+="<A href='?src=[REF(src)];[HrefToken()];ac_set_wanted_name=1'>Criminal Name</A>: [src.admincaster_wanted_message.criminal] <BR>"
dat+="<A href='?src=[REF(src)];[HrefToken()];ac_set_wanted_desc=1'>Description</A>: [src.admincaster_wanted_message.body] <BR>"
if(wanted_already)
dat+="<B>Wanted Issue created by:</B><FONT COLOR='green'>[GLOB.news_network.wanted_issue.scannedUser]</FONT><BR>"
else
dat+="<B>Wanted Issue will be created under prosecutor:</B><FONT COLOR='green'>[src.admin_signature]</FONT><BR>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_submit_wanted=[end_param]'>[(wanted_already) ? ("Edit Issue") : ("Submit")]</A>"
if(wanted_already)
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_cancel_wanted=1'>Take down Issue</A>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[0]'>Cancel</A>"
if(15)
dat+="<FONT COLOR='green'>Wanted issue for [src.admincaster_wanted_message.criminal] is now in Network Circulation.</FONT><BR><BR>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[0]'>Return</A><BR>"
if(16)
dat+="<B><FONT COLOR='maroon'>ERROR: Wanted Issue rejected by Network.</B></FONT><HR><BR>"
if(src.admincaster_wanted_message.criminal =="" || src.admincaster_wanted_message.criminal == "\[REDACTED\]")
dat+="<FONT COLOR='maroon'>•Invalid name for person wanted.</FONT><BR>"
if(src.admincaster_wanted_message.body == "" || src.admincaster_wanted_message.body == "\[REDACTED\]")
dat+="<FONT COLOR='maroon'>•Invalid description.</FONT><BR>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[0]'>Return</A><BR>"
if(17)
dat+="<B>Wanted Issue successfully deleted from Circulation</B><BR>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[0]'>Return</A><BR>"
if(18)
dat+="<B><FONT COLOR ='maroon'>-- STATIONWIDE WANTED ISSUE --</B></FONT><BR><FONT SIZE=2>\[Submitted by: <FONT COLOR='green'>[GLOB.news_network.wanted_issue.scannedUser]</FONT>\]</FONT><HR>"
dat+="<B>Criminal</B>: [GLOB.news_network.wanted_issue.criminal]<BR>"
dat+="<B>Description</B>: [GLOB.news_network.wanted_issue.body]<BR>"
dat+="<B>Photo:</B>: "
if(GLOB.news_network.wanted_issue.img)
usr << browse_rsc(GLOB.news_network.wanted_issue.img, "tmp_photow.png")
dat+="<BR><img src='tmp_photow.png' width = '180'>"
else
dat+="None"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[0]'>Back</A><BR>"
if(19)
dat+="<FONT COLOR='green'>Wanted issue for [src.admincaster_wanted_message.criminal] successfully edited.</FONT><BR><BR>"
dat+="<BR><A href='?src=[REF(src)];[HrefToken()];ac_setScreen=[0]'>Return</A><BR>"
else
dat+="I'm sorry to break your immersion. This shit's bugged. Report this bug to Agouri, polyxenitopalidou@gmail.com"
usr << browse(dat, "window=admincaster_main;size=400x600")
onclose(usr, "admincaster_main")
/client/proc/admin_change_sec_level()
set category = "Admin.Events"
set name = "Set Security Level"
+3 -3
View File
@@ -441,13 +441,13 @@
if(!GLOB.news_network)
tgui_alert(usr,"No news network found on station. Aborting.")
var/channelexists = 0
for(var/datum/newscaster/feed_channel/FC in GLOB.news_network.network_channels)
for(var/datum/feed_channel/FC in GLOB.news_network.network_channels)
if(FC.channel_name == "Nanotrasen Book Club")
channelexists = 1
break
if(!channelexists)
GLOB.news_network.CreateFeedChannel("Nanotrasen Book Club", "Library", null)
GLOB.news_network.SubmitArticle(scanner.cache.dat, "[scanner.cache.name]", "Nanotrasen Book Club", null)
GLOB.news_network.create_feed_channel("Nanotrasen Book Club", "Library", "The official station book club!" , null)
GLOB.news_network.submit_article(scanner.cache.dat, "[scanner.cache.name]", "Nanotrasen Book Club", null)
tgui_alert(usr,"Upload complete. Your uploaded title is now available on station newscasters.")
if(href_list["orderbyid"])
if(printer_cooldown > world.time)
@@ -6,7 +6,7 @@
extended_desc = "A multi-platform network for placing requests across the station, with payment across the network being possible.."
requires_ntnet = TRUE
size = 10
tgui_id = "NtosRequestKiosk"
tgui_id = "NtosBountyBoard"
///Reference to the currently logged in user.
var/datum/bank_account/current_user
///The station request datum being affected by UI actions.
@@ -23,6 +23,20 @@
var/list/formatted_requests = list()
var/list/formatted_applicants = list()
var/obj/item/computer_hardware/card_slot/card_slot = computer.all_components[MC_CARD]
if(current_user)
data["user"] = list()
data["user"]["name"] = current_user.account_holder
if(current_user.account_job)
data["user"]["job"] = current_user.account_job.title
data["user"]["department"] = current_user.account_job.paycheck_department
else
data["user"]["job"] = "No Job"
data["user"]["department"] = "No Department"
else
data["user"] = list()
data["user"]["name"] = user.name
data["user"]["job"] = "N/A"
data["user"]["department"] = "N/A"
if(!networked)
GLOB.allbountyboards += computer
networked = TRUE
@@ -92,6 +106,7 @@
return
request_target.transfer_money(current_user, active_request.value)
computer.say("Paid out [active_request.value] credits.")
GLOB.request_list.Remove(active_request)
return TRUE
if("clear")
if(current_user)
@@ -781,14 +781,6 @@
build_path = /obj/item/wallframe/status_display
category = list("initial", "Construction")
/datum/design/bounty_board_frame
name = "Bounty Board Frame"
id = "bountyboard_frame"
build_type = AUTOLATHE
materials = list(/datum/material/iron = 14000, /datum/material/glass = 8000)
build_path = /obj/item/wallframe/bounty_board
category = list("initial", "Construction")
/datum/design/syringe
name = "Syringe"
id = "syringe"
Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 15 KiB

+4 -2
View File
@@ -1176,7 +1176,6 @@
#include "code\game\machinery\announcement_system.dm"
#include "code\game\machinery\autolathe.dm"
#include "code\game\machinery\bank_machine.dm"
#include "code\game\machinery\bounty_board.dm"
#include "code\game\machinery\buttons.dm"
#include "code\game\machinery\canister_frame.dm"
#include "code\game\machinery\cell_charger.dm"
@@ -1208,7 +1207,6 @@
#include "code\game\machinery\medical_kiosk.dm"
#include "code\game\machinery\medipen_refiller.dm"
#include "code\game\machinery\navbeacon.dm"
#include "code\game\machinery\newscaster.dm"
#include "code\game\machinery\PDApainter.dm"
#include "code\game\machinery\prisongate.dm"
#include "code\game\machinery\prisonlabor.dm"
@@ -1294,6 +1292,9 @@
#include "code\game\machinery\embedded_controller\airlock_controller.dm"
#include "code\game\machinery\embedded_controller\embedded_controller_base.dm"
#include "code\game\machinery\embedded_controller\simple_vent_controller.dm"
#include "code\game\machinery\newscaster\newscaster_data.dm"
#include "code\game\machinery\newscaster\newscaster_machine.dm"
#include "code\game\machinery\newscaster\newspaper.dm"
#include "code\game\machinery\pipe\construction.dm"
#include "code\game\machinery\pipe\pipe_dispenser.dm"
#include "code\game\machinery\porta_turret\portable_turret.dm"
@@ -1868,6 +1869,7 @@
#include "code\modules\admin\smites\supply_pod.dm"
#include "code\modules\admin\smites\supply_pod_quick.dm"
#include "code\modules\admin\verbs\admin.dm"
#include "code\modules\admin\verbs\admin_newscaster.dm"
#include "code\modules\admin\verbs\adminevents.dm"
#include "code\modules\admin\verbs\adminfun.dm"
#include "code\modules\admin\verbs\admingame.dm"
@@ -1,21 +1,22 @@
import { useBackend } from '../backend';
import { Box, Button, Collapsible, Flex, LabeledList, NumberInput, Section, Stack, TextArea } from '../components';
import { UserDetails } from './Vending';
import { BlockQuote, Box, Button, Collapsible, Flex, NumberInput, Section, Stack, TextArea } from '../components';
import { formatMoney } from '../format';
import { Window } from '../layouts';
export const RequestKiosk = (props, context) => {
export const BountyBoard = (props, context) => {
return (
<Window
width={550}
height={600}>
<Window.Content scrollable>
<RequestKioskContent />
<BountyBoardContent />
</Window.Content>
</Window>
);
};
export const RequestKioskContent = (props, context) => {
export const BountyBoardContent = (props, context) => {
const { act, data } = useBackend(context);
const {
accountName,
@@ -23,27 +24,27 @@ export const RequestKioskContent = (props, context) => {
applicants = [],
bountyValue,
bountyText,
user,
} = data;
const color = 'rgba(13, 13, 213, 0.7)';
const backColor = 'rgba(0, 0, 69, 0.5)';
const backColor = 'rgba(50, 50, 170, 0.5)';
return (
<>
<Section>
<LabeledList>
<LabeledList.Item
label="Current Account"
buttons={(
<Button
icon="power-off"
content="Log out"
onClick={() => act('clear')} />
)}>
{accountName || 'N/A'}
</LabeledList.Item>
</LabeledList>
<Section
title={"User Details"}
buttons={(
<Button
icon="power-off"
content="Reset Account"
onClick={() => act('clear')} />
)}>
<UserDetails />
</Section>
<Flex mb={1}>
<Flex.Item grow={1} basis={0}>
<Flex
mb={1}>
<Flex.Item
grow={1}
basis={0}>
{requests?.map(request => (
<Collapsible
key={request.name}
@@ -64,6 +65,9 @@ export const RequestKioskContent = (props, context) => {
fluid
icon="pen-fancy"
content="Apply"
disabled={
request.owner === user.name
}
onClick={() => act('apply', {
request: request.acc_number,
})} />
@@ -77,9 +81,11 @@ export const RequestKioskContent = (props, context) => {
})} />
</Stack.Item>
</Stack>
<Section align="center">
<BlockQuote
pt={1}
align="center">
<i>&quot;{request.description}&quot;</i>
</Section>
</BlockQuote>
<Section
title="Request Applicants">
{applicants?.map(applicant => (
@@ -89,7 +95,8 @@ export const RequestKioskContent = (props, context) => {
grow={1}
p={0.5}
backgroundColor={backColor}
width="510px"
width="500px"
textAlign="center"
style={{
border: `2px solid ${color}`,
}}>
@@ -99,7 +106,9 @@ export const RequestKioskContent = (props, context) => {
align="end">
<Button
fluid
p={1}
icon="cash-register"
tooltip="Pay out to this applicant."
onClick={() => act('payApplicant', {
applicant: applicant.requestee_id,
request: request.acc_number,
@@ -121,7 +130,7 @@ export const RequestKioskContent = (props, context) => {
<Section>
<TextArea
fluid
height="250px"
height="150px"
width="200px"
backgroundColor="black"
textColor="white"
@@ -139,11 +148,12 @@ export const RequestKioskContent = (props, context) => {
onChange={(e, value) => act('bountyVal', {
bountyval: value,
})} />
<Button
icon="print"
content="Submit bounty"
disabled={user.name === "Unknown"}
onClick={() => act('createBounty')} />
</Box>
<Button
icon="print"
content="Submit bounty"
onClick={() => act('createBounty')} />
</Section>
</Collapsible>
</Flex.Item>
+608
View File
@@ -0,0 +1,608 @@
/**
* @file
* @author Original by ArcaneMusic (https://github.com/ArcaneMusic)
* @author Changes Shadowh4nD/jlsnow301
* @license MIT
*/
import { decodeHtmlEntities } from 'common/string';
import { useBackend, useSharedState, useLocalState } from '../backend';
import { BountyBoardContent } from './BountyBoard';
import { UserDetails } from './Vending';
import { BlockQuote, Box, Button, Divider, LabeledList, Modal, Section, Stack, Tabs, TextArea } from '../components';
import { Window } from '../layouts';
import { marked } from 'marked';
import { sanitizeText } from "../sanitize";
const CENSOR_MESSAGE = "This channel has been deemed as threatening to \
the welfare of the station, and marked with a Nanotrasen D-Notice.";
export const Newscaster = (props, context) => {
const { act, data } = useBackend(context);
const NEWSCASTER_SCREEN = 1;
const BOUNTYBOARD_SCREEN = 2;
const [screenmode, setScreenmode] = useSharedState(context, 'tab_main', NEWSCASTER_SCREEN);
return (
<Window
width={575}
height={560}>
<NewscasterChannelCreation />
<NewscasterCommentCreation />
<NewscasterWantedScreen />
<Window.Content scrollable>
<Stack fill vertical>
<Stack.Item>
<Tabs fluid textAlign="center">
<Tabs.Tab
color="Green"
selected={screenmode === NEWSCASTER_SCREEN}
onClick={() => setScreenmode(NEWSCASTER_SCREEN)}>
Newscaster
</Tabs.Tab>
<Tabs.Tab
Color="Blue"
selected={screenmode === BOUNTYBOARD_SCREEN}
onClick={() => setScreenmode(BOUNTYBOARD_SCREEN)}>
Bounty Board
</Tabs.Tab>
</Tabs>
</Stack.Item>
<Stack.Item grow>
{screenmode === NEWSCASTER_SCREEN && (
<NewscasterContent />
)}
{screenmode === BOUNTYBOARD_SCREEN && (
<BountyBoardContent />
)}
</Stack.Item>
</Stack>
</Window.Content>
</Window>
);
};
/** The modal menu that contains the prompts to making new channels. */
const NewscasterChannelCreation = (props, context) => {
const { act, data } = useBackend(context);
const [lockedmode, setLockedmode] = useLocalState(context, 'lockedmode', 1);
const {
creating_channel,
name,
desc,
} = data;
if (!creating_channel) {
return null;
}
return (
<Modal
textAlign="center"
mr={1.5}>
<Stack vertical>
<>
<Stack.Item>
<Box pb={1}>
Enter channel name here:
<Button
content="X"
color="red"
position="relative"
top="20%"
left="15%"
onClick={() => act('cancelCreation')} />
</Box>
<TextArea
fluid
height="40px"
width="240px"
backgroundColor="black"
textColor="white"
maxLength={42}
onChange={(e, name) => act('setChannelName', {
channeltext: name,
})}>
Channel Name
</TextArea>
</Stack.Item>
<Stack.Item>
<Box pb={1}>
Enter channel description here:
</Box>
<TextArea
fluid
height="150px"
width="240px"
backgroundColor="black"
textColor="white"
maxLength={512}
onChange={(e, desc) => act('setChannelDesc', {
channeldesc: desc,
})}>
Channel Description
</TextArea>
</Stack.Item>
<Stack.Item>
<Section>
Set Channel as Public or Private
<Box pt={1}>
<Button
selected={!lockedmode}
content="Public"
onClick={() => setLockedmode(false)} />
<Button
selected={!!lockedmode}
content="Private"
onClick={() => setLockedmode(true)} />
</Box>
</Section>
</Stack.Item>
<Stack.Item>
<Box>
<Button
content="Submit Channel"
onClick={() => act('createChannel', {
lockedmode: lockedmode,
})} />
</Box>
</Stack.Item>
</>
</Stack>
</Modal>
);
};
/** The modal menu that contains the prompts to making new comments. */
const NewscasterCommentCreation = (props, context) => {
const { act, data } = useBackend(context);
const {
creating_comment,
viewing_message,
} = data;
if (!creating_comment) {
return null;
}
return (
<Modal
textAlign="center"
mr={1.5}>
<Stack vertical>
<Stack.Item>
<Box pb={1}>
Enter comment:
<Button
content="X"
color="red"
position="relative"
top="20%"
left="25%"
onClick={() => act('cancelCreation')} />
</Box>
<TextArea
fluid
height="120px"
width="240px"
backgroundColor="black"
textColor="white"
maxLength={512}
onChange={(e, comment) => act('setCommentBody', {
commenttext: comment,
})}>
Channel Name
</TextArea>
</Stack.Item>
<Stack.Item>
<Box>
<Button
content={"Submit Comment"}
onClick={() => act('createComment', {
messageID: viewing_message,
})} />
</Box>
</Stack.Item>
</Stack>
</Modal>
);
};
const NewscasterWantedScreen = (props, context) => {
const { act, data } = useBackend(context);
const {
viewing_wanted,
photo_data,
security_mode,
wanted = [],
criminal_name,
crime_description,
} = data;
if (!viewing_wanted) {
return null;
}
return (
<Modal
textAlign="center"
mr={1.5}
width={25}>
{wanted.map(activeWanted => (
<>
<Stack vertical>
<Stack.Item>
<Box bold color="red">
{activeWanted.active?"Active Wanted Issue:"
:"Dismissed Wanted Issue:"}
<Button
content="X"
color="red"
position="relative"
top="20%"
left="18%"
onClick={() => act('cancelCreation')} />
</Box>
<Section>
<Box bold>
{activeWanted.criminal}
</Box>
<Box italic>
{activeWanted.crime}
</Box>
</Section>
<Box
as="img"
src={activeWanted.image
? activeWanted.image
: null} />
<Box italic>
Posted by {activeWanted.author ? activeWanted.author : "N/A"}
</Box>
</Stack.Item>
</Stack>
<Divider />
</>
))}
{security_mode
?(
<>
<LabeledList>
<LabeledList.Item
label="Criminal Name">
<Button
content={criminal_name ? criminal_name : " N/A"}
disabled={!security_mode}
icon="pen"
onClick={() => act('setCriminalName')} />
</LabeledList.Item>
<LabeledList.Item
label="Criminal Activity">
<Button
content={crime_description ? crime_description : " N/A"}
nowrap={false}
disabled={!security_mode}
icon="pen"
onClick={() => act('setCrimeData')} />
</LabeledList.Item>
</LabeledList>
<Section>
<Button
icon="camera"
selected={photo_data}
disabled={!security_mode}
content={photo_data ? "Remove photo" : "Attach photo"}
onClick={() => act('togglePhoto')} />
<Button
content={"Set Wanted Issue"}
disabled={!security_mode}
icon="volume-up"
onClick={() => act('submitWantedIssue')} />
<Button
content={"Clear Wanted"}
disabled={!security_mode}
icon="times"
color="red"
onClick={() => act('clearWantedIssue')} />
</Section>
</>
) : (
<Box>
{wanted.active
? "Please contact your local security officer if spotted."
: "No wanted issue posted. Have a secure day."}
</Box>
)}
</Modal>
);
};
const NewscasterContent = (props, context) => {
const { act, data } = useBackend(context);
const {
current_channel = {},
} = data;
return (
<Stack fill vertical>
<Stack.Item grow>
<Stack fill>
<Stack.Item grow>
<NewscasterChannelSelector />
</Stack.Item>
<Stack.Item grow={2}>
<Stack fill vertical>
<Stack.Item>
<UserDetails />
</Stack.Item>
<Stack.Item grow>
<NewscasterChannelBox
channelName={current_channel.name}
channelOwner={current_channel.owner}
channelDesc={current_channel.desc} />
</Stack.Item>
</Stack>
</Stack.Item>
</Stack>
</Stack.Item>
<Stack.Item grow>
<NewscasterChannelMessages />
</Stack.Item>
</Stack>
);
};
/** The Channel Box is the basic channel information where buttons live.*/
const NewscasterChannelBox = (_, context) => {
const { act, data } = useBackend(context);
const {
channelName,
channelDesc,
channelLocked,
channelAuthor,
channelCensored,
viewing_channel,
security_mode,
photo_data,
paper,
user,
} = data;
return (
<Section fill title={channelName}>
<Stack fill vertical>
<Stack.Item grow>
{channelCensored ? (
<Section>
<BlockQuote color="red">
<b>ATTENTION:</b> {CENSOR_MESSAGE}
</BlockQuote>
</Section>)
: (
<Section fill scrollable>
<BlockQuote italic fontSize={1.2} wrap>
{decodeHtmlEntities(channelDesc)}
</BlockQuote>
</Section>
)}
</Stack.Item>
<Stack.Item>
<Box>
<Button
icon="print"
content="Submit Story"
disabled={(channelLocked && (channelAuthor !== user.name))
|| channelCensored}
onClick={() => act('createStory', { current: viewing_channel })}
mt={1} />
<Button
icon="camera"
selected={photo_data}
content="Select Photo"
disabled={(channelLocked && (channelAuthor !== user.name))
|| channelCensored}
onClick={() => act('togglePhoto')} />
{!!security_mode && (
<Button
icon="ban"
content={"D-Notice"}
tooltip="Censor the whole channel and it's \
contents as dangerous to the station. Cannot be undone."
disabled={!security_mode || !viewing_channel}
onClick={() => act('channelDNotice', {
secure: security_mode,
channel: viewing_channel,
})} />
)}
</Box>
<Box>
<Button
icon="newspaper"
content="Print Newspaper"
disabled={paper <= 0}
onClick={() => act('printNewspaper')} />
</Box>
</Stack.Item>
</Stack>
</Section>
);
};
/** Channel select is the left-hand menu where all the channels are listed. */
const NewscasterChannelSelector = (props, context) => {
const { act, data } = useBackend(context);
const {
channels = [],
viewing_channel,
security_mode,
wanted = [],
} = data;
return (
<Section
minHeight="100%"
width={(window.innerWidth - 410) + "px"}>
<Tabs vertical>
{wanted.map(activeWanted => (
<Tabs.Tab
pt={0.75}
pb={0.75}
mr={1}
key={activeWanted.index}
icon={activeWanted.active ? "skull-crossbones" : null}
textColor={activeWanted.active ? "red" : "grey"}
onClick={() => act('toggleWanted')}>
Wanted Issue
</Tabs.Tab>
))}
{channels.map(channel => (
<Tabs.Tab
key={channel.index}
pt={0.75}
pb={0.75}
mr={1}
selected={viewing_channel === channel.ID}
icon={channel.censored ? 'ban' : null}
textColor={channel.censored ? "red" : "white"}
onClick={() => act('setChannel', {
channel: channel.ID,
})}>
{channel.name}
</Tabs.Tab>
))}
<Tabs.Tab
pt={0.75}
pb={0.75}
mr={1}
textColor="white"
color="Green"
onClick={() => act('startCreateChannel')}>
Create Channel [+]
</Tabs.Tab>
</Tabs>
</Section>
);
};
const processedText = value => {
const textHtml = {
__html: sanitizeText(marked(value, {
breaks: true,
smartypants: true,
smartLists: true,
baseUrl: 'thisshouldbreakhttp',
})),
};
return textHtml;
};
/** This is where the channels comments get spangled out (tm) */
const NewscasterChannelMessages = (_, context) => {
const { act, data } = useBackend(context);
const {
messages = [],
viewing_channel,
security_mode,
channelCensored,
channelLocked,
channelAuthor,
user,
} = data;
if (channelCensored) {
return (
<Section color="red">
<b>ATTENTION:</b> Comments cannot be read at this time.<br />
Thank you for your understanding, and have a secure day.
</Section>
);
}
const visibleMessages = messages.filter(message => (
message.ID !== viewing_channel
));
return (
<Section>
{visibleMessages.map(message => {
return (
<Section
key={message.index}
textColor="white"
title={(
<i>
{message.censored_author ? (
<Box textColor="red">
By: [REDACTED]. <b>D-Notice Notice</b> .
</Box>
):(
<>
By: {message.auth} at {message.time}
</>
)}
</i>
)}
buttons={(
<>
{!!security_mode && (
<Button
icon="comment-slash"
tooltip="Censor Story"
disabled={!security_mode}
onClick={() => act('storyCensor', {
messageID: message.ID,
})} />
)}
{!!security_mode && (
<Button
icon="user-slash"
tooltip="Censor Author"
disabled={!security_mode}
onClick={() => act('authorCensor', {
messageID: message.ID,
})} />
)}
<Button
icon="comment"
tooltip="Leave a Comment."
disabled={
message.censored_author
|| message.censored_message
|| user.name === "Unknown"
|| !!channelLocked && (channelAuthor !== user.name)
}
onClick={() => act('startComment', {
messageID: message.ID,
})}
/>
</>
)} >
<BlockQuote>
{message.censored_message ? (
<Section textColor="red">
This message was deemed dangerous to the general welfare
of the station and therefore marked with a <b>D-Notice</b>.
</Section>
):(
<Section
dangerouslySetInnerHTML={processedText(message.body)}
pl={1} />
)}
{message.photo !== null && !message.censored_message &&(
<Box
as="img"
src={message.photo} />
)}
{!!message.comments &&(
<Box>
{message.comments.map(comment => (
<BlockQuote
key={comment.index}>
<Box
italic
textColor="white">
By: {comment.auth} at {comment.time}
</Box>
<Section
dangerouslySetInnerHTML={processedText(comment.body)}
ml={2.5} />
</BlockQuote>
))}
</Box>
)}
</BlockQuote>
<Divider />
</Section>
); }
)}
</Section>
);
};
@@ -1,13 +1,13 @@
import { RequestKioskContent } from './RequestKiosk';
import { BountyBoardContent } from './BountyBoard';
import { NtosWindow } from '../layouts';
export const NtosRequestKiosk = (props, context) => {
export const NtosBountyBoard = (props, context) => {
return (
<NtosWindow
width={550}
height={600}>
<NtosWindow.Content scrollable>
<RequestKioskContent />
<BountyBoardContent />
</NtosWindow.Content>
</NtosWindow>
);
+1 -1
View File
@@ -85,7 +85,7 @@ export const Vending = (_, context) => {
};
/** Displays user details if an ID is present and the user is on the station */
const UserDetails = (_, context) => {
export const UserDetails = (_, context) => {
const { data } = useBackend<VendingData>(context);
const { user } = data;