-
-
Notifications
You must be signed in to change notification settings - Fork 444
/
Copy pathmind_transfer.dm
139 lines (115 loc) · 5.03 KB
/
mind_transfer.dm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/datum/action/cooldown/spell/pointed/mind_transfer
name = "Mind Swap"
desc = "This spell allows the user to switch bodies with a target next to him."
button_icon_state = "mindswap"
ranged_mousepointer = 'icons/effects/mouse_pointers/mindswap_target.dmi'
school = SCHOOL_TRANSMUTATION
cooldown_time = 60 SECONDS
cooldown_reduction_per_rank = 10 SECONDS
spell_requirements = SPELL_REQUIRES_NO_ANTIMAGIC|SPELL_REQUIRES_MIND|SPELL_CASTABLE_AS_BRAIN
antimagic_flags = MAGIC_RESISTANCE|MAGIC_RESISTANCE_MIND
invocation = "GIN'YU CAPAN"
invocation_type = INVOCATION_WHISPER
active_msg = "You prepare to swap minds with a target..."
deactive_msg = "You dispel mind swap."
cast_range = 1
/// If TRUE, we cannot mindswap into mobs with minds if they do not currently have a key / player.
var/target_requires_key = TRUE
/// If TRUE, we cannot mindswap into people without a mind.
/// You may be wondering "What's the point of mindswap if the target has no mind"?
/// Primarily for debugging - targets hit with this set to FALSE will init a mind, then do the swap.
var/target_requires_mind = TRUE
/// For how long is the caster stunned for after the spell
var/unconscious_amount_caster = 40 SECONDS
/// For how long is the victim stunned for after the spell
var/unconscious_amount_victim = 40 SECONDS
/// List of mobs we cannot mindswap into.
var/static/list/mob/living/blacklisted_mobs = typecacheof(list(
/mob/living/brain,
/mob/living/silicon/pai,
/mob/living/simple_animal/slaughter,
/mob/living/simple_animal/hostile/megafauna,
))
/datum/action/cooldown/spell/pointed/mind_transfer/can_cast_spell(feedback = TRUE)
. = ..()
if(!.)
return FALSE
if(!isliving(owner))
return FALSE
if(owner.suiciding)
if(feedback)
to_chat(owner, span_warning("You're killing yourself! You can't concentrate enough to do this!"))
return FALSE
return TRUE
/datum/action/cooldown/spell/pointed/mind_transfer/is_valid_target(atom/cast_on)
. = ..()
if(!.)
return FALSE
if(!isliving(cast_on))
to_chat(owner, span_warning("You can only swap minds with living beings!"))
return FALSE
if(is_type_in_typecache(cast_on, blacklisted_mobs))
to_chat(owner, span_warning("This creature is too [pick("powerful", "strange", "arcane", "obscene")] to control!"))
return FALSE
if(isguardian(cast_on))
var/mob/living/simple_animal/hostile/guardian/stand = cast_on
if(stand.summoner && stand.summoner == owner)
to_chat(owner, span_warning("Swapping minds with your own guardian would just put you back into your own head!"))
return FALSE
var/mob/living/living_target = cast_on
if(ishuman(living_target))
var/mob/living/carbon/human/living_human = cast_on
if(is_synth(living_human))
to_chat(owner, span_warning("This creature isn't alive in the regular sense, this wouldn't be a good idea."))
return FALSE
if(living_target.stat == DEAD)
to_chat(owner, span_warning("You don't particularly want to be dead!"))
return FALSE
if(!living_target.mind && target_requires_mind)
to_chat(owner, span_warning("[living_target.p_theyve(TRUE)] doesn't appear to have a mind to swap into!"))
return FALSE
if(!living_target.key && target_requires_key)
to_chat(owner, span_warning("[living_target.p_theyve(TRUE)] appear[living_target.p_s()] to be catatonic! \
Not even magic can affect [living_target.p_their()] vacant mind."))
return FALSE
return TRUE
/datum/action/cooldown/spell/pointed/mind_transfer/cast(mob/living/cast_on)
. = ..()
swap_minds(owner, cast_on)
/datum/action/cooldown/spell/pointed/mind_transfer/proc/swap_minds(mob/living/caster, mob/living/cast_on)
var/mob/living/to_swap = cast_on
if(isguardian(cast_on))
var/mob/living/simple_animal/hostile/guardian/stand = cast_on
if(stand.summoner)
to_swap = stand.summoner
// Gives the target a mind if we don't require one and they don't have one
if(!to_swap.mind && !target_requires_mind)
to_swap.mind_initialize()
var/datum/mind/mind_to_swap = to_swap.mind
if(to_swap.can_block_magic(antimagic_flags) \
|| mind_to_swap.has_antag_datum(/datum/antagonist/wizard) \
|| mind_to_swap.has_antag_datum(/datum/antagonist/cult) \
|| mind_to_swap.has_antag_datum(/datum/antagonist/changeling) \
|| mind_to_swap.has_antag_datum(/datum/antagonist/rev) \
|| mind_to_swap.key?[1] == "@" \
)
to_chat(caster, span_warning("[to_swap.p_their(TRUE)] mind is resisting your spell!"))
return FALSE
// MIND TRANSFER BEGIN
var/datum/mind/caster_mind = caster.mind
var/datum/mind/to_swap_mind = to_swap.mind
var/to_swap_key = to_swap.key
caster_mind.transfer_to(to_swap)
to_swap_mind.transfer_to(caster)
// Just in case the swappee's key wasn't grabbed by transfer_to...
if(to_swap_key)
caster.key = to_swap_key
// MIND TRANSFER END
// Now we knock both mobs out for a time.
caster.Unconscious(unconscious_amount_caster)
to_swap.Unconscious(unconscious_amount_victim)
// Only the caster and victim hear the sounds,
// that way no one knows for sure if the swap happened
SEND_SOUND(caster, sound('sound/magic/mandswap.ogg'))
SEND_SOUND(to_swap, sound('sound/magic/mandswap.ogg'))
return TRUE