Skip to content

Commit

Permalink
Merge pull request #224 from wraith-54321/upstream-wizard-rightwrong
Browse files Browse the repository at this point in the history
Ports the new ritual from TG and fixes chuunibyou casting
  • Loading branch information
Zonespace27 authored Aug 24, 2023
2 parents 4f5b563 + 5d21d15 commit 9973cb4
Show file tree
Hide file tree
Showing 17 changed files with 250 additions and 74 deletions.
2 changes: 2 additions & 0 deletions code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_HOLY "holy"
/// This allows a person who has antimagic to cast spells without getting blocked
#define TRAIT_ANTIMAGIC_NO_SELFBLOCK "anti_magic_no_selfblock"
/// The user can do things like use magic staffs without penalty
#define TRAIT_MAGICALLY_GIFTED "magically_gifted"
#define TRAIT_DEPRESSION "depression"
#define TRAIT_BLOOD_DEFICIENCY "blood_deficiency"
#define TRAIT_JOLLY "jolly"
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/granters/magic/_spell_granter.dm
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
if(!granted_action)
CRASH("Someone attempted to learn [type], which did not have an spell set.")
if(locate(granted_action) in user.actions)
if(IS_WIZARD(user))
if(HAS_MIND_TRAIT(user, TRAIT_MAGICALLY_GIFTED))
to_chat(user, span_warning("You're already far more versed in the spell [action_name] \
than this flimsy how-to book can provide!"))
else
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/weaponry.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1119,7 +1119,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301
bare_wound_bonus = 25

/obj/item/highfrequencyblade/wizard/attack_self(mob/user, modifiers)
if(!IS_WIZARD(user))
if(!HAS_MIND_TRAIT(user, TRAIT_MAGICALLY_GIFTED))
balloon_alert(user, "you're too weak!")
return
return ..()
7 changes: 4 additions & 3 deletions code/modules/antagonists/_common/antag_helpers.dm
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
//Returns MINDS of the assigned antags of given type/subtypes
/proc/get_antag_minds(antag_type,specific = FALSE)
/// Returns MINDS of the assigned antags of given type/subtypes
/// Supplying no antag type grants all minds with antag datums
/proc/get_antag_minds(antag_type, specific = FALSE)
RETURN_TYPE(/list/datum/mind)
. = list()
for(var/datum/antagonist/A in GLOB.antagonists)
if(!A.owner)
continue
if(!antag_type || !specific && istype(A,antag_type) || specific && A.type == antag_type)
. += A.owner
. |= A.owner

/// From a list of players (minds, mobs or clients), finds the one with the highest playtime (either from a specific role or overall living) and returns it.
/proc/get_most_experienced(list/players, specific_role)
Expand Down
8 changes: 8 additions & 0 deletions code/modules/antagonists/survivalist/survivalist.dm
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,11 @@
magic.owner = owner
objectives += magic
..()

/datum/antagonist/survivalist/magic/on_gain()
. = ..()
ADD_TRAIT(owner, TRAIT_MAGICALLY_GIFTED, REF(src))

/datum/antagonist/survivalist/magic/on_removal()
REMOVE_TRAIT(owner, TRAIT_MAGICALLY_GIFTED, REF(src))
return..()
7 changes: 5 additions & 2 deletions code/modules/antagonists/wizard/equipment/chuunibyou_spell.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,15 @@
if(ishuman(cast_on))
var/mob/living/carbon/human/human_cast_on = cast_on
human_cast_on.dropItemToGround(human_cast_on.glasses)
var/obj/item/clothing/head/wizard/wizhat = human_cast_on.head
//monkestation removal start
/* var/obj/item/clothing/head/wizard/wizhat = human_cast_on.head
if(istype(wizhat))
to_chat(human_cast_on, span_notice("Your [wizhat] transforms into an eyepatch."))
qdel(wizhat)
else
to_chat(human_cast_on, span_notice("An eyepatch pops into existence over one of your eyes."))
to_chat(human_cast_on, span_notice("An eyepatch pops into existence over one of your eyes.")) */
//monkestation removal end
to_chat(human_cast_on, span_notice("An eyepatch pops into existence over one of your eyes.")) //monkestation edit: makes it not remove your wizard hat
human_cast_on.equip_to_slot_or_del(new /obj/item/clothing/glasses/eyepatch/medical/chuuni(human_cast_on), ITEM_SLOT_EYES)

qdel(src)
4 changes: 2 additions & 2 deletions code/modules/antagonists/wizard/equipment/soulstone.dm
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@

