diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index f821b19e665..03a684fc743 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -306,6 +306,22 @@ proc/isInSight(var/atom/A, var/atom/B) return candidates +/proc/get_candidate_ghosts(be_special_type, afk_bracket=3000, override_age=0, override_jobban=0) + var/roletext = get_roletext(be_special_type) + var/list/candidates = list() + // Keep looping until we find a non-afk candidate within the time bracket (we limit the bracket to 10 minutes (6000)) + while(!candidates.len && afk_bracket < 6000) + for(var/mob/dead/observer/G in player_list) + if(G.client != null) + if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD)) + if(!G.client.is_afk(afk_bracket) && (be_special_type in G.client.prefs.be_special)) + if(!override_jobban || (!jobban_isbanned(G, roletext) && !jobban_isbanned(G,"Syndicate"))) + if(override_age || player_old_enough_antag(G.client,be_special_type)) + candidates += G + afk_bracket += 600 // Add a minute to the bracket, for every attempt + + return candidates + /proc/ScreenText(obj/O, maptext="", screen_loc="CENTER-7,CENTER-7", maptext_height=480, maptext_width=480) if(!isobj(O)) O = new /obj/screen/text() O.maptext = maptext diff --git a/code/datums/spells/area_teleport.dm b/code/datums/spells/area_teleport.dm index 6a087a2a643..6041122fd98 100644 --- a/code/datums/spells/area_teleport.dm +++ b/code/datums/spells/area_teleport.dm @@ -26,6 +26,10 @@ var/area/thearea = teleportlocs[A] + if(thearea.tele_proof && !istype(thearea, /area/wizard_station)) + usr << "A mysterious force disrupts your arcane spell matrix, and you remain where you are." + return + return thearea /obj/effect/proc_holder/spell/targeted/area_teleport/cast(list/targets,area/thearea) diff --git a/code/game/gamemodes/wizard/raginmages.dm b/code/game/gamemodes/wizard/raginmages.dm index d2818448736..cb9283979d7 100644 --- a/code/game/gamemodes/wizard/raginmages.dm +++ b/code/game/gamemodes/wizard/raginmages.dm @@ -10,6 +10,8 @@ var/time_checked = 0 var/players_per_mage = 4 // If the admin wants to tweak things or something but_wait_theres_more = 1 + var/delay_per_mage = 4200 // Every 7 minutes by default + var/time_till_chaos = 18000 // Half-hour in /datum/game_mode/wizard/raginmages/announce() world << "The current game mode is - Ragin' Mages!" @@ -76,7 +78,7 @@ if (wizards_alive) if(!time_checked) time_checked = world.time - if(world.time > time_checked + 3000 && (mages_made < max_mages)) + if(world.time > time_till_chaos && world.time > time_checked + delay_per_mage && (mages_made < max_mages)) time_checked = world.time make_more_mages() else @@ -100,7 +102,8 @@ 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." + if(L.stat == CONSCIOUS) // Probably a troublemaker - I'd like to see YOU fight when unconscious + L << "STOP FIGHTING." L.ghostize() if(istype(L, /mob/living/carbon/brain)) // diediedie @@ -123,11 +126,11 @@ return 0 making_mage = 1 var/list/candidates = list() - var/client/theclient = null + var/mob/dead/observer/harry = 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) + candidates = get_candidate_ghosts(ROLE_WIZARD) if(!candidates.len) message_admins("No applicable clients for the next ragin' mage, asking ghosts instead.") var/time_passed = world.time @@ -138,7 +141,7 @@ if("Yes") if((world.time-time_passed)>300)//If more than 30 game seconds passed. continue - candidates += G.client + candidates += G if("No") continue sleep(300) @@ -148,20 +151,38 @@ return else candidates = shuffle(candidates) - for(var/client/i in candidates) + for(var/mob/dead/observer/i in candidates) if(!i) continue //Dont bother removing them from the list since we only grab one wizard - theclient = i + // YER A WIZZERD HARRY + harry = i break making_mage = 0 - if(theclient) - var/mob/living/carbon/human/new_character= create_human_for_client_from_prefs(theclient) + if(harry) + var/mob/living/carbon/human/new_character= makeBody(harry) new_character.mind.make_Wizard() // This puts them at the wizard spawn, worry not mages_made++ return 1 + else + log_to_dd("The candidates list for ragin' mages contained non-observer entries!") + return 0 + +// ripped from -tg-'s wizcode, because whee lets make a very general proc for a very specific gamemode +// This probably wouldn't do half bad as a proc in __HELPERS +// Lemme know if this causes species to mess up spectacularly or anything +/datum/game_mode/wizard/raginmages/proc/makeBody(var/mob/dead/observer/G) + if(!G || !G.key) return // Let's not steal someone's soul here + + var/mob/living/carbon/human/new_character = new(pick(latejoin)) + + G.client.prefs.copy_to(new_character) + + new_character.key = G.key + + return new_character /datum/game_mode/wizard/raginmages/declare_completion() if(finished) diff --git a/code/game/objects/items/weapons/scrolls.dm b/code/game/objects/items/weapons/scrolls.dm index ba66e57f19e..8458058c131 100644 --- a/code/game/objects/items/weapons/scrolls.dm +++ b/code/game/objects/items/weapons/scrolls.dm @@ -54,6 +54,10 @@ if(!((user == loc || (in_range(src, user) && istype(src.loc, /turf))))) return + if(thearea.tele_proof && !istype(thearea, /area/wizard_station)) + user << "A mysterious force disrupts your arcane spell matrix, and you remain where you are." + return + var/datum/effect/system/harmless_smoke_spread/smoke = new /datum/effect/system/harmless_smoke_spread() smoke.set_up(5, 0, user.loc) smoke.attach(user) diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index e8d01ac9f8e..b8f4ce565af 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1566,6 +1566,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts return 1 /datum/preferences/proc/copy_to(mob/living/carbon/human/character) + character.change_species(species) // Yell at me if this causes everything to melt if(be_random_name) real_name = random_name(gender,species) @@ -1641,7 +1642,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts else if(status == "mechanical") I.robotize() - if(disabilities & DISABILITY_FLAG_FAT && character.species.flags & CAN_BE_FAT)//character.species.flags & CAN_BE_FAT) + if(disabilities & DISABILITY_FLAG_FAT && character.species.flags & CAN_BE_FAT) character.mutations += FAT character.mutations += OBESITY if(disabilities & DISABILITY_FLAG_NEARSIGHTED) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index ead31b1427f..12bf73b43d4 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1870,87 +1870,3 @@ 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-ragemagefix.yml b/html/changelogs/crazylemon-ragemagefix.yml new file mode 100644 index 00000000000..45ad5ac9e6e --- /dev/null +++ b/html/changelogs/crazylemon-ragemagefix.yml @@ -0,0 +1,32 @@ +################################ +# 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 +delete-after: True +changes: + - rscadd: "Added a changelog editing system that should cause fewer conflicts and more accurate timestamps." + - bugfix: "Wizards now can't teleport to other antag spawn points." + - bugfix: "Removes an extruding pixel from the left-facing IPC glider monitor sprite." + - tweak: "Ragin' Mages now spawn every 7 minutes, instead of 5. Admins can further adjust this by modifying the 'delay_per_mage' variable." + - bugfix: "Ragin' Mages are now made with 100% less in-use souls (Apprentices won't have their consciousness yoinked)." + - tweak: "It takes half an hour for the REAL chaos of ragin' mages to start, for at least a semblance of normality." diff --git a/icons/mob/human_face.dmi b/icons/mob/human_face.dmi index ffecceda82e..4350582bae2 100644 Binary files a/icons/mob/human_face.dmi and b/icons/mob/human_face.dmi differ