From 50c4c120baae1f6c78f5e724e3dc55dd535fc43b Mon Sep 17 00:00:00 2001 From: Cael_Aislinn Date: Sat, 15 Dec 2012 12:39:22 +1000 Subject: [PATCH] space ninja candidates have a timed popup asking the player if they accept (using ShadowDarke's sd_Alert), minor formatting cleanups Signed-off-by: Cael_Aislinn --- baystation12.dme | 1 + code/defines/procs/sd_Alert.dm | 168 ++++++++++++++++++++++ code/game/gamemodes/events.dm | 19 ++- code/game/gamemodes/events/space_ninja.dm | 39 +++-- 4 files changed, 206 insertions(+), 21 deletions(-) create mode 100644 code/defines/procs/sd_Alert.dm diff --git a/baystation12.dme b/baystation12.dme index bdbb2ffbcb..18ee361f93 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -397,6 +397,7 @@ #include "code\defines\procs\icon_procs_readme.dm" #include "code\defines\procs\logging.dm" #include "code\defines\procs\religion_name.dm" +#include "code\defines\procs\sd_Alert.dm" #include "code\defines\procs\station_name.dm" #include "code\defines\procs\statistics.dm" #include "code\defines\procs\syndicate_name.dm" diff --git a/code/defines/procs/sd_Alert.dm b/code/defines/procs/sd_Alert.dm new file mode 100644 index 0000000000..c63cab8f8b --- /dev/null +++ b/code/defines/procs/sd_Alert.dm @@ -0,0 +1,168 @@ +/* sd_Alert library + by Shadowdarke (shadowdarke@byond.com) + + sd_Alert() is a powerful and flexible alternative to the built in BYOND + alert() proc. sd_Alert offers timed popups, unlimited buttons, custom + appearance, and even the option to popup without stealing keyboard focus + from the map or command line. + + Please see demo.dm for detailed examples. + +FORMAT + sd_Alert(who, message, title, buttons, default, duration, unfocus, \ + size, table, style, tag, select, flags) + +ARGUMENTS + who - the client or mob to display the alert to. + message - text message to display + title - title of the alert box + buttons - list of buttons + Default Value: list("Ok") + default - default button selestion + Default Value: the first button in the list + duration - the number of ticks before this alert expires. If not + set, the alert lasts until a button is clicked. + Default Value: 0 (unlimited) + unfocus - if this value is set, the popup will not steal keyboard + focus from the map or command line. + Default Value: 1 (do not take focus) + size - size of the popup window in px + Default Value: "300x200" + table - optional parameters for the HTML table in the alert + Default Value: "width=100% height=100%" (fill the window) + style - optional style sheet information + tag - lets you specify a certain tag for this sd_Alert so you may manipulate it + externally. (i.e. force the alert to close, change options and redisplay, + reuse the same window, etc.) + select - if set, the buttons will be replaced with a selection box with a number of + lines displayed equal to this value. + Default value: 0 (use buttons) + flags - optional flags effecting the alert display. These flags may be ORed (|) + together for multiple effects. + SD_ALERT_SCROLL = display a scrollbar + SD_ALERT_SELECT_MULTI = forces selection box display (instead of + buttons) allows the user to select multiple + choices. + SD_ALERT_LINKS = display each choice as a plain text link. + Any selection box style overrides this flag. + SD_ALERT_NOVALIDATE = don't validate responses + Default value: SD_ALERT_SCROLL + (button display with scroll bar, validate responses) +RETURNS + The text of the selected button, or null if the alert duration expired + without a button click. + +Version 1 changes (from version 0): +* Added the tag, select, and flags arguments, thanks to several suggestions from Foomer. +* Split the sd_Alert/Alert() proc into New(), Display(), and Response() to allow more + customization by developers. Primarily developers would want to use Display() to change + the display of active tagged windows + +*/ + + +#define SD_ALERT_SCROLL 1 +#define SD_ALERT_SELECT_MULTI 2 +#define SD_ALERT_LINKS 4 +#define SD_ALERT_NOVALIDATE 8 + +proc/sd_Alert(client/who, message, title, buttons = list("Ok"),\ + default, duration = 0, unfocus = 1, size = "300x200", \ + table = "width=100% height=100%", style, tag, select, flags = SD_ALERT_SCROLL) + + if(ismob(who)) + var/mob/M = who + who = M.client + if(!istype(who)) CRASH("sd_Alert: Invalid target:[who] (\ref[who])") + + var/sd_alert/T = locate(tag) + if(T) + if(istype(T)) del(T) + else CRASH("sd_Alert: tag \"[tag]\" is already in use by datum '[T]' (type: [T.type])") + T = new(who, tag) + if(duration) + spawn(duration) + if(T) del(T) + return + T.Display(message,title,buttons,default,unfocus,size,table,style,select,flags) + . = T.Response() + +sd_alert + var + client/target + response + list/validation + + Del() + target << browse(null,"window=\ref[src]") + ..() + + New(who, tag) + ..() + target = who + src.tag = tag + + Topic(href,params[]) + if(usr.client != target) return + response = params["clk"] + + proc/Display(message,title,list/buttons,default,unfocus,size,table,style,select,flags) + if(unfocus) spawn() target << browse(null,null) + if(istext(buttons)) buttons = list(buttons) + if(!default) default = buttons[1] + if(!(flags & SD_ALERT_NOVALIDATE)) validation = buttons.Copy() + + var/html = {"[title][style]\ +
[message]
"} + + if(select || (flags & SD_ALERT_SELECT_MULTI)) // select style choices + html += {"
\ + +
" + else if(flags & SD_ALERT_LINKS) // text link style + for(var/b in buttons) + var/list/L = list() + L["clk"] = b + var/html_string=list2params(L) + var/focus + if(b == default) focus = " ID=fcs" + html += "[html_encode(b)]\ +
" + else // button style choices + for(var/b in buttons) + var/list/L = list() + L["clk"] = b + var/html_string=list2params(L) + var/focus + if(b == default) focus = " ID=fcs" + html += " " + + html += "
" + + target << browse(html,"window=\ref[src];size=[size];can_close=0") + + proc/Response() + var/validated + while(!validated) + while(target && !response) // wait for a response + sleep(2) + + if(response && validation) + if(istype(response, /list)) + var/list/L = response - validation + if(L.len) response = null + else validated = 1 + else if(response in validation) validated = 1 + else response=null + else validated = 1 + spawn(2) del(src) + return response diff --git a/code/game/gamemodes/events.dm b/code/game/gamemodes/events.dm index acb669a4a9..de6f670aba 100644 --- a/code/game/gamemodes/events.dm +++ b/code/game/gamemodes/events.dm @@ -21,8 +21,11 @@ /proc/event() event = 1 + if(!sent_ninja_to_station) + choose_space_ninja() + return - var/eventNumbersToPickFrom = list(1,2,4,5,6,7,8,9,10,11,12,13,14, 15) //so ninjas don't cause "empty" events. + var/eventNumbersToPickFrom = list(1,2,4,5,6,7,8,9,10,11,12,13,14,15) //so ninjas don't cause "empty" events. if((world.time/10)>=3600 && toggle_space_ninja && !sent_ninja_to_station)//If an hour has passed, relatively speaking. Also, if ninjas are allowed to spawn and if there is not already a ninja for the round. eventNumbersToPickFrom += 3 @@ -36,7 +39,6 @@ spawn(700) meteor_wave() spawn_meteors() - /*if(2) command_alert("Gravitational anomalies detected on the station. There is no additional data.", "Anomaly Alert") world << sound('sound/AI/granomalies.ogg') @@ -44,8 +46,7 @@ var/obj/effect/bhole/bh = new /obj/effect/bhole( T.loc, 30 ) spawn(rand(50, 300)) del(bh)*/ - /* - if(3) //Leaving the code in so someone can try and delag it, but this event can no longer occur randomly, per SoS's request. --NEO + /*if(3) //Leaving the code in so someone can try and delag it, but this event can no longer occur randomly, per SoS's request. --NEO command_alert("Space-time anomalies detected on the station. There is no additional data.", "Anomaly Alert") world << sound('sound/AI/spanomalies.ogg') var/list/turfs = new @@ -65,14 +66,12 @@ P.icon_state = "anom" P.name = "wormhole" spawn(rand(300,600)) - del(P) - */ - /*if(3) - if((world.time/10)>=3600 && toggle_space_ninja && !sent_ninja_to_station)//If an hour has passed, relatively speaking. Also, if ninjas are allowed to spawn and if there is not already a ninja for the round. - space_ninja_arrival()//Handled in space_ninja.dm. Doesn't announce arrival, all sneaky-like.*/ + del(P)*/ + if(3) + //Handled in space_ninja.dm. Doesn't announce arrival, all sneaky-like. + choose_space_ninja() if(4) mini_blob_event() - if(5) high_radiation_event() if(6) diff --git a/code/game/gamemodes/events/space_ninja.dm b/code/game/gamemodes/events/space_ninja.dm index 7536f9c231..90ac38ca97 100644 --- a/code/game/gamemodes/events/space_ninja.dm +++ b/code/game/gamemodes/events/space_ninja.dm @@ -93,7 +93,33 @@ When I already created about 4 new objectives, this doesn't seem terribly import /var/global/toggle_space_ninja = 1//If ninjas can spawn or not. /var/global/sent_ninja_to_station = 0//If a ninja is already on the station. -/proc/space_ninja_arrival() +/proc/choose_space_ninja() + var/list/candidates = list() //list of candidate keys + for(var/mob/dead/observer/G in player_list) + if(G.client && ((G.client.inactivity/10)/60) <= 5 && G.client.be_spaceninja) + if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) + candidates += G + if(!candidates.len) return + candidates = shuffle(candidates)//Incorporating Donkie's list shuffle + + //loop over all viable candidates, giving them a popup asking if they want to be space ninja + var/mob/dead/observer/accepted_ghost + while(candidates.len && !accepted_ghost) + //ask a different random candidate + var/mob/dead/observer/G = pick(candidates) + //give the popup a 30 second timeout in case the player is AFK + if(sd_Alert(G, "A space ninja is about to spawn. Would you like to play as the ninja?", "Space Ninja", list("Yes","No"), "Yes", 300, 1, "350x125") == "Yes") + accepted_ghost = G + else + candidates -= G + + if(accepted_ghost) + //someone accepted + space_ninja_arrival(accepted_ghost) + +/proc/space_ninja_arrival(var/mob/dead/observer/G) + if(!G) + return choose_space_ninja() var/datum/game_mode/current_mode = ticker.mode var/datum/mind/current_mind @@ -137,18 +163,9 @@ Malf AIs/silicons aren't added. Monkeys aren't added. Messes with objective comp if(L.name == "carpspawn") spawn_list.Add(L) - - var/list/candidates = list() //list of candidate keys - for(var/mob/dead/observer/G in player_list) - if(G.client && !G.client.holder && ((G.client.inactivity/10)/60) <= 5 && G.client.be_spaceninja) - if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) - candidates += G.key - if(!candidates.len) return - candidates = shuffle(candidates)//Incorporating Donkie's list shuffle - //The ninja will be created on the right spawn point or at late join. var/mob/living/carbon/human/new_ninja = create_space_ninja(pick(spawn_list.len ? spawn_list : latejoin )) - new_ninja.key = pick(candidates) + new_ninja.key = G.ckey new_ninja.wear_suit:randomize_param()//Give them a random set of suit parameters. new_ninja.internal = new_ninja.s_store //So the poor ninja has something to breath when they spawn in spess. new_ninja.internals.icon_state = "internal1"