Spess.TV Season 1 (#26083)

This commit is contained in:
DamianX
2020-04-01 00:15:24 +02:00
committed by GitHub
parent df81fe287d
commit a729001002
58 changed files with 703 additions and 42 deletions

View File

@@ -15,3 +15,4 @@
#define CAMERANET_POWERALARMS "Power Alarms"
#define CAMERANET_SINGULARITY "Singularity"
#define CAMERANET_RD "RD"
#define CAMERANET_SPESSTV "Spess.TV" // Sponsored

View File

@@ -414,6 +414,7 @@
#define PLUMPHJUICE "plumphjuice"
#define PLUMPHWINE "phwine"
#define IRONROT "ironrot"
#define GEOMETER "geometer"
#define TUNGSTEN "tungsten"
#define LITHIUMSODIUMTUNGSTATE "lithiumsodiumtungstate"

View File

@@ -64,6 +64,7 @@
#define CATBEAST "loose catbeast"
#define RAMBLER "soul rambler"
#define PLAGUEMOUSE "plague mouse"
#define STREAMER "streamer"
#define GREET_DEFAULT "default"
#define GREET_ROUNDSTART "roundstart"

View File

@@ -1622,3 +1622,10 @@ var/proccalls = 1
// How many times to retry winset()ing window parameters before giving up
#define WINSET_MAX_ATTEMPTS 10
// E-Sports teams
#define ESPORTS_CULTISTS "Team Geometer"
#define ESPORTS_SECURITY "Team Security"
var/list/weekend_days = list("Friday", "Saturday", "Sunday")
#define IS_WEEKEND (weekend_days.Find(time2text(world.timeofday, "Day")))

View File

@@ -65,7 +65,7 @@
#define ui_internal "EAST-1:[28*PIXEL_MULTIPLIER],CENTER-0.5:[17*PIXEL_MULTIPLIER]"
#define ui_health "EAST-1:[28*PIXEL_MULTIPLIER],CENTER-1.5:[15*PIXEL_MULTIPLIER]"
#define ui_under_health "EAST-1:[28*PIXEL_MULTIPLIER],CENTER-2.5:[13*PIXEL_MULTIPLIER]"
#define ui_more_under_health_and_to_the_left "EAST-2:[14*PIXEL_MULTIPLIER],CENTER-5:[24*PIXEL_MULTIPLIER]"
//borgs
#define ui_borg_health "EAST-1:[28*PIXEL_MULTIPLIER],SOUTH+5:[7*PIXEL_MULTIPLIER]"
#define ui_borg_album "EAST-1:[28*PIXEL_MULTIPLIER],SOUTH+4:[7*PIXEL_MULTIPLIER]"

View File

@@ -26,6 +26,7 @@ var/global/obj/abstract/screen/clicker/catcher = new()
var/list/obj/abstract/screen/hand_hud_objects = list()
var/obj/abstract/screen/action_intent
var/obj/abstract/screen/move_intent
var/obj/abstract/screen/streamer_display // Sponsored
var/obj/abstract/screen/movable/action_button/hide_toggle/hide_actions_toggle
var/action_buttons_hidden = FALSE

View File

@@ -170,6 +170,14 @@
mymob.client.screen += list(vampire_blood_display)
/datum/hud/proc/streamer_hud(ui_style = 'icons/mob/screen1_Midnight.dmi')
streamer_display = getFromPool(/obj/abstract/screen)
streamer_display.name = "Streaming Stats"
streamer_display.icon = null
streamer_display.screen_loc = ui_more_under_health_and_to_the_left
mymob.client.screen += list(streamer_display)
/datum/hud/proc/changeling_hud()
vampire_blood_display = getFromPool(/obj/abstract/screen)

View File

@@ -57,6 +57,8 @@ var/list/arcane_tomes = list()
var i = 1
for(var/subtype in subtypesof(/datum/rune_spell))
var/datum/rune_spell/blood_cult/instance = subtype
if(instance == /datum/rune_spell/blood_cult)
continue
if (initial(instance.Act_restriction) <= veil_thickness)
dat += "<a href='byond://?src=\ref[src];page=[i]'><label> \Roman[i] </label> <li> [initial(instance.name)] </li></a>"
if (i == current_page)
@@ -1220,6 +1222,16 @@ var/list/arcane_tomes = list()
starting_materials = list(MAT_IRON = 3750)
w_type=RECYK_METAL
/obj/item/weapon/storage/cult/sponsored
name = "sponsored coffer"
desc = "A sponsor-sticker-plastered storage chest."
/obj/item/weapon/storage/cult/sponsored/New()
..()
var/obj/item/weapon/reagent_containers/food/drinks/cult/cup = new(src)
cup.reagents.add_reagent(BLOOD, 50)
for(var/i in 1 to 2)
new /obj/item/weapon/reagent_containers/food/drinks/soda_cans/geometer(src)
///////////////////////////////////////CULT GLASS////////////////////////////////////////////////
/obj/item/weapon/reagent_containers/food/drinks/cult
@@ -1262,6 +1274,11 @@ var/list/arcane_tomes = list()
reagents.trans_to(H, gulp_size)
transfer(get_turf(hit_atom), null, splashable_units = -1)
/obj/item/weapon/reagent_containers/food/drinks/cult/gamer
name = "gamer goblet"
desc = "A plastic cup in the shape of a skull. Typically full of Geometer-Fuel."
icon_state = "cult_gamer"
///////////////////////////////////////BLOOD TESSERACT////////////////////////////////////////////////
/obj/item/weapon/blood_tesseract

View File

@@ -1037,6 +1037,10 @@
else
message_admins("Blood Cult: A conversion ritual occured...but we cannot find the cult faction...")//failsafe in case of admin varedit fuckery
cult_risk(activator)//risk of exposing the cult early if too many conversions
var/datum/role/streamer/streamer_role = activator?.mind?.GetRole(STREAMER)
if(streamer_role && streamer_role.team == ESPORTS_CULTISTS)
streamer_role.conversions += IS_WEEKEND ? 2 : 1
streamer_role.update_antag_hud()
switch (success)
if (CONVERSION_ACCEPT)
@@ -2699,6 +2703,33 @@ var/list/bloodcult_exitportals = list()
plane = ABOVE_HUMAN_PLANE
mouse_opacity = 0
//RUNE XXI
/datum/rune_spell/blood_cult/stream
name = "Stream"
desc = "Start or stop streaming on Spess.TV"
desc_talisman = "Start or stop streaming on Spess.TV"
Act_restriction = CULT_PROLOGUE
invocation = "L'k' c'mm'nt 'n' s'bscr'b! P'g ch'mp! Kappah!"
word1 = /datum/runeword/blood_cult/other
word2 = /datum/runeword/blood_cult/see
word3 = /datum/runeword/blood_cult/self
page = "This rune lets you start (or stop) streaming on Spess.TV so that you can let your audience watch and cheer for you while you slay infidels in the name of Nar-sie. #Sponsored"
/datum/rune_spell/blood_cult/stream/cast()
var/datum/role/streamer/streamer = activator.mind.GetRole(STREAMER)
if(!streamer)
streamer = new /datum/role/streamer
streamer.team = ESPORTS_CULTISTS
if(!streamer.AssignToRole(activator.mind, 1))
streamer.Drop()
return
streamer.OnPostSetup()
streamer.Greet(GREET_DEFAULT)
streamer.AnnounceObjectives()
streamer.team = ESPORTS_CULTISTS
if(!streamer.camera)
streamer.set_camera(new /obj/machinery/camera/arena/spesstv(activator))
streamer.toggle_streaming()
qdel(src)
#undef RUNE_STAND

View File

@@ -0,0 +1,37 @@
/datum/objective/reach_followers
var/followers_jectie = 15
explanation_text = "Reach 15 followers."
name = "(streamer) Reach followers"
/datum/objective/reach_followers/PostAppend()
followers_jectie = round(rand(10, 20))
explanation_text = "Reach [followers_jectie] followers."
return TRUE
/datum/objective/reach_followers/IsFulfilled()
if (..())
return TRUE
var/datum/role/streamer/S = owner.GetRole(STREAMER)
if (!S)
message_admins("BUG: [owner.current] was given a streamer objective but is not affiliated with Spess.TV!")
return FALSE
return length(S.followers) >= followers_jectie
/datum/objective/reach_subscribers
var/subscribers_jectie = 7
explanation_text = "Reach 7 subscribers."
name = "(streamer) Reach subscribers"
/datum/objective/reach_subscribers/PostAppend()
subscribers_jectie = round(rand(5, 10))
explanation_text = "Reach [subscribers_jectie] subscribers."
return TRUE
/datum/objective/reach_subscribers/IsFulfilled()
if (..())
return TRUE
var/datum/role/streamer/S = owner.GetRole(STREAMER)
if (!S)
message_admins("BUG: [owner.current] was given a streamer objective but is not affiliated with Spess.TV!")
return FALSE
return length(S.subscribers) >= subscribers_jectie

View File

@@ -0,0 +1,137 @@
/datum/role/streamer
id = STREAMER
name = STREAMER
logo_state = "streamer-logo"
greets = list(GREET_DEFAULT, GREET_CUSTOM)
var/list/followers = list()
var/list/subscribers = list()
var/team
var/conversions = 0
var/hits = 0
var/obj/machinery/camera/arena/spesstv/camera
/datum/role/streamer/Greet(greeting, custom)
if(!greeting)
return
var/icon/logo = icon('icons/logos.dmi', logo_state)
switch(greeting)
if (GREET_CUSTOM)
to_chat(antag.current, "<img src='data:image/png;base64,[icon2base64(logo)]' style='position: relative; top: 10;'/> [custom]")
else
to_chat(antag.current, "<img src='data:image/png;base64,[icon2base64(logo)]' style='position: relative; top: 10;'/> <span class='danger'>You are now online!<br/></span>")
to_chat(antag.current, "Entertain your audience to obtain followers and subscribers!")
antag.current << sound('sound/machines/lawsync.ogg')
/datum/role/streamer/OnPostSetup()
. = ..()
update_streamer_hud()
ForgeObjectives()
/datum/role/streamer/RemoveFromRole(var/datum/mind/M)
if(antag.current.client && antag.current.hud_used)
if(antag.current.hud_used.streamer_display)
antag.current.client.screen -= list(antag.current.hud_used.streamer_display)
..()
/datum/role/streamer/AdminPanelEntry(var/show_logo = FALSE,var/datum/admins/A)
var/icon/logo = icon('icons/logos.dmi', logo_state)
var/mob/M = antag.current
var/text
if (!M) // Body destroyed
text = "[antag.name]/[antag.key] (BODY DESTROYED)"
else
text = {"[show_logo ? "<img src='data:image/png;base64,[icon2base64(logo)]' style='position: relative; top: 10;'/> " : "" ]
[name] <a href='?_src_=holder;adminplayeropts=\ref[M]'>[key_name(M)]</a>[M.client ? "" : " <i> - (logged out)</i>"][M.stat == DEAD ? " <b><font color=red> - (DEAD)</font></b>" : ""]
- <a href='?src=\ref[usr];priv_msg=\ref[M]'>(priv msg)</a>
- <a href='?_src_=holder;traitor=\ref[M]'>(role panel)</a> - <a href='?src=\ref[src]&mind=\ref[antag]&giveblood=1'>Give blood</a>"}
return text
/datum/role/streamer/ForgeObjectives()
AppendObjective(/datum/objective/reach_followers)
AppendObjective(/datum/objective/reach_subscribers)
/datum/role/streamer/GetScoreboard()
switch(team)
if(ESPORTS_CULTISTS)
. += "Conversions: <b>[conversions]</b><br>"
if(ESPORTS_SECURITY)
. += "Hits: <b>[hits]</b><br>"
. += "Followers: <b>[length(followers)]</b><br>"
. += "Subscribers: <b>[length(subscribers)]</b><br>"
. += ..()
/datum/role/streamer/update_antag_hud()
update_streamer_hud()
/datum/role/streamer/proc/update_streamer_hud()
var/mob/M = antag.current
if(!M || M.gcDestroyed || !M.client || !M.hud_used)
return
var/obj/abstract/screen/streamer_display = M.hud_used.streamer_display
if(!streamer_display)
M.hud_used.streamer_hud()
streamer_display = M.hud_used.streamer_display
streamer_display.maptext_width = (WORLD_ICON_SIZE*2)+20
streamer_display.maptext_height = WORLD_ICON_SIZE*2
var/list/text = list("<div align='left' valign='top' style='position:relative; top:0px; left:6px'>")
if(IS_WEEKEND)
text += "Double XP <font color='#33FF33'>enabled</span>!</font><br>"
switch(team)
if(ESPORTS_CULTISTS)
text += "Conversions: <font color='#FF1133'>[conversions]</font>"
if(ESPORTS_SECURITY)
text += "Hits: <font color='#FF1133'>[hits]</font>"
text += "<br>Followers: <font color='#33FF33'>[length(followers)]</font>"
text += "<br>Subscribers:<font color='#FFFF00'>[length(subscribers)]</font></div>"
streamer_display.maptext = jointext(text, null)
/datum/role/streamer/proc/try_add_follower(datum/mind/new_follower)
if(new_follower == antag)
to_chat(new_follower.current, "<span class='warning'>Following yourself is against Spess.TV's End User License Agreement.</span>")
return
if(followers.Find(new_follower))
to_chat(new_follower.current, "<span class='warning'>You are already following [antag.name].</span>")
return
followers += new_follower
update_antag_hud()
new_follower.current.visible_message("<span class='big notice'>[new_follower.current] is now following [antag.name]!</span>")
/datum/role/streamer/proc/try_add_subscription(datum/mind/new_subscriber, obj/machinery/computer/security/telescreen/entertainment/spesstv/tv)
if(new_subscriber == antag)
to_chat(new_subscriber.current, "<span class='warning'>Subscribing to yourself is against Spess.TV's End User License Agreement.</span>")
return
if(subscribers.Find(new_subscriber))
to_chat(new_subscriber.current, "<span class='warning'>You're already subscribed to [antag.name]!</span>")
return
tv.reconnect_database()
if(tv.charge_flow(tv.linked_db, new_subscriber.current.get_id_card(), new_subscriber.current, 250, station_account, "Spess.TV subscription to [antag.name]") == CARD_CAPTURE_SUCCESS)
tv.visible_message("<span class='big notice'>[new_subscriber.current] just subscribed to [name]!</span>")
playsound(tv, pick('sound/effects/noisemaker1.ogg', 'sound/effects/noisemaker2.ogg', 'sound/effects/noisemaker3.ogg'), 100, TRUE)
playsound(antag.current, pick('sound/effects/noisemaker1.ogg', 'sound/effects/noisemaker2.ogg', 'sound/effects/noisemaker3.ogg'), 100, TRUE)
else
playsound(tv, 'sound/machines/alert.ogg', 50, TRUE)
tv.visible_message("[bicon(tv)]<span class='warning'>Something went wrong processing [new_subscriber.current]'s payment.</span>")
return
subscribers += new_subscriber
update_antag_hud()
switch(team)
if(ESPORTS_CULTISTS)
new /obj/item/weapon/storage/cult/sponsored(get_turf(antag.current))
for(var/i in 1 to 3)
new /obj/item/weapon/reagent_containers/food/drinks/soda_cans/geometer(get_turf(new_subscriber.current))
if(ESPORTS_SECURITY)
new /obj/item/weapon/storage/lockbox/security_sponsored(get_turf(antag.current))
for(var/i in 1 to 4)
new /obj/item/weapon/reagent_containers/food/snacks/donitos(get_turf(new_subscriber.current))
/datum/role/streamer/proc/toggle_streaming()
camera.deactivate()
antag.current.visible_message("<span class='big notice'>[antag.current] is now [camera.status ? "streaming!" : "offline."]</span>")
/datum/role/streamer/proc/set_camera(obj/machinery/camera/arena/spesstv/new_camera)
ASSERT(istype(new_camera))
camera = new_camera
camera.streamer = src
camera.name_camera()

View File

@@ -1366,3 +1366,57 @@
/datum/religion/belmont/equip_chaplain(var/mob/living/carbon/human/H)
H.equip_or_collect(new /obj/item/clothing/suit/vamphunter, slot_w_uniform)
H.equip_or_collect(new /obj/item/clothing/head/vamphunter, slot_shoes)
/datum/religion/esports
name = "E-Sports"
deity_name = "E-Sports"
bible_name = "Spess.TV End User License Agreement"
male_adept = "Donitos Pope"
female_adept = "Donitos Priestess"
keys = list("gaming", "esport", "esports", "e-sports", "electronic sports", "donitos", "geometer")
convert_method = "having others hold a bag of Donitos, while you do the same."
bookstyle = "Creeper"
/datum/religion/esports/equip_chaplain(mob/living/carbon/human/H)
var/turf/here = get_turf(H)
new /obj/item/weapon/crowbar/red(here)
var/obj/item/clothing/head/donitos_pope/pope_hat = new(here)
H.equip_to_appropriate_slot(pope_hat, override=TRUE)
var/obj/structure/closet/crate/flatpack/tv_pack1 = new(here)
tv_pack1.insert_machine(new /obj/machinery/computer/security/telescreen/entertainment/spesstv/flatscreen)
var/obj/structure/closet/crate/flatpack/tv_pack2 = new(here)
tv_pack2.insert_machine(new /obj/machinery/computer/security/telescreen/entertainment/spesstv/flatscreen)
var/obj/structure/closet/crate/flatpack/cameras_pack = new(here)
cameras_pack.insert_machine(new /obj/item/weapon/storage/lockbox/team_security_cameras)
var/obj/structure/closet/crate/flatpack/vending_machine_pack = new(here)
vending_machine_pack.insert_machine(new /obj/machinery/vending/team_security)
tv_pack1.add_stack(tv_pack2)
tv_pack1.add_stack(cameras_pack)
tv_pack1.add_stack(vending_machine_pack)
/datum/religion/esports/convertCeremony(mob/living/preacher, mob/living/subject)
var/obj/item/weapon/reagent_containers/food/snacks/donitos/preacher_donitos = preacher.get_held_item_by_index(preacher.find_held_item_by_type(/obj/item/weapon/reagent_containers/food/snacks/donitos))
if(!preacher_donitos)
to_chat(preacher, "<span class='warning'>You need to hold a bag of Donitos to begin the conversion.</span>")
return FALSE
var/obj/item/weapon/reagent_containers/food/snacks/donitos/subject_donitos = subject.get_held_item_by_index(subject.find_held_item_by_type(/obj/item/weapon/reagent_containers/food/snacks/donitos))
if(!subject_donitos)
to_chat(preacher, "<span class='warning'>The subject needs to hold a bag of Donitos to begin the conversion.</span>")
return FALSE
subject.visible_message("<span class='notice'>\The [preacher] attemps to convert \the [subject] to [name].</span>")
if(!convertCheck(subject))
subject.visible_message("<span class='warning'>\The [subject] refuses conversion.</span>")
return FALSE
preacher_donitos.attack_self(preacher)
subject_donitos.attack_self(subject)
subject.visible_message("<span class='notice'>\The [subject] signs Spess.TV's End User License Agreement and becomes a registered user! Let's go watch some [deity_name]!</span>")
convert(subject, preacher)
return TRUE

View File

@@ -2431,3 +2431,11 @@ var/list/all_supply_groups = list("Supplies","Clothing","Security","Hospitality"
containertype = /obj/structure/stackopacks
containername = "Al's Fun And Games stack of packs"
group = "Vending Machine Packs"
/datum/supply_packs/teamsecurity
name = "Team Security stack of packs"
contains = list(/obj/structure/vendomatpack/team_security, /obj/structure/vendomatpack/team_security)
cost = 10
containertype = /obj/structure/stackopacks
containername = "Team Security stack of packs"
group = "Vending Machine packs"

View File

@@ -946,23 +946,41 @@
for(var/client/C in viewers)
C.images -= override_image
//Attack Animation for ghost object being pixel shifted onto person
var/image/item = image(icon=tool.icon, icon_state = tool.icon_state)
item.appearance = tool.attack_icon()
item.alpha = 128
item.loc = target
item.pixel_x = target.pixel_x - horizontal * 0.5 * WORLD_ICON_SIZE
item.pixel_y = target.pixel_y - vertical * 0.5 * WORLD_ICON_SIZE
item.mouse_opacity = 0
spawn()
//Attack Animation for ghost object being pixel shifted onto person
var/image/item = image(icon=tool.icon, icon_state = tool.icon_state)
item.appearance = tool.attack_icon()
item.alpha = 128
item.loc = target
item.pixel_x = target.pixel_x - horizontal * 0.5 * WORLD_ICON_SIZE
item.pixel_y = target.pixel_y - vertical * 0.5 * WORLD_ICON_SIZE
item.mouse_opacity = 0
var/viewers = item_animation_viewers.Copy()
for(var/client/C in viewers)
C.images += item
var/viewers = item_animation_viewers.Copy()
for(var/client/C in viewers)
C.images += item
animate(item, pixel_x = target.pixel_x, pixel_y = target.pixel_y, time = 3)
sleep(3)
for(var/client/C in viewers)
C.images -= item
animate(item, pixel_x = target.pixel_x, pixel_y = target.pixel_y, time = 3)
sleep(3)
for(var/client/C in viewers)
C.images -= item
spawn()
target.do_hitmarker(usr)
/atom/proc/do_hitmarker(mob/shooter)
spawn()
var/datum/role/streamer/streamer_role = shooter?.mind?.GetRole(STREAMER)
if(streamer_role?.team == ESPORTS_SECURITY)
streamer_role.hits += IS_WEEKEND ? 2 : 1
streamer_role.update_antag_hud()
playsound(src, 'sound/effects/hitmarker.ogg', 100, FALSE)
var/image/hitmarker = image(icon='icons/effects/effects.dmi', loc=src, icon_state="hitmarker")
for(var/client/C in clients)
C.images += hitmarker
sleep(3)
for(var/client/C in clients)
C.images -= hitmarker
/atom/movable/proc/make_invisible(var/source_define, var/time, var/include_clothing) //Makes things practically invisible, not actually invisible. Alpha is set to 1.
return invisibility || alpha <= 1 //already invisible

View File

@@ -352,7 +352,7 @@ var/list/camera_messages = list()
/obj/machinery/camera/attack_pai(mob/user as mob)
wirejack(user)
/obj/machinery/camera/proc/deactivate(user as mob, var/choice = 1)
/obj/machinery/camera/proc/deactivate(user as mob, var/choice = 1, quiet = FALSE)
vision_flags = SEE_SELF
if(assembly)
update_upgrades()
@@ -362,20 +362,21 @@ var/list/camera_messages = list()
update_icon()
if (!(src.status))
if(user)
visible_message("<span class='warning'>[user] has deactivated [src]!</span>")
add_hiddenprint(user)
if(!quiet)
visible_message("<span class='warning'>[user] has deactivated [src]!</span>")
else
visible_message("<span class='warning'> \The [src] deactivates!</span>")
playsound(src, 'sound/items/Wirecutter.ogg', 50, 1)
add_hiddenprint(user)
if(!quiet)
visible_message("<span class='warning'> \The [src] deactivates!</span>")
else
if(user)
visible_message("<span class='warning'> [user] has reactivated [src]!</span>")
add_hiddenprint(user)
if(!quiet)
visible_message("<span class='warning'> [user] has reactivated [src]!</span>")
else
visible_message("<span class='warning'> \The [src] reactivates!</span>")
if(!quiet)
visible_message("<span class='warning'> \The [src] reactivates!</span>")
if(!quiet)
playsound(src, 'sound/items/Wirecutter.ogg', 50, 1)
add_hiddenprint(user)
add_hiddenprint(user)
cameranet.updateVisibility(src, 0)
// now disconnect anyone using the camera
//Apparently, this will disconnect anyone even if the camera was re-activated.
@@ -546,6 +547,35 @@ var/list/camera_messages = list()
/obj/machinery/camera/arena/bullet_act(var/obj/item/projectile/Proj)
return
/obj/machinery/camera/arena/spesstv
name = "\improper Spess.TV camera"
network = list(CAMERANET_SPESSTV)
var/datum/role/streamer/streamer
/obj/machinery/camera/arena/spesstv/New()
..()
for(var/obj/item/weapon/reagent_containers/food/snacks/grown/carrot in assembly.upgrades)
assembly.upgrades -= carrot
update_upgrades()
deactivate()
/obj/machinery/camera/arena/spesstv/name_camera()
var/team_name = streamer?.team
var/basename = streamer?.antag?.name || "Unknown"
if(team_name)
basename = "\[[team_name]\] [basename]"
var/nethash = english_list(network)
var/suffix = 0
while(!suffix || (nethash+c_tag in camera_names))
c_tag = "[basename]"
if(suffix)
c_tag += " [suffix]"
suffix++
camera_names[nethash+c_tag]=src
/obj/machinery/camera/deactivate(mob/user, choice = TRUE, quiet = TRUE)
..()
/obj/machinery/camera/kick_act(mob/living/carbon/human/H)
H.visible_message("<span class='danger'>[H] attempts to kick \the [src].</span>", "<span class='danger'>You attempt to kick \the [src].</span>")
to_chat(H, "<span class='danger'>Dumb move! You strain a muscle.</span>")

View File

@@ -20,8 +20,7 @@ var/list/obj/machinery/camera/cyborg_cams = list(
light_color = LIGHT_COLOR_RED
/obj/machinery/computer/security/New()
..()
/obj/machinery/computer/security/proc/init_action_buttons()
var/datum/action/camera/previous/P = new(src)
var/datum/action/camera/cancel/C = new(src)
var/datum/action/camera/cyborg/C1 = new(src)
@@ -29,6 +28,10 @@ var/list/obj/machinery/camera/cyborg_cams = list(
var/datum/action/camera/next/N = new(src)
our_actions = list(P, C, C1, L, N)
/obj/machinery/computer/security/New()
..()
init_action_buttons()
if (ticker && ticker.current_state == GAME_STATE_PLAYING)
init_cams()
@@ -72,7 +75,7 @@ var/list/obj/machinery/camera/cyborg_cams = list(
if (src.z > 6)
to_chat(user, "<span class='danger'>Unable to establish a connection: </span>You're too far away from the station!")
return
if(stat & (NOPOWER|BROKEN))
if(!is_operational())
return
if(!isAI(user))
@@ -97,12 +100,13 @@ var/list/obj/machinery/camera/cyborg_cams = list(
density = 0
circuit = null
layer = ABOVE_WINDOW_LAYER
pass_flags = PASSTABLE
light_color = null
/obj/machinery/computer/security/telescreen/examine(mob/user)
..()
to_chat(user, "Looks like the current channel is \"<span class='info'>[current.c_tag]</span>\"")
if(current?.c_tag)
to_chat(user, "Looks like the current channel is \"<span class='info'>[current.c_tag]</span>\"")
/obj/machinery/computer/security/telescreen/update_icon()
icon_state = initial(icon_state)
@@ -115,12 +119,43 @@ var/list/obj/machinery/camera/cyborg_cams = list(
desc = "Damn, they better have chicken-channel on these things."
icon = 'icons/obj/status_display.dmi'
icon_state = "entertainment"
network = list(CAMERANET_THUNDER, CAMERANET_COURTROOM)
network = list(CAMERANET_THUNDER, CAMERANET_COURTROOM, CAMERANET_SPESSTV)
density = 0
circuit = null
light_color = null
/obj/machinery/computer/security/telescreen/entertainment/spesstv
name = "low-latency Spess.TV CRT monitor"
desc = "An ancient computer monitor. They don't make them like they used to. A sticker reads: \"Come be their hero\"."
icon = 'icons/obj/spesstv.dmi'
icon_state = "crt"
network = list(CAMERANET_SPESSTV)
density = TRUE
/obj/machinery/computer/security/telescreen/entertainment/spesstv/is_operational()
return TRUE
/obj/machinery/computer/security/telescreen/entertainment/spesstv/update_icon()
/obj/machinery/computer/security/telescreen/entertainment/spesstv/init_action_buttons()
var/datum/action/camera/previous/P = new(src)
var/datum/action/camera/cancel/C = new(src)
var/datum/action/camera/listing/L = new(src)
var/datum/action/camera/next/N = new(src)
var/datum/action/camera/follow/F = new(src)
var/datum/action/camera/subscribe/S = new(src)
our_actions = list(P, C, L, N, F, S)
/obj/machinery/computer/security/telescreen/entertainment/spesstv/flatscreen
name = "high-definition Spess.TV telescreen"
icon = 'icons/obj/status_display.dmi'
icon_state = "entertainment"
/obj/machinery/computer/security/telescreen/entertainment/spesstv/flatscreen/New()
..()
overlays += "spesstv_overlay"
/obj/machinery/computer/security/telescreen/entertainment/wooden_tv
icon_state = "security_det"
icon = 'icons/obj/computer.dmi'
@@ -285,6 +320,39 @@ var/list/obj/machinery/camera/cyborg_cams = list(
var/mob/living/user = owner
user.cancel_camera()
/datum/action/camera/follow
name = "Follow!"
desc = "Follow this streamer to be notified when they go online."
icon_icon = 'icons/obj/camera_buttons.dmi'
button_icon_state = "follow"
/datum/action/camera/follow/Trigger()
if(usr.incapacitated())
return
var/obj/machinery/computer/security/telescreen/entertainment/spesstv/tv = target
if(!in_range(tv, usr))
return
var/obj/machinery/camera/arena/spesstv/camera = tv.current
var/datum/role/streamer/streamer_role = camera.streamer
streamer_role.try_add_follower(usr.mind)
/datum/action/camera/subscribe
name = "Subscribe! ($250)"
desc = "Support this streamer and get a subscriber badge and a loot box!"
icon_icon = 'icons/obj/camera_buttons.dmi'
button_icon_state = "subscribe"
/datum/action/camera/subscribe/Trigger()
if(usr.incapacitated())
return
var/obj/machinery/computer/security/telescreen/entertainment/spesstv/tv = target
if(!in_range(tv, usr))
return
var/obj/machinery/camera/arena/spesstv/camera = tv.current
var/datum/role/streamer/streamer_role = camera.streamer
streamer_role.try_add_subscription(usr.mind, tv)
/datum/action/camera/cyborg
name = "Cyborg camera listing"
desc = "List all the cyborg cameras conected to this network."

View File

@@ -3383,3 +3383,48 @@ var/global/num_vending_terminals = 1
pack = /obj/structure/vendomatpack/games
vend_reply = "Don't have too much fun!"
/obj/machinery/vending/team_security
name = "\improper Team Security Merch"
desc = "A refurbished vending machine selling merch for Team Security."
icon_state = "teamsec"
vend_reply = "Team Security is my Guideline."
product_slogans = list(
"Security helmet: on. Knuckles: cracked. Clown: brutalized. Yep...it's Team Security time.",
"It's a steal!",
"Get caught red-handed."
)
product_ads = list(
"For Security, by Security.",
"For the Bold.",
"Colonel Quality, guaranteed.",
"Red Team cuts off demon wings.",
)
products = list(
/obj/item/weapon/reagent_containers/food/snacks/donitos = 10,
/obj/item/clothing/head/soft/sec = 10,
/obj/item/clothing/under/team_security = 10,
/obj/item/clothing/under/team_security/dark = 10,
/obj/item/clothing/under/spesstv = 1,
/obj/item/clothing/shoes/jackboots = 10,
)
contraband = list(
/obj/item/clothing/under/team_geometer = 10,
/obj/item/weapon/reagent_containers/food/snacks/donitos/coolranch = 10,
)
premium = list(
/obj/item/clothing/under/team_nt = 1,
/obj/item/weapon/gun/energy/taser/team_security = 1,
)
prices = list(
/obj/item/weapon/reagent_containers/food/snacks/donitos = 10,
/obj/item/weapon/reagent_containers/food/snacks/donitos/coolranch = 10,
/obj/item/clothing/head/soft/sec = 25,
/obj/item/clothing/under/team_security = 25,
/obj/item/clothing/under/team_security/dark = 25,
/obj/item/clothing/shoes/jackboots = 25,
/obj/item/weapon/gun/energy/taser/team_security = 100,
)
pack = /obj/structure/vendomatpack/team_security
machine_flags = SCREWTOGGLE | WRENCHMOVE | FIXED2WORK | CROWDESTROY | EJECTNOTDEL | EMAGGABLE

View File

@@ -224,6 +224,11 @@
targetvendomat = /obj/machinery/vending/games
icon_state = "games"
/obj/structure/vendomatpack/team_security
name = "Team Security recharge pack"
targetvendomat = /obj/machinery/vending/team_security
icon_state = "team_security"
//////EMPTY PACKS//////
/obj/item/emptyvendomatpack

View File

@@ -112,6 +112,14 @@
name = "\improper Discount Dan's Chocolate Bar"
icon_state = "danbar"
/obj/item/trash/donitos
name = "Donitos"
icon_state = "donitos"
/obj/item/trash/donitos_coolranch
name = "Donitos Cool Ranch"
icon_state = "donitos_coolranch"
/obj/item/trash/danitos
name = "\improper Danitos"
icon_state = "danitos"

View File

@@ -50,6 +50,10 @@
..()
update()
/obj/item/weapon/implanter/spesstv
name = "promotional Spess.TV implanter"
desc = "Does anyone know where the implanter went? I have a lockbox full of loyalty implants here..."
/obj/item/weapon/implanter/traitor
name = "greytide conversion kit"
desc = "Any humanoid injected with this implant will become loyal to the injector and the greytide, unless of course the host is already loyal to someone else."

View File

@@ -463,3 +463,26 @@
.=..()
if (.)
playsound(loc, 'sound/machines/click.ogg', 30, -5)
/obj/item/weapon/storage/lockbox/security_sponsored
name = "sponsored Team Security lockbox"
desc = "A sponsor-sticker-plastered lockbox."
req_one_access = list(access_brig)
storage_slots = 6
/obj/item/weapon/storage/lockbox/security_sponsored/New()
..()
for(var/i in 1 to 4)
new /obj/item/weapon/reagent_containers/food/snacks/donitos/coolranch(src)
new /obj/item/weapon/implanter/spesstv(src)
/obj/item/weapon/storage/lockbox/team_security_cameras
name = "sponsored Team Security cameras lockbox"
desc = "A sponsor-sticker-plastered lockbox."
req_one_access = list(access_brig)
storage_slots = 6
/obj/item/weapon/storage/lockbox/team_security_cameras/New()
..()
for(var/i in 1 to 6)
new /obj/item/clothing/accessory/spesstv_tactical_camera(src)

View File

@@ -0,0 +1,46 @@
/obj/item/clothing/accessory/spesstv_tactical_camera
name = "\improper Spess.TV tactical camera"
desc = "A compact, tactical camera with built-in Spess.TV integration. Fits on uniform, armor and headgear. It features a Team Security logo."
icon_state = "small_camera" // Credits to https://github.com/discordia-space/CEV-Eris
accessory_exclusion = ACCESSORY_LIGHT
var/obj/machinery/camera/arena/spesstv/internal_camera
/obj/item/clothing/accessory/spesstv_tactical_camera/New()
..()
internal_camera = new(src)
new /datum/action/item_action/toggle_streaming(src)
/obj/item/clothing/accessory/spesstv_tactical_camera/can_attach_to(obj/item/clothing/C)
var/static/list/allowed_clothing = list(/obj/item/clothing/under, /obj/item/clothing/head, /obj/item/clothing/suit/armor)
return is_type_in_list(C, allowed_clothing)
/obj/item/clothing/accessory/spesstv_tactical_camera/attack_self(mob/user)
..()
if(user.incapacitated())
return
if(!internal_camera.streamer)
if(user.mind.GetRole(STREAMER))
to_chat(user, "<span class='warning'>A camera is already linked to your Spess.TV account!</span>")
return
var/datum/role/streamer/new_streamer_role = new /datum/role/streamer
if(!new_streamer_role.AssignToRole(user.mind, 1))
new_streamer_role.Drop()
to_chat(user, "<span class='warning'>Something went wrong during your registration to Spess.TV. Please try again.</span>")
return
new_streamer_role.team = ESPORTS_SECURITY
new_streamer_role.camera = internal_camera
new_streamer_role.set_camera(internal_camera)
new_streamer_role.OnPostSetup()
new_streamer_role.Greet(GREET_DEFAULT)
new_streamer_role.AnnounceObjectives()
if(internal_camera.streamer.antag != user.mind)
to_chat(user, "<span class='warning'>You are not the registered user of this camera.</span>")
return
internal_camera.streamer.toggle_streaming()
/datum/action/item_action/toggle_streaming
name = "Toggle streaming"
/datum/action/item_action/toggle_streaming/Trigger()
var/obj/item/target_item = target
target_item.attack_self(owner)

View File

@@ -591,6 +591,20 @@
*/
var/displays_id = 1
clothing_flags = CANEXTINGUISH
var/icon/jersey_overlays
// Associative list of exact type -> number
var/list/jersey_numbers = list()
/obj/item/clothing/under/New()
..()
if(jersey_overlays)
var/number = jersey_numbers[type]++ % 99
var/first_digit = num2text(round((number / 10) % 10))
var/second_digit = num2text(round(number % 10))
var/image/jersey_overlay = image(jersey_overlays, src, "[first_digit]-")
jersey_overlay.overlays += image(jersey_overlays, src, second_digit)
dynamic_overlay["[UNIFORM_LAYER]"] = jersey_overlay
/obj/item/clothing/under/examine(mob/user)
..()

View File

@@ -569,3 +569,7 @@
icon_state = "sombrero"
item_state = "sombrero"
/obj/item/clothing/head/donitos_pope
name = "\improper Donitos Pope hat"
desc = "An oversized Donitos promotional plastic donut-shaped hat."
icon_state = "donitos_pope"

View File

@@ -809,3 +809,42 @@
item_state = "clownpsyche"
_color = "clownpsyche"
clothing_flags = ONESIZEFITSALL
/obj/item/clothing/under/team_security
name = "light Team Security suit"
desc = "A snappy white and red suit worn by Team Security members and fans."
icon_state = "teamsec_light"
_color = "teamsec_light"
jersey_overlays = 'icons/mob/uniform_overlays.dmi'
clothing_flags = ONESIZEFITSALL
/obj/item/clothing/under/team_security/dark
name = "dark Team Security suit"
desc = "A snappy black and red suit worn by Team Security members and fans."
icon_state = "teamsec_dark"
_color = "teamsec_dark"
clothing_flags = ONESIZEFITSALL
/obj/item/clothing/under/spesstv
name = "promotional Spess.TV suit"
desc = "A cheap green and white suit worn by Spess.TV members and fans."
icon_state = "spesstv"
_color = "spesstv"
jersey_overlays = 'icons/mob/uniform_overlays.dmi'
clothing_flags = ONESIZEFITSALL
/obj/item/clothing/under/team_geometer
name = "\improper Team Geometer suit"
desc = "A smelly green and black suit worn by team Geometer members and fans."
icon_state = "teamgeometer"
_color = "teamgeometer"
jersey_overlays = 'icons/mob/uniform_overlays.dmi'
clothing_flags = ONESIZEFITSALL
/obj/item/clothing/under/team_nt
name = "\improper NanoTrasen sports suit"
desc = "A dusty blue and white suit worn by NanoTrasen referees."
icon_state = "teamnt"
_color = "teamnt"
jersey_overlays = 'icons/mob/uniform_overlays.dmi'
clothing_flags = ONESIZEFITSALL

View File

@@ -56,6 +56,11 @@
else
charge_tick = 0
/obj/item/weapon/gun/energy/taser/team_security
name = "\improper Team Security sniper taser gun"
icon_state = "taser"
charge_cost = 500
fire_sound = 'sound/effects/intervention.ogg'
/obj/item/weapon/gun/energy/stunrevolver
name = "stun revolver"

View File

@@ -241,6 +241,7 @@ var/list/impact_master = list()
visible_message("<span class='warning'>[A.name] is hit by the [src.name] in the [parse_zone(def_zone)]!</span>")//X has fired Y is now given by the guns so you cant tell who shot you if you could not see the shooter
admin_warn(M)
if(istype(firer, /mob))
M.do_hitmarker(firer)
if(!iscarbon(firer))
M.LAssailant = null
else

View File

@@ -5190,6 +5190,13 @@
M.dizziness += 5
M.drowsyness = 0
/datum/reagent/drink/cold/geometer
name = "Geometer"
id = GEOMETER
description = "Summon the Beast."
color = "#ffd700"
adj_sleepy = -2
/datum/reagent/drink/cold/spacemountainwind
name = "Space Mountain Wind"
id = SPACEMOUNTAINWIND

View File

@@ -848,6 +848,19 @@
reagents.add_reagent(BEER, 25)
reagents.add_reagent(POTATO, 25)
/obj/item/weapon/reagent_containers/food/drinks/soda_cans/geometer
name = "Geometer"
desc = "Summon the Beast."
icon_state = "geometer"
/obj/item/weapon/reagent_containers/food/drinks/soda_cans/geometer/New()
..()
reagents.add_reagent(GEOMETER, 50)
/obj/item/weapon/reagent_containers/food/drinks/soda_cans/geometer/blanco
name = "Geometer Blanco"
desc = "'member when we had to research words..."
icon_state = "geometer_blanco"
/obj/item/weapon/reagent_containers/food/drinks/soda_cans/greyshitvodka
name = "Greyshit Vodka"
desc = "Experts spent a long time squatting around a mixing bench to bring you this."

View File

@@ -1525,6 +1525,27 @@
bitesize = 2
/obj/item/weapon/reagent_containers/food/snacks/donitos
name = "Donitos"
desc = "Ranch or cool ranch?"
icon_state = "donitos"
trash = /obj/item/trash/donitos
/obj/item/weapon/reagent_containers/food/snacks/donitos/New()
..()
reagents.add_reagent(NUTRIMENT, 1)
reagents.add_reagent(SPRINKLES, 10)
/obj/item/weapon/reagent_containers/food/snacks/donitos/coolranch
name = "Donitos Cool Ranch"
desc = "Cool ranch."
icon_state = "donitos_coolranch"
trash = /obj/item/trash/donitos_coolranch
/obj/item/weapon/reagent_containers/food/snacks/donitos/coolranch/New()
..()
reagents.add_reagent(SPRINKLES, 5)
/obj/item/weapon/reagent_containers/food/snacks/danitos
name = "Danitos"
desc = "For only the most MLG hardcore robust spessmen."

View File

@@ -191,6 +191,12 @@
update_icon()
/obj/structure/closet/crate/flatpack/proc/insert_machine(atom/movable/thing)
thing.forceMove(src)
name += " ([thing.name])"
machine = thing
update_icon()
/*
#define Fl_ACTION "action"
@@ -294,3 +300,4 @@
/obj/structure/closet/crate/flatpack/starscreen_capacitor/New()
..()
machine = new /obj/machinery/shield_capacitor(src)

View File

@@ -64,10 +64,7 @@
src.overlays -= image(icon = icon, icon_state = "[base_state]_ani")
if(being_built)
var/obj/structure/closet/crate/flatpack/FP = new
being_built.forceMove(FP)
FP.name += " ([being_built.name])"
FP.machine = being_built
FP.update_icon()
FP.insert(being_built)
var/turf/output = get_output()
FP.forceMove(get_turf(output))
src.visible_message("[bicon(src)] \The [src] beeps: \"Successfully completed \the [being_built.name].\"")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 526 KiB

After

Width:  |  Height:  |  Size: 527 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 KiB

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 KiB

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 604 B

After

Width:  |  Height:  |  Size: 870 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 KiB

After

Width:  |  Height:  |  Size: 200 KiB

BIN
icons/obj/spesstv.dmi Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

BIN
sound/effects/hitmarker.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -390,6 +390,7 @@
#include "code\datums\gamemode\objectives\ramble.dm"
#include "code\datums\gamemode\objectives\sample.dm"
#include "code\datums\gamemode\objectives\silence.dm"
#include "code\datums\gamemode\objectives\spesstv.dm"
#include "code\datums\gamemode\objectives\spray_blood.dm"
#include "code\datums\gamemode\objectives\steal_priority_items.dm"
#include "code\datums\gamemode\objectives\summon_narsie.dm"
@@ -433,6 +434,7 @@
#include "code\datums\gamemode\role\rambler.dm"
#include "code\datums\gamemode\role\rev.dm"
#include "code\datums\gamemode\role\role.dm"
#include "code\datums\gamemode\role\streamer.dm"
#include "code\datums\gamemode\role\summonsurvivors.dm"
#include "code\datums\gamemode\role\syndicate.dm"
#include "code\datums\gamemode\role\vampire_role.dm"
@@ -1328,6 +1330,7 @@
#include "code\modules\clothing\accessories\armor_shards.dm"
#include "code\modules\clothing\accessories\holomap.dm"
#include "code\modules\clothing\accessories\holster.dm"
#include "code\modules\clothing\accessories\spesstv.dm"
#include "code\modules\clothing\accessories\storage.dm"
#include "code\modules\clothing\accessories\tactical_light.dm"
#include "code\modules\clothing\back\cape.dm"