mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-30 07:27:57 +01:00
Merge pull request #11421 from Arkatos1/WizardRevenge
Wizard Update - Revenge of the Federation
This commit is contained in:
@@ -45,6 +45,16 @@
|
||||
You can restore yourself to your original form while morphed by shift-clicking yourself.<br> \
|
||||
Finally, you can attack any item or dead creature to consume it - creatures will restore 1/3 of your max health.</b>"
|
||||
|
||||
/mob/living/simple_animal/hostile/morph/wizard
|
||||
name = "magical morph"
|
||||
real_name = "magical morph"
|
||||
desc = "A revolting, pulsating pile of flesh. This one looks somewhat.. magical."
|
||||
|
||||
/mob/living/simple_animal/hostile/morph/wizard/New()
|
||||
. = ..()
|
||||
AddSpell(new /obj/effect/proc_holder/spell/targeted/smoke)
|
||||
AddSpell(new /obj/effect/proc_holder/spell/targeted/forcewall)
|
||||
|
||||
/mob/living/simple_animal/hostile/morph/examine(mob/user)
|
||||
if(morphed)
|
||||
if(form)
|
||||
|
||||
@@ -290,6 +290,10 @@
|
||||
emote_hear = list("gaffaws", "laughs")
|
||||
response_help = "hugs"
|
||||
attacktext = "wildly tickles"
|
||||
maxHealth = 150
|
||||
health = 150
|
||||
melee_damage_lower = 20
|
||||
melee_damage_upper = 20
|
||||
|
||||
attack_sound = 'sound/items/bikehorn.ogg'
|
||||
feast_sound = 'sound/spookoween/scary_horn2.ogg'
|
||||
|
||||
@@ -3,36 +3,35 @@
|
||||
config_tag = "raginmages"
|
||||
required_players = 20
|
||||
use_huds = 1
|
||||
but_wait_theres_more = 1
|
||||
var/max_mages = 0
|
||||
var/making_mage = 0
|
||||
var/making_mage = FALSE
|
||||
var/mages_made = 1
|
||||
var/time_checked = 0
|
||||
var/players_per_mage = 6 // If the admin wants to tweak things or something
|
||||
but_wait_theres_more = 1
|
||||
var/players_per_mage = 10 // If the admin wants to tweak things or something
|
||||
var/delay_per_mage = 4200 // Every 7 minutes by default
|
||||
var/time_till_chaos = 18000 // Half-hour in
|
||||
|
||||
/datum/game_mode/wizard/raginmages/announce()
|
||||
to_chat(world, "<B>The current game mode is - Ragin' Mages!</B>")
|
||||
to_chat(world, "<B>The <font color='red'>Space Wizard Federation</font> is pissed, help defeat all the space wizards!</B>")
|
||||
|
||||
to_chat(world, "<B>The <font color='red'>Space Wizard Federation</font> is pissed, crew must help defeat all the Space Wizards invading the station!</B>")
|
||||
|
||||
/datum/game_mode/wizard/raginmages/greet_wizard(var/datum/mind/wizard, var/you_are=1)
|
||||
if(you_are)
|
||||
to_chat(wizard.current, "<span class='danger'>You are the Space Wizard!</span>")
|
||||
to_chat(wizard.current, "<B>The Space Wizards Federation has given you the following tasks:</B>")
|
||||
to_chat(wizard.current, "<B>The Space Wizard Federation has given you the following tasks:</B>")
|
||||
|
||||
var/obj_count = 1
|
||||
to_chat(wizard.current, "<b>Supreme Objective</b>: Make sure the station pays for its actions against our diplomats. We might send more Wizards to the station if the situation is not developing in our favour.")
|
||||
for(var/datum/objective/objective in wizard.objectives)
|
||||
to_chat(wizard.current, "<B>Objective #[obj_count]</B>: [objective.explanation_text]")
|
||||
obj_count++
|
||||
to_chat(wizard.current, "<b>Objective Alpha</b>: Make sure the station pays for its actions against our diplomats")
|
||||
return
|
||||
|
||||
/datum/game_mode/wizard/raginmages/check_finished()
|
||||
var/wizards_alive = 0
|
||||
// Accidental pun!
|
||||
var/wizard_cap = (max_mages || (num_players_started() / players_per_mage))
|
||||
var/wizard_cap = CEILING((num_players_started() / players_per_mage), 1)
|
||||
max_mages = wizard_cap
|
||||
for(var/datum/mind/wizard in wizards)
|
||||
if(isnull(wizard.current))
|
||||
continue
|
||||
@@ -115,71 +114,44 @@
|
||||
qdel(B)
|
||||
|
||||
/datum/game_mode/wizard/raginmages/proc/make_more_mages()
|
||||
|
||||
if(making_mage || SSshuttle.emergency.mode >= SHUTTLE_ESCAPE)
|
||||
return 0
|
||||
making_mage = 1
|
||||
var/list/candidates = list()
|
||||
return FALSE
|
||||
making_mage = TRUE
|
||||
|
||||
var/list/mob/dead/observer/candidates = pollCandidates("Do you want to play as a raging Space Wizard?", ROLE_WIZARD, TRUE, poll_time = 20 SECONDS)
|
||||
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_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
|
||||
for(var/mob/dead/observer/G in GLOB.player_list)
|
||||
if(!jobban_isbanned(G, "wizard") && !jobban_isbanned(G, "Syndicate"))
|
||||
spawn(0)
|
||||
switch(alert(G, "Do you wish to be considered for the position of Space Wizard Foundation 'diplomat'?","Please answer in 30 seconds!","Yes","No"))
|
||||
if("Yes")
|
||||
if((world.time-time_passed)>300)//If more than 30 game seconds passed.
|
||||
continue
|
||||
candidates += G
|
||||
if("No")
|
||||
continue
|
||||
sleep(300)
|
||||
if(!candidates.len)
|
||||
message_admins("This is awkward, sleeping until another mage check...")
|
||||
making_mage = 0
|
||||
return
|
||||
message_admins("SWF is still pissed, sending another wizard - [max_mages - mages_made] left.")
|
||||
|
||||
if(!candidates.len)
|
||||
message_admins("This is awkward, sleeping until another mage check..")
|
||||
making_mage = FALSE
|
||||
sleep(300)
|
||||
return
|
||||
else
|
||||
harry = pick(candidates)
|
||||
making_mage = FALSE
|
||||
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 TRUE
|
||||
else
|
||||
candidates = shuffle(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
|
||||
|
||||
// YER A WIZZERD HARRY
|
||||
harry = i
|
||||
break
|
||||
|
||||
making_mage = 0
|
||||
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_runtime(EXCEPTION("The candidates list for ragin' mages contained non-observer entries!"), src)
|
||||
return 0
|
||||
log_runtime(EXCEPTION("The candidates list for ragin' mages contained non-observer entries!"), src)
|
||||
return FALSE
|
||||
|
||||
// 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
|
||||
|
||||
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)
|
||||
feedback_set_details("round_end_result","raging wizard loss - wizard killed")
|
||||
to_chat(world, "<span class='warning'><FONT size = 3><B> The crew has managed to hold off the wizard attack! The Space Wizards Federation has been taught a lesson they will not soon forget!</B></FONT></span>")
|
||||
feedback_set_details("round_end_result", "raging wizard loss - wizard killed")
|
||||
to_chat(world, "<span class='warning'><FONT size = 3><B> The crew has managed to hold off the Wizard attack! The Space Wizard Federation has been taught a lesson they will not soon forget!</B></FONT></span>")
|
||||
..(1)
|
||||
|
||||
@@ -229,6 +229,12 @@
|
||||
log_name = "LD"
|
||||
category = "Defensive"
|
||||
|
||||
/datum/spellbook_entry/lichdom/IsAvailible()
|
||||
if(SSticker.mode.name == "ragin' mages")
|
||||
return FALSE
|
||||
else
|
||||
return TRUE
|
||||
|
||||
/datum/spellbook_entry/lightningbolt
|
||||
name = "Lightning Bolt"
|
||||
spell_type = /obj/effect/proc_holder/spell/targeted/lightning
|
||||
@@ -398,8 +404,8 @@
|
||||
name = "Bottle of Tickles"
|
||||
desc = "A bottle of magically infused fun, the smell of which will \
|
||||
attract adorable extradimensional beings when broken. These beings \
|
||||
are similar to slaughter demons, but they do not permamently kill \
|
||||
their victims, instead putting them in an extradimensional hugspace, \
|
||||
are similar to slaughter demons, but are a little weaker and they do not permamently \
|
||||
kill their victims, instead putting them in an extradimensional hugspace, \
|
||||
to be released on the demon's death. Chaotic, but not ultimately \
|
||||
damaging. The crew's reaction to the other hand could be very \
|
||||
destructive."
|
||||
@@ -411,7 +417,7 @@
|
||||
|
||||
/datum/spellbook_entry/item/oozebottle
|
||||
name = "Bottle of Ooze"
|
||||
desc = "A bottle of magically infused ooze, which will awake an all-consuming Morph, capable of cunningly disguising itself as any object it comes in contact with. Be careful though, as Morph diet includes Wizards."
|
||||
desc = "A bottle of magically infused ooze, which will awake an all-consuming Morph, capable of cunningly disguising itself as any object it comes in contact with and even casting some very basic spells. Be careful though, as Morph diet includes Wizards."
|
||||
item_path = /obj/item/antag_spawner/morph
|
||||
cost = 1
|
||||
log_name = "BO"
|
||||
@@ -419,7 +425,7 @@
|
||||
category = "Assistance"
|
||||
|
||||
/datum/spellbook_entry/item/tarotdeck
|
||||
name = "Tarot Deck"
|
||||
name = "Guardian Deck"
|
||||
desc = "A deck of guardian tarot cards, capable of binding a personal guardian to your body. There are multiple types of guardian available, but all of them will transfer some amount of damage to you. \
|
||||
It would be wise to avoid buying these with anything capable of causing you to swap bodies with others."
|
||||
item_path = /obj/item/guardiancreator
|
||||
@@ -439,14 +445,6 @@
|
||||
item_path = /obj/item/twohanded/singularityhammer
|
||||
log_name = "SI"
|
||||
|
||||
/datum/spellbook_entry/item/cursed_heart
|
||||
name = "Cursed Heart"
|
||||
desc = "A heart that has been revived by dark magicks. The user must ensure the heart is manually beaten or their blood circulation will suffer, but every beat heals their injuries. It must beat every 6 seconds."
|
||||
item_path = /obj/item/organ/internal/heart/cursed/wizard
|
||||
log_name = "CH"
|
||||
cost = 1
|
||||
category = "Defensive"
|
||||
|
||||
/datum/spellbook_entry/summon
|
||||
name = "Summon Stuff"
|
||||
category = "Rituals"
|
||||
@@ -473,9 +471,12 @@
|
||||
name = "Summon Ghosts"
|
||||
desc = "Spook the crew out by making them see dead people. Be warned, ghosts are capricious and occasionally vindicative, and some will use their incredibly minor abilities to frustrate you."
|
||||
cost = 0
|
||||
log_name = "SGH"
|
||||
|
||||
/datum/spellbook_entry/summon/ghosts/IsAvailible()
|
||||
if(!SSticker.mode)
|
||||
if(!SSticker.mode) // In case spellbook is placed on map
|
||||
return FALSE
|
||||
if(SSticker.mode.name == "ragin' mages")
|
||||
return FALSE
|
||||
else
|
||||
return TRUE
|
||||
@@ -489,18 +490,17 @@
|
||||
|
||||
/datum/spellbook_entry/summon/guns
|
||||
name = "Summon Guns"
|
||||
category = "Rituals"
|
||||
desc = "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill you. Just be careful not to stand still too long!"
|
||||
desc = "Nothing could possibly go wrong with arming a crew of lunatics just itching for an excuse to kill you. Just be careful not to stand still too long! You will also receive 1 extra point to use in your spellbook."
|
||||
cost = 0
|
||||
log_name = "SG"
|
||||
|
||||
/datum/spellbook_entry/summon/guns/IsAvailible()
|
||||
if(!SSticker.mode) // In case spellbook is placed on map
|
||||
return 0
|
||||
return FALSE
|
||||
if(SSticker.mode.name == "ragin' mages")
|
||||
return 0
|
||||
return FALSE
|
||||
else
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/datum/spellbook_entry/summon/guns/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book)
|
||||
feedback_add_details("wizard_spell_learned",log_name)
|
||||
@@ -512,18 +512,17 @@
|
||||
|
||||
/datum/spellbook_entry/summon/magic
|
||||
name = "Summon Magic"
|
||||
category = "Challenges"
|
||||
desc = "Share the wonders of magic with the crew and show them why they aren't to be trusted with it at the same time."
|
||||
desc = "Share the wonders of magic with the crew and show them why they aren't to be trusted with it at the same time. You will also receive 1 extra point to use in your spellbook."
|
||||
cost = 0
|
||||
log_name = "SU"
|
||||
|
||||
/datum/spellbook_entry/summon/magic/IsAvailible()
|
||||
if(!SSticker.mode) // In case spellbook is placed on map
|
||||
return 0
|
||||
return FALSE
|
||||
if(SSticker.mode.name == "ragin' mages")
|
||||
return 0
|
||||
return FALSE
|
||||
else
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/datum/spellbook_entry/summon/magic/Buy(var/mob/living/carbon/human/user,var/obj/item/spellbook/book)
|
||||
feedback_add_details("wizard_spell_learned",log_name)
|
||||
@@ -611,9 +610,6 @@
|
||||
dat += "Items are not bound to you and can be stolen. Additionaly they cannot typically be returned once purchased.<BR>"
|
||||
dat += "For spells: the number after the spell name is the cooldown time.<BR>"
|
||||
dat += "You can reduce this number by spending more points on the spell.<BR>"
|
||||
if("Challenges")
|
||||
dat += "The Wizard Federation typically has hard limits on the potency and number of spells brought to the station based on risk.<BR>"
|
||||
dat += "Arming the station against you will increases the risk, but will grant you one more charge for your spellbook.<BR>"
|
||||
if("Rituals")
|
||||
dat += "These powerful spells change the very fabric of reality. Not always in your favour.<BR>"
|
||||
return dat
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
required_enemies = 1
|
||||
recommended_enemies = 1
|
||||
free_golems_disabled = TRUE
|
||||
|
||||
var/use_huds = 0
|
||||
var/finished = 0
|
||||
var/but_wait_theres_more = 0
|
||||
@@ -17,7 +16,6 @@
|
||||
to_chat(world, "<B>The current game mode is - Wizard!</B>")
|
||||
to_chat(world, "<B>There is a <font color='red'>SPACE WIZARD</font> on the station. You can't let him achieve his objective!</B>")
|
||||
|
||||
|
||||
/datum/game_mode/wizard/can_start()//This could be better, will likely have to recode it later
|
||||
if(!..())
|
||||
return 0
|
||||
@@ -42,7 +40,6 @@
|
||||
..()
|
||||
return 1
|
||||
|
||||
|
||||
/datum/game_mode/wizard/post_setup()
|
||||
for(var/datum/mind/wizard in wizards)
|
||||
log_game("[key_name(wizard)] has been selected as a Wizard")
|
||||
@@ -74,7 +71,6 @@
|
||||
wizhud.join_hud(wiz_mind.current)
|
||||
set_antag_hud(wiz_mind.current, ((wiz_mind in wizards) ? "hudwizard" : "apprentice"))
|
||||
|
||||
|
||||
/datum/game_mode/proc/update_wiz_icons_removed(datum/mind/wiz_mind)
|
||||
var/datum/atom_hud/antag/wizhud = huds[ANTAG_HUD_WIZ]
|
||||
wizhud.leave_hud(wiz_mind.current)
|
||||
@@ -86,7 +82,6 @@
|
||||
wizard.objectives += wiz_objective
|
||||
return
|
||||
|
||||
|
||||
/datum/game_mode/proc/name_wizard(mob/living/carbon/human/wizard_mob)
|
||||
//Allows the wizard to choose a custom name or go with a random one. Spawn 0 so it does not lag the round starting.
|
||||
var/wizard_name_first = pick(GLOB.wizard_first)
|
||||
@@ -104,7 +99,6 @@
|
||||
wizard_mob.mind.name = newname
|
||||
return
|
||||
|
||||
|
||||
/datum/game_mode/proc/greet_wizard(var/datum/mind/wizard, var/you_are=1)
|
||||
addtimer(CALLBACK(wizard.current, /mob/.proc/playsound_local, null, 'sound/ambience/antag/ragesmages.ogg', 100, 0), 30)
|
||||
if(you_are)
|
||||
@@ -117,7 +111,6 @@
|
||||
obj_count++
|
||||
return
|
||||
|
||||
|
||||
/*/datum/game_mode/proc/learn_basic_spells(mob/living/carbon/human/wizard_mob)
|
||||
if(!istype(wizard_mob))
|
||||
return
|
||||
@@ -165,7 +158,6 @@
|
||||
wizard_mob.gene_stability += DEFAULT_GENE_STABILITY //magic
|
||||
return 1
|
||||
|
||||
|
||||
/datum/game_mode/wizard/check_finished()
|
||||
var/wizards_alive = 0
|
||||
var/traitors_alive = 0
|
||||
@@ -190,8 +182,6 @@
|
||||
finished = 1
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
/datum/game_mode/wizard/declare_completion(var/ragin = 0)
|
||||
if(finished && !ragin)
|
||||
feedback_set_details("round_end_result","wizard loss - wizard killed")
|
||||
@@ -199,7 +189,6 @@
|
||||
..()
|
||||
return 1
|
||||
|
||||
|
||||
/datum/game_mode/proc/auto_declare_completion_wizard()
|
||||
if(wizards.len)
|
||||
var/text = "<br><font size=3><b>the wizards/witches were:</b></font>"
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
var/mob/living/demon_type = /mob/living/simple_animal/slaughter
|
||||
|
||||
/obj/item/antag_spawner/slaughter_demon/attack_self(mob/user)
|
||||
if(level_blocks_magic(user.z))//this is to make sure the wizard does NOT summon a demon from the Den..
|
||||
if(level_blocks_magic(user.z)) //this is to make sure the wizard does NOT summon a demon from the Den..
|
||||
to_chat(user, "<span class='notice'>You should probably wait until you reach the station.</span>")
|
||||
return
|
||||
|
||||
@@ -177,7 +177,10 @@
|
||||
used = TRUE
|
||||
to_chat(user, "<span class='notice'>You break the seal on the bottle, calling upon the dire spirits of the underworld...</span>")
|
||||
|
||||
var/list/candidates = pollCandidates("Do you want to play as a slaughter demon summoned by [user.real_name]?", ROLE_DEMON, 1, 100)
|
||||
var/type = "slaughter"
|
||||
if(demon_type == /mob/living/simple_animal/slaughter/laughter)
|
||||
type = "laughter"
|
||||
var/list/candidates = pollCandidates("Do you want to play as a [type] demon summoned by [user.real_name]?", ROLE_DEMON, 1, 100)
|
||||
|
||||
if(candidates.len > 0)
|
||||
var/mob/C = pick(candidates)
|
||||
@@ -208,7 +211,6 @@
|
||||
KillDaCrew.owner = S.mind
|
||||
KillDaCrew.explanation_text = "[objective_verb] everyone else while you're at it."
|
||||
S.mind.objectives += KillDaCrew
|
||||
S.mind.objectives += KillDaCrew
|
||||
to_chat(S, "<B>Objective #[1]</B>: [KillDaWiz.explanation_text]")
|
||||
to_chat(S, "<B>Objective #[2]</B>: [KillDaCrew.explanation_text]")
|
||||
|
||||
@@ -220,7 +222,7 @@
|
||||
color = "#FF69B4" // HOT PINK
|
||||
veil_msg = "<span class='warning'>You sense an adorable presence \
|
||||
lurking just beyond the veil...</span>"
|
||||
objective_verb = "Hug and Tickle"
|
||||
objective_verb = "Hug and tickle"
|
||||
demon_type = /mob/living/simple_animal/slaughter/laughter
|
||||
|
||||
///////////MORPH
|
||||
@@ -248,7 +250,7 @@
|
||||
used = TRUE
|
||||
to_chat(user, "<span class='notice'>You break the seal on the bottle, calling upon the dire sludge to awaken...</span>")
|
||||
|
||||
var/list/candidates = pollCandidates("Do you want to play as a morph awakened by [user.real_name]?", ROLE_MORPH, 1, 100)
|
||||
var/list/candidates = pollCandidates("Do you want to play as a magical morph awakened by [user.real_name]?", ROLE_MORPH, 1, 100)
|
||||
|
||||
if(candidates.len > 0)
|
||||
var/mob/C = pick(candidates)
|
||||
@@ -262,7 +264,7 @@
|
||||
to_chat(user, "<span class='notice'>The sludge does not respond to your attempt to awake it. Perhaps you should try again later.</span>")
|
||||
|
||||
/obj/item/antag_spawner/morph/spawn_antag(client/C, turf/T, type = "", mob/user)
|
||||
var/mob/living/simple_animal/hostile/morph/M = new /mob/living/simple_animal/hostile/morph(pick(xeno_spawn))
|
||||
var/mob/living/simple_animal/hostile/morph/wizard/M = new /mob/living/simple_animal/hostile/morph/wizard(pick(xeno_spawn))
|
||||
M.key = C.key
|
||||
M.mind.assigned_role = SPECIAL_ROLE_MORPH
|
||||
M.mind.special_role = SPECIAL_ROLE_MORPH
|
||||
|
||||
@@ -95,6 +95,11 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
updateallghostimages()
|
||||
return ..()
|
||||
|
||||
/mob/dead/observer/examine(mob/user)
|
||||
..()
|
||||
if(!invisibility)
|
||||
to_chat(user, "It seems extremely obvious.")
|
||||
|
||||
// This seems stupid, but it's the easiest way to avoid absolutely ridiculous shit from happening
|
||||
// Copying an appearance directly from a mob includes it's verb list, it's invisibility, it's alpha, and it's density
|
||||
// You might recognize these things as "fucking ridiculous to put in an appearance"
|
||||
|
||||
Reference in New Issue
Block a user