Files
CHOMPStation2/code/modules/mob/new_player/new_player.dm
Leshana f17ea64bbe Enables round-to-round persistence of a few aspects of characters.
* More accurately, it automates updating your character setup.  None of this code does anything you could not already do manually on the Character Setup screen, it simply does it automatically for you.
* Specifically a few things are saved either at round end or when you cryo:
  * Your late-join spawn location is determined by which cryo/elevator/etc you used to leave last time.  Departing thru the elevators will set your spawn location to elevators etc.
  * Your weight is saved (also any extra or deficient nutrition is resolved into weight gain/loss)
  * Your limbs settings are updated based on your status at end of round (whether limbs are normal, missing, robotic, etc)
  * Your markings are saved so they will be the same as when they were at end of round.
* ALL of these changes are optional, toggled on the VORE tab of character setup.
* Replaced hard coded numbers for weight gain with constant defines.
2017-04-04 07:33:09 -04:00

552 lines
19 KiB
Plaintext

//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:33
/mob/new_player
var/ready = 0
var/spawning = 0//Referenced when you want to delete the new_player later on in the code.
var/totalPlayers = 0 //Player counts for the Lobby tab
var/totalPlayersReady = 0
var/datum/browser/panel
universal_speak = 1
invisibility = 101
density = 0
stat = 2
canmove = 0
anchored = 1 // don't get pushed around
/mob/new_player/New()
mob_list += src
/mob/new_player/verb/new_player_panel()
set src = usr
new_player_panel_proc()
/mob/new_player/proc/new_player_panel_proc()
var/output = "<div align='center'>"
output +="<hr>"
output += "<p><a href='byond://?src=\ref[src];show_preferences=1'>Setup Character</A></p>"
if(!ticker || ticker.current_state <= GAME_STATE_PREGAME)
if(ready)
output += "<p>\[ <span class='linkOn'><b>Ready</b></span> | <a href='byond://?src=\ref[src];ready=0'>Not Ready</a> \]</p>"
else
output += "<p>\[ <a href='byond://?src=\ref[src];ready=1'>Ready</a> | <span class='linkOn'><b>Not Ready</b></span> \]</p>"
else
output += "<a href='byond://?src=\ref[src];manifest=1'>View the Crew Manifest</A><br><br>"
output += "<p><a href='byond://?src=\ref[src];late_join=1'>Join Game!</A></p>"
output += "<p><a href='byond://?src=\ref[src];observe=1'>Observe</A></p>"
if(!IsGuestKey(src.key))
establish_db_connection()
if(dbcon.IsConnected())
var/isadmin = 0
if(src.client && src.client.holder)
isadmin = 1
var/DBQuery/query = dbcon.NewQuery("SELECT id FROM erro_poll_question WHERE [(isadmin ? "" : "adminonly = false AND")] Now() BETWEEN starttime AND endtime AND id NOT IN (SELECT pollid FROM erro_poll_vote WHERE ckey = \"[ckey]\") AND id NOT IN (SELECT pollid FROM erro_poll_textreply WHERE ckey = \"[ckey]\")")
query.Execute()
var/newpoll = 0
while(query.NextRow())
newpoll = 1
break
if(newpoll)
output += "<p><b><a href='byond://?src=\ref[src];showpoll=1'>Show Player Polls</A> (NEW!)</b></p>"
else
output += "<p><a href='byond://?src=\ref[src];showpoll=1'>Show Player Polls</A></p>"
if(client.check_for_new_server_news())
output += "<p><b><a href='byond://?src=\ref[src];shownews=1'>Show News</A> (NEW!)</b></p>"
else
output += "<p><a href='byond://?src=\ref[src];shownews=1'>Show News</A></p>"
output += "</div>"
panel = new(src, "Welcome","Welcome", 210, 280, src)
panel.set_window_options("can_close=0")
panel.set_content(output)
panel.open()
return
/mob/new_player/Stat()
..()
if(statpanel("Lobby") && ticker)
if(ticker.hide_mode)
stat("Game Mode:", "Secret")
else
if(ticker.hide_mode == 0)
stat("Game Mode:", "[config.mode_names[master_mode]]") // Old setting for showing the game mode
if(ticker.current_state == GAME_STATE_PREGAME)
stat("Time To Start:", "[ticker.pregame_timeleft][round_progressing ? "" : " (DELAYED)"]")
stat("Players: [totalPlayers]", "Players Ready: [totalPlayersReady]")
totalPlayers = 0
totalPlayersReady = 0
for(var/mob/new_player/player in player_list)
stat("[player.key]", (player.ready)?("(Playing)"):(null))
totalPlayers++
if(player.ready)totalPlayersReady++
/mob/new_player/Topic(href, href_list[])
if(!client) return 0
if(href_list["show_preferences"])
client.prefs.ShowChoices(src)
return 1
if(href_list["ready"])
if(!ticker || ticker.current_state <= GAME_STATE_PREGAME) // Make sure we don't ready up after the round has started
ready = text2num(href_list["ready"])
else
ready = 0
if(href_list["refresh"])
//src << browse(null, "window=playersetup") //closes the player setup window
panel.close()
new_player_panel_proc()
if(href_list["observe"])
if(alert(src,"Are you sure you wish to observe? You will have to wait 1 minute before being able to respawn!","Player Setup","Yes","No") == "Yes")
if(!client) return 1
var/mob/observer/dead/observer = new()
spawning = 1
src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS cant last forever yo
observer.started_as_observer = 1
close_spawn_windows()
var/obj/O = locate("landmark*Observer-Start")
if(istype(O))
src << "<span class='notice'>Now teleporting.</span>"
observer.loc = O.loc
else
src << "<span class='danger'>Could not locate an observer spawn point. Use the Teleport verb to jump to the station map.</span>"
observer.timeofdeath = world.time // Set the time of death so that the respawn timer works correctly.
announce_ghost_joinleave(src)
var/mob/living/carbon/human/dummy/mannequin = new()
client.prefs.dress_preview_mob(mannequin)
observer.appearance = mannequin
observer.alpha = 127
observer.layer = initial(observer.layer)
observer.invisibility = initial(observer.invisibility)
qdel(mannequin)
if(client.prefs.be_random_name)
client.prefs.real_name = random_name(client.prefs.identifying_gender)
observer.real_name = client.prefs.real_name
observer.name = observer.real_name
if(!client.holder && !config.antag_hud_allowed) // For new ghosts we remove the verb from even showing up if it's not allowed.
observer.verbs -= /mob/observer/dead/verb/toggle_antagHUD // Poor guys, don't know what they are missing!
observer.key = key
qdel(src)
return 1
if(href_list["late_join"])
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
usr << "\red The round is either not ready, or has already finished..."
return
/*
if(client.prefs.species != "Human" && !check_rights(R_ADMIN, 0)) //VORESTATION EDITS: THE COMMENTED OUT AREAS FROM LINE 154 TO 178
if (config.usealienwhitelist)
if(!is_alien_whitelisted(src, client.prefs.species))
src << alert("You are currently not whitelisted to Play [client.prefs.species].")
return 0
*/
LateChoices()
if(href_list["manifest"])
ViewManifest()
if(href_list["SelectedJob"])
if(!config.enter_allowed)
usr << "<span class='notice'>There is an administrative lock on entering the game!</span>"
return
else if(ticker && ticker.mode && ticker.mode.explosion_in_progress)
usr << "<span class='danger'>The station is currently exploding. Joining would go poorly.</span>"
return
/*
if(!is_alien_whitelisted(src, all_species[client.prefs.species]))
src << alert("You are currently not whitelisted to play [client.prefs.species].")
return 0
*/
var/datum/species/S = all_species[client.prefs.species]
if(!(S.spawn_flags & SPECIES_CAN_JOIN))
src << alert("Your current species, [client.prefs.species], is not available for play on the station.")
return 0
AttemptLateSpawn(href_list["SelectedJob"],client.prefs.spawnpoint)
return
if(href_list["privacy_poll"])
establish_db_connection()
if(!dbcon.IsConnected())
return
var/voted = 0
//First check if the person has not voted yet.
var/DBQuery/query = dbcon.NewQuery("SELECT * FROM erro_privacy WHERE ckey='[src.ckey]'")
query.Execute()
while(query.NextRow())
voted = 1
break
//This is a safety switch, so only valid options pass through
var/option = "UNKNOWN"
switch(href_list["privacy_poll"])
if("signed")
option = "SIGNED"
if("anonymous")
option = "ANONYMOUS"
if("nostats")
option = "NOSTATS"
if("later")
usr << browse(null,"window=privacypoll")
return
if("abstain")
option = "ABSTAIN"
if(option == "UNKNOWN")
return
if(!voted)
var/sql = "INSERT INTO erro_privacy VALUES (null, Now(), '[src.ckey]', '[option]')"
var/DBQuery/query_insert = dbcon.NewQuery(sql)
query_insert.Execute()
usr << "<b>Thank you for your vote!</b>"
usr << browse(null,"window=privacypoll")
if(!ready && href_list["preference"])
if(client)
client.prefs.process_link(src, href_list)
else if(!href_list["late_join"])
new_player_panel()
if(href_list["showpoll"])
handle_player_polling()
return
if(href_list["pollid"])
var/pollid = href_list["pollid"]
if(istext(pollid))
pollid = text2num(pollid)
if(isnum(pollid))
src.poll_player(pollid)
return
if(href_list["votepollid"] && href_list["votetype"])
var/pollid = text2num(href_list["votepollid"])
var/votetype = href_list["votetype"]
switch(votetype)
if("OPTION")
var/optionid = text2num(href_list["voteoptionid"])
vote_on_poll(pollid, optionid)
if("TEXT")
var/replytext = href_list["replytext"]
log_text_poll_reply(pollid, replytext)
if("NUMVAL")
var/id_min = text2num(href_list["minid"])
var/id_max = text2num(href_list["maxid"])
if( (id_max - id_min) > 100 ) //Basic exploit prevention
usr << "The option ID difference is too big. Please contact administration or the database admin."
return
for(var/optionid = id_min; optionid <= id_max; optionid++)
if(!isnull(href_list["o[optionid]"])) //Test if this optionid was replied to
var/rating
if(href_list["o[optionid]"] == "abstain")
rating = null
else
rating = text2num(href_list["o[optionid]"])
if(!isnum(rating))
return
vote_on_numval_poll(pollid, optionid, rating)
if("MULTICHOICE")
var/id_min = text2num(href_list["minoptionid"])
var/id_max = text2num(href_list["maxoptionid"])
if( (id_max - id_min) > 100 ) //Basic exploit prevention
usr << "The option ID difference is too big. Please contact administration or the database admin."
return
for(var/optionid = id_min; optionid <= id_max; optionid++)
if(!isnull(href_list["option_[optionid]"])) //Test if this optionid was selected
vote_on_poll(pollid, optionid, 1)
if(href_list["shownews"])
handle_server_news()
return
/mob/new_player/proc/handle_server_news()
if(!client)
return
var/savefile/F = get_server_news()
if(F)
client.prefs.lastnews = md5(F["body"])
client.prefs.save_preferences()
var/dat = "<html><body><center>"
dat += "<h1>[F["title"]]</h1>"
dat += "<br>"
dat += "[F["body"]]"
dat += "<br>"
dat += "<font size='2'><i>Last written by [F["author"]], on [F["timestamp"]].</i></font>"
dat += "</center></body></html>"
var/datum/browser/popup = new(src, "Server News", "Server News", 450, 300, src)
popup.set_content(dat)
popup.open()
/mob/new_player/proc/IsJobAvailable(rank)
var/datum/job/job = job_master.GetJob(rank)
if(!job) return 0
if(!job.is_position_available()) return 0
if(jobban_isbanned(src,rank)) return 0
if(!job.player_old_enough(src.client)) return 0
if(!is_job_whitelisted(src,rank)) return 0 //VOREStation Code
return 1
/mob/new_player/proc/AttemptLateSpawn(rank,var/spawning_at)
if (src != usr)
return 0
if(!ticker || ticker.current_state != GAME_STATE_PLAYING)
usr << "\red The round is either not ready, or has already finished..."
return 0
if(!config.enter_allowed)
usr << "<span class='notice'>There is an administrative lock on entering the game!</span>"
return 0
if(!IsJobAvailable(rank))
src << alert("[rank] is not available. Please try another.")
return 0
if (!attempt_vr(src,"spawn_checks_vr",list())) return 0 // VOREStation Insert
spawning = 1
close_spawn_windows()
job_master.AssignRole(src, rank, 1)
var/mob/living/character = create_character() //creates the human and transfers vars and mind
character = job_master.EquipRank(character, rank, 1) //equips the human
UpdateFactionList(character)
// AIs don't need a spawnpoint, they must spawn at an empty core
if(character.mind.assigned_role == "AI")
character = character.AIize(move=0) // AIize the character, but don't move them yet
// IsJobAvailable for AI checks that there is an empty core available in this list
var/obj/structure/AIcore/deactivated/C = empty_playable_ai_cores[1]
empty_playable_ai_cores -= C
character.loc = C.loc
AnnounceCyborg(character, rank, "has been downloaded to the empty core in \the [character.loc.loc]")
ticker.mode.latespawn(character)
qdel(C)
qdel(src)
return
//Find our spawning point.
var/join_message = job_master.LateSpawn(character, rank)
// Equip our custom items only AFTER deploying to spawn points eh?
equip_custom_items(character)
character.lastarea = get_area(loc)
// Moving wheelchair if they have one
if(character.buckled && istype(character.buckled, /obj/structure/bed/chair/wheelchair))
character.buckled.loc = character.loc
character.buckled.set_dir(character.dir)
ticker.mode.latespawn(character)
if(character.mind.assigned_role != "Cyborg")
data_core.manifest_inject(character)
ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn
//Grab some data from the character prefs for use in random news procs.
AnnounceArrival(character, rank, join_message)
else
AnnounceCyborg(character, rank, join_message)
qdel(src)
/mob/new_player/proc/AnnounceCyborg(var/mob/living/character, var/rank, var/join_message)
if (ticker.current_state == GAME_STATE_PLAYING)
if(character.mind.role_alt_title)
rank = character.mind.role_alt_title
// can't use their name here, since cyborg namepicking is done post-spawn, so we'll just say "A new Cyborg has arrived"/"A new Android has arrived"/etc.
global_announcer.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer")
/mob/new_player/proc/LateChoices()
var/name = client.prefs.be_random_name ? "friend" : client.prefs.real_name
var/dat = "<html><body><center>"
dat += "<b>Welcome, [name].<br></b>"
dat += "Round Duration: [roundduration2text()]<br>"
if(emergency_shuttle) //In case NanoTrasen decides reposess CentCom's shuttles.
if(emergency_shuttle.going_to_centcom()) //Shuttle is going to centcomm, not recalled
dat += "<font color='red'><b>The station has been evacuated.</b></font><br>"
if(emergency_shuttle.online())
if (emergency_shuttle.evac) // Emergency shuttle is past the point of no recall
dat += "<font color='red'>The station is currently undergoing evacuation procedures.</font><br>"
else // Crew transfer initiated
dat += "<font color='red'>The station is currently undergoing crew transfer procedures.</font><br>"
dat += "Choose from the following open/valid positions:<br>"
for(var/datum/job/job in job_master.occupations)
if(job && IsJobAvailable(job.title))
if(job.minimum_character_age && (client.prefs.age < job.minimum_character_age))
continue
var/active = 0
// Only players with the job assigned and AFK for less than 10 minutes count as active
for(var/mob/M in player_list) if(M.mind && M.client && M.mind.assigned_role == job.title && M.client.inactivity <= 10 * 60 * 10)
active++
dat += "<a href='byond://?src=\ref[src];SelectedJob=[job.title]'>[job.title] ([job.current_positions]) (Active: [active])</a><br>"
dat += "</center>"
src << browse(dat, "window=latechoices;size=300x640;can_close=1")
/mob/new_player/proc/create_character()
if (!attempt_vr(src,"spawn_checks_vr",list())) return 0 // VOREStation Insert
spawning = 1
close_spawn_windows()
var/mob/living/carbon/human/new_character
var/use_species_name
var/datum/species/chosen_species
if(client.prefs.species)
chosen_species = all_species[client.prefs.species]
use_species_name = chosen_species.get_station_variant() //Only used by pariahs atm.
if(chosen_species && use_species_name)
// Have to recheck admin due to no usr at roundstart. Latejoins are fine though.
if(is_alien_whitelisted(chosen_species))
new_character = new(loc, use_species_name)
if(!new_character)
new_character = new(loc)
new_character.lastarea = get_area(loc)
if(ticker.random_players)
new_character.gender = pick(MALE, FEMALE)
client.prefs.real_name = random_name(new_character.gender)
client.prefs.randomize_appearance_and_body_for(new_character)
else
client.prefs.copy_to(new_character)
src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS cant last forever yo
if(mind)
mind.active = 0 //we wish to transfer the key manually
if(mind.assigned_role == "Clown") //give them a clownname if they are a clown
new_character.real_name = pick(clown_names) //I hate this being here of all places but unfortunately dna is based on real_name!
new_character.rename_self("clown")
mind.original = new_character
// VOREStation
mind.loaded_from_ckey = client.ckey
mind.loaded_from_slot = client.prefs.default_slot
// VOREStation
mind.transfer_to(new_character) //won't transfer key since the mind is not active
new_character.name = real_name
new_character.dna.ready_dna(new_character)
new_character.dna.b_type = client.prefs.b_type
new_character.sync_organ_dna()
if(client.prefs.disabilities)
// Set defer to 1 if you add more crap here so it only recalculates struc_enzymes once. - N3X
new_character.dna.SetSEState(GLASSESBLOCK,1,0)
new_character.disabilities |= NEARSIGHTED
for(var/lang in client.prefs.alternate_languages)
var/datum/language/chosen_language = all_languages[lang]
if(chosen_language)
if(is_lang_whitelisted(src,chosen_language) || (new_character.species && (chosen_language.name in new_character.species.secondary_langs)))
new_character.add_language(lang)
// And uncomment this, too.
//new_character.dna.UpdateSE()
// Do the initial caching of the player's body icons.
new_character.force_update_limbs()
new_character.update_eyes()
new_character.regenerate_icons()
new_character.key = key //Manually transfer the key to log them in
return new_character
/mob/new_player/proc/ViewManifest()
var/dat = "<div align='center'>"
dat += data_core.get_manifest(OOC = 1)
//src << browse(dat, "window=manifest;size=370x420;can_close=1")
var/datum/browser/popup = new(src, "Crew Manifest", "Crew Manifest", 370, 420, src)
popup.set_content(dat)
popup.open()
/mob/new_player/Move()
return 0
/mob/new_player/proc/close_spawn_windows()
src << browse(null, "window=latechoices") //closes late choices window
//src << browse(null, "window=playersetup") //closes the player setup window
panel.close()
/mob/new_player/proc/has_admin_rights()
return check_rights(R_ADMIN, 0, src)
/mob/new_player/get_species()
var/datum/species/chosen_species
if(client.prefs.species)
chosen_species = all_species[client.prefs.species]
if(!chosen_species)
return "Human"
if(is_alien_whitelisted(chosen_species))
return chosen_species.name
return "Human"
/mob/new_player/get_gender()
if(!client || !client.prefs) ..()
return client.prefs.biological_gender
/mob/new_player/is_ready()
return ready && ..()
// Prevents lobby players from seeing say, even with ghostears
/mob/new_player/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "",var/italics = 0, var/mob/speaker = null)
return
// Prevents lobby players from seeing emotes, even with ghosteyes
/mob/new_player/show_message(msg, type, alt, alt_type)
return
/mob/new_player/hear_radio()
return
/mob/new_player/MayRespawn()
return 1