/obj/structure/constructshell/examine(mob/user)
. = ..()
if(IS_CULTIST(user) || IS_WIZARD(user) || user.stat == DEAD)
if(IS_CULTIST(user) || HAS_MIND_TRAIT(user, TRAIT_MAGICALLY_GIFTED) || user.stat == DEAD)
. += {"<span class='cult'>A construct shell, used to house bound souls from a soulstone.\n
Placing a soulstone with a soul into this shell allows you to produce your choice of the following:\n
An <b>Artificer</b>, which can produce <b>more shells and soulstones</b>, as well as fortifications.\n
Expand All @@ -276,7 +276,7 @@
/obj/structure/constructshell/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/soulstone))
var/obj/item/soulstone/SS = O
if(!IS_CULTIST(user) && !IS_WIZARD(user) && !SS.theme == THEME_HOLY)
if(!IS_CULTIST(user) && !HAS_MIND_TRAIT(user, TRAIT_MAGICALLY_GIFTED) && !SS.theme == THEME_HOLY)
to_chat(user, span_danger("An overwhelming feeling of dread comes over you as you attempt to place [SS] into the shell. It would be wise to be rid of this quickly."))
if(isliving(user))
var/mob/living/living_user = user
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@
* * user - the mob who's bought the spell
* * book - what book they've bought the spell from
*
* Return TRUE if the purchase was successful, FALSE otherwise
* Return truthy if the purchase was successful, FALSE otherwise
*/
/datum/spellbook_entry/proc/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book)
/datum/spellbook_entry/proc/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book, log_buy = TRUE)
var/datum/action/cooldown/spell/existing = locate(spell_type) in user.actions
if(existing)
var/before_name = existing.name
Expand All @@ -96,20 +96,23 @@

//we'll need to update the cooldowns for the spellbook
set_spell_info()
log_spellbook("[key_name(user)] improved their knowledge of [initial(existing.name)] to level [existing.spell_level] for [cost] points")
SSblackbox.record_feedback("nested tally", "wizard_spell_improved", 1, list("[name]", "[existing.spell_level]"))
log_purchase(user.key)
return TRUE

if(log_buy)
log_spellbook("[key_name(user)] improved their knowledge of [initial(existing.name)] to level [existing.spell_level] for [cost] points")
SSblackbox.record_feedback("nested tally", "wizard_spell_improved", 1, list("[name]", "[existing.spell_level]"))
log_purchase(user.key)
return existing

//No same spell found - just learn it
var/datum/action/cooldown/spell/new_spell = new spell_type(user.mind || user)
new_spell.Grant(user)
to_chat(user, span_notice("You have learned [new_spell.name]."))

log_spellbook("[key_name(user)] learned [new_spell] for [cost] points")
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
log_purchase(user.key)
return TRUE
if(log_buy)
log_spellbook("[key_name(user)] learned [new_spell] for [cost] points")
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
log_purchase(user.key)
return new_spell

/datum/spellbook_entry/proc/log_purchase(key)
if(!islist(GLOB.wizard_spellbook_purchases_by_key[key]))
Expand Down Expand Up @@ -196,12 +199,13 @@
/// Typepath of what item we create when purchased
var/obj/item/item_path

/datum/spellbook_entry/item/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book)
var/atom/spawned_path = new item_path(get_turf(user))
log_spellbook("[key_name(user)] bought [src] for [cost] points")
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
/datum/spellbook_entry/item/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book, log_buy = TRUE)
var/atom/spawned_path = new item_path(user.loc)
if(log_buy)
log_spellbook("[key_name(user)] bought [src] for [cost] points")
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
log_purchase(user.key)
try_equip_item(user, spawned_path)
log_purchase(user.key)
return spawned_path

/// Attempts to give the item to the buyer on purchase.
Expand All @@ -216,10 +220,11 @@
refundable = FALSE
buy_word = "Cast"

/datum/spellbook_entry/summon/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book)
log_spellbook("[key_name(user)] cast [src] for [cost] points")
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
log_purchase(user.key)
/datum/spellbook_entry/summon/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book, log_buy = TRUE)
if(log_buy)
log_spellbook("[key_name(user)] cast [src] for [cost] points")
SSblackbox.record_feedback("tally", "wizard_spell_learned", 1, name)
log_purchase(user.key)
return TRUE

/// Non-purchasable flavor spells to populate the spell book with, for style.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
var/was_equipped = user.equip_to_slot_if_possible(to_equip, ITEM_SLOT_BELT, disable_warning = TRUE)
to_chat(user, span_notice("\A [to_equip.name] has been summoned [was_equipped ? "on your waist" : "at your feet"]."))

/datum/spellbook_entry/item/soulstones/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book)
/datum/spellbook_entry/item/soulstones/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book, log_buy = TRUE)
. =..()
if(!.)
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@
/datum/spellbook_entry/challenge/antiwizard
name = "Friendly Wizard Scum"
desc = "A \"Friendly\" Wizard will protect the station, and try to kill you. They get a spellbook much like you, but will use it for \"GOOD\"."

