mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-09 16:14:13 +00:00
[done][needs test merge][waiting for test merge since 3 weeks ago] curb your roundend 2: curb harder: return of curb (#20333)
* Working proof of concept * Seems to be fully functional, yet ugly * Beats me * Perfect layout * Looks great now * Clear credits correctly * Actually fix the rejoin situation * Credits work when rebooting world manually * Comments the debug out until I make a proper verb for it * Adds credits panel & slight refactors * Adds images to credits * Adds more disclaimers and episode names * Names * Fixes prespawned corpses in the credits Celt is an idiot and this did not actually work
This commit is contained in:
committed by
Intigracy
parent
98eed8c1e3
commit
2edde95469
@@ -239,6 +239,7 @@ var/list/score=list(
|
||||
"foodeaten" = 0, //How much food was consumed
|
||||
"clownabuse" = 0, //How many times a clown was punched, struck or otherwise maligned
|
||||
"slips" = 0, //How many people have slipped during this round
|
||||
"gunsspawned" = 0, //Guns spawned by the Summon Guns spell. Only guns, not other artifacts.
|
||||
"richestname" = null, //This is all stuff to show who was the richest alive on the shuttle
|
||||
"richestjob" = null, //Kinda pointless if you dont have a money system i guess
|
||||
"richestcash" = 0,
|
||||
@@ -248,6 +249,7 @@ var/list/score=list(
|
||||
"dmgestdamage" = 0,
|
||||
"dmgestkey" = null,
|
||||
"explosions" = 0, //How many explosions happened total
|
||||
"deadpets" = 0, //Only counts 'special' simple_mobs, like Ian, Poly, Runtime, Sasha etc
|
||||
|
||||
"arenafights" = 0,
|
||||
"arenabest" = null,
|
||||
|
||||
@@ -166,6 +166,7 @@
|
||||
var/mommi_static = 0 //Scrambling mobs for mommis or not
|
||||
|
||||
var/skip_minimap_generation = 0 //If 1, don't generate minimaps
|
||||
var/skip_holominimap_generation = 0 //If 1, don't generate holominimaps
|
||||
var/skip_vault_generation = 0 //If 1, don't generate vaults
|
||||
var/shut_up_automatic_diagnostic_and_announcement_system = 0 //If 1, don't play the vox sounds at the start of every shift.
|
||||
|
||||
@@ -555,6 +556,8 @@
|
||||
mommi_static = 1
|
||||
if("skip_minimap_generation")
|
||||
skip_minimap_generation = 1
|
||||
if("skip_holominimap_generation")
|
||||
skip_holominimap_generation = 1
|
||||
if("skip_vault_generation")
|
||||
skip_vault_generation = 1
|
||||
if("shut_up_automatic_diagnostic_and_announcement_system")
|
||||
|
||||
@@ -20,10 +20,15 @@ var/datum/subsystem/more_init/SSmore_init
|
||||
create_global_parallax_icons()
|
||||
log_startup_progress(" Finished caching space parallax simulation in [stop_watch(watch)]s.")
|
||||
|
||||
watch=start_watch()
|
||||
log_startup_progress("Generating holominimaps...")
|
||||
generateHoloMinimaps()
|
||||
log_startup_progress(" Finished holominimaps in [stop_watch(watch)]s.")
|
||||
if (!config.skip_minimap_generation)
|
||||
watch=start_watch()
|
||||
log_startup_progress("Generating holominimaps...")
|
||||
generateHoloMinimaps()
|
||||
log_startup_progress(" Finished holominimaps in [stop_watch(watch)]s.")
|
||||
else
|
||||
holomaps_initialized = 1 //Assume holominimaps were prerendered, the worst thing that happens if they're missing is that the minimap consoles don't show a minimap
|
||||
log_startup_progress("Not generating holominimaps - SKIP_HOLOMINIMAP_GENERATION found in config/config.txt")
|
||||
..()
|
||||
|
||||
buildcamlist()
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
var/mind=null
|
||||
var/list/languages = list()
|
||||
var/times_cloned=0
|
||||
var/talkcount
|
||||
|
||||
/datum/dna2/record/proc/GetData()
|
||||
var/list/ser=list("data" = null, "owner" = null, "label" = null, "type" = null, "ue" = 0)
|
||||
|
||||
@@ -2,7 +2,7 @@ var/datum/controller/gameticker/ticker
|
||||
|
||||
/datum/controller/gameticker
|
||||
var/remaining_time = 0
|
||||
var/const/restart_timeout = 600
|
||||
var/const/restart_timeout = 60 SECONDS
|
||||
var/current_state = GAME_STATE_PREGAME
|
||||
|
||||
var/hide_mode = 0
|
||||
@@ -425,6 +425,7 @@ var/datum/controller/gameticker/ticker
|
||||
|
||||
spawn
|
||||
declare_completion()
|
||||
end_credits.on_roundend()
|
||||
if(config.map_voting)
|
||||
//testing("Vote picked [chosen_map]")
|
||||
vote.initiate_vote("map","The Server", popup = 1, weighted_vote = config.weighted_votes)
|
||||
@@ -465,14 +466,14 @@ var/datum/controller/gameticker/ticker
|
||||
if (watchdog.waiting)
|
||||
to_chat(world, "<span class='notice'><B>Server will shut down for an automatic update in [config.map_voting ? "[(restart_timeout/10)] seconds." : "a few seconds."]</B></span>")
|
||||
if(config.map_voting)
|
||||
sleep(restart_timeout) //waiting for a mapvote to end
|
||||
sleep(restart_timeout - end_credits.starting_delay) //waiting for a mapvote to end
|
||||
if(!delay_end)
|
||||
watchdog.signal_ready()
|
||||
else
|
||||
to_chat(world, "<span class='notice'><B>An admin has delayed the round end</B></span>")
|
||||
delay_end = 2
|
||||
else if(!delay_end)
|
||||
sleep(restart_timeout)
|
||||
sleep(restart_timeout - end_credits.starting_delay)
|
||||
if(!delay_end)
|
||||
CallHook("Reboot",list())
|
||||
world.Reboot()
|
||||
|
||||
@@ -221,6 +221,10 @@
|
||||
continue
|
||||
score["litter"]++
|
||||
|
||||
for(var/mob/living/simple_animal/SA in dead_mob_list)
|
||||
if(SA.is_pet)
|
||||
score["deadpets"]++
|
||||
|
||||
//Bonus Modifiers
|
||||
//var/traitorwins = score["traitorswon"]
|
||||
var/deathpoints = score["deadcrew"] * 250 //Human beans aren't free
|
||||
|
||||
@@ -142,6 +142,7 @@
|
||||
if("bulletstorm")
|
||||
new /obj/item/weapon/gun/bulletstorm(get_turf(src))
|
||||
playsound(src,'sound/effects/summon_guns.ogg', 50, 1)
|
||||
score["gunsspawned"]++
|
||||
|
||||
/mob/living/carbon/human/proc/equip_swords()
|
||||
var/randomizeswords = pick("unlucky", "misc", "throw", "armblade", "pickaxe", "pcutter", "esword", "alt-esword", "machete", "kitchen", "medieval", "katana", "axe", "boot", "saw", "scalpel", "switchtool", "shitcurity")
|
||||
|
||||
@@ -1501,3 +1501,52 @@ proc/formatPlayerPanel(var/mob/U,var/text="PP")
|
||||
tomob.ckey = frommob.ckey
|
||||
qdel(frommob)
|
||||
return 1
|
||||
|
||||
/datum/admins/proc/CreditsPanel()
|
||||
if(!check_rights(0))
|
||||
return
|
||||
|
||||
var/dat = "<center><B>Credits Panel</B></center><hr>"
|
||||
dat += "<center><B>Episode Name:</B></center>"
|
||||
dat += "Chosen Name: [end_credits.episode_name == "" ? "(Will Generate Automatically)" : end_credits.episode_name] <A href='?src=\ref[src];credits=setname'>(Set) </A>"
|
||||
if(end_credits.episode_name != "" && !end_credits.generated)
|
||||
dat += "<A href='?src=\ref[src];credits=resetname'>(Reset)</A>"
|
||||
else if(end_credits.generated)
|
||||
dat += "<A href='?src=\ref[src];credits=rerollname'>(Reroll!)</A>"
|
||||
dat += "<br>"
|
||||
if(!end_credits.generated)
|
||||
dat += "<span style='color:red'>The round isn't over, so the name possibilities haven't been drafted yet.<br>You can manually write down a set name now, or come back when the round ends.</span>"
|
||||
else
|
||||
dat += "Drafted Name Possibilities: "
|
||||
dat += "<div id='draftednames'>"
|
||||
for(var/datum/episode_name/N in end_credits.episode_names)
|
||||
dat += "[N.make_div(src)]<br>"
|
||||
dat += "</div>"
|
||||
dat += "<hr>"
|
||||
dat += "<center><B>Disclaimers:</B></center>"
|
||||
if(!end_credits.generated)
|
||||
dat += "<span style='color:red'>The round isn't over, so the disclaimers haven't been generated yet.<br>You can add some now (they will show up at the top), or come back when the round ends.</span>"
|
||||
dat += "<br>Generated Disclaimers: "
|
||||
dat += "<div id='disclaimers'>"
|
||||
dat += "<a href='?src=\ref[src];credits=newdisclaimer'>(Add New)</a></br>"
|
||||
for(var/i = 1; i <= end_credits.disclaimers.len; i++)
|
||||
var/disclaimer = end_credits.disclaimers[i]
|
||||
if(i > 1)
|
||||
dat += "<a href='?src=\ref[src];credits=disclaimerup;disclaimerindex=[i]'>∧</a>"
|
||||
else
|
||||
dat += " "
|
||||
if(i < end_credits.disclaimers.len)
|
||||
dat += "<a href='?src=\ref[src];credits=disclaimerdown;disclaimerindex=[i]'>∨</a>"
|
||||
else
|
||||
dat += " "
|
||||
dat += "<a href='?src=\ref[src];credits=editdisclaimer;disclaimerindex=[i]'> (Edit) </a>"
|
||||
if(findtext(disclaimer, "<img"))
|
||||
dat += "[disclaimer]"
|
||||
else
|
||||
dat += "[html_encode(disclaimer)]"
|
||||
dat += "<br>"
|
||||
dat += "</div>"
|
||||
|
||||
dat += "<hr><br><center>ADVANCED: <a href='?_src_=vars;Vars=\ref[end_credits]'>Debug Credits Datum</A></center>"
|
||||
|
||||
usr << browse(dat, "window=creditspanel;size=600x800")
|
||||
|
||||
@@ -77,7 +77,8 @@ var/list/admin_verbs_admin = list(
|
||||
/client/proc/allow_character_respawn, /* Allows a ghost to respawn */
|
||||
/client/proc/watchdog_force_restart, /*forces restart using watchdog feature*/
|
||||
/client/proc/manage_religions,
|
||||
/client/proc/set_veil_thickness
|
||||
/client/proc/set_veil_thickness,
|
||||
/client/proc/credits_panel /*allows you to customize the roundend credits before they happen*/
|
||||
)
|
||||
var/list/admin_verbs_ban = list(
|
||||
/client/proc/unban_panel,
|
||||
@@ -1210,3 +1211,11 @@ var/list/admin_verbs_mod = list(
|
||||
else
|
||||
alert(src, "An external server error has occurred. Please report this.")
|
||||
return 0
|
||||
|
||||
/client/proc/credits_panel()
|
||||
set name = "Credits Panel"
|
||||
set category = "Admin"
|
||||
if(holder)
|
||||
holder.CreditsPanel()
|
||||
feedback_add_details("admin_verb","CP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
return
|
||||
|
||||
@@ -4830,6 +4830,68 @@
|
||||
return
|
||||
mind.role_panel()
|
||||
|
||||
else if(href_list["credits"])
|
||||
switch(href_list["credits"])
|
||||
if("resetname")
|
||||
if(!end_credits.generated) //Just in case the button somehow gets clicked when it shouldn't
|
||||
end_credits.episode_name = ""
|
||||
log_admin("[key_name(usr)] reset the current round's episode name. A new one will automatically generate later.")
|
||||
message_admins("[key_name_admin(usr)] reset the current round's episode name. A new one will automatically generate later.")
|
||||
if("rerollname")
|
||||
end_credits.pick_name()
|
||||
log_admin("[key_name(usr)] re-rolled the current round's episode name. New name: '[end_credits.episode_name]'")
|
||||
message_admins("[key_name_admin(usr)] re-rolled the current round's episode name. New name: '[end_credits.episode_name]'")
|
||||
if("setname")
|
||||
var/newname = input(usr,"Write the name of this latest rerun...","New Episode Name") as text|null
|
||||
if(newname)
|
||||
end_credits.episode_name = newname
|
||||
log_admin("[key_name(usr)] forced the current round's episode name to '[newname]'")
|
||||
message_admins("[key_name_admin(usr)] forced the current round's episode name to '[newname]'")
|
||||
|
||||
if("namedatumedit")
|
||||
var/datum/episode_name/N = locate(href_list["nameref"])
|
||||
if(N)
|
||||
var/newname = input(usr,"Write a new possible episode name. This is NOT guaranteed to be picked as the final name, unless you modified the weight to 99999% or something.","Edit Name",N.thename) as text|null
|
||||
if(newname)
|
||||
N.thename = newname
|
||||
if("namedatumweight")
|
||||
var/datum/episode_name/N = locate(href_list["nameref"])
|
||||
if(N)
|
||||
var/newweight = input(usr,"Write the new possibility that '[N.thename]' will be selected as the final episode name. Default is 100.","Edit Weight",N.weight) as num|null
|
||||
if(newweight)
|
||||
N.weight = newweight
|
||||
if("namedatumremove")
|
||||
var/datum/episode_name/N = locate(href_list["nameref"])
|
||||
if(N && alert("Are you sure you want to remove the name '[N.thename]' from the possible episode names to be picked?", "Removing possible name", "Yes", "No") == "Yes")
|
||||
end_credits.episode_names -= N
|
||||
qdel(N)
|
||||
|
||||
if("newdisclaimer")
|
||||
var/newdisclaimer = input(usr,"Write a new rolling disclaimer. Probably something stupid like 'Sponsored by Toxins-R-Us'. This will show up at the top, right after the crew names. Add '\<br>' at the end if you want extra spacing.","New Disclaimer") as message|null
|
||||
if(newdisclaimer)
|
||||
end_credits.disclaimers.Insert(1,newdisclaimer)
|
||||
log_admin("[key_name(usr)] added a new disclaimer to the current round's credits: '[newdisclaimer]'")
|
||||
message_admins("[key_name_admin(usr)] added a new disclaimer to the current round's credits: '[newdisclaimer]'")
|
||||
if("editdisclaimer")
|
||||
var/i = text2num(href_list["disclaimerindex"])
|
||||
var/olddisclaimer = end_credits.disclaimers[i]
|
||||
var/newdisclaimer = input(usr,"Write a new rolling disclaimer.","Edit Disclaimer",olddisclaimer) as message|null
|
||||
if(newdisclaimer)
|
||||
log_admin("[key_name(usr)] edited a rolling credits disclaimer. New disclaimer: '[newdisclaimer]'")
|
||||
message_admins("[key_name_admin(usr)] edited a rolling credits disclaimer. New disclaimer: '[newdisclaimer]'")
|
||||
end_credits.disclaimers[i] = newdisclaimer
|
||||
if("disclaimerup")
|
||||
var/i = text2num(href_list["disclaimerindex"])
|
||||
if(i > 1)
|
||||
end_credits.disclaimers.Swap(i,i-1)
|
||||
if("disclaimerdown")
|
||||
var/i = text2num(href_list["disclaimerindex"])
|
||||
if(i < end_credits.disclaimers.len)
|
||||
end_credits.disclaimers.Swap(i,i+1)
|
||||
|
||||
CreditsPanel() //refresh!
|
||||
|
||||
|
||||
// ----- Religion and stuff
|
||||
if (href_list["religions"])
|
||||
#define MAX_MSG_LENGTH 200
|
||||
|
||||
@@ -185,6 +185,7 @@
|
||||
prefs.client = src
|
||||
prefs.initialize_preferences(client_login = 1)
|
||||
|
||||
|
||||
. = ..() //calls mob.Login()
|
||||
chatOutput.start()
|
||||
|
||||
@@ -215,6 +216,8 @@
|
||||
//Set map label to correct map name
|
||||
winset(src, "rpane.map", "text=\"[map.nameLong]\"")
|
||||
|
||||
clear_credits() //Otherwise these persist if the client doesn't close the game between rounds
|
||||
|
||||
// Notify scanners.
|
||||
INVOKE_EVENT(on_login,list(
|
||||
"client"=src,
|
||||
|
||||
25
code/modules/credits/credit_disclaimers.dm
Normal file
25
code/modules/credits/credit_disclaimers.dm
Normal file
@@ -0,0 +1,25 @@
|
||||
/datum/credits/proc/draft_disclaimers()
|
||||
var/inline_images = ""
|
||||
for(var/filename in flist("icons/credits/"))
|
||||
var/icon/I = icon("icons/credits/[filename]")
|
||||
inline_images += "<span style='display: inline-block, vertical-align: middle, margin: 0px 20px;'><img style='display: inline-block,' src='data:image/png;base64,[icon2base64(I)]'></span>"
|
||||
|
||||
disclaimers += "Filmed on Location at [station_name()]."
|
||||
disclaimers += "Filmed with BYOND© cameras and lenses. Outer space footage provided by NASA."
|
||||
disclaimers += "Additional special visual effects by LUMMOX® JR. Motion Picture Productions."
|
||||
disclaimers += "Unofficially Sponsored by The United States Navy."
|
||||
disclaimers += "All rights reserved."
|
||||
disclaimers += "<br>"
|
||||
disclaimers += pick("All stunts were performed by underpaid and expendable interns. Do NOT try at home.", "[director] do not endorse behaviour depicted. Attempt at your own risk.")
|
||||
if(score["deadpets"] == 0)
|
||||
disclaimers += "No animals were harmed in the making of this film.[(score["clownabuse"] > 50) ? " However, many clowns were." : ""]"
|
||||
else if(score["clownabuse"] == 0)
|
||||
disclaimers += "No clowns were harmed in the making of this film."
|
||||
else if(score["clownabuse"] > 50)
|
||||
disclaimers += "All clowns were harmed in the making of this film."
|
||||
disclaimers += "<br>"
|
||||
disclaimers += inline_images
|
||||
disclaimers += "<br>"
|
||||
disclaimers += "This motion picture is (not) protected under the copyright laws of the United States and all countries throughout the universe. Country of first publication: United States of America. Any unauthorized exhibition, distribution, or copying of this picture or any part thereof (including soundtrack) is an infringement of the relevant copyright and will subject the infringer to civil liability and criminal prosecution."
|
||||
disclaimers += "The story, all names, characters, and incidents portrayed in this production are fictitious. No identification with actual persons (living or deceased), places, buildings, and products is intended or should be inferred."
|
||||
disclaimers += "No person or entity associated with this film received payment or anything of value, or entered into any agreement, in connection with the depiction of tobacco products."
|
||||
147
code/modules/credits/credits.dm
Normal file
147
code/modules/credits/credits.dm
Normal file
@@ -0,0 +1,147 @@
|
||||
var/global/datum/credits/end_credits = new
|
||||
|
||||
/datum/credits
|
||||
var/generated = FALSE
|
||||
var/starting_delay = 8 SECONDS
|
||||
var/control = "mapwindow.credits"
|
||||
var/file = 'code/modules/credits/credits.html'
|
||||
|
||||
var/director = "Pomf Chicken Productions"
|
||||
var/list/producers = list()
|
||||
var/mob/living/carbon/human/star
|
||||
var/list/disclaimers = list()
|
||||
var/list/datum/episode_name/episode_names = list()
|
||||
var/episode_name = ""
|
||||
|
||||
var/producers_string = ""
|
||||
var/episode_string = ""
|
||||
var/cast_string = ""
|
||||
var/disclaimers_string = ""
|
||||
|
||||
/datum/credits/proc/on_roundend()
|
||||
generate_caststring() //roundend grief not included in the credits
|
||||
generate_producerstring() //so that we show admins who have logged out before the credits roll
|
||||
draft_disclaimers()
|
||||
draft_episode_names() //only selects the possibilities, doesn't pick one yet
|
||||
generated = TRUE
|
||||
|
||||
/datum/credits/proc/rollem()
|
||||
world << sound('sound/music/Frolic_Luciano_Michelini.ogg')
|
||||
|
||||
finalize_disclaimerstring() //finalize it after the admins have had time to edit them
|
||||
if(episode_name == "") //admin might've already set one
|
||||
pick_name()
|
||||
finalize_episodestring()
|
||||
|
||||
var/scrollytext = episode_string + cast_string + disclaimers_string
|
||||
|
||||
var/list/js_args = list(scrollytext, producers_string, 25, 2000)
|
||||
|
||||
for(var/client/C in clients)
|
||||
C.show_credits(js_args)
|
||||
|
||||
/client/proc/show_credits(var/list/js_args)
|
||||
set waitfor = FALSE
|
||||
|
||||
verbs += /client/proc/clear_credits
|
||||
|
||||
src << output(end_credits.file, end_credits.control)
|
||||
sleep(end_credits.starting_delay)
|
||||
src << output(list2params(js_args), "[end_credits.control]:makeCredits")
|
||||
winset(src, end_credits.control, "is-visible=true")
|
||||
|
||||
/client/proc/clear_credits()
|
||||
set name = "Skip Credits"
|
||||
set category = "OOC"
|
||||
verbs -= /client/proc/clear_credits
|
||||
winset(src, end_credits.control, "is-visible=false")
|
||||
|
||||
|
||||
|
||||
|
||||
/datum/credits/proc/pick_name()
|
||||
var/list/drafted_names = list()
|
||||
for(var/datum/episode_name/N in episode_names)
|
||||
drafted_names["[N.thename]"] = N.weight
|
||||
episode_name = pickweight(drafted_names)
|
||||
|
||||
/datum/credits/proc/finalize_episodestring(var/thename)
|
||||
episode_string = "<h1>SEASON [rand(1,22)] EPISODE [rand(1,17)]<br>[uppertext(episode_name)]</h1><br><div style='padding-bottom: 75px;'></div>"
|
||||
|
||||
/datum/credits/proc/finalize_disclaimerstring()
|
||||
disclaimers_string = "<div class='disclaimers'>"
|
||||
for(var/disclaimer in disclaimers)
|
||||
disclaimers_string += "[disclaimer]<br>"
|
||||
disclaimers_string += "</div>"
|
||||
|
||||
/datum/credits/proc/generate_producerstring()
|
||||
var/list/staff = list("<h1>PRODUCTION STAFF</h1><br>")
|
||||
var/list/staffjobs = list("Coffee Fetcher", "Cameraman", "Angry Yeller", "Chair Operator", "Choreographer", "Historical Consultant", "Costume Designer", "Chief Editor", "Executive Assistant", "Key Grip")
|
||||
if(!admins.len)
|
||||
staff += "<h2>PRODUCER - Alan Smithee</h2><br>"
|
||||
for(var/client/C in admins)
|
||||
if(!C.holder)
|
||||
continue
|
||||
if(C.holder.rights & (R_DEBUG|R_ADMIN))
|
||||
var/observername = ""
|
||||
if(C.mob && istype(C.mob,/mob/dead/observer))
|
||||
var/mob/dead/observer/O = C.mob
|
||||
if(O.started_as_observer)
|
||||
observername = "[O.real_name] a.k.a. "
|
||||
staff += "<h2>[uppertext(pick(staffjobs))] - [observername]'[C.key]'</h2><br>"
|
||||
|
||||
producers = list("<h1>Directed by</br>[uppertext(director)]</h1>","[jointext(staff,"")]")
|
||||
for(var/head in data_core.get_manifest_json()["heads"])
|
||||
producers += "<h1>[head["rank"]]<br>[uppertext(head["name"])]</h1><br>"
|
||||
if(star)
|
||||
producers += "<h1>Starring<br>[thebigstar(star)]</h1><br>"
|
||||
|
||||
producers_string = ""
|
||||
for(var/producer in end_credits.producers)
|
||||
producers_string += "[producer]%n" //%n being an arbitrary "new producer" char we use to split this string back in the javascript
|
||||
|
||||
/datum/credits/proc/generate_caststring()
|
||||
cast_string = "<h1>CAST:</h1><br><h2>(in order of appearance)</h2><br>"
|
||||
cast_string += "<table class='crewtable'>"
|
||||
for(var/mob/living/carbon/human/H in living_mob_list|dead_mob_list)
|
||||
if(H.iscorpse || (H.timeofdeath && H.timeofdeath < 5 MINUTES)) //don't mention these losers (prespawned corpses mostly)
|
||||
continue
|
||||
if(!star || H.talkcount > star.talkcount)
|
||||
star = H
|
||||
|
||||
cast_string += "[gender_credits(H)]"
|
||||
|
||||
cast_string += "</table><br>"
|
||||
cast_string += "<div class='disclaimers'>"
|
||||
var/list/corpses = list()
|
||||
for(var/mob/living/carbon/human/H in dead_mob_list)
|
||||
if(H.iscorpse || (H.timeofdeath && H.timeofdeath < 5 MINUTES)) //no prespawned corpses
|
||||
continue
|
||||
else if(H.real_name)
|
||||
corpses += H.real_name
|
||||
if(corpses.len)
|
||||
var/true_story_bro = "<br>[pick("BASED ON","INSPIRED BY","A RE-ENACTMENT OF")] [pick("A TRUE STORY","REAL EVENTS","THE EVENTS ABOARD [uppertext(station_name())]")]"
|
||||
cast_string += "<h3>[true_story_bro]</h3><br>In memory of those that did not make it.<br>[english_list(corpses)].<br>"
|
||||
cast_string += "</div><br>"
|
||||
|
||||
/proc/gender_credits(var/mob/living/carbon/human/H)
|
||||
if(H.mind && H.mind.key)
|
||||
return "<tr><td class='actorname'>[uppertext(H.mind.key)]</td><td class='actorsegue'> as </td><td class='actorrole'>[H.real_name], [H.get_assignment()]</td></tr>"
|
||||
else
|
||||
var/t_him = "Them"
|
||||
if(H.gender == MALE)
|
||||
t_him = "Him"
|
||||
else if(H.gender == FEMALE)
|
||||
t_him = "Her"
|
||||
return "<tr><td class='actorname'>[uppertext(H.real_name)]</td><td class='actorsegue'> as </td><td class='actorrole'>[t_him]self</td></tr>"
|
||||
|
||||
/proc/thebigstar(var/mob/living/carbon/human/H)
|
||||
if(H.mind && H.mind.key)
|
||||
return "[uppertext(H.mind.key)] as [H.real_name]"
|
||||
else
|
||||
var/t_him = "Them"
|
||||
if(H.gender == MALE)
|
||||
t_him = "Him"
|
||||
else if(H.gender == FEMALE)
|
||||
t_him = "Her"
|
||||
return "[uppertext(H.real_name)] as [t_him]self"
|
||||
130
code/modules/credits/credits.html
Normal file
130
code/modules/credits/credits.html
Normal file
@@ -0,0 +1,130 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<style>
|
||||
body {
|
||||
overflow: hidden;
|
||||
background-color: black;
|
||||
color: white;
|
||||
font-family: Georgia, serif
|
||||
}
|
||||
#container {
|
||||
position: relative;
|
||||
width: 100vw;
|
||||
text-align: center;
|
||||
}
|
||||
#splash {
|
||||
display: table-cell;
|
||||
height: 100vh;
|
||||
}
|
||||
.crewtable{
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.crewtable td{
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 1.17em;
|
||||
}
|
||||
.actorname {
|
||||
text-align: right;
|
||||
float: right;
|
||||
}
|
||||
.actorsegue {
|
||||
text-align: center;
|
||||
width: 40px;
|
||||
}
|
||||
.actorrole {
|
||||
float: left;
|
||||
text-align: left;
|
||||
}
|
||||
.letterboxer {
|
||||
width: 10%;
|
||||
}
|
||||
.disclaimers {
|
||||
font-family: Arial, Helvetica, sans-serif
|
||||
}
|
||||
h1, h2, h3 {
|
||||
display: inline;
|
||||
font-weight:normal;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table id="container"> <!-- Yes we use a table to center ourselves. StackOverflow says this is not acceptable practice past 2012 but we're operating with 2009 tech so... !-->
|
||||
<tr>
|
||||
<td class="letterboxer"></td>
|
||||
<td id="splash">
|
||||
IF YOU CAN SEE THIS, TELL A CODER WHAT HAPPENED!
|
||||
</td>
|
||||
<td class="letterboxer"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="letterboxer"></td>
|
||||
<td id="marquee">
|
||||
IF YOU CAN SEE THIS, REALLY TELL A CODER WHAT HAPPENED!
|
||||
</td>
|
||||
<td class="letterboxer"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<script type="text/javascript">
|
||||
var producers = [];
|
||||
var lastinterval;
|
||||
|
||||
function setScrollingText(text){
|
||||
document.getElementById("marquee").innerHTML = text;
|
||||
}
|
||||
function setProducers(text){
|
||||
producers = text.split("%n");
|
||||
producers = producers.slice(0, -1); //get rid of the last %n
|
||||
}
|
||||
function makeCredits(scrollyString, producersString, scrollSpeed, splashTime){
|
||||
if (splashTime === undefined) {
|
||||
splashTime = 2000;
|
||||
}
|
||||
splashTime = parseInt(splashTime); //Just in case
|
||||
|
||||
if (scrollSpeed === undefined) {
|
||||
scrollSpeed = 25;
|
||||
}
|
||||
scrollSpeed = parseInt(scrollSpeed); //Just in case
|
||||
|
||||
setScrollingText(scrollyString);
|
||||
setProducers(producersString);
|
||||
|
||||
splashLoop(producers, 0, splashTime);
|
||||
setTimeout(rollMarquee, producers.length*splashTime, scrollSpeed);
|
||||
}
|
||||
|
||||
function splashLoop(arr, index, time) {
|
||||
if (index === arr.length){
|
||||
return;
|
||||
}
|
||||
document.getElementById("splash").innerHTML = arr[index];
|
||||
setTimeout(splashLoop, time, arr, index+1, time)
|
||||
}
|
||||
|
||||
function rollMarquee(speed){
|
||||
var div = document.getElementById("container");
|
||||
var bottom = 0;
|
||||
lastinterval = setInterval(function () {
|
||||
bottom = bottom + 1;
|
||||
div.style.bottom = bottom + "px";
|
||||
if(bottom > 3000){ //RUNAWAY CREDIT ALART - no seriously this will keep going if the player doesn't close the game between rounds
|
||||
//document.documentElement.innerHTML = "<textarea rows='4' cols='50'>" + document.documentElement.innerHTML + "</textarea>"; clearInterval(lastinterval); return; //debugging
|
||||
clearInterval(lastinterval);
|
||||
window.location = 'byond://winset?id=mapwindow.credits;is-visible=false';
|
||||
return;
|
||||
}
|
||||
}, speed);
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
45
code/modules/credits/episode_name.dm
Normal file
45
code/modules/credits/episode_name.dm
Normal file
@@ -0,0 +1,45 @@
|
||||
/datum/episode_name
|
||||
var/thename = ""
|
||||
var/reason = "Default episode name." //Explanation on why this episode name fits this round. For the admin panel.
|
||||
var/weight = 100 //50 will have 50% the chance of being picked. 200 will have 200% the chance of being picked. etc
|
||||
|
||||
/datum/episode_name/New(var/thename, var/reason, var/weight)
|
||||
if(!thename)
|
||||
return
|
||||
src.thename = thename
|
||||
if(reason)
|
||||
src.reason = reason
|
||||
if(weight)
|
||||
src.weight = weight
|
||||
|
||||
/datum/episode_name/proc/make_div(var/admindatum) //This is just for the admin panel.
|
||||
. = "[weight]% <a href='?src=\ref[admindatum];credits=namedatumweight;nameref=\ref[src]'>(Set)</a> - "
|
||||
. += "[thename] - <a href='?src=\ref[admindatum];credits=namedatumedit;nameref=\ref[src]'>(Edit)</a> "
|
||||
. += "<a href='?src=\ref[admindatum];credits=namedatumremove;nameref=\ref[src]'>(Remove)</a> "
|
||||
. += "<span title='[reason]'>(?)</span>"
|
||||
|
||||
/datum/credits/proc/draft_episode_names()
|
||||
episode_names += new /datum/episode_name("THE [pick("DOWNFALL OF", "RISE OF", "TROUBLE WITH", "FINAL STAND OF", "DARK SIDE OF")] [pick("SPACEMEN", "HUMANITY", "DIGNITY", "SANITY", "THE CHIMPANZEES", "THE VENDOMAT PRICES","[uppertext(station_name())]")]")
|
||||
episode_names += new /datum/episode_name("THE CREW GETS [pick("RACIST", "PICKLED", "AN INCURABLE DISEASE", "PIZZA", "A VALUABLE HISTORY LESSON", "A BREAK", "HIGH", "TO LIVE", "TO RELIVE THEIR CHILDHOOD", "EMBROILED IN CIVIL WAR", "SERIOUS ABOUT [pick("DRUG ABUSE", "CRIME", "PRODUCTIVITY", "ANCIENT AMERICAN CARTOONS", "SPACEBALL")]")]")
|
||||
episode_names += new /datum/episode_name("THE CREW LEARNS ABOUT [pick("LOVE", "DRUGS", "THE DANGERS OF MONEY LAUNDERING", "SPACE 'NAM", "INVESTMENT FRAUD", "KELOTANE ABUSE", "RADIATION PROTECTION", "SACRED GEOMETRY", "STRING THEORY", "ABSTRACT MATHEMATICS", "[pick("CATBEAST", "DIONAN", "PLASMAMAN", "VOX", "GREY")] MATING RITUALS", "ANCIENT CHINESE MEDICINE","LAWSETS")]")
|
||||
episode_names += new /datum/episode_name("[pick("MUCH ADO ABOUT NOTHING", "WHAT HAPPENS WHEN YOU MIX MOMMIS AND COMMERCIAL-GRADE PACKING FOAM", "ATTACK! ATTACK! ATTACK!", "SEX BOMB", "THE BALLAD OF [uppertext(station_name())]")]")
|
||||
episode_names += new /datum/episode_name("[pick("SPACE", "SEXY", "DRAGON", "WARLOCK", "LAUNDRY", "GUN", "ADVERTISING", "DOG", "CARBON MONOXIDE", "NINJA", "WIZARD", "SOCRATIC", "JUVENILE DELIQUENCY", "POLITICALLY MOTIVATED", "RADTACULAR SICKNASTY")] [pick("QUEST", "FORCE", "ADVENTURE")]")
|
||||
episode_names += new /datum/episode_name("[pick("THE DAY [uppertext(station_name())] STOOD STILL", "HUNT FOR THE GREEN WEENIE", "ALIEN VS VENDOMAT", "SPACE TRACK")]")
|
||||
if(SNOW_THEME)
|
||||
episode_names += new /datum/episode_name("A VERY [pick("NANOTRASEN", "EXPEDITIONARY", "SECURE", "PLASMA", "MARTIAN")] CHRISTMAS", "'Tis the season.", 500)
|
||||
if(score["gunsspawned"] > 0)
|
||||
episode_names += new /datum/episode_name("GUNS, GUNS EVERYWHERE", "[score["gunsspawned"]] guns were spawned this round.", max(100, score["gunsspawned"]*10))
|
||||
if(score["richestcash"] > 30000)
|
||||
episode_names += new /datum/episode_name("THE IRRESISTIBLE RISE OF [uppertext(score["richestname"])]", "Scrooge Mc[score["richestkey"]] racked up [score["richestcash"]] credits this round.", max(100, score["richestcash"]/300))
|
||||
if(score["deadaipenalty"] > 2)
|
||||
episode_names += new /datum/episode_name("THE ONE WHERE [score["deadaipenalty"]] AIS DIE", "That's a lot of dead AIs.", max(100, score["deadaipenalty"]*50))
|
||||
if(score["deadcrew"] == 0)
|
||||
episode_names += new /datum/episode_name("[pick("EMPLOYEE TRANSFER", "PEACE AND QUIET IN [uppertext(station_name())]", "THE CREW TRIES TO KILL A FLY FOR [round(score["time"]/60)] MINUTES")]", "No-one died this round.", 200)
|
||||
if(score["escapees"] == 0 && emergency_shuttle.location == CENTCOMM_Z)
|
||||
episode_names += new /datum/episode_name("[pick("DEAD SPACE", "THE CREW GOES MISSING", "A ONE-WAY TICKET TO FLAVORTOWN")]", "There were no escapees on the shuttle.", 200)
|
||||
if(score["slips"] > 100)
|
||||
episode_names += new /datum/episode_name("THE CREW GOES BANANAS", "[score["slips"]] people slipped this round.", min(200, score["slips"]/2))
|
||||
for(var/mob/living/simple_animal/corgi/C in living_mob_list)
|
||||
if(C.spell_list.len > 0)
|
||||
episode_names += new /datum/episode_name("[pick("A VERY MAGICAL DAY", "IAN SAYS", "IAN'S DAY OUT", "CORGI MAGIC")]", "You know what you did.", 300)
|
||||
break
|
||||
@@ -227,6 +227,7 @@
|
||||
var/mob/living/carbon/human/H = new /mob/living/carbon/human(src, R.dna.species, delay_ready_dna = TRUE)
|
||||
occupant = H
|
||||
H.times_cloned = R.times_cloned +1
|
||||
H.talkcount = R.talkcount
|
||||
|
||||
if(!connected.emagged)
|
||||
icon_state = "pod_1"
|
||||
|
||||
@@ -495,6 +495,7 @@
|
||||
R.types=DNA2_BUF_UI|DNA2_BUF_UE|DNA2_BUF_SE
|
||||
R.languages = subject.languages.Copy()
|
||||
R.times_cloned = subject.times_cloned
|
||||
R.talkcount = subject.talkcount
|
||||
|
||||
//Add an implant if needed
|
||||
var/obj/item/weapon/implant/health/imp = locate(/obj/item/weapon/implant/health, subject)
|
||||
|
||||
@@ -91,4 +91,5 @@
|
||||
var/show_client_status_on_examine = TRUE //If false, don't display catatonic/braindead messages to non-admins
|
||||
|
||||
var/become_zombie_after_death = FALSE
|
||||
var/times_cloned = 0 //How many times this person has been cloned
|
||||
var/times_cloned = 0 //How many times this person has been cloned
|
||||
var/talkcount = 0 // How many times a person has talked - used for determining who's been the "star" for the purposes of round end credits
|
||||
|
||||
@@ -247,6 +247,10 @@ var/list/department_radio_keys = list(
|
||||
for (var/atom/movable/listener in listening_nonmobs)
|
||||
listener.Hear(speech, rendered)
|
||||
|
||||
/mob/living/carbon/human/send_speech(var/datum/speech/speech, var/message_range=7, var/bubble_type)
|
||||
talkcount++
|
||||
. = ..()
|
||||
|
||||
/mob/living/proc/say_test(var/text)
|
||||
var/ending = copytext(text, length(text))
|
||||
if (ending == "?")
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
icon_living = "cat"
|
||||
icon_dead = "cat_dead"
|
||||
gender = FEMALE
|
||||
is_pet = TRUE
|
||||
|
||||
/mob/living/simple_animal/cat/Proc
|
||||
name = "Proc"
|
||||
@@ -152,4 +153,4 @@ var/list/wizard_snakes = list()
|
||||
/mob/living/simple_animal/cat/snek/wizard/Destroy()
|
||||
wizard_snakes[src] = null
|
||||
wizard_snakes -= src
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -472,6 +472,7 @@
|
||||
response_disarm = "bops"
|
||||
response_harm = "kicks"
|
||||
spin_emotes = list("dances around","chases his tail")
|
||||
is_pet = TRUE
|
||||
|
||||
/mob/living/simple_animal/corgi/Ian/santa
|
||||
name = "Santa's Corgi Helper"
|
||||
@@ -631,6 +632,7 @@
|
||||
icon_living = "doby"
|
||||
icon_dead = "doby_dead"
|
||||
spin_emotes = list("prances around","chases her nub of a tail")
|
||||
is_pet = TRUE
|
||||
|
||||
species_type = /mob/living/simple_animal/corgi/sasha
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/animal
|
||||
|
||||
@@ -859,6 +859,7 @@
|
||||
name = "Poly"
|
||||
desc = "Poly the Parrot. An expert on quantum cracker theory."
|
||||
speak = list("Poly wanna cracker!", ":e Check the singlo, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN HARDSUITS?",":e OH GOD ITS FREE CALL THE SHUTTLE")
|
||||
is_pet = TRUE
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/New()
|
||||
ears = new /obj/item/device/radio/headset/headset_eng(src)
|
||||
|
||||
@@ -72,7 +72,7 @@ var/global/list/animal_count = list() //Stores types, and amount of animals of t
|
||||
var/melee_damage_type = BRUTE
|
||||
var/attacktext = "attacks"
|
||||
var/attack_sound = null
|
||||
var/friendly = "nuzzles" //If the mob does no damage with it's attack
|
||||
var/friendly = "nuzzles" //If the mob does no damage with its attack
|
||||
// var/environment_smash = 0 //Set to 1 to allow breaking of crates,lockers,racks,tables; 2 for walls; 3 for Rwalls
|
||||
var/environment_smash_flags = 0
|
||||
|
||||
@@ -100,6 +100,8 @@ var/global/list/animal_count = list() //Stores types, and amount of animals of t
|
||||
var/life_tick = 0
|
||||
var/list/colourmatrix = list()
|
||||
|
||||
var/is_pet = FALSE //We're somebody's precious, precious pet.
|
||||
|
||||
/mob/living/simple_animal/apply_beam_damage(var/obj/effect/beam/B)
|
||||
var/lastcheck=last_beamchecks["\ref[B]"]
|
||||
|
||||
|
||||
@@ -269,26 +269,11 @@ var/savefile/panicfile
|
||||
Master.Shutdown()
|
||||
paperwork_stop()
|
||||
|
||||
spawn()
|
||||
world << sound(pick(
|
||||
'sound/AI/newroundsexy.ogg',
|
||||
'sound/misc/RoundEndSounds/apcdestroyed.ogg',
|
||||
'sound/misc/RoundEndSounds/bangindonk.ogg',
|
||||
'sound/misc/RoundEndSounds/slugmissioncomplete.ogg',
|
||||
'sound/misc/RoundEndSounds/bayojingle.ogg',
|
||||
'sound/misc/RoundEndSounds/gameoveryeah.ogg',
|
||||
'sound/misc/RoundEndSounds/rayman.ogg',
|
||||
'sound/misc/RoundEndSounds/marioworld.ogg',
|
||||
'sound/misc/RoundEndSounds/soniclevelcomplete.ogg',
|
||||
'sound/misc/RoundEndSounds/calamitytrigger.ogg',
|
||||
'sound/misc/RoundEndSounds/duckgame.ogg',
|
||||
'sound/misc/RoundEndSounds/FTLvictory.ogg',
|
||||
'sound/misc/RoundEndSounds/tfvictory.ogg',
|
||||
'sound/misc/RoundEndSounds/megamanX.ogg',
|
||||
'sound/misc/RoundEndSounds/castlevania.ogg',
|
||||
)) // random end sounds!! - LastyBatsy
|
||||
if(!end_credits.generated)
|
||||
end_credits.on_roundend()
|
||||
end_credits.rollem()
|
||||
|
||||
sleep(5)//should fix the issue of players not hearing the restart sound.
|
||||
sleep(end_credits.starting_delay + 10)
|
||||
|
||||
for(var/client/C in clients)
|
||||
if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite
|
||||
|
||||
@@ -296,6 +296,10 @@ RENDERS_URL http://ss13.pomf.se/img/map-renders
|
||||
## Uncomment to disable generation of minimaps (makes the server start faster!)
|
||||
SKIP_MINIMAP_GENERATION
|
||||
|
||||
## SKIP_HOLOMINIMAP_GENERATION
|
||||
## Uncomment to disable generation of holominimaps (makes the server start faster!)
|
||||
SKIP_HOLOMINIMAP_GENERATION
|
||||
|
||||
## SKIP_VAULT_GENERATION
|
||||
## Uncomment to disable generation of vaults (makes the server start faster!)
|
||||
SKIP_VAULT_GENERATION
|
||||
|
||||
BIN
icons/credits/1zas.png
Normal file
BIN
icons/credits/1zas.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
BIN
icons/credits/2cluck.png
Normal file
BIN
icons/credits/2cluck.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
BIN
icons/credits/3MPAOSA.png
Normal file
BIN
icons/credits/3MPAOSA.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
@@ -816,6 +816,17 @@ window "mapwindow"
|
||||
text-color = none
|
||||
is-default = true
|
||||
saved-params = "icon-size"
|
||||
elem "credits"
|
||||
type = BROWSER
|
||||
pos = 0,0
|
||||
size = 640x480
|
||||
anchor1 = 0,0
|
||||
anchor2 = 100,100
|
||||
text-color = #ffffff
|
||||
background-color = #000000
|
||||
is-visible = false
|
||||
saved-params = ""
|
||||
auto-format = false
|
||||
|
||||
window "outputwindow"
|
||||
elem "outputwindow"
|
||||
@@ -1063,4 +1074,3 @@ window "window1"
|
||||
background-color = #fffdd0
|
||||
border = sunken
|
||||
saved-params = "max-lines"
|
||||
|
||||
|
||||
BIN
sound/music/Frolic_Luciano_Michelini.ogg
Normal file
BIN
sound/music/Frolic_Luciano_Michelini.ogg
Normal file
Binary file not shown.
BIN
sound/music/Frolic_Luciano_Michelini_Short.ogg
Normal file
BIN
sound/music/Frolic_Luciano_Michelini_Short.ogg
Normal file
Binary file not shown.
@@ -1328,6 +1328,9 @@
|
||||
#include "code\modules\components\ai\target_holders\target_holder.dm"
|
||||
#include "code\modules\context_click\context_click.dm"
|
||||
#include "code\modules\context_click\remote.dm"
|
||||
#include "code\modules\credits\credit_disclaimers.dm"
|
||||
#include "code\modules\credits\credits.dm"
|
||||
#include "code\modules\credits\episode_name.dm"
|
||||
#include "code\modules\customitems\item_spawning.dm"
|
||||
#include "code\modules\customitems\definitions\base.dm"
|
||||
#include "code\modules\customitems\definitions\N3X15.dm"
|
||||
|
||||
Reference in New Issue
Block a user