GLOBAL_VAR(scoreboard) // Variable to save the scoreboard string once it's been generated //Thresholds for Score Ratings #define SINGULARITY_DESERVES_BETTER -3500 #define SINGULARITY_FODDER -3000 #define ALL_FIRED -2500 #define WASTE_OF_OXYGEN -2000 #define HEAP_OF_SCUM -1500 #define LAB_MONKEYS -1000 #define UNDESIREABLES -500 #define SERVANTS_OF_SCIENCE 500 #define GOOD_BUNCH 1000 #define MACHINE_THIRTEEN 1500 #define PROMOTIONS_FOR_EVERYONE 2000 #define AMBASSADORS_OF_DISCOVERY 3000 #define PRIDE_OF_SCIENCE 4000 #define NANOTRASEN_FINEST 5000 /datum/scoreboard /// Overall combined score for the whole round. var/crewscore = 0 /// How many useful items have cargo shipped out? var/score_things_shipped = 0 /// How many harvests have hydroponics done? var/score_things_harvested = 0 /// How much ore has been mined on the mining z level? var/score_ore_mined = 0 /// How much research was done by science? var/score_research_done = 0 /// How many random events did the station survive? var/score_events_endured = 0 /// How many APCs have poor charge? var/score_power_loss = 0 /// How many people got out alive? var/score_escapees = 0 /// How many people /didn't/ get out alive? var/score_dead_crew = 0 /// How much blood, puke, stains etc went uncleaned? var/score_mess = 0 /// How many meals were made? var/score_meals = 0 /// How many rampant, uncured diseases are on board the station? var/score_disease = 0 /// How many command members died? (Revolution) var/score_dead_command = 0 /// How many antagonists are alive in the brig? (Nuke ops & Revolution) var/score_arrested = 0 /// How many operatives were killed? (Nuke ops & Revolution) var/score_ops_killed = 0 /// How much noms were had by the crew? var/score_food_eaten = 0 /// How many times was the clown punched, struck, or otherwise maligned? var/score_clown_abuse = 0 // Booleans // /// Were the antagonists successful? var/score_greentext = FALSE /// Did the crew catch all of the antags alive? var/all_arrested = FALSE /// Is the NAD safe and secure? var/disc_secure = FALSE // Points penalties/bonuses // /// If all APCs on the station are running optimally, big bonus. var/power_bonus = FALSE /// If there are no messes on the station anywhere, huge bonus. var/mess_bonus = FALSE /// If the AI is dead, big points penalty. var/dead_ai = FALSE /// Was the station blown into little bits? var/nuked = FALSE /// Points penalty for being blown to little bits. var/nuked_penalty = 0 // Player Stats // /// What was the name of the richest person on the shuttle? var/richest_name = "" /// What was the ckey of the richest person on the shuttle? var/richest_key = "" /// What was the job of the richest person on the shuttle? var/richest_job = "" /// How much money did the richest person on the shuttle have? var/richest_cash = 0 /// What was the name of the most injured person on the shuttle? var/damaged_name /// What was the ckey of the most injured person on the shuttle? var/damaged_key /// What was the job of the most injured person on the shuttle? var/damaged_job /// How damaged was the most injured person on the shuttle? var/damaged_health /datum/scoreboard/proc/scoreboard() // Print a list of antagonists to the server log. log_antags() for(var/_I in GLOB.mob_list) var/mob/M = _I if(is_station_level(M.z)) check_station_player(M) else if(!M.loc) stack_trace("[M] ended up without a location!") else if(SSshuttle.emergency.mode >= SHUTTLE_ENDGAME && istype(get_area(M), SSshuttle.emergency.areaInstance)) check_shuttle_player(M) check_apc_power() check_cleanables() generate_scoreboard() /datum/scoreboard/proc/log_antags() var/list/total_antagonists = list() // Look into all mobs in the world, dead or alive for(var/mind in SSticker.minds) var/datum/mind/M = mind var/role = M.special_role // If they're an antagonist of some sort. if(role) if(total_antagonists[role]) // If the role exists already, add the name to it. total_antagonists[role] += ", [M.name]([M.key])" else // If the role doesn't exist in the list, create it and add the mob total_antagonists[role] += ": [M.name]([M.key])" // Now print them all into the log! log_game("Antagonists at round end were...") for(var/I in total_antagonists) log_game("[I]s[total_antagonists[I]].") /datum/scoreboard/proc/check_station_player(mob/M) if(!is_station_level(M.z) || M.stat != DEAD) return if(isAI(M)) dead_ai = TRUE score_dead_crew++ else if(ishuman(M)) score_dead_crew++ /datum/scoreboard/proc/check_shuttle_player(mob/M) if(!M.mind || M.stat == DEAD || !ishuman(M)) return var/mob/living/carbon/human/H = M score_escapees++ var/cash_score = get_score_person_worth(H) if(cash_score > richest_cash) richest_cash = cash_score richest_name = H.real_name richest_job = H.job richest_key = (H.client?.prefs.toggles2 & PREFTOGGLE_2_ANON) ? "Anon" : H.key var/damage_score = H.getBruteLoss() + H.getFireLoss() + H.getToxLoss() + H.getOxyLoss() if(damage_score > damaged_health) damaged_health = damage_score damaged_name = H.real_name damaged_job = H.job damaged_key = (H.client?.prefs.toggles2 & PREFTOGGLE_2_ANON) ? "Anon" : H.key /// A function to determine the cash plus the account balance of the wealthiest escapee /datum/scoreboard/proc/get_score_person_worth(mob/living/carbon/human/H) if(!H.mind) return // if they have no mind, we don't care // return value of space cash on the person + whatever balance they currently have in their original money account return get_score_container_worth(H) + H.mind.initial_account?.credit_balance /// A recursive function to properly determine the cash on the wealthiest escapee /datum/scoreboard/proc/get_score_container_worth(atom/C, level = 0) . = 0 if(level >= 5) // in case the containers recurse or something return 0 for(var/obj/item/stack/spacecash/cash in C.contents) . += cash.amount for(var/obj/item/storage/S in C.contents) . += .(S, level + 1) /datum/scoreboard/proc/check_apc_power() for(var/_A in GLOB.apcs) var/obj/machinery/power/apc/A = _A if(!is_station_level(A.z)) continue var/obj/item/stock_parts/cell/C = A.cell if(!C || C.charge < 2300) score_power_loss++ //200 charge leeway /datum/scoreboard/proc/check_cleanables() for(var/obj/effect/decal/cleanable/C in world) if(!is_station_level(C.z)) continue if(istype(C, /obj/effect/decal/cleanable/blood/gibs)) score_mess += 3 else if(istype(C, /obj/effect/decal/cleanable/blood)) score_mess += 1 else if(istype(C, /obj/effect/decal/cleanable/vomit)) score_mess += 1 /datum/scoreboard/proc/generate_scoreboard() // Point modifiers var/points_events_endured = score_events_endured * 50 var/points_research_done = score_research_done * 30 var/points_disease = score_disease * 30 var/points_dead_crew = score_dead_crew * 25 var/points_escapees = score_escapees * 25 var/points_power_loss = score_power_loss * 20 var/points_things_harvested = score_things_harvested * 5 var/points_things_shipped = score_things_shipped * 5 var/points_meals = score_meals * 5 var/points_ore_mined = score_ore_mined * 2 // Bonuses crewscore += points_events_endured crewscore += points_research_done crewscore += points_escapees crewscore += points_things_harvested crewscore += points_things_shipped crewscore += points_meals crewscore += points_ore_mined if(!score_power_loss) crewscore += 2500 power_bonus = TRUE if(!score_mess) crewscore += 1500 mess_bonus = TRUE if(all_arrested) // This only seems to be implemented for Rev and Nukies. -DaveKorhal crewscore *= 3 // This needs to be here for the bonus to be applied properly // Penalties crewscore -= points_dead_crew crewscore -= points_power_loss crewscore -= points_disease crewscore -= score_mess if(dead_ai) crewscore -= 250 // Generate the score panel var/list/dat = list("Round Statistics and Score

