[MIRROR] TGUI Apprentice Contracts (#8088)
* TGUI Apprentice Contracts (#61094) TGUI-ifies apprentice contracts. Yummy! * TGUI Apprentice Contracts Co-authored-by: tralezab <40974010+tralezab@users.noreply.github.com>
@@ -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 = "<B>You have already summoned your apprentice.</B><BR>"
|
||||
else
|
||||
dat = "<B>Contract of Apprenticeship:</B><BR>"
|
||||
dat += "<I>Using this contract, you may summon an apprentice to aid you on your mission.</I><BR>"
|
||||
dat += "<I>If you are unable to establish contact with your apprentice, you can feed the contract back to the spellbook to refund your points.</I><BR>"
|
||||
dat += "<B>Which school of magic is your apprentice studying?:</B><BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];school=[APPRENTICE_DESTRUCTION]'>Destruction</A><BR>"
|
||||
dat += "<I>Your apprentice is skilled in offensive magic. They know Magic Missile and Fireball.</I><BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];school=[APPRENTICE_BLUESPACE]'>Bluespace Manipulation</A><BR>"
|
||||
dat += "<I>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.</I><BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];school=[APPRENTICE_HEALING]'>Healing</A><BR>"
|
||||
dat += "<I>Your apprentice is training to cast spells that will aid your survival. They know Forcewall and Charge and come with a Staff of Healing.</I><BR>"
|
||||
dat += "<A href='byond://?src=[REF(src)];school=[APPRENTICE_ROBELESS]'>Robeless</A><BR>"
|
||||
dat += "<I>Your apprentice is training to cast spells without their robes. They know Knock and Mindswap.</I><BR>"
|
||||
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)
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
@@ -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 (
|
||||
<Window
|
||||
width={620}
|
||||
height={600}
|
||||
theme="wizard">
|
||||
<Window.Content>
|
||||
<Stack vertical fill>
|
||||
<Stack.Item>
|
||||
<Section textColor="lightgreen" fontSize="15px">
|
||||
If you cannot reach any of your apprentices today,
|
||||
you can feed the contract back into your spellbook to refund it.
|
||||
</Section>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
<ApprenticeSelection
|
||||
iconName="fire"
|
||||
fluffName="Apprentice of Destruction"
|
||||
schoolTitle="destruction"
|
||||
assetName="destruction.png"
|
||||
blurb={multiline`
|
||||
Your apprentice is skilled in offensive magic.
|
||||
They know Magic Missile and Fireball.
|
||||
`} />
|
||||
<ApprenticeSelection
|
||||
iconName="route"
|
||||
fluffName="Student of Translocation"
|
||||
schoolTitle="bluespace"
|
||||
assetName="bluespace.png"
|
||||
blurb={multiline`
|
||||
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.
|
||||
`} />
|
||||
<ApprenticeSelection
|
||||
iconName="medkit"
|
||||
fluffName="Neophyte of Restoration"
|
||||
schoolTitle="healing"
|
||||
assetName="healing.png"
|
||||
blurb={multiline`
|
||||
Your apprentice is training to cast spells that will
|
||||
aid your survival. They know Forcewall and Charge and
|
||||
come with a Staff of Healing.
|
||||
`} />
|
||||
<ApprenticeSelection
|
||||
iconName="user-secret"
|
||||
fluffName="Robeless Pupil"
|
||||
schoolTitle="robeless"
|
||||
assetName="robeless.png"
|
||||
blurb={multiline`
|
||||
Your apprentice is training to cast spells without
|
||||
their robes. They know Knock and Mindswap.
|
||||
`} />
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Window.Content>
|
||||
</Window>
|
||||
);
|
||||
};
|
||||
|
||||
const ApprenticeSelection = (props, context) => {
|
||||
const { act } = useBackend(context);
|
||||
const {
|
||||
iconName,
|
||||
fluffName,
|
||||
schoolTitle,
|
||||
assetName,
|
||||
blurb,
|
||||
} = props;
|
||||
return (
|
||||
<Section>
|
||||
<Stack align="middle" fill>
|
||||
<Stack.Item>
|
||||
<Stack vertical>
|
||||
<Stack.Item>
|
||||
<img
|
||||
src={resolveAsset(assetName)}
|
||||
style={{
|
||||
"border-style": "solid",
|
||||
"border-color": "#7e90a7",
|
||||
}} />
|
||||
</Stack.Item>
|
||||
<Stack.Item>
|
||||
<Button
|
||||
textAlign="center"
|
||||
fluid
|
||||
onClick={() => act('buy', {
|
||||
school: schoolTitle,
|
||||
})}>
|
||||
Select
|
||||
</Button>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Stack.Item>
|
||||
<Stack.Item grow>
|
||||
<Box fontSize="20px" height="30%">
|
||||
<Icon name={iconName} /> {fluffName}
|
||||
</Box>
|
||||
<BlockQuote height="70%" fontSize="16px">
|
||||
{blurb}
|
||||
</BlockQuote>
|
||||
</Stack.Item>
|
||||
</Stack>
|
||||
</Section>
|
||||
);
|
||||
};
|
||||