/datum/spellbook_entry/challenge/can_be_purchased() //im pretty sure this makes these not show up, kinda removing the point of them
return FALSE
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
and some will use their incredibly minor abilities to frustrate you."
cost = 0

/datum/spellbook_entry/summon/ghosts/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book)
/datum/spellbook_entry/summon/ghosts/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book, log_buy = TRUE)
summon_ghosts(user)
playsound(get_turf(user), 'sound/effects/ghost2.ogg', 50, TRUE)
return ..()
Expand All @@ -27,7 +27,7 @@
// Also must be config enabled
return !CONFIG_GET(flag/no_summon_guns)

/datum/spellbook_entry/summon/guns/buy_spell(mob/living/carbon/human/user,obj/item/spellbook/book)
/datum/spellbook_entry/summon/guns/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book, log_buy = TRUE)
summon_guns(user, 10)
playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, TRUE)
return ..()
Expand All @@ -45,7 +45,7 @@
// Also must be config enabled
return !CONFIG_GET(flag/no_summon_magic)

/datum/spellbook_entry/summon/magic/buy_spell(mob/living/carbon/human/user,obj/item/spellbook/book)
/datum/spellbook_entry/summon/magic/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book, log_buy = TRUE)
summon_magic(user, 10)
playsound(get_turf(user), 'sound/magic/castsummon.ogg', 50, TRUE)
return ..()
Expand All @@ -67,7 +67,7 @@
// Also, must be config enabled
return !CONFIG_GET(flag/no_summon_events)

/datum/spellbook_entry/summon/events/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book)
/datum/spellbook_entry/summon/events/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book, log_buy = TRUE)
var/turf/user_turf = get_turf(user) //monkestation edit: you need to be on station to cast summon events to make sure you will also feel the effects
if(user_turf && !is_station_level(user_turf.z)) //monkestation edit
to_chat(user, span_warning("You need to be on the station!")) //monkestation edit
Expand All @@ -81,12 +81,71 @@
desc = "Curses the station, warping the minds of everyone inside, causing lasting traumas. Warning: this spell can affect you if not cast from a safe distance."
cost = 4

/datum/spellbook_entry/summon/curse_of_madness/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book)
/datum/spellbook_entry/summon/curse_of_madness/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book, log_buy = TRUE)
var/message = tgui_input_text(user, "Whisper a secret truth to drive your victims to madness", "Whispers of Madness")
if(!message)
if(!message || QDELETED(user) || QDELETED(book) || !can_buy(user, book))
return FALSE
curse_of_madness(user, message)
playsound(user, 'sound/magic/mandswap.ogg', 50, TRUE)
return ..()

/// A wizard ritual that allows the wizard to teach a specific spellbook enty to everyone on the station.
/// This includes item entries (which will be given to everyone) but disincludes other rituals like itself
/datum/spellbook_entry/summon/specific_spell
name = "Mass Wizard Teaching"
desc = "Teach a specific spell (or give a specific item) to everyone on the station. \
The cost of this is increased by the cost of the spell you choose. And don't worry - you, too, will learn the spell!"
cost = 3 // cheapest is 4 cost, most expensive is 7 cost
limit = 1

/datum/spellbook_entry/summon/specific_spell/buy_spell(mob/living/carbon/human/user, obj/item/spellbook/book, log_buy = TRUE)
var/list/spell_options = list()
for(var/datum/spellbook_entry/entry as anything in book.entries)
if(istype(entry, /datum/spellbook_entry/summon))
continue
if(!entry.can_be_purchased())
continue

spell_options[entry.name] = entry

sortTim(spell_options, GLOBAL_PROC_REF(cmp_text_asc))
var/chosen_spell_name = tgui_input_list(user, "Choose a spell (or item) to grant to everyone...", "Wizardly Teaching", spell_options)
if(isnull(chosen_spell_name) || QDELETED(user) || QDELETED(book))
return FALSE
if(GLOB.mass_teaching)
tgui_alert(user, "Someone's already cast [name]!", "Wizardly Teaching", list("Shame"))
return FALSE

var/datum/spellbook_entry/chosen_entry = spell_options[chosen_spell_name]
if(cost + chosen_entry.cost > book.uses)
tgui_alert(user, "You can't afford to grant everyone [chosen_spell_name]! ([cost] points needed)", "Wizardly Teaching", list("Shame"))
return FALSE

cost += chosen_entry.cost
if(!can_buy(user, book))
cost = initial(cost)
return FALSE

GLOB.mass_teaching = new(chosen_entry.type)
GLOB.mass_teaching.equip_all_affected()