") if(SSticker.mode) dat += SSticker.mode.get_scoreboard_stats() dat += {" General Statistics
The Good
Ore Mined: [score_ore_mined] ([points_ore_mined] Points)
"} if(score_escapees) dat += "Shuttle Escapees: [score_escapees] ([points_escapees] Points)
" dat += "Whole Station Powered: [power_bonus ? "Yes" : "No"] ([power_bonus * 2500] Points)
" dat += "Whole Station Cleaned: [mess_bonus ? "Yes" : "No"] ([mess_bonus * 1500] Points)

" dat += "The Bad
" dat += "Dead bodies on Station: [score_dead_crew] (-[points_dead_crew] Points)
" if(!mess_bonus) dat += "Uncleaned Messes: [score_mess] (-[score_mess] Points)
" if(!power_bonus) dat += "Station Power Issues: [score_power_loss] (-[points_power_loss] Points)
" dat += {" AI Destroyed: [dead_ai ? "Yes" : "No"] (-[dead_ai * 250] Points)

The Weird
Food Eaten: [score_food_eaten] bites/sips.
Times a Clown was Abused: [score_clown_abuse]

"} if(score_escapees) dat += "Richest Escapee: [richest_name], [richest_job]: $[num2text(richest_cash, 50)] ([richest_key])
" if(damaged_health) dat += "Most Battered Escapee: [damaged_name], [damaged_job]: [damaged_health] damage ([damaged_key])
" else if(SSshuttle.emergency.mode <= SHUTTLE_STRANDED) dat += "The station wasn't evacuated!
" else dat += "No-one escaped!
" dat += SSticker.mode.declare_job_completion() dat += {"

