diff --git a/code/modules/antagonists/_common/antag_spawner.dm b/code/modules/antagonists/_common/antag_spawner.dm index 4b30be12f78..0f81b9ef305 100644 --- a/code/modules/antagonists/_common/antag_spawner.dm +++ b/code/modules/antagonists/_common/antag_spawner.dm @@ -18,58 +18,55 @@ desc = "A magic contract previously signed by an apprentice. In exchange for instruction in the magical arts, they are bound to answer your call for aid." icon = 'icons/obj/wizard.dmi' icon_state ="scroll2" + var/polling = FALSE -/obj/item/antag_spawner/contract/attack_self(mob/user) - user.set_machine(src) - var/dat - if(used) - dat = "You have already summoned your apprentice.
" - else - dat = "Contract of Apprenticeship:
" - dat += "Using this contract, you may summon an apprentice to aid you on your mission.
" - dat += "If you are unable to establish contact with your apprentice, you can feed the contract back to the spellbook to refund your points.
" - dat += "Which school of magic is your apprentice studying?:
" - dat += "Destruction
" - dat += "Your apprentice is skilled in offensive magic. They know Magic Missile and Fireball.
" - dat += "Bluespace Manipulation
" - dat += "Your apprentice is able to defy physics, melting through solid objects and travelling great distances in the blink of an eye. They know Teleport and Ethereal Jaunt.
" - dat += "Healing
" - dat += "Your apprentice is training to cast spells that will aid your survival. They know Forcewall and Charge and come with a Staff of Healing.
" - dat += "Robeless
" - dat += "Your apprentice is training to cast spells without their robes. They know Knock and Mindswap.
" - user << browse(dat, "window=radio") - onclose(user, "radio") - return - -/obj/item/antag_spawner/contract/Topic(href, href_list) +/obj/item/antag_spawner/contract/can_interact(mob/user) . = ..() + if(!.) + return FALSE + if(polling) + balloon_alert(user, "already calling an apprentice!") + return FALSE - if(usr.stat != CONSCIOUS || HAS_TRAIT(usr, TRAIT_HANDS_BLOCKED)) +/obj/item/antag_spawner/contract/ui_interact(mob/user, datum/tgui/ui) + ui = SStgui.try_update_ui(user, src, ui) + if(!ui) + ui = new(user, src, "ApprenticeContract", name) + ui.open() + +/obj/item/antag_spawner/contract/ui_state(mob/user) + if(used) + return GLOB.never_state + return GLOB.default_state + +/obj/item/antag_spawner/contract/ui_assets(mob/user) + . = ..() + return list( + get_asset_datum(/datum/asset/simple/contracts), + ) + +/obj/item/antag_spawner/contract/ui_act(action, list/params) + . = ..() + if(used || polling || !ishuman(usr)) return - if(!ishuman(usr)) - return TRUE - var/mob/living/carbon/human/H = usr + INVOKE_ASYNC(src, .proc/poll_for_student, usr, params["school"]) + SStgui.close_uis(src) - if(loc == H || (in_range(src, H) && isturf(loc))) - H.set_machine(src) - if(href_list["school"]) - if(used) - to_chat(H, span_warning("You already used this contract!")) - return - var/list/candidates = poll_candidates_for_mob("Do you want to play as a wizard's [href_list["school"]] apprentice?", ROLE_WIZARD, ROLE_WIZARD, 15 SECONDS, src) - if(LAZYLEN(candidates)) - if(QDELETED(src)) - return - if(used) - to_chat(H, span_warning("You already used this contract!")) - return - used = TRUE - var/mob/dead/observer/C = pick(candidates) - spawn_antag(C.client, get_turf(src), href_list["school"],H.mind) - else - to_chat(H, span_warning("Unable to reach your apprentice! You can either attack the spellbook with the contract to refund your points, or wait and try again later.")) +/obj/item/antag_spawner/contract/proc/poll_for_student(mob/living/carbon/human/teacher, apprentice_school) + balloon_alert(teacher, "contacting apprentice...") + polling = TRUE + var/list/candidates = poll_candidates_for_mob("Do you want to play as a wizard's [apprentice_school] apprentice?", ROLE_WIZARD, ROLE_WIZARD, 15 SECONDS, src) + polling = FALSE + if(!LAZYLEN(candidates)) + to_chat(teacher, span_warning("Unable to reach your apprentice! You can either attack the spellbook with the contract to refund your points, or wait and try again later.")) + return + if(QDELETED(src) || used) + return + used = TRUE + var/mob/dead/observer/student = pick(candidates) + spawn_antag(student.client, get_turf(src), apprentice_school, teacher.mind) -/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, kind ,datum/mind/user) +/obj/item/antag_spawner/contract/spawn_antag(client/C, turf/T, kind, datum/mind/user) new /obj/effect/particle_effect/smoke(T) var/mob/living/carbon/human/M = new/mob/living/carbon/human(T) C.prefs.safe_transfer_prefs_to(M, is_antag = TRUE) diff --git a/code/modules/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm index 001068f3a14..c72eabe3b16 100644 --- a/code/modules/asset_cache/asset_list_items.dm +++ b/code/modules/asset_cache/asset_list_items.dm @@ -500,6 +500,14 @@ "safe_dial.png" = 'icons/ui_icons/safe/safe_dial.png' ) +/datum/asset/simple/contracts + assets = list( + "bluespace.png" = 'icons/ui_icons/contracts/bluespace.png', + "destruction.png" = 'icons/ui_icons/contracts/destruction.png', + "healing.png" = 'icons/ui_icons/contracts/healing.png', + "robeless.png" = 'icons/ui_icons/contracts/robeless.png', + ) + /datum/asset/spritesheet/fish name = "fish" diff --git a/icons/UI_Icons/contracts/bluespace.png b/icons/UI_Icons/contracts/bluespace.png new file mode 100644 index 00000000000..f62bde4c952 Binary files /dev/null and b/icons/UI_Icons/contracts/bluespace.png differ diff --git a/icons/UI_Icons/contracts/destruction.png b/icons/UI_Icons/contracts/destruction.png new file mode 100644 index 00000000000..ed101d8f25a Binary files /dev/null and b/icons/UI_Icons/contracts/destruction.png differ diff --git a/icons/UI_Icons/contracts/healing.png b/icons/UI_Icons/contracts/healing.png new file mode 100644 index 00000000000..78d1a8d1a26 Binary files /dev/null and b/icons/UI_Icons/contracts/healing.png differ diff --git a/icons/UI_Icons/contracts/robeless.png b/icons/UI_Icons/contracts/robeless.png new file mode 100644 index 00000000000..8da57fb9bab Binary files /dev/null and b/icons/UI_Icons/contracts/robeless.png differ diff --git a/icons/ui_icons/contracts/bluespace.png b/icons/ui_icons/contracts/bluespace.png new file mode 100644 index 00000000000..f62bde4c952 Binary files /dev/null and b/icons/ui_icons/contracts/bluespace.png differ diff --git a/icons/ui_icons/contracts/destruction.png b/icons/ui_icons/contracts/destruction.png new file mode 100644 index 00000000000..ed101d8f25a Binary files /dev/null and b/icons/ui_icons/contracts/destruction.png differ diff --git a/icons/ui_icons/contracts/healing.png b/icons/ui_icons/contracts/healing.png new file mode 100644 index 00000000000..78d1a8d1a26 Binary files /dev/null and b/icons/ui_icons/contracts/healing.png differ diff --git a/icons/ui_icons/contracts/robeless.png b/icons/ui_icons/contracts/robeless.png new file mode 100644 index 00000000000..8da57fb9bab Binary files /dev/null and b/icons/ui_icons/contracts/robeless.png differ diff --git a/tgui/packages/tgui/interfaces/ApprenticeContract.tsx b/tgui/packages/tgui/interfaces/ApprenticeContract.tsx new file mode 100644 index 00000000000..333b4bc1560 --- /dev/null +++ b/tgui/packages/tgui/interfaces/ApprenticeContract.tsx @@ -0,0 +1,112 @@ +import { multiline } from 'common/string'; +import { resolveAsset } from '../assets'; +import { useBackend } from '../backend'; +import { BlockQuote, Box, Button, Icon, Section, Stack } from '../components'; +import { Window } from '../layouts'; + +export const ApprenticeContract = (props, context) => { + return ( + + + + +
+ If you cannot reach any of your apprentices today, + you can feed the contract back into your spellbook to refund it. +
+
+ + + + + + +
+
+
+ ); +}; + +const ApprenticeSelection = (props, context) => { + const { act } = useBackend(context); + const { + iconName, + fluffName, + schoolTitle, + assetName, + blurb, + } = props; + return ( +
+ + + + + + + + + + + + + + {fluffName} + +
+ {blurb} +
+
+
+
+ ); +};