var/item_entry = istype(chosen_entry, /datum/spellbook_entry/item)
to_chat(user, span_hypnophrase("You have [item_entry ? "granted everyone the power" : "taught everyone the ways"] of [chosen_spell_name]!"))
message_admins("[ADMIN_LOOKUPFLW(user)] gave everyone the [item_entry ? "item" : "spell"] \"[chosen_spell_name]\"!")
user.log_message("has gave everyone the [item_entry ? "item" : "spell"] \"[chosen_spell_name]\"!", LOG_GAME)

name = "[name]: [chosen_spell_name]"
return ..()

/datum/spellbook_entry/summon/specific_spell/can_buy(mob/living/carbon/human/user, obj/item/spellbook/book)
if(GLOB.mass_teaching)
return FALSE
return ..()

/datum/spellbook_entry/summon/specific_spell/can_be_purchased()
if(get_active_player_count() < MINIMUM_POP_FOR_RITUALS)
return FALSE
// Also, must be config enabled
return !CONFIG_GET(flag/no_summon_events)

#undef MINIMUM_POP_FOR_RITUALS
7 changes: 7 additions & 0 deletions code/modules/antagonists/wizard/wizard.dm
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key)

/datum/antagonist/wizard_minion/on_gain()
create_objectives()
. = ..()
ADD_TRAIT(owner, TRAIT_MAGICALLY_GIFTED, REF(src))

/datum/antagonist/wizard_minion/on_removal()
REMOVE_TRAIT(owner, TRAIT_MAGICALLY_GIFTED, REF(src))
return ..()

/datum/antagonist/wizard_minion/proc/create_objectives()
Expand All @@ -83,6 +88,7 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key)
. = ..()
if(allow_rename)
rename_wizard()
ADD_TRAIT(owner, TRAIT_MAGICALLY_GIFTED, REF(src))

/datum/antagonist/wizard/create_team(datum/team/wizard/new_team)
if(!new_team)
Expand Down Expand Up @@ -172,6 +178,7 @@ GLOBAL_LIST_EMPTY(wizard_spellbook_purchases_by_key)
qdel(spell)
owner.current.actions -= spell

REMOVE_TRAIT(owner, TRAIT_MAGICALLY_GIFTED, REF(src))
return ..()

/datum/antagonist/wizard/proc/equip_wizard()
Expand Down
2 changes: 0 additions & 2 deletions code/modules/mob/dead/new_player/new_player.dm
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,6 @@

log_manifest(character.mind.key,character.mind,character,latejoin = TRUE)

SEND_GLOBAL_SIGNAL(COMSIG_GLOB_CREWMEMBER_JOINED, character, rank)

if(humanc)
for(var/datum/loadout_item/item as anything in loadout_list_to_datums(humanc?.client?.prefs?.loadout_list))
if (item.restricted_roles && length(item.restricted_roles) && !(job.title in item.restricted_roles))
Expand Down
7 changes: 2 additions & 5 deletions code/modules/projectiles/guns/magic/staff.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,7 @@
var/allow_intruder_use = FALSE

/obj/item/gun/magic/staff/proc/is_wizard_or_friend(mob/user)
if(!user?.mind?.has_antag_datum(/datum/antagonist/wizard) \
&& !user.mind.has_antag_datum(/datum/antagonist/survivalist/magic) \
&& !user.mind.has_antag_datum(/datum/antagonist/wizard_minion) \
&& !allow_intruder_use)
if(!HAS_MIND_TRAIT(user, TRAIT_MAGICALLY_GIFTED) && !allow_intruder_use)
return FALSE
return TRUE

Expand Down Expand Up @@ -87,7 +84,7 @@
if(!is_wizard_or_friend(user))
to_chat(user, span_hypnophrase("<span style='font-size: 24px'>The staff feels weaker as you touch it</span>"))
user.balloon_alert(user, "the staff feels weaker as you touch it")

/obj/item/gun/magic/staff/healing/examine(mob/user)
. = ..()
if(!is_wizard_or_friend(user))
Expand Down
2 changes: 1 addition & 1 deletion code/modules/spells/spell.dm
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@
if(feedback)
to_chat(owner, span_warning("You don't feel strong enough without your robe!"))
return FALSE
if(!(human_owner.head?.clothing_flags & CASTING_CLOTHES) || (human_owner.glasses?.clothing_flags & CASTING_CLOTHES))
if(!(human_owner.head?.clothing_flags & CASTING_CLOTHES) && !(human_owner.glasses?.clothing_flags & CASTING_CLOTHES))
if(feedback)
to_chat(owner, span_warning("You don't feel strong enough without your hat!"))
return FALSE
Expand Down
Loading

0 comments on commit 9973cb4

Please sign in to comment.