FINAL SCORE: [crewscore]
"} var/score_rating = "The Aristocrats!" switch(crewscore) if(-INFINITY to SINGULARITY_DESERVES_BETTER) score_rating = "Even the Singularity Deserves Better" if(SINGULARITY_DESERVES_BETTER+1 to SINGULARITY_FODDER) score_rating = "Singularity Fodder" if(SINGULARITY_FODDER+1 to ALL_FIRED) score_rating = "You're All Fired" if(ALL_FIRED+1 to WASTE_OF_OXYGEN) score_rating = "A Waste of Perfectly Good Oxygen" if(WASTE_OF_OXYGEN+1 to HEAP_OF_SCUM) score_rating = "A Wretched Heap of Scum and Incompetence" if(HEAP_OF_SCUM+1 to LAB_MONKEYS) score_rating = "Outclassed by Lab Monkeys" if(LAB_MONKEYS+1 to UNDESIREABLES) score_rating = "The Undesirables" if(UNDESIREABLES+1 to SERVANTS_OF_SCIENCE-1) score_rating = "Ambivalently Average" if(SERVANTS_OF_SCIENCE to GOOD_BUNCH-1) score_rating = "Skillful Servants of Science" if(GOOD_BUNCH to MACHINE_THIRTEEN-1) score_rating = "Best of a Good Bunch" if(MACHINE_THIRTEEN to PROMOTIONS_FOR_EVERYONE-1) score_rating = "Lean Mean Machine Thirteen" if(PROMOTIONS_FOR_EVERYONE to AMBASSADORS_OF_DISCOVERY-1) score_rating = "Promotions for Everyone" if(AMBASSADORS_OF_DISCOVERY to PRIDE_OF_SCIENCE-1) score_rating = "Ambassadors of Discovery" if(PRIDE_OF_SCIENCE to NANOTRASEN_FINEST-1) score_rating = "The Pride of Science Itself" if(NANOTRASEN_FINEST to INFINITY) score_rating = "Nanotrasen's Finest" dat += "RATING: [score_rating]" GLOB.scoreboard = jointext(dat, "") for(var/mob/E in GLOB.player_list) if(E.client) to_chat(E, "The crew's final score is:") to_chat(E, "[crewscore]") if(!E.get_preference(PREFTOGGLE_DISABLE_SCOREBOARD)) E << browse(GLOB.scoreboard, "window=roundstats;size=500x600") /datum/game_mode/proc/get_scoreboard_stats() return null /datum/game_mode/proc/set_scoreboard_vars() return null #undef SINGULARITY_DESERVES_BETTER #undef SINGULARITY_FODDER #undef ALL_FIRED #undef WASTE_OF_OXYGEN #undef HEAP_OF_SCUM #undef LAB_MONKEYS #undef UNDESIREABLES #undef SERVANTS_OF_SCIENCE #undef GOOD_BUNCH #undef MACHINE_THIRTEEN #undef PROMOTIONS_FOR_EVERYONE #undef AMBASSADORS_OF_DISCOVERY #undef PRIDE_OF_SCIENCE #undef NANOTRASEN_FINEST