Adds a magic monkey to the wizard's den (#22677)

* merlin time

* bam

* boom

* oops

* Apply suggestions from code review

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>

* autodoc

* Update code/modules/mob/living/carbon/human/npcs.dm

Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com>

---------

Co-authored-by: Luc <89928798+lewcc@users.noreply.github.com>
Co-authored-by: Henri215 <77684085+Henri215@users.noreply.github.com>
This commit is contained in:
Contrabang
2023-10-16 19:01:35 +01:00
committed by GitHub
co-authored by Luc Henri215
parent e77026b500
commit 973542bc1d
6 changed files with 118 additions and 24 deletions
+19 -19
View File
@@ -1433,10 +1433,6 @@
icon_state = "cmo"
},
/area/shuttle/escape)
"fz" = (
/mob/living/carbon/human/monkey,
/turf/simulated/floor/wood,
/area/wizard_station)
"fE" = (
/obj/structure/table,
/obj/item/storage/box/handcuffs,
@@ -3561,19 +3557,6 @@
},
/turf/simulated/floor/plasteel,
/area/admin)
"mh" = (
/obj/structure/rack,
/obj/item/clothing/under/rank/centcom/captain{
pixel_x = -3;
pixel_y = 3
},
/obj/item/clothing/under/rank/centcom/officer,
/obj/item/clothing/under/rank/procedure/representative{
pixel_x = 3;
pixel_y = -3
},
/turf/simulated/floor/plasteel,
/area/admin)
"mi" = (
/obj/structure/rack,
/obj/item/clothing/suit/pirate_black{
@@ -7402,6 +7385,19 @@
},
/turf/simulated/floor/plasteel,
/area/tdome/arena_source)
"Ar" = (
/obj/structure/rack,
/obj/item/clothing/under/rank/centcom/captain{
pixel_x = -3;
pixel_y = 3
},
/obj/item/clothing/under/rank/centcom/officer,
/obj/item/clothing/under/rank/procedure/representative{
pixel_x = 3;
pixel_y = -3
},
/turf/simulated/floor/plasteel,
/area/admin)
"As" = (
/obj/structure/table/wood,
/obj/item/reagent_containers/food/drinks/drinkingglass/devilskiss,
@@ -12581,6 +12577,10 @@
/obj/structure/filingcabinet/security,
/turf/simulated/floor/wood,
/area/centcom/control)
"Sv" = (
/mob/living/carbon/human/monkey/magic,
/turf/simulated/floor/wood,
/area/wizard_station)
"Sw" = (
/obj/structure/sign/poster/official/high_class_martini,
/turf/simulated/wall/indestructible/riveted,
@@ -61499,7 +61499,7 @@ BX
UJ
GN
BR
fz
Sv
ed
fx
GN
@@ -68522,7 +68522,7 @@ wk
lI
lY
mb
mh
Ar
mx
mU
nm
+1 -1
View File
@@ -10,7 +10,7 @@
selection_activated_message = "<span class='notice'>You prepare to transfer your mind. Click on a target to cast the spell.</span>"
selection_deactivated_message = "<span class='notice'>You decide that your current form is good enough.</span>"
cooldown_min = 200 //100 deciseconds reduction per rank
var/list/protected_roles = list("Wizard","Changeling","Cultist") //which roles are immune to the spell
var/list/protected_roles = list(SPECIAL_ROLE_WIZARD, SPECIAL_ROLE_CHANGELING, SPECIAL_ROLE_CULTIST) //which roles are immune to the spell
var/paralysis_amount_caster = 40 SECONDS //how much the caster is paralysed for after the spell
var/paralysis_amount_victim = 40 SECONDS //how much the victim is paralysed for after the spell
action_icon_state = "mindswap"
@@ -28,9 +28,10 @@
/mob/living/carbon/human/proc/mind_checks()
if(!mind)
return
return FALSE
if(mind.miming)
qdel(GetComponent(/datum/component/footstep))
return TRUE
/**
* Sets up DNA and species.
@@ -21,3 +21,91 @@
real_name = name
resize = 0.8
update_transform()
/mob/living/carbon/human/monkey/magic
/// Stores the timer ID of the timer that happens in Life() to prevent multiple of the same timer happening.
var/return_timer
/mob/living/carbon/human/monkey/magic/Initialize(mapload)
. = ..()
var/headwear = pick(/obj/item/clothing/head/wizard, /obj/item/clothing/head/wizard/red, /obj/item/clothing/head/wizard/black)
name = pick(GLOB.wizard_first)
if(prob(20))
name = "[name] [pick(GLOB.wizard_second)]"
if(prob(0.1))
name = "MERLIN THE MAGNIFICENT"
headwear = /obj/item/clothing/head/wizard // he's gotta wear blue, ya know?
resize = 2
update_transform()
real_name = name
equip_to_slot_or_del(new headwear(src), SLOT_HUD_HEAD)
RegisterSignal(src, list(COMSIG_HUMAN_ATTACKED, COMSIG_HOSTILE_ATTACKINGTARGET), PROC_REF(ouch))
for(var/trait in list(TRAIT_RESISTHEAT, TRAIT_NOBREATH, TRAIT_RESISTCOLD, TRAIT_RESISTHIGHPRESSURE, TRAIT_RESISTLOWPRESSURE))
ADD_TRAIT(src, trait, MAGIC_TRAIT)
/mob/living/carbon/human/monkey/magic/proc/ouch(mob/living/victim, mob/living/attacker)
SIGNAL_HANDLER
if(src == attacker)
return // I'm afraid you do not get a free blink
if(blink_away())
return COMPONENT_CANCEL_ATTACK_CHAIN // prevent people from attacking the monkey
/mob/living/carbon/human/monkey/magic/proc/blink_away()
if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
return
// A monkey, with a blink spell? Preposterous
playsound(get_turf(src), 'sound/magic/blink.ogg', 50, TRUE)
var/list/turfs = list()
var/list/target_turfs = range(src, 5) - range(src, 1)
for(var/turf/T in target_turfs)
if(isspaceturf(T))
continue
if(is_blocked_turf(T))
continue
if(T.x > world.maxx - 5 || T.x < 5)
continue //putting them at the edge is dumb
if(T.y > world.maxy - 5 || T.y < 5)
continue
if(islava(T) || ischasm(T))
continue
turfs += T
var/turf/picked = pick(turfs)
if(!picked || !isturf(picked))
return
visible_message("<span class='warning'>[src] blinks away!</span>", "<span class='danger'>Your instincts kick in, and you blink away!</span>")
INVOKE_ASYNC(src, PROC_REF(after_the_attack), picked)
playsound(get_turf(src), 'sound/magic/blink.ogg', 50, TRUE)
return_timer = null
return TRUE
/mob/living/carbon/human/monkey/magic/proc/after_the_attack(turf/picked)
forceMove(picked)
var/datum/effect_system/smoke_spread/smoke = new /datum/effect_system/smoke_spread()
smoke.set_up(1, FALSE, src)
smoke.start()
/mob/living/carbon/human/monkey/magic/proc/i_want_to_go_home()
if(client || !istype(loc, /turf/simulated/floor/plating/asteroid))
return
blink_away()
/mob/living/carbon/human/monkey/magic/Life(seconds, times_fired)
. = ..()
if(!client && !return_timer && prob(10) && istype(loc, /turf/simulated/floor/plating/asteroid))
return_timer = addtimer(CALLBACK(src, PROC_REF(i_want_to_go_home)), 5 MINUTES)
// I'm out out the wizard's den, I want to go back inside!
/mob/living/carbon/human/monkey/magic/mind_checks()
if(!..())
return FALSE
mind.AddSpell(new /obj/effect/proc_holder/spell/turf_teleport/blink(null))
mind.special_role = SPECIAL_ROLE_WIZARD
@@ -48,10 +48,14 @@
/datum/species/monkey/handle_npc(mob/living/carbon/human/H)
if(H.stat != CONSCIOUS)
return
if(prob(33) && (H.mobility_flags & MOBILITY_MOVE) && isturf(H.loc) && !H.pulledby) //won't move if being pulled
step(H, pick(GLOB.cardinal))
if(prob(1))
H.emote(pick("scratch","jump","roll","tail"))
if(prob(33) && (H.mobility_flags & MOBILITY_MOVE) && isturf(H.loc) && !H.pulledby) //won't move if being pulled
var/dir_to_go = pick(GLOB.cardinal)
var/turf/to_go = get_step(H, dir_to_go)
if(islava(to_go) || ischasm(to_go))
return
step(H, dir_to_go)
/datum/species/monkey/get_random_name()
return "[lowertext(name)] ([rand(100,999)])"
@@ -326,7 +326,8 @@
FindTarget()
/mob/living/simple_animal/hostile/proc/AttackingTarget()
SEND_SIGNAL(src, COMSIG_HOSTILE_ATTACKINGTARGET, target)
if(SEND_SIGNAL(target, COMSIG_HOSTILE_ATTACKINGTARGET, src) & COMPONENT_CANCEL_ATTACK_CHAIN)
return FALSE
in_melee = TRUE
return target.attack_animal(src)