diff --git a/code/game/gamemodes/wizard/raginmages.dm b/code/game/gamemodes/wizard/raginmages.dm
index 30af14862cd..d2818448736 100644
--- a/code/game/gamemodes/wizard/raginmages.dm
+++ b/code/game/gamemodes/wizard/raginmages.dm
@@ -3,23 +3,23 @@
config_tag = "raginmages"
required_players = 1
required_players_secret = 15
+ use_huds = 1
var/max_mages = 0
var/making_mage = 0
var/mages_made = 1
var/time_checked = 0
+ var/players_per_mage = 4 // If the admin wants to tweak things or something
+ but_wait_theres_more = 1
-/datum/game_mode/wizard/announce()
+/datum/game_mode/wizard/raginmages/announce()
world << "The current game mode is - Ragin' Mages!"
world << "The \red Space Wizard Federation\black is pissed, help defeat all the space wizards!"
-/datum/game_mode/wizard/raginmages/post_setup()
- var/playercount = 0
- ..()
+/datum/game_mode/wizard/raginmages/pre_setup()
+ . = ..()
if(!max_mages)
- for(var/mob/living/player in mob_list)
- if (player.client && player.stat != DEAD)
- playercount += 1
- max_mages = round(playercount / 5)
+ max_mages = round(num_players() / players_per_mage)
+
/datum/game_mode/wizard/raginmages/greet_wizard(var/datum/mind/wizard, var/you_are=1)
if (you_are)
@@ -36,17 +36,42 @@
/datum/game_mode/wizard/raginmages/check_finished()
var/wizards_alive = 0
for(var/datum/mind/wizard in wizards)
+ if(isnull(wizard.current))
+ continue
if(!istype(wizard.current,/mob/living/carbon))
+ if(istype(get_area(wizard.current), /area/wizard_station)) // We don't want people camping other wizards
+ wizard.current << "If there aren't any admins on and another wizard is camping you in the wizard lair, report them on the forums"
+ message_admins("[wizard.current] was transformed in the wizard lair, another wizard is likely camping")
+ end_squabble(get_area(wizard.current))
continue
if(istype(wizard.current,/mob/living/carbon/brain))
+ if(istype(get_area(wizard.current), /area/wizard_station)) // We don't want people camping other wizards
+ wizard.current << "If there aren't any admins on and another wizard is camping you in the wizard lair, report them on the forums"
+ message_admins("[wizard.current] was brainified in the wizard lair, another wizard is likely camping")
+ end_squabble(get_area(wizard.current))
continue
if(wizard.current.stat==DEAD)
+ if(istype(get_area(wizard.current), /area/wizard_station)) // We don't want people camping other wizards
+ wizard.current << "If there aren't any admins on and another wizard is camping you in the wizard lair, report them on the forums"
+ message_admins("[wizard.current] died in the wizard lair, another wizard is likely camping")
+ end_squabble(get_area(wizard.current))
continue
if(wizard.current.stat==UNCONSCIOUS)
if(wizard.current.health < 0)
- wizard.current << "\red The Space Wizard Federation is upset with your performance and have terminated your employment."
- wizard.current.death()
+ if(istype(get_area(wizard.current), /area/wizard_station))
+ wizard.current << "If there aren't any admins on and another wizard is camping you in the wizard lair, report them on the forums"
+ message_admins("[wizard.current] went into crit in the wizard lair, another wizard is likely camping")
+ end_squabble(get_area(wizard.current))
+ else
+ wizard.current << "\red The Space Wizard Federation is upset with your performance and have terminated your employment."
+ wizard.current.gib() // *REAL* ACTION!! *REAL* DRAMA!! *REAL* BLOODSHED!!
continue
+ if(wizard.current.client && wizard.current.client.is_afk() > 10 * 60 * 10) // 10 minutes
+ wizard.current << "\red The Space Wizard Federation is upset with your performance and have terminated your employment."
+ wizard.current.gib() // Let's keep the round moving
+ continue
+ if(!wizard.current.client)
+ continue // Could just be a bad connection, so SSD wiz's shouldn't be gibbed over it, but they're not "alive" either
wizards_alive++
if (wizards_alive)
@@ -62,6 +87,34 @@
make_more_mages()
return ..()
+// To silence all struggles within the wizard's lair
+/datum/game_mode/wizard/raginmages/proc/end_squabble(var/area/wizard_station/A)
+ if(!istype(A)) return // You could probably do mean things with this otherwise
+ var/list/marked_for_death = list()
+ for(var/mob/living/L in A) // To hit non-wizard griefers
+ if(L.mind || L.client)
+ marked_for_death |= L
+ for(var/datum/mind/M in wizards)
+ if(istype(M.current) && istype(get_area(M.current), /area/wizard_station))
+ mages_made -= 1
+ wizards -= M // No, you don't get to occupy a slot
+ marked_for_death |= M.current
+ for(var/mob/living/L in marked_for_death)
+ L << "STOP FIGHTING."
+ L.ghostize()
+ if(istype(L, /mob/living/carbon/brain))
+ // diediedie
+ var/mob/living/carbon/brain/B = L
+ if(istype(B.loc, /obj/item))
+ qdel(B.loc)
+ if(B && B.container)
+ qdel(B.container)
+ if(L)
+ qdel(L)
+ for(var/obj/item/weapon/spellbook/B in A)
+ // No goodies for you
+ qdel(B)
+
/datum/game_mode/wizard/raginmages/proc/make_more_mages()
if(making_mage || shuttle_master.emergency.mode >= SHUTTLE_ESCAPE)
@@ -70,12 +123,13 @@
return 0
making_mage = 1
var/list/candidates = list()
- var/mob/dead/observer/theghost = null
+ var/client/theclient = null
spawn(rand(200, 600))
message_admins("SWF is still pissed, sending another wizard - [max_mages - mages_made] left.")
+ //Protip: This returns clients, not ghosts
candidates = get_candidates(ROLE_WIZARD)
if(!candidates.len)
- message_admins("No applicable ghosts for the next ragin' mage, asking ghosts instead.")
+ message_admins("No applicable clients for the next ragin' mage, asking ghosts instead.")
var/time_passed = world.time
for(var/mob/dead/observer/G in player_list)
if(!jobban_isbanned(G, "wizard") && !jobban_isbanned(G, "Syndicate"))
@@ -84,10 +138,9 @@
if("Yes")
if((world.time-time_passed)>300)//If more than 30 game seconds passed.
continue
- candidates += G
+ candidates += G.client
if("No")
continue
-
sleep(300)
if(!candidates.len)
message_admins("This is awkward, sleeping until another mage check...")
@@ -95,18 +148,20 @@
return
else
candidates = shuffle(candidates)
- for(var/mob/i in candidates)
- if(!i || !i.client) continue //Dont bother removing them from the list since we only grab one wizard
+ for(var/client/i in candidates)
+ if(!i) continue //Dont bother removing them from the list since we only grab one wizard
- theghost = i
+ theclient = i
break
- if(theghost)
- var/mob/living/carbon/human/new_character= makeBody(theghost)
- new_character.mind.make_Wizard()
making_mage = 0
- mages_made++
- return 1
+ if(theclient)
+ var/mob/living/carbon/human/new_character= create_human_for_client_from_prefs(theclient)
+
+
+ new_character.mind.make_Wizard() // This puts them at the wizard spawn, worry not
+ mages_made++
+ return 1
/datum/game_mode/wizard/raginmages/declare_completion()
if(finished)
diff --git a/code/game/gamemodes/wizard/wizard.dm b/code/game/gamemodes/wizard/wizard.dm
index 45beb619642..2d690cdbb17 100644
--- a/code/game/gamemodes/wizard/wizard.dm
+++ b/code/game/gamemodes/wizard/wizard.dm
@@ -14,6 +14,7 @@
var/use_huds = 0
var/finished = 0
+ var/but_wait_theres_more = 0
/datum/game_mode/wizard/announce()
world << "The current game mode is - Wizard!"
@@ -223,7 +224,7 @@
continue
traitors_alive++
- if (wizards_alive || traitors_alive)
+ if (wizards_alive || traitors_alive || but_wait_theres_more)
return ..()
else
finished = 1
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 49466400585..0d1629ef0dc 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -1872,3 +1872,87 @@
for(var/obj/item/clothing/C in src) //If they have some clothing equipped that lets them see reagents, they can see reagents
if(C.scan_reagents)
return 1
+
+// ugh this is so hackish
+// but why don't we have a proc for this already
+/proc/create_human_for_client_from_prefs(var/client/C)
+
+ var/turf/start = pick(latejoin)
+
+ var/mob/living/carbon/human/new_character
+
+ var/datum/species/chosen_species
+ if(C.prefs.species)
+ chosen_species = all_species[C.prefs.species]
+ if(chosen_species)
+ // Have to recheck admin due to no usr at roundstart. Latejoins are fine though.
+ if(is_alien_whitelisted(C, chosen_species) || check_rights_for(C, R_ADMIN))
+
+ new_character = new(start, C.prefs.species)
+
+ if(!new_character)
+ new_character = new(start)
+
+ new_character.lastarea = get_area(start)
+
+ var/datum/language/chosen_language
+ if(C.prefs.language)
+ chosen_language = all_languages[C.prefs.language]
+ if(chosen_language)
+ if(is_alien_whitelisted(C, C.prefs.language) || !config.usealienwhitelist || !(chosen_language.flags & WHITELISTED))
+ new_character.add_language(C.prefs.language)
+ if(ticker.random_players || appearance_isbanned(new_character))
+ C.prefs.random_character()
+ C.prefs.real_name = random_name(new_character.gender)
+ C.prefs.copy_to(new_character)
+
+ src << sound(null, repeat = 0, wait = 0, volume = 85, channel = 1) // MAD JAMS cant last forever yo
+
+ var/datum/mind/M = new/datum/mind(C.key)
+ M.active = 0
+ M.original = new_character
+ M.current = new_character
+ M.transfer_to(new_character) //won't transfer key since the mind is not active
+
+ new_character.name = C.prefs.real_name
+ new_character.dna.ready_dna(new_character)
+ new_character.dna.b_type = C.prefs.b_type
+
+ if(C.prefs.disabilities & DISABILITY_FLAG_NEARSIGHTED)
+ new_character.dna.SetSEState(GLASSESBLOCK,1,1)
+ new_character.disabilities |= NEARSIGHTED
+
+ if(C.prefs.disabilities & DISABILITY_FLAG_FAT)
+ new_character.mutations += FAT
+ new_character.overeatduration = 600 // Max overeat
+
+ if(C.prefs.disabilities & DISABILITY_FLAG_EPILEPTIC)
+ new_character.dna.SetSEState(EPILEPSYBLOCK,1,1)
+ new_character.disabilities |= EPILEPSY
+
+ if(C.prefs.disabilities & DISABILITY_FLAG_DEAF)
+ new_character.dna.SetSEState(DEAFBLOCK,1,1)
+ new_character.sdisabilities |= DEAF
+
+ if(C.prefs.disabilities & DISABILITY_FLAG_BLIND)
+ new_character.dna.SetSEState(BLINDBLOCK,1,1)
+ new_character.sdisabilities |= BLIND
+
+ if(C.prefs.disabilities & DISABILITY_FLAG_MUTE)
+ new_character.dna.SetSEState(MUTEBLOCK,1,1)
+ new_character.sdisabilities |= MUTE
+
+ chosen_species.handle_dna(new_character)
+
+ domutcheck(new_character)
+ new_character.dna.UpdateSE()
+ new_character.sync_organ_dna() //just fucking incase I guess
+
+ // 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 = C.key //Manually transfer the key to log them in
+
+ return new_character
\ No newline at end of file
diff --git a/html/changelogs/crazylemon-RAGINMAGES.yml b/html/changelogs/crazylemon-RAGINMAGES.yml
new file mode 100644
index 00000000000..59a5aab7046
--- /dev/null
+++ b/html/changelogs/crazylemon-RAGINMAGES.yml
@@ -0,0 +1,35 @@
+################################
+# Example Changelog File
+#
+# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
+#
+# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
+# When it is, any changes listed below will disappear.
+#
+# Valid Prefixes:
+# bugfix
+# wip (For works in progress)
+# tweak
+# soundadd
+# sounddel
+# rscadd (general adding of nice things)
+# rscdel (general deleting of nice things)
+# imageadd
+# imagedel
+# spellcheck (typo fixes)
+# experiment
+#################################
+
+# Your name. Remove the quotation mark and put in your name when copy+pasting the example changelog.
+author: Crazylemon
+
+# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
+delete-after: True
+
+# Any changes you've made. See valid prefix list above.
+# INDENT WITH TWO SPACES. NOT TABS. SPACES.
+# SCREW THIS UP AND IT WON'T WORK.
+# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit.
+# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog.
+changes:
+ - rscadd: "Brought RAGIN' MAGES back up to function."