diff --git a/code/modules/antagonists/roguetown/villain/peasantrebel.dm b/code/modules/antagonists/roguetown/villain/peasantrebel.dm index c6d1962bc..3636902ef 100644 --- a/code/modules/antagonists/roguetown/villain/peasantrebel.dm +++ b/code/modules/antagonists/roguetown/villain/peasantrebel.dm @@ -111,21 +111,6 @@ return FALSE return TRUE -/obj/effect/proc_holder/spell/self/rebelconvert - name = "RECRUIT REBELS" - desc = "!" - antimagic_allowed = TRUE - charge_max = 150 - -/obj/effect/proc_holder/spell/self/rebelconvert/cast(list/targets,mob/user = usr) - ..() - var/inputty = input("Make a speech!", "ROGUETOWN") as text|null - if(inputty) - user.say(inputty, forced = "spell") - var/datum/antagonist/prebel/PR = user.mind.has_antag_datum(/datum/antagonist/prebel) - for(var/mob/living/carbon/human/L in get_hearers_in_view(6, get_turf(user))) - addtimer(CALLBACK(L,TYPE_PROC_REF(/mob/living/carbon/human, rev_ask), user,PR,inputty),1) - /mob/living/carbon/human/proc/rev_ask(mob/living/carbon/human/guy,datum/antagonist/prebel/mind_datum,offer) if(!guy || !mind_datum || !offer) return diff --git a/code/modules/antagonists/roguetown/villain/werewolf/werewolf_spells.dm b/code/modules/antagonists/roguetown/villain/werewolf/werewolf_spells.dm index 9bfba3928..e904fe0de 100644 --- a/code/modules/antagonists/roguetown/villain/werewolf/werewolf_spells.dm +++ b/code/modules/antagonists/roguetown/villain/werewolf/werewolf_spells.dm @@ -32,6 +32,7 @@ message_admins("WEREWOLF: [werewolf_player.wolfname] howls: [message]") +//Old version, ugly and no feedback with the new icons /obj/effect/proc_holder/spell/self/claws name = "Lupine Claws" desc = "!" @@ -62,4 +63,32 @@ user.put_in_hands(r, TRUE, FALSE, TRUE) //user.visible_message("Your claws extend.", "You feel your claws extending.", "You hear a sound of claws extending.") extended = TRUE - \ No newline at end of file + +//New version (to work nicely with the new icons) +/obj/effect/proc_holder/spell/invoked/claws + name = "Lupine Claws" + desc = "!" + overlay_state = "claws" + antimagic_allowed = TRUE + charge_max = 20 //2 seconds + var/extended = FALSE + var/obj/item/rogueweapon/werewolf_claw/left/l + var/obj/item/rogueweapon/werewolf_claw/right/r + +/obj/effect/proc_holder/spell/invoked/claws/on_activation(mob/user = usr) + l = new(user,1) + r = new(user,2) + user.put_in_hands(l, TRUE, FALSE, TRUE) + user.put_in_hands(r, TRUE, FALSE, TRUE) + //user.visible_message("Your claws extend.", "You feel your claws extending.", "You hear a sound of claws extending.") + extended = TRUE + +/obj/effect/proc_holder/spell/invoked/claws/on_deactivation(mob/user = usr) + l = user.get_active_held_item() + r = user.get_inactive_held_item() + user.dropItemToGround(l, TRUE) + user.dropItemToGround(r, TRUE) + qdel(l) + qdel(r) + //user.visible_message("Your claws retract.", "You feel your claws retracting.", "You hear a sound of claws retracting.") + extended = FALSE diff --git a/code/modules/antagonists/roguetown/villain/werewolf/werewolf_transformation.dm b/code/modules/antagonists/roguetown/villain/werewolf/werewolf_transformation.dm index 96ff16cb8..433c645bd 100644 --- a/code/modules/antagonists/roguetown/villain/werewolf/werewolf_transformation.dm +++ b/code/modules/antagonists/roguetown/villain/werewolf/werewolf_transformation.dm @@ -116,7 +116,7 @@ W.mind.adjust_skillrank(/datum/skill/misc/climbing, 6, TRUE) W.AddSpell(new /obj/effect/proc_holder/spell/self/howl) - W.AddSpell(new /obj/effect/proc_holder/spell/self/claws) + W.AddSpell(new /obj/effect/proc_holder/spell/invoked/claws) ADD_TRAIT(src, TRAIT_NOSLEEP, TRAIT_GENERIC) @@ -171,7 +171,7 @@ W.mind.skill_experience = WA.stored_experience.Copy() W.RemoveSpell(new /obj/effect/proc_holder/spell/self/howl) - W.RemoveSpell(new /obj/effect/proc_holder/spell/self/claws) + W.RemoveSpell(new /obj/effect/proc_holder/spell/invoked/claws) W.regenerate_icons() diff --git a/code/modules/jobs/job_types/roguetown/adventurer/types/combat/mage.dm b/code/modules/jobs/job_types/roguetown/adventurer/types/combat/mage.dm index 68f5a5e90..aa9e0c46f 100644 --- a/code/modules/jobs/job_types/roguetown/adventurer/types/combat/mage.dm +++ b/code/modules/jobs/job_types/roguetown/adventurer/types/combat/mage.dm @@ -56,6 +56,20 @@ H.change_stat("intelligence", 3) H.change_stat("constitution", 1) H.change_stat("endurance", -1) - H.mind.AddSpell(new /obj/effect/proc_holder/spell/invoked/projectile/fireball) - H.mind.AddSpell(new /obj/effect/proc_holder/spell/invoked/projectile/lightningbolt) - H.mind.AddSpell(new /obj/effect/proc_holder/spell/invoked/projectile/fetch) + var/list/possible_spells = list( + "/obj/effect/proc_holder/spell/arcane/telepathy", + "/obj/effect/proc_holder/spell/arcane/ignite", + "/obj/effect/proc_holder/spell/arcane/blink", + "/obj/effect/proc_holder/spell/arcane/swap", + "/obj/effect/proc_holder/spell/arcane/smokescreen", + "/obj/effect/proc_holder/spell/arcane/blindness", + "/obj/effect/proc_holder/spell/arcane/invisibility", + "/obj/effect/proc_holder/spell/arcane/projectile/fetch" + ) + H.mind.AddSpell(pick(new /obj/effect/proc_holder/spell/arcane/projectile/fireball,new /obj/effect/proc_holder/spell/arcane/projectile/lightningbolt)) + for(var/i=2,i>0,i--) + var/random_item = pick(possible_spells) + var typepath = text2path(random_item) + H.mind.AddSpell(new typepath) + possible_spells.Remove(random_item) + possible_spells = null diff --git a/code/modules/jobs/job_types/roguetown/adventurer/types/combat/sorceress.dm b/code/modules/jobs/job_types/roguetown/adventurer/types/combat/sorceress.dm index c389c526d..ed967e742 100644 --- a/code/modules/jobs/job_types/roguetown/adventurer/types/combat/sorceress.dm +++ b/code/modules/jobs/job_types/roguetown/adventurer/types/combat/sorceress.dm @@ -27,7 +27,7 @@ backl = /obj/item/storage/backpack/rogue/satchel beltr = /obj/item/reagent_containers/glass/bottle/rogue/manapot beltl = /obj/item/rogueweapon/huntingknife - neck = /obj/item/storage/belt/rogue/pouch/coins/poor + neck = /obj/item/storage/belt/rogue/pouch/coins/poor r_hand = /obj/item/rogueweapon/woodstaff if(H.mind) H.mind.adjust_skillrank(/datum/skill/combat/polearms, 1, TRUE) @@ -47,6 +47,20 @@ H.change_stat("strength", -1) H.change_stat("intelligence", 4) H.change_stat("speed", 1) - H.mind.AddSpell(new /obj/effect/proc_holder/spell/invoked/projectile/fireball) - H.mind.AddSpell(new /obj/effect/proc_holder/spell/invoked/projectile/lightningbolt) - H.mind.AddSpell(new /obj/effect/proc_holder/spell/invoked/projectile/fetch) + var/list/possible_spells = list( + "/obj/effect/proc_holder/spell/arcane/telepathy", + "/obj/effect/proc_holder/spell/arcane/ignite", + "/obj/effect/proc_holder/spell/arcane/blink", + "/obj/effect/proc_holder/spell/arcane/swap", + "/obj/effect/proc_holder/spell/arcane/smokescreen", + "/obj/effect/proc_holder/spell/arcane/blindness", + "/obj/effect/proc_holder/spell/arcane/invisibility", + "/obj/effect/proc_holder/spell/arcane/projectile/fetch" + ) + H.mind.AddSpell(pick(new /obj/effect/proc_holder/spell/arcane/projectile/fireball,new /obj/effect/proc_holder/spell/arcane/projectile/lightningbolt)) + for(var/i=2,i>0,i--) + var/random_item = pick(possible_spells) + var typepath = text2path(random_item) + H.mind.AddSpell(new typepath) + possible_spells.Remove(random_item) + possible_spells = null diff --git a/code/modules/jobs/job_types/roguetown/church/priest.dm b/code/modules/jobs/job_types/roguetown/church/priest.dm index 71f321eb7..d2d1d1c85 100644 --- a/code/modules/jobs/job_types/roguetown/church/priest.dm +++ b/code/modules/jobs/job_types/roguetown/church/priest.dm @@ -154,19 +154,3 @@ to_chat(src, span_warning("I need to do this from the chapel.")) return FALSE priority_announce("[inputty]", title = "The Priest Speaks", sound = 'sound/misc/bell.ogg') - -/obj/effect/proc_holder/spell/self/convertrole/templar - name = "Recruit Templar" - new_role = "Templar" - recruitment_faction = "Templars" - recruitment_message = "Serve the nine, %RECRUIT!" - accept_message = "FOR THE NINE!" - refuse_message = "I refuse." - -/obj/effect/proc_holder/spell/self/convertrole/monk - name = "Recruit Acolyte" - new_role = "Acolyte" - recruitment_faction = "Church" - recruitment_message = "Serve the nine, %RECRUIT!" - accept_message = "FOR THE NINE!" - refuse_message = "I refuse." diff --git a/code/modules/jobs/job_types/roguetown/courtier/magician.dm b/code/modules/jobs/job_types/roguetown/courtier/magician.dm index 514193072..dd5aa0d50 100644 --- a/code/modules/jobs/job_types/roguetown/courtier/magician.dm +++ b/code/modules/jobs/job_types/roguetown/courtier/magician.dm @@ -13,7 +13,6 @@ "Half-Elf", "Aasimar", ) - spells = list(/obj/effect/proc_holder/spell/invoked/projectile/fireball/greater, /obj/effect/proc_holder/spell/invoked/projectile/fireball, /obj/effect/proc_holder/spell/invoked/projectile/lightningbolt, /obj/effect/proc_holder/spell/invoked/projectile/fetch) display_order = JDO_MAGICIAN tutorial = "Your creed is one dedicated to the conquering of the arcane arts and the constant thrill of knowledge. \ You owe your life to the Lord, for it was his coin that allowed you to continue your studies in these dark times. \ @@ -70,3 +69,24 @@ head = /obj/item/clothing/head/roguetown/wizhat armor = /obj/item/clothing/suit/roguetown/shirt/robe/wizard H.dna.species.soundpack_m = new /datum/voicepack/male/wizard() + + var/list/possible_spells = list( + "/obj/effect/proc_holder/spell/arcane/telepathy", + "/obj/effect/proc_holder/spell/arcane/ignite", + "/obj/effect/proc_holder/spell/arcane/blink", + "/obj/effect/proc_holder/spell/arcane/swap", + "/obj/effect/proc_holder/spell/arcane/smokescreen", + "/obj/effect/proc_holder/spell/arcane/projectile/lightningbolt", + "/obj/effect/proc_holder/spell/arcane/projectile/fireball", + "/obj/effect/proc_holder/spell/arcane/blindness", + "/obj/effect/proc_holder/spell/arcane/invisibility", + "/obj/effect/proc_holder/spell/arcane/projectile/fetch" + ) + H.mind.AddSpell(new /obj/effect/proc_holder/spell/arcane/projectile/fireball/greater) + for(var/i=3,i>0,i--) + var/random_item = pick(possible_spells) + var typepath = text2path(random_item) + H.mind.AddSpell(new typepath) + possible_spells.Remove(random_item) + possible_spells = null + diff --git a/code/modules/jobs/job_types/roguetown/garrison/bogmaster.dm b/code/modules/jobs/job_types/roguetown/garrison/bogmaster.dm index 59c344183..1a42c946e 100644 --- a/code/modules/jobs/job_types/roguetown/garrison/bogmaster.dm +++ b/code/modules/jobs/job_types/roguetown/garrison/bogmaster.dm @@ -86,18 +86,3 @@ ADD_TRAIT(H, TRAIT_HEAVYARMOR, TRAIT_GENERIC) ADD_TRAIT(H, TRAIT_MEDIUMARMOR, TRAIT_GENERIC) ADD_TRAIT(H, TRAIT_STEELHEARTED, TRAIT_GENERIC) - -/obj/effect/proc_holder/spell/self/convertrole/bog - name = "Recruit Bogmen" - new_role = "Bog Guard" - recruitment_faction = "Bog Guard" - recruitment_message = "Serve the bog, %RECRUIT!" - accept_message = "FOR THE BOG!" - refuse_message = "I refuse." - -/obj/effect/proc_holder/spell/self/convertrole/bog/convert(mob/living/carbon/human/recruit, mob/living/carbon/human/recruiter) - . = ..() - if(!.) - return - recruit.verbs |= /mob/proc/haltyell - diff --git a/code/modules/jobs/job_types/roguetown/nobility/lady.dm b/code/modules/jobs/job_types/roguetown/nobility/lady.dm index ee34bb202..ff3b07b63 100644 --- a/code/modules/jobs/job_types/roguetown/nobility/lady.dm +++ b/code/modules/jobs/job_types/roguetown/nobility/lady.dm @@ -71,12 +71,3 @@ H.change_stat("speed", 2) H.change_stat("perception", 2) H.change_stat("fortune", 5) - -/obj/effect/proc_holder/spell/self/convertrole/servant - name = "Recruit Servant" - new_role = "Servant" - recruitment_faction = "Servants" - recruitment_message = "Serve the crown, %RECRUIT!" - accept_message = "FOR THE CROWN!" - refuse_message = "I refuse." - charge_max = 100 diff --git a/code/modules/jobs/job_types/roguetown/nobility/lord.dm b/code/modules/jobs/job_types/roguetown/nobility/lord.dm index 7f1c70288..fda6ad66f 100644 --- a/code/modules/jobs/job_types/roguetown/nobility/lord.dm +++ b/code/modules/jobs/job_types/roguetown/nobility/lord.dm @@ -65,12 +65,12 @@ GLOBAL_LIST_EMPTY(lord_titles) belt = /obj/item/storage/belt/rogue/leather/plaquegold l_hand = /obj/item/rogueweapon/lordscepter backpack_contents = list(/obj/item/rogueweapon/huntingknife/idagger/steel/special = 1) - id = /obj/item/clothing/ring/active/nomag + id = /obj/item/clothing/ring/active/nomag if(H.gender == MALE) pants = /obj/item/clothing/under/roguetown/tights/black shirt = /obj/item/clothing/suit/roguetown/shirt/undershirt/black armor = /obj/item/clothing/suit/roguetown/armor/leather/vest/black - shoes = /obj/item/clothing/shoes/roguetown/boots + shoes = /obj/item/clothing/shoes/roguetown/boots if(H.mind) H.mind.adjust_skillrank(/datum/skill/combat/polearms, 2, TRUE) H.mind.adjust_skillrank(/datum/skill/combat/maces, 2, TRUE) @@ -140,61 +140,3 @@ GLOBAL_LIST_EMPTY(lord_titles) else family_guy.fully_replace_character_name(family_guy.real_name, family_guy.real_name + " " + GLOB.lordsurname) return family_guy.real_name - -/obj/effect/proc_holder/spell/self/grant_title - name = "Grant Title" - desc = "Grant someone a title of honor... Or shame." - antimagic_allowed = TRUE - charge_max = 100 - /// Maximum range for title granting - var/title_range = 3 - /// Maximum length for the title - var/title_length = 42 - -/obj/effect/proc_holder/spell/self/grant_title/cast(list/targets, mob/user = usr) - . = ..() - var/granted_title = input(user, "What title do you wish to grant?", "[name]") as null|text - granted_title = reject_bad_text(granted_title, title_length) - if(!granted_title) - return - var/list/recruitment = list() - for(var/mob/living/carbon/human/village_idiot in (get_hearers_in_view(title_range, user) - user)) - //not allowed - if(!can_title(village_idiot)) - continue - recruitment[village_idiot.name] = village_idiot - if(!length(recruitment)) - to_chat(user, span_warning("There are no potential honoraries in range.")) - return - var/inputty = input(user, "Select an honorary!", "[name]") as anything in recruitment - if(inputty) - var/mob/living/carbon/human/recruit = recruitment[inputty] - if(!QDELETED(recruit) && (recruit in get_hearers_in_view(title_range, user))) - INVOKE_ASYNC(src, PROC_REF(village_idiotify), recruit, user, granted_title) - else - to_chat(user, span_warning("Honorific failed!")) - else - to_chat(user, span_warning("Honorific cancelled.")) - -/obj/effect/proc_holder/spell/self/grant_title/proc/can_title(mob/living/carbon/human/recruit) - //wtf - if(QDELETED(recruit)) - return FALSE - //need a mind - if(!recruit.mind) - return FALSE - //need to see their damn face - if(!recruit.get_face_name(null)) - return FALSE - return TRUE - -/obj/effect/proc_holder/spell/self/grant_title/proc/village_idiotify(mob/living/carbon/human/recruit, mob/living/carbon/human/recruiter, granted_title) - if(QDELETED(recruit) || QDELETED(recruiter) || !granted_title) - return FALSE - if(GLOB.lord_titles[recruit.real_name]) - recruiter.say("I HEREBY STRIP YOU, [uppertext(recruit.name)], OF THE TITLE OF [uppertext(GLOB.lord_titles[recruit.real_name])]!") - GLOB.lord_titles -= recruit.real_name - return FALSE - recruiter.say("I HEREBY GRANT YOU, [uppertext(recruit.name)], THE TITLE OF [uppertext(granted_title)]!") - GLOB.lord_titles[recruit.real_name] = granted_title - return TRUE diff --git a/code/modules/jobs/job_types/roguetown/nobility/sheriff.dm b/code/modules/jobs/job_types/roguetown/nobility/sheriff.dm index ab2d70635..0ecad3d07 100644 --- a/code/modules/jobs/job_types/roguetown/nobility/sheriff.dm +++ b/code/modules/jobs/job_types/roguetown/nobility/sheriff.dm @@ -91,91 +91,3 @@ ADD_TRAIT(H, TRAIT_MEDIUMARMOR, TRAIT_GENERIC) ADD_TRAIT(H, TRAIT_STEELHEARTED, TRAIT_GENERIC) H.verbs |= /mob/proc/haltyell - -/obj/effect/proc_holder/spell/self/convertrole - name = "Recruit Beggar" - desc = "Recruit someone to your cause." - antimagic_allowed = TRUE - charge_max = 100 - /// Role given if recruitment is accepted - var/new_role = "Beggar" - /// Faction shown to the user in the recruitment prompt - var/recruitment_faction = "Beggars" - /// Message the recruiter gives - var/recruitment_message = "Serve the beggars, %RECRUIT!" - /// Range to search for potential recruits - var/recruitment_range = 3 - /// Say message when the recruit accepts - var/accept_message = "I will serve!" - /// Say message when the recruit refuses - var/refuse_message = "I refuse." - -/obj/effect/proc_holder/spell/self/convertrole/cast(list/targets,mob/user = usr) - . = ..() - var/list/recruitment = list() - for(var/mob/living/carbon/human/recruit in (get_hearers_in_view(recruitment_range, user) - user)) - //not allowed - if(!can_convert(recruit)) - continue - recruitment[recruit.name] = recruit - if(!length(recruitment)) - to_chat(user, span_warning("There are no potential recruits in range.")) - return - var/inputty = input(user, "Select a potential recruit!", "[name]") as anything in recruitment - if(inputty) - var/mob/living/carbon/human/recruit = recruitment[inputty] - if(!QDELETED(recruit) && (recruit in get_hearers_in_view(recruitment_range, user))) - INVOKE_ASYNC(src, PROC_REF(convert), recruit, user) - else - to_chat(user, span_warning("Recruitment failed!")) - else - to_chat(user, span_warning("Recruitment cancelled.")) - -/obj/effect/proc_holder/spell/self/convertrole/proc/can_convert(mob/living/carbon/human/recruit) - //wtf - if(QDELETED(recruit)) - return FALSE - //need a mind - if(!recruit.mind) - return FALSE - //only migrants and peasants - if(!(recruit.job in GLOB.peasant_positions) && \ - !(recruit.job in GLOB.yeoman_positions) && \ - !(recruit.job in GLOB.allmig_positions) && \ - !(recruit.job in GLOB.mercenary_positions)) - return FALSE - //need to see their damn face - if(!recruit.get_face_name(null)) - return FALSE - return TRUE - -/obj/effect/proc_holder/spell/self/convertrole/proc/convert(mob/living/carbon/human/recruit, mob/living/carbon/human/recruiter) - if(QDELETED(recruit) || QDELETED(recruiter)) - return FALSE - recruiter.say(replacetext(recruitment_message, "%RECRUIT", "[recruit]"), forced = "[name]") - var/prompt = alert(recruit, "Do you wish to become a [new_role]?", "[recruitment_faction] Recruitment", "Yes", "No") - if(QDELETED(recruit) || QDELETED(recruiter) || !(recruiter in get_hearers_in_view(recruitment_range, recruit))) - return FALSE - if(prompt != "Yes") - if(refuse_message) - recruit.say(refuse_message, forced = "[name]") - return FALSE - if(accept_message) - recruit.say(accept_message, forced = "[name]") - if(new_role) - recruit.job = new_role - return TRUE - -/obj/effect/proc_holder/spell/self/convertrole/guard - name = "Recruit Guardsmen" - new_role = "Watchman" - recruitment_faction = "Watchman" - recruitment_message = "Serve the town guard, %RECRUIT!" - accept_message = "FOR THE KING!" - refuse_message = "I refuse." - -/obj/effect/proc_holder/spell/self/convertrole/guard/convert(mob/living/carbon/human/recruit, mob/living/carbon/human/recruiter) - . = ..() - if(!.) - return - recruit.verbs |= /mob/proc/haltyell diff --git a/code/modules/jobs/job_types/roguetown/yeomen/archivist.dm b/code/modules/jobs/job_types/roguetown/yeomen/archivist.dm index a21f10a64..547a0a70c 100644 --- a/code/modules/jobs/job_types/roguetown/yeomen/archivist.dm +++ b/code/modules/jobs/job_types/roguetown/yeomen/archivist.dm @@ -6,7 +6,7 @@ faction = "Station" total_positions = 1 spawn_positions = 1 - spells = list(/obj/effect/proc_holder/spell/invoked/projectile/fetch) + spells = list(/obj/effect/proc_holder/spell/arcane/projectile/fetch) allowed_races = list( "Humen", "Elf", @@ -46,9 +46,8 @@ H.mind.adjust_skillrank(/datum/skill/misc/alchemy, 6, TRUE) H.mind.adjust_skillrank(/datum/skill/misc/medicine, 3, TRUE) H.mind.adjust_skillrank(/datum/skill/misc/riding, 2, TRUE) + H.mind.adjust_skillrank(/datum/skill/magic/arcane, 1, TRUE) H.change_stat("strength", -2) H.change_stat("intelligence", 8) H.change_stat("constitution", -2) H.change_stat("speed", -2) - - diff --git a/code/modules/spells/roguetown/_roguetown.dm b/code/modules/spells/roguetown/_roguetown.dm index 1e8983ed6..23f6af13f 100644 --- a/code/modules/spells/roguetown/_roguetown.dm +++ b/code/modules/spells/roguetown/_roguetown.dm @@ -11,12 +11,29 @@ invocation_type = "shout" var/active_sound +//Old update icon +///obj/effect/proc_holder/spell/update_icon() +// if(!action) +// return +// action.button_icon_state = "[base_icon_state][active]" +// if(overlay_state) +// action.overlay_state = overlay_state +// action.name = name +// action.UpdateButtonIcon() + +//That is a ugly way of checking it the spell is a mmb cast or not and I know it... +//But it's what worked better so far for some reason. /obj/effect/proc_holder/spell/update_icon() if(!action) return - action.button_icon_state = "[base_icon_state][active]" - if(overlay_state) - action.overlay_state = overlay_state + action.button_icon_state = base_icon_state + if (selection_type == "view") + if(overlay_state) + action.overlay_state = "[overlay_state]1" + else + action.button_icon_state = "[base_icon_state][active]" + if(overlay_state) + action.overlay_state = "[overlay_state][active]" action.name = name action.UpdateButtonIcon() diff --git a/code/modules/spells/roguetown/arcane.dm b/code/modules/spells/roguetown/arcane.dm new file mode 100644 index 000000000..3d569679c --- /dev/null +++ b/code/modules/spells/roguetown/arcane.dm @@ -0,0 +1,193 @@ +//This is basically a pseudo spell/Invoked clone +//Might as well do this if we end having both arcane and divine versions some spells +//That will also help organizing future lists and shit (specially if we are adding spell books later) + +/obj/effect/proc_holder/spell/arcane + name = "arcane spell" + range = -1 + selection_type = "range" + no_early_release = TRUE + charge_max = 30 + charge_type = "recharge" + invocation_type = "shout" + var/active_sound + clothes_req = FALSE + warnie = "spellwarning" + no_early_release = TRUE + chargedloop = /datum/looping_sound/invokegen + associated_skill = /datum/skill/magic/arcane + charging_slowdown = 1 + +/obj/effect/proc_holder/spell/arcane/Click() + var/mob/living/user = usr + if(!istype(user)) + return + if(!can_cast(user)) + start_recharge() + deactivate(user) + return + if(active) + deactivate(user) + else + if(active_sound) + user.playsound_local(user,active_sound,100,vary = FALSE) + active = TRUE + add_ranged_ability(user, null, TRUE) + on_activation(user) + update_icon() + start_recharge() + +/obj/effect/proc_holder/spell/arcane/deactivate(mob/living/user) + ..() + active = FALSE + remove_ranged_ability(null) + on_deactivation(user) + +/obj/effect/proc_holder/spell/arcane/proc/on_activation(mob/user) + return + +/obj/effect/proc_holder/spell/arcane/proc/on_deactivation(mob/user) + return + +/obj/effect/proc_holder/spell/arcane/InterceptClickOn(mob/living/caller, params, atom/target) + . = ..() + if(.) + return FALSE + if(!can_cast(caller) || !cast_check(FALSE, ranged_ability_user)) + return FALSE + if(perform(list(target), TRUE, user = ranged_ability_user)) + caller.mind.adjust_experience(associated_skill, (caller.STAINT*0.3))//Arcane Skill exp gain - Delete/Edit if on your leisure + return TRUE + +/obj/effect/proc_holder/spell/arcane/projectile + var/projectile_type = /obj/projectile/magic/teleport + var/list/projectile_var_overrides = list() + var/projectile_amount = 1 //Projectiles per cast. + var/current_amount = 0 //How many projectiles left. + var/projectiles_per_fire = 1 //Projectiles per fire. Probably not a good thing to use unless you override ready_projectile(). + +/obj/effect/proc_holder/spell/arcane/projectile/proc/ready_projectile(obj/projectile/P, atom/target, mob/user, iteration) + return + +/obj/effect/proc_holder/spell/arcane/projectile/cast(list/targets, mob/living/user) + . = ..() + var/target = targets[1] + var/turf/T = user.loc + var/turf/U = get_step(user, user.dir) // Get the tile infront of the move, based on their direction + if(!isturf(U) || !isturf(T)) + return FALSE + fire_projectile(user, target) + user.newtonian_move(get_dir(U, T)) + update_icon() + start_recharge() + return TRUE + +/obj/effect/proc_holder/spell/arcane/projectile/proc/fire_projectile(mob/living/user, atom/target) + current_amount-- + for(var/i in 1 to projectiles_per_fire) + var/obj/projectile/P = new projectile_type(user.loc) + if(istype(P, /obj/projectile/magic/bloodsteal)) + var/obj/projectile/magic/bloodsteal/B = P + B.sender = user + P.firer = user + P.preparePixelProjectile(target, user) + for(var/V in projectile_var_overrides) + if(P.vars[V]) + P.vv_edit_var(V, projectile_var_overrides[V]) + ready_projectile(P, target, user, i) + P.fire() + return TRUE + +/obj/effect/proc_holder/spell/arcane/targeted //can mean aoe for mobs (limited/unlimited number) or one target mob + var/max_targets = 1 //leave 0 for unlimited targets in range, 1 for one selectable target in range, more for limited number of casts (can all target one guy, depends on target_ignore_prev) in range + var/target_ignore_prev = 1 //only important if max_targets > 1, affects if the spell can be cast multiple times at one person from one cast + var/include_user = 0 //if it includes usr in the target list + var/random_target = 0 // chooses random viable target instead of asking the caster + var/random_target_priority = TARGET_CLOSEST // if random_target is enabled how it will pick the target + + +/obj/effect/proc_holder/spell/arcane/aoe_turf //affects all turfs in view or range (depends) + var/inner_radius = -1 //for all your ring spell needs + +/obj/effect/proc_holder/spell/arcane/targeted/choose_targets(mob/user = usr) + var/list/targets = list() + + switch(max_targets) + if(0) //unlimited + for(var/mob/living/target in view_or_range(range, user, selection_type)) + if(!can_target(target)) + continue + targets += target + if(1) //single target can be picked + if(range < 0) + targets += user + else + var/possible_targets = list() + + for(var/mob/living/M in view_or_range(range, user, selection_type)) + if(!include_user && user == M) + continue + if(!can_target(M)) + continue + possible_targets += M + + //targets += input("Choose the target for the spell.", "Targeting") as mob in possible_targets + //Adds a safety check post-input to make sure those targets are actually in range. + var/mob/M + if(!random_target) + M = input("Choose the target for the spell.", "Targeting") as null|mob in sortNames(possible_targets) + else + switch(random_target_priority) + if(TARGET_RANDOM) + M = pick(possible_targets) + if(TARGET_CLOSEST) + for(var/mob/living/L in possible_targets) + if(M) + if(get_dist(user,L) < get_dist(user,M)) + if(los_check(user,L)) + M = L + else + if(los_check(user,L)) + M = L + if(M in view_or_range(range, user, selection_type)) + targets += M + + else + var/list/possible_targets = list() + for(var/mob/living/target in view_or_range(range, user, selection_type)) + if(!can_target(target)) + continue + possible_targets += target + for(var/i=1,i<=max_targets,i++) + if(!possible_targets.len) + break + if(target_ignore_prev) + var/target = pick(possible_targets) + possible_targets -= target + targets += target + else + targets += pick(possible_targets) + + if(!include_user && (user in targets)) + targets -= user + + if(!targets.len && !cast_without_targets) //doesn't waste the spell + revert_cast(user) + return + + perform(targets,user=user) + +/obj/effect/proc_holder/spell/arcane/aoe_turf/choose_targets(mob/user = usr) + var/list/targets = list() + + for(var/turf/target in view_or_range(range,user,selection_type)) + if(!can_target(target)) + continue + if(!(target in view_or_range(inner_radius,user,selection_type))) + targets += target + + if(!targets.len) //doesn't waste the spell + revert_cast() + return + + perform(targets,user=user) diff --git a/code/modules/spells/roguetown/arcane/blindness.dm b/code/modules/spells/roguetown/arcane/blindness.dm new file mode 100644 index 000000000..dbce6704c --- /dev/null +++ b/code/modules/spells/roguetown/arcane/blindness.dm @@ -0,0 +1,23 @@ +// BLINDNESS-------------- + +/obj/effect/proc_holder/spell/arcane/blindness + name = "Blindness" + desc = "" + overlay_state = "blindness" + releasedrain = 40 + chargedrain = 0 + chargetime = 0 + charge_max = 10 SECONDS + range = 7 + movement_interrupt = FALSE + sound = 'sound/magic/churn.ogg' + antimagic_allowed = TRUE + +/obj/effect/proc_holder/spell/arcane/blindness/cast(list/targets, mob/user = usr) + if(isliving(targets[1])) + var/mob/living/target = targets[1] + if(target.anti_magic_check(TRUE, TRUE)) + return FALSE + target.visible_message(span_warning("[user] points at [target]'s eyes!"),span_warning("My eyes are covered in darkness!")) + target.blind_eyes(2) + return TRUE \ No newline at end of file diff --git a/code/modules/spells/roguetown/arcane/blink.dm b/code/modules/spells/roguetown/arcane/blink.dm new file mode 100644 index 000000000..93446d3e4 --- /dev/null +++ b/code/modules/spells/roguetown/arcane/blink.dm @@ -0,0 +1,30 @@ +//BLINK----------------- + +/obj/effect/proc_holder/spell/arcane/blink + name = "Blink" + desc = "" + overlay_state = "blink" + sound = 'sound/magic/magic_nulled.ogg' + range = 8 + releasedrain = 50 + chargedrain = 0 + chargetime = 0 + charge_max = 15 SECONDS + var/include_space = FALSE //whether it includes space tiles in possible teleport locations + var/include_dense = FALSE //whether it includes dense tiles in possible teleport locations + +/obj/effect/temp_visual/blink + icon_state = "anom" + layer = ABOVE_MOB_LAYER + plane = GAME_PLANE_UPPER + +/obj/effect/proc_holder/spell/arcane/blink/cast(list/targets,mob/user = usr) + . = ..() + if(isopenturf(targets[1])) + var/atom/location = get_turf(targets[1]) + if(location in oview(range,user)) + new /obj/effect/temp_visual/swap(get_turf(user)) + new /obj/effect/temp_visual/swap(get_turf(location)) + do_teleport(user, location, forceMove = TRUE, channel = TELEPORT_CHANNEL_MAGIC) + return TRUE + return FALSE diff --git a/code/modules/spells/roguetown/arcane/fetch.dm b/code/modules/spells/roguetown/arcane/fetch.dm new file mode 100644 index 000000000..f17f4a070 --- /dev/null +++ b/code/modules/spells/roguetown/arcane/fetch.dm @@ -0,0 +1,26 @@ +//FETCH------------------------- + +/obj/effect/proc_holder/spell/arcane/projectile/fetch + name = "Fetch" + desc = "" + range = 15 + projectile_type = /obj/projectile/magic/fetch + overlay_state = "fetch" + sound = list('sound/magic/magnet.ogg') + releasedrain = 5 + chargedrain = 0 + chargetime = 0 + charge_max = 5 SECONDS + warnie = "spellwarning" + no_early_release = TRUE + charging_slowdown = 1 + +/obj/projectile/magic/fetch/on_hit(target) + . = ..() + if(ismob(target)) + var/mob/M = target + if(M.anti_magic_check()) + visible_message(span_warning("[target] repells the fetch!")) + playsound(get_turf(target), 'sound/magic/magic_nulled.ogg', 100) + qdel(src) + return BULLET_ACT_BLOCK \ No newline at end of file diff --git a/code/modules/spells/roguetown/arcane/fireball.dm b/code/modules/spells/roguetown/arcane/fireball.dm new file mode 100644 index 000000000..b7037c025 --- /dev/null +++ b/code/modules/spells/roguetown/arcane/fireball.dm @@ -0,0 +1,72 @@ +//FIREBALL------------------------- + +/obj/effect/proc_holder/spell/arcane/projectile/fireball + name = "Fireball" + desc = "" + clothes_req = FALSE + range = 8 + projectile_type = /obj/projectile/magic/aoe/fireball/rogue + overlay_state = "fireball" + sound = list('sound/magic/fireball.ogg') + active = FALSE + releasedrain = 30 + chargedrain = 1 + chargetime = 15 + charge_max = 10 SECONDS + warnie = "spellwarning" + no_early_release = TRUE + movement_interrupt = FALSE + charging_slowdown = 3 + +/obj/effect/proc_holder/spell/arcane/projectile/fireball/fire_projectile(list/targets, mob/living/user) + projectile_var_overrides = list("range" = 8) + return ..() + +/obj/projectile/magic/aoe/fireball/rogue + name = "fireball" + exp_heavy = 0 + exp_light = 0 + exp_flash = 0 + exp_fire = 1 + damage = 10 + damage_type = BURN + nodamage = FALSE + flag = "magic" + hitsound = 'sound/blank.ogg' + +/obj/projectile/magic/aoe/fireball/rogue/on_hit(target) + . = ..() + if(ismob(target)) + var/mob/M = target + if(M.anti_magic_check()) + visible_message(span_warning("[src] fizzles on contact with [target]!")) + playsound(get_turf(target), 'sound/magic/magic_nulled.ogg', 100) + qdel(src) + return BULLET_ACT_BLOCK + +//GREATER FIREBALL------------------------- + +/obj/effect/proc_holder/spell/arcane/projectile/fireball/greater + name = "Greater Fireball" + desc = "" + clothes_req = FALSE + range = 8 + projectile_type = /obj/projectile/magic/aoe/fireball/rogue/great + overlay_state = "greaterfireball" + sound = list('sound/magic/fireball.ogg') + releasedrain = 50 + chargedrain = 1 + chargetime = 15 + charge_max = 10 SECONDS + warnie = "spellwarning" + no_early_release = TRUE + movement_interrupt = TRUE + chargedloop = /datum/looping_sound/invokegen + +/obj/projectile/magic/aoe/fireball/rogue/great + name = "fireball" + exp_heavy = 0 + exp_light = 1 + exp_flash = 2 + exp_fire = 2 + flag = "magic" \ No newline at end of file diff --git a/code/modules/spells/roguetown/arcane/ignite.dm b/code/modules/spells/roguetown/arcane/ignite.dm new file mode 100644 index 000000000..6c08ccda2 --- /dev/null +++ b/code/modules/spells/roguetown/arcane/ignite.dm @@ -0,0 +1,35 @@ +//IGNITE------------------ + +/obj/effect/proc_holder/spell/arcane/ignite + name = "Ignite" + desc = "" + overlay_state = "flame" + sound = 'sound/items/firelight.ogg' + range = 4 + releasedrain = 30 + chargedrain = 0 + chargetime = 0 + charge_max = 10 SECONDS + +/obj/effect/proc_holder/spell/arcane/ignite/cast(list/targets, mob/user = usr) + . = ..() + if(isliving(targets[1])) + var/mob/living/L = targets[1] + user.visible_message("[user] points at [L]!") + if(L.anti_magic_check(TRUE, TRUE)) + return FALSE + L.adjust_fire_stacks(5) + L.IgniteMob() + addtimer(CALLBACK(L, TYPE_PROC_REF(/mob/living, ExtinguishMob)), 5 SECONDS) + return TRUE + + // Spell interaction with ignitable objects (burn wooden things, light torches up) + else if(isobj(targets[1])) + var/obj/O = targets[1] + if(O.fire_act()) + user.visible_message("[user] points at [O], igniting it in flames!") + return TRUE + else + to_chat(user, span_warning("You point at [O], but it fails to catch fire.")) + return FALSE + return FALSE \ No newline at end of file diff --git a/code/modules/spells/roguetown/arcane/invisibility.dm b/code/modules/spells/roguetown/arcane/invisibility.dm new file mode 100644 index 000000000..6d1579936 --- /dev/null +++ b/code/modules/spells/roguetown/arcane/invisibility.dm @@ -0,0 +1,26 @@ +// INVISIBILITY-------------- + +/obj/effect/proc_holder/spell/arcane/invisibility + name = "Invisibility" + desc = "" + overlay_state = "invisibility" + releasedrain = 50 + chargedrain = 0 + chargetime = 0 + charge_max = 30 SECONDS + range = 3 + movement_interrupt = FALSE + sound = 'sound/misc/area.ogg' //This sound doesnt play for some reason. Fix me. + antimagic_allowed = TRUE + +/obj/effect/proc_holder/spell/arcane/invisibility/cast(list/targets, mob/living/user) + if(isliving(targets[1])) + var/mob/living/target = targets[1] + if(target.anti_magic_check(TRUE, TRUE)) + return FALSE + target.visible_message(span_warning("[target] starts to fade into thin air!"), span_notice("You start to become invisible!")) + animate(target, alpha = 0, time = 1 SECONDS, easing = EASE_IN) + target.mob_timers[MT_INVISIBILITY] = world.time + 15 SECONDS + addtimer(CALLBACK(target, TYPE_PROC_REF(/mob/living, update_sneak_invis), TRUE), 15 SECONDS) + addtimer(CALLBACK(target, TYPE_PROC_REF(/atom/movable, visible_message), span_warning("[target] fades back into view."), span_notice("You become visible again.")), 15 SECONDS) + return FALSE \ No newline at end of file diff --git a/code/modules/spells/roguetown/arcane/lightning.dm b/code/modules/spells/roguetown/arcane/lightning.dm new file mode 100644 index 000000000..1476cdfc2 --- /dev/null +++ b/code/modules/spells/roguetown/arcane/lightning.dm @@ -0,0 +1,48 @@ +//LIGHTNING--------------- + +/obj/effect/proc_holder/spell/arcane/projectile/lightningbolt + name = "Bolt of Lightning" + desc = "" + overlay_state = "lightning" + sound = 'sound/magic/lightning.ogg' + range = 8 + projectile_type = /obj/projectile/magic/lightning + releasedrain = 30 + chargedrain = 1 + chargetime = 15 + charge_max = 10 SECONDS + movement_interrupt = FALSE + charging_slowdown = 3 + +/obj/projectile/magic/lightning + name = "bolt of lightning" + tracer_type = /obj/effect/projectile/tracer/stun + muzzle_type = null + impact_type = null + hitscan = TRUE + movement_type = UNSTOPPABLE + light_color = LIGHT_COLOR_WHITE + damage = 15 + damage_type = BURN + nodamage = FALSE + speed = 0.3 + flag = "magic" + light_color = "#ffffff" + light_range = 7 + +/obj/projectile/magic/lightning/on_hit(target) + . = ..() + if(ismob(target)) + var/mob/M = target + if(M.anti_magic_check()) + visible_message(span_warning("[src] fizzles on contact with [target]!")) + playsound(get_turf(target), 'sound/magic/magic_nulled.ogg', 100) + qdel(src) + return BULLET_ACT_BLOCK + if(isliving(target)) + var/mob/living/L = target +// for(var/obj/item/I in L.get_equipped_items()) //Maybe add 5 damage for each metal gear in the target? +// if(I.smeltresult == /obj/item/ingot/iron) //More damage if the target is on water tuff too? +// damage += 5 //(dont know it that code work tho) + L.electrocute_act(1, src) + qdel(src) \ No newline at end of file diff --git a/code/modules/spells/roguetown/arcane/smokescreen.dm b/code/modules/spells/roguetown/arcane/smokescreen.dm new file mode 100644 index 000000000..d1b30d5ae --- /dev/null +++ b/code/modules/spells/roguetown/arcane/smokescreen.dm @@ -0,0 +1,68 @@ +//SMOKESCREEN----------------- + +/obj/effect/proc_holder/spell/arcane/smokescreen + name = "Smokescreen" + desc = "" + overlay_state = "smoke" + sound = 'sound/items/firesnuff.ogg' + range = 8 + releasedrain = 30 + chargedrain = 0 + chargetime = 0 + charge_max = 10 SECONDS + smoke_spread = 1 //Just Smoke + smoke_amt = 2 + +/obj/effect/proc_holder/spell/arcane/smokescreen/cast(list/targets,mob/user = usr) + . = ..() + if(isliving(targets[1])) + return TRUE + else if(isopenturf(targets[1])) + return TRUE + return FALSE + +//DENSE SMOKE------------------- + +/obj/effect/proc_holder/spell/arcane/densesmoke + name = "Dense Smoke" + desc = "" + overlay_state = "smoke" + sound = 'sound/items/firesnuff.ogg' + range = 8 + releasedrain = 40 + chargedrain = 1 + chargetime = 10 + charge_max = 15 SECONDS + smoke_spread = 2 //Now it makes the target cough and drop items in hand + smoke_amt = 1 + +/obj/effect/proc_holder/spell/arcane/densesmoke/cast(list/targets,mob/user = usr) + . = ..() + if(isliving(targets[1])) + return TRUE + else if(isopenturf(targets[1])) + return TRUE + return FALSE + +//SLEEPING GAS------------------- + +/obj/effect/proc_holder/spell/arcane/sleepgas + name = "Sleeping Gas" + desc = "" + overlay_state = "smoke" + sound = 'sound/items/firesnuff.ogg' + range = 8 + releasedrain = 60 + chargedrain = 1 + chargetime = 30 + charge_max = 30 SECONDS + smoke_spread = 3 //Now this will make the target to fall asleep + smoke_amt = 2 + +/obj/effect/proc_holder/spell/arcane/sleepgas/cast(list/targets,mob/user = usr) + . = ..() + if(isliving(targets[1])) + return TRUE + else if(isopenturf(targets[1])) + return TRUE + return FALSE \ No newline at end of file diff --git a/code/modules/spells/roguetown/arcane/swap.dm b/code/modules/spells/roguetown/arcane/swap.dm new file mode 100644 index 000000000..2ef5e107e --- /dev/null +++ b/code/modules/spells/roguetown/arcane/swap.dm @@ -0,0 +1,35 @@ +//SWAP PLACES----------------- + +/obj/effect/proc_holder/spell/arcane/swap + name = "Location Swap" + desc = "" + overlay_state = "swap" + sound = 'sound/magic/magic_nulled.ogg' + range = 8 + releasedrain = 50 + chargedrain = 1 + chargetime = 15 + charge_max = 20 SECONDS + charging_slowdown = 3 + var/include_space = FALSE //whether it includes space tiles in possible teleport locations + var/include_dense = FALSE //whether it includes dense tiles in possible teleport locations + +/obj/effect/temp_visual/swap + icon_state = "anom" + layer = ABOVE_MOB_LAYER + plane = GAME_PLANE_UPPER + +/obj/effect/proc_holder/spell/arcane/swap/cast(list/targets, mob/living/user) + if(isliving(targets[1])) + var/mob/living/target = targets[1] + if(target.anti_magic_check(TRUE, TRUE)) + return FALSE + new /obj/effect/temp_visual/swap(get_turf(user)) + new /obj/effect/temp_visual/swap(get_turf(target)) + var/atom/targl = get_turf(target) + if(do_teleport(target, user, forceMove = TRUE, channel = TELEPORT_CHANNEL_MAGIC)) + do_teleport(user, targl, forceMove = TRUE, channel = TELEPORT_CHANNEL_MAGIC) + if(ismob(target)) + var/mob/M = target + to_chat(M, span_warning("You find myself somewhere else...")) + return TRUE \ No newline at end of file diff --git a/code/modules/spells/roguetown/arcane/telepathy.dm b/code/modules/spells/roguetown/arcane/telepathy.dm new file mode 100644 index 000000000..ed70c87cf --- /dev/null +++ b/code/modules/spells/roguetown/arcane/telepathy.dm @@ -0,0 +1,28 @@ +//TELEPATHY--------------------------- + +/obj/effect/proc_holder/spell/arcane/telepathy + name = "telepathy" + desc = "" + range = 15 + overlay_state = "psy" + sound = list('sound/magic/magnet.ogg') + releasedrain = 20 + chargedrain = 0 + chargetime = 0 + charge_max = 15 SECONDS + warnie = "spellwarning" + no_early_release = TRUE + charging_slowdown = 1 + +/obj/effect/proc_holder/spell/arcane/telepathy/cast(list/targets,mob/user = usr) + . = ..() + if(isliving(targets[1])) + var/mob/living/target = targets[1] + if(target.anti_magic_check(TRUE, TRUE)) + return FALSE + var/input = stripped_input(user, "What message are you sending?", null, "") + if(!input) + return FALSE + to_chat(user, span_warning("I transmit to [target]: " + "[input]")) + to_chat(target, span_warning("You hear a voice in your head saying: ") + span_boldwarning("[input]")) + return TRUE \ No newline at end of file diff --git a/code/modules/spells/roguetown/other/grant_title.dm b/code/modules/spells/roguetown/other/grant_title.dm new file mode 100644 index 000000000..03bd7da94 --- /dev/null +++ b/code/modules/spells/roguetown/other/grant_title.dm @@ -0,0 +1,60 @@ +//Grant Title--------------------- + +/obj/effect/proc_holder/spell/self/grant_title + name = "Grant Title" + desc = "Grant someone a title of honor... Or shame." + overlay_state = "recruit" + antimagic_allowed = TRUE + charge_max = 100 + /// Maximum range for title granting + var/title_range = 3 + /// Maximum length for the title + var/title_length = 42 + +/obj/effect/proc_holder/spell/self/grant_title/cast(list/targets, mob/user = usr) + . = ..() + var/granted_title = input(user, "What title do you wish to grant?", "[name]") as null|text + granted_title = reject_bad_text(granted_title, title_length) + if(!granted_title) + return + var/list/recruitment = list() + for(var/mob/living/carbon/human/village_idiot in (get_hearers_in_view(title_range, user) - user)) + //not allowed + if(!can_title(village_idiot)) + continue + recruitment[village_idiot.name] = village_idiot + if(!length(recruitment)) + to_chat(user, span_warning("There are no potential honoraries in range.")) + return + var/inputty = input(user, "Select an honorary!", "[name]") as anything in recruitment + if(inputty) + var/mob/living/carbon/human/recruit = recruitment[inputty] + if(!QDELETED(recruit) && (recruit in get_hearers_in_view(title_range, user))) + INVOKE_ASYNC(src, PROC_REF(village_idiotify), recruit, user, granted_title) + else + to_chat(user, span_warning("Honorific failed!")) + else + to_chat(user, span_warning("Honorific cancelled.")) + +/obj/effect/proc_holder/spell/self/grant_title/proc/can_title(mob/living/carbon/human/recruit) + //wtf + if(QDELETED(recruit)) + return FALSE + //need a mind + if(!recruit.mind) + return FALSE + //need to see their damn face + if(!recruit.get_face_name(null)) + return FALSE + return TRUE + +/obj/effect/proc_holder/spell/self/grant_title/proc/village_idiotify(mob/living/carbon/human/recruit, mob/living/carbon/human/recruiter, granted_title) + if(QDELETED(recruit) || QDELETED(recruiter) || !granted_title) + return FALSE + if(GLOB.lord_titles[recruit.real_name]) + recruiter.say("I HEREBY STRIP YOU, [uppertext(recruit.name)], OF THE TITLE OF [uppertext(GLOB.lord_titles[recruit.real_name])]!") + GLOB.lord_titles -= recruit.real_name + return FALSE + recruiter.say("I HEREBY GRANT YOU, [uppertext(recruit.name)], THE TITLE OF [uppertext(granted_title)]!") + GLOB.lord_titles[recruit.real_name] = granted_title + return TRUE \ No newline at end of file diff --git a/code/modules/spells/roguetown/jester.dm b/code/modules/spells/roguetown/other/jester.dm similarity index 100% rename from code/modules/spells/roguetown/jester.dm rename to code/modules/spells/roguetown/other/jester.dm diff --git a/code/modules/spells/roguetown/other/recruiting.dm b/code/modules/spells/roguetown/other/recruiting.dm new file mode 100644 index 000000000..1f9369f6b --- /dev/null +++ b/code/modules/spells/roguetown/other/recruiting.dm @@ -0,0 +1,155 @@ +/obj/effect/proc_holder/spell/self/convertrole + name = "Recruit Beggar" + desc = "Recruit someone to your cause." + overlay_state = "recruit" + antimagic_allowed = TRUE + charge_max = 100 + /// Role given if recruitment is accepted + var/new_role = "Beggar" + /// Faction shown to the user in the recruitment prompt + var/recruitment_faction = "Beggars" + /// Message the recruiter gives + var/recruitment_message = "Serve the beggars, %RECRUIT!" + /// Range to search for potential recruits + var/recruitment_range = 3 + /// Say message when the recruit accepts + var/accept_message = "I will serve!" + /// Say message when the recruit refuses + var/refuse_message = "I refuse." + +/obj/effect/proc_holder/spell/self/convertrole/cast(list/targets,mob/user = usr) + . = ..() + var/list/recruitment = list() + for(var/mob/living/carbon/human/recruit in (get_hearers_in_view(recruitment_range, user) - user)) + //not allowed + if(!can_convert(recruit)) + continue + recruitment[recruit.name] = recruit + if(!length(recruitment)) + to_chat(user, span_warning("There are no potential recruits in range.")) + return + var/inputty = input(user, "Select a potential recruit!", "[name]") as anything in recruitment + if(inputty) + var/mob/living/carbon/human/recruit = recruitment[inputty] + if(!QDELETED(recruit) && (recruit in get_hearers_in_view(recruitment_range, user))) + INVOKE_ASYNC(src, PROC_REF(convert), recruit, user) + else + to_chat(user, span_warning("Recruitment failed!")) + else + to_chat(user, span_warning("Recruitment cancelled.")) + +/obj/effect/proc_holder/spell/self/convertrole/proc/can_convert(mob/living/carbon/human/recruit) + //wtf + if(QDELETED(recruit)) + return FALSE + //need a mind + if(!recruit.mind) + return FALSE + //only migrants and peasants + if(!(recruit.job in GLOB.peasant_positions) && \ + !(recruit.job in GLOB.yeoman_positions) && \ + !(recruit.job in GLOB.allmig_positions) && \ + !(recruit.job in GLOB.mercenary_positions)) + return FALSE + //need to see their damn face + if(!recruit.get_face_name(null)) + return FALSE + return TRUE + +/obj/effect/proc_holder/spell/self/convertrole/proc/convert(mob/living/carbon/human/recruit, mob/living/carbon/human/recruiter) + if(QDELETED(recruit) || QDELETED(recruiter)) + return FALSE + recruiter.say(replacetext(recruitment_message, "%RECRUIT", "[recruit]"), forced = "[name]") + var/prompt = alert(recruit, "Do you wish to become a [new_role]?", "[recruitment_faction] Recruitment", "Yes", "No") + if(QDELETED(recruit) || QDELETED(recruiter) || !(recruiter in get_hearers_in_view(recruitment_range, recruit))) + return FALSE + if(prompt != "Yes") + if(refuse_message) + recruit.say(refuse_message, forced = "[name]") + return FALSE + if(accept_message) + recruit.say(accept_message, forced = "[name]") + if(new_role) + recruit.job = new_role + return TRUE + +//GUARD-------------------------------------- + +/obj/effect/proc_holder/spell/self/convertrole/guard + name = "Recruit Guardsmen" + new_role = "Watchman" + recruitment_faction = "Watchman" + recruitment_message = "Serve the town guard, %RECRUIT!" + accept_message = "FOR THE KING!" + refuse_message = "I refuse." + +/obj/effect/proc_holder/spell/self/convertrole/guard/convert(mob/living/carbon/human/recruit, mob/living/carbon/human/recruiter) + . = ..() + if(!.) + return + recruit.verbs |= /mob/proc/haltyell + +//BOG GUARD-------------------------------------- + +/obj/effect/proc_holder/spell/self/convertrole/bog + name = "Recruit Bogmen" + new_role = "Bog Guard" + recruitment_faction = "Bog Guard" + recruitment_message = "Serve the bog, %RECRUIT!" + accept_message = "FOR THE BOG!" + refuse_message = "I refuse." + +/obj/effect/proc_holder/spell/self/convertrole/bog/convert(mob/living/carbon/human/recruit, mob/living/carbon/human/recruiter) + . = ..() + if(!.) + return + recruit.verbs |= /mob/proc/haltyell + +//SERVANT-------------------------------------- + +/obj/effect/proc_holder/spell/self/convertrole/servant + name = "Recruit Servant" + new_role = "Servant" + recruitment_faction = "Servants" + recruitment_message = "Serve the crown, %RECRUIT!" + accept_message = "FOR THE CROWN!" + refuse_message = "I refuse." + charge_max = 100 + +//TEMPLAR-------------------------------------- + +/obj/effect/proc_holder/spell/self/convertrole/templar + name = "Recruit Templar" + new_role = "Templar" + recruitment_faction = "Templars" + recruitment_message = "Serve the nine, %RECRUIT!" + accept_message = "FOR THE NINE!" + refuse_message = "I refuse." + +//ACOLYTE-------------------------------------- + +/obj/effect/proc_holder/spell/self/convertrole/monk + name = "Recruit Acolyte" + new_role = "Acolyte" + recruitment_faction = "Church" + recruitment_message = "Serve the nine, %RECRUIT!" + accept_message = "FOR THE NINE!" + refuse_message = "I refuse." + +//REBEL-------------------------------------- + +/obj/effect/proc_holder/spell/self/rebelconvert + name = "RECRUIT REBELS" + desc = "!" + overlay_state = "recruit" + antimagic_allowed = TRUE + charge_max = 150 + +/obj/effect/proc_holder/spell/self/rebelconvert/cast(list/targets,mob/user = usr) + ..() + var/inputty = input("Make a speech!", "ROGUETOWN") as text|null + if(inputty) + user.say(inputty, forced = "spell") + var/datum/antagonist/prebel/PR = user.mind.has_antag_datum(/datum/antagonist/prebel) + for(var/mob/living/carbon/human/L in get_hearers_in_view(6, get_turf(user))) + addtimer(CALLBACK(L,TYPE_PROC_REF(/mob/living/carbon/human, rev_ask), user,PR,inputty),1) diff --git a/icons/mob/actions/roguespells.dmi b/icons/mob/actions/roguespells.dmi index 62263e41e..ddc68f3a6 100644 Binary files a/icons/mob/actions/roguespells.dmi and b/icons/mob/actions/roguespells.dmi differ diff --git a/icons/mob/actions/roguespellsbackup.dmi b/icons/mob/actions/roguespellsbackup.dmi new file mode 100644 index 000000000..62263e41e Binary files /dev/null and b/icons/mob/actions/roguespellsbackup.dmi differ diff --git a/roguetown.dme b/roguetown.dme index 6948c28ae..40cdb514c 100644 --- a/roguetown.dme +++ b/roguetown.dme @@ -3257,8 +3257,8 @@ #include "code\modules\shuttle\white_ship.dm" #include "code\modules\spells\spell.dm" #include "code\modules\spells\roguetown\_roguetown.dm" +#include "code\modules\spells\roguetown\arcane.dm" #include "code\modules\spells\roguetown\confessor.dm" -#include "code\modules\spells\roguetown\jester.dm" #include "code\modules\spells\roguetown\monk.dm" #include "code\modules\spells\roguetown\necromancer.dm" #include "code\modules\spells\roguetown\priest.dm" @@ -3270,6 +3270,19 @@ #include "code\modules\spells\roguetown\acolyte\necra.dm" #include "code\modules\spells\roguetown\acolyte\noc.dm" #include "code\modules\spells\roguetown\acolyte\pestra.dm" +#include "code\modules\spells\roguetown\arcane\blindness.dm" +#include "code\modules\spells\roguetown\arcane\blink.dm" +#include "code\modules\spells\roguetown\arcane\fetch.dm" +#include "code\modules\spells\roguetown\arcane\fireball.dm" +#include "code\modules\spells\roguetown\arcane\ignite.dm" +#include "code\modules\spells\roguetown\arcane\invisibility.dm" +#include "code\modules\spells\roguetown\arcane\lightning.dm" +#include "code\modules\spells\roguetown\arcane\smokescreen.dm" +#include "code\modules\spells\roguetown\arcane\swap.dm" +#include "code\modules\spells\roguetown\arcane\telepathy.dm" +#include "code\modules\spells\roguetown\other\grant_title.dm" +#include "code\modules\spells\roguetown\other\jester.dm" +#include "code\modules\spells\roguetown\other\recruiting.dm" #include "code\modules\spells\spell_types\aimed.dm" #include "code\modules\spells\spell_types\area_teleport.dm" #include "code\modules\spells\spell_types\barnyard.dm"