Merge pull request #14760 from keronshb/floorcluwneport

Ports Floor Cluwnes and Cluwnes.
This commit is contained in:
silicons
2021-06-09 11:21:22 -07:00
committed by GitHub
32 changed files with 773 additions and 3 deletions
+1
View File
@@ -53,6 +53,7 @@
#define GELADIKINESIS /datum/mutation/human/geladikinesis
#define CRYOKINESIS /datum/mutation/human/cryokinesis
#define SPIDER_WEB /datum/mutation/human/webbing
#define CLUWNEMUT /datum/mutation/human/cluwne
#define UI_CHANGED "ui changed"
#define UE_CHANGED "ue changed"
+1
View File
@@ -82,6 +82,7 @@
#define ADMIN_PUNISHMENT_PICKLE "Pickle-ify"
#define ADMIN_PUNISHMENT_FRY "Fry"
#define ADMIN_PUNISHMENT_PERFORATE ":B:erforate"
#define ADMIN_PUNISHMENT_CLUWNE "Cluwne"
#define AHELP_ACTIVE 1
#define AHELP_CLOSED 2
+57
View File
@@ -0,0 +1,57 @@
/datum/mutation/human/cluwne
name = "Cluwne"
quality = NEGATIVE
locked = TRUE
text_gain_indication = "<span class='danger'>You feel like your brain is tearing itself apart.</span>"
/datum/mutation/human/cluwne/on_acquiring(mob/living/carbon/human/owner)
if(..())
return
owner.dna.add_mutation(CLOWNMUT)
owner.dna.add_mutation(EPILEPSY)
owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 199, 199)
var/mob/living/carbon/human/H = owner
if(!istype(H.wear_mask, /obj/item/clothing/mask/gas/cluwne))
if(!H.dropItemToGround(H.wear_mask))
qdel(H.wear_mask)
H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/cluwne(H), SLOT_WEAR_MASK)
if(!istype(H.w_uniform, /obj/item/clothing/under/cluwne))
if(!H.dropItemToGround(H.w_uniform))
qdel(H.w_uniform)
H.equip_to_slot_or_del(new /obj/item/clothing/under/cluwne(H), SLOT_W_UNIFORM)
if(!istype(H.shoes, /obj/item/clothing/shoes/clown_shoes/cluwne))
if(!H.dropItemToGround(H.shoes))
qdel(H.shoes)
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/clown_shoes/cluwne(H), SLOT_SHOES)
owner.equip_to_slot_or_del(new /obj/item/clothing/gloves/color/white(owner), SLOT_GLOVES) // this is purely for cosmetic purposes incase they aren't wearing anything in that slot
owner.equip_to_slot_or_del(new /obj/item/storage/backpack/clown(owner), SLOT_BACK) // ditto
/datum/mutation/human/cluwne/on_life(mob/living/carbon/human/owner)
if((prob(15) && owner.IsUnconscious()))
owner.adjustOrganLoss(ORGAN_SLOT_BRAIN, 199, 199) // there I changed it to setBrainLoss
switch(rand(1, 6))
if(1)
owner.say("HONK")
if(2 to 5)
owner.emote("scream")
if(6)
owner.Stun(1)
owner.Knockdown(20)
owner.Jitter(500)
/datum/mutation/human/cluwne/on_losing(mob/living/carbon/human/owner)
owner.adjust_fire_stacks(1)
owner.IgniteMob()
owner.dna.add_mutation(CLUWNEMUT)
/mob/living/carbon/human/proc/cluwneify()
dna.add_mutation(CLUWNEMUT)
emote("scream")
regenerate_icons()
visible_message("<span class='danger'>[src]'s body glows green, the glow dissipating only to leave behind a cluwne formerly known as [src]!</span>", \
"<span class='danger'>Your brain feels like it's being torn apart, there is only the honkmother now.</span>")
flash_act()
+1
View File
@@ -116,6 +116,7 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list(
/client/proc/show_tip,
/client/proc/smite,
/client/proc/admin_away,
/client/proc/spawn_floor_cluwne,
/client/proc/cmd_admin_toggle_fov, //CIT CHANGE - FOV
/client/proc/roll_dices //CIT CHANGE - Adds dice verb
))
+29 -3
View File
@@ -1333,9 +1333,10 @@ Traitors and the like can also be revived with the previous role mostly intact.
ADMIN_PUNISHMENT_SHOES,
ADMIN_PUNISHMENT_PICKLE,
ADMIN_PUNISHMENT_FRY,
ADMIN_PUNISHMENT_CRACK,
ADMIN_PUNISHMENT_BLEED,
ADMIN_PUNISHMENT_SCARIFY)
ADMIN_PUNISHMENT_CRACK,
ADMIN_PUNISHMENT_BLEED,
ADMIN_PUNISHMENT_SCARIFY,
ADMIN_PUNISHMENT_CLUWNE)
var/punishment = input("Choose a punishment", "DIVINE SMITING") as null|anything in punishment_list
@@ -1501,6 +1502,11 @@ Traitors and the like can also be revived with the previous role mostly intact.
to_chat(usr,"<span class='warning'>[C] does not have knottable shoes!</span>")
return
sick_kicks.adjust_laces(SHOES_KNOTTED)
if(ADMIN_PUNISHMENT_CLUWNE)
if(!iscarbon(target))
to_chat(usr,"<span class='warning'>This must be used on a carbon mob.</span>")
return
target.cluwneify()
punish_log(target, punishment)
@@ -1691,3 +1697,23 @@ Traitors and the like can also be revived with the previous role mostly intact.
if(!source)
return
REMOVE_TRAIT(D,chosen_trait,source)
/client/proc/spawn_floor_cluwne()
set category = "Admin.Fun"
set name = "Unleash Floor Cluwne"
set desc = "Pick a specific target or just let it select randomly and spawn the floor cluwne mob on the station. Be warned: spawning more than one may cause issues!"
var/target
if(!check_rights(R_FUN))
return
var/turf/T = get_turf(usr)
target = input("Any specific target in mind? Please note only live, non cluwned, human targets are valid.", "Target", target) as null|anything in GLOB.player_list
if(target && ishuman(target))
var/mob/living/carbon/human/H = target
var/mob/living/simple_animal/hostile/floor_cluwne/FC = new /mob/living/simple_animal/hostile/floor_cluwne(T)
FC.Acquire_Victim(H)
else
new /mob/living/simple_animal/hostile/floor_cluwne(T)
log_admin("[key_name(usr)] spawned floor cluwne.")
message_admins("[key_name(usr)] spawned floor cluwne.")
@@ -252,6 +252,10 @@
name = "Barnyard Curse"
spell_type = /obj/effect/proc_holder/spell/pointed/barnyardcurse
/datum/spellbook_entry/cluwne
name = "Cluwne Curse"
spell_type = /obj/effect/proc_holder/spell/targeted/cluwnecurse
/datum/spellbook_entry/charge
name = "Charge"
spell_type = /obj/effect/proc_holder/spell/targeted/charge
+106
View File
@@ -0,0 +1,106 @@
/obj/item/clothing/mask/gas/cluwne
name = "clown wig and mask"
desc = "A true prankster's facial attire. A clown is incomplete without his wig and mask."
flags_cover = MASKCOVERSEYES
icon_state = "cluwne"
item_state = "cluwne"
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
clothing_flags = ALLOWINTERNALS
item_flags = ABSTRACT | DROPDEL
flags_inv = HIDEEARS|HIDEEYES
var/voicechange = TRUE
var/last_sound = 0
var/delay = 15
/obj/item/clothing/mask/gas/cluwne/Initialize()
.=..()
ADD_TRAIT(src, TRAIT_NODROP, CLOTHING_TRAIT)
ADD_TRAIT(src, CURSED_ITEM_TRAIT, CLOTHING_TRAIT)
/obj/item/clothing/mask/gas/cluwne/proc/play_laugh1()
if(world.time - delay > last_sound)
playsound (src, 'sound/voice/cluwnelaugh1.ogg', 30, 1)
last_sound = world.time
/obj/item/clothing/mask/gas/cluwne/proc/play_laugh2()
if(world.time - delay > last_sound)
playsound (src, 'sound/voice/cluwnelaugh2.ogg', 30, 1)
last_sound = world.time
/obj/item/clothing/mask/gas/cluwne/proc/play_laugh3()
if(world.time - delay > last_sound)
playsound (src, 'sound/voice/cluwnelaugh3.ogg', 30, 1)
last_sound = world.time
/obj/item/clothing/mask/gas/cluwne/equipped(mob/user, slot) //when you put it on
var/mob/living/carbon/C = user
if((C.wear_mask == src) && (voicechange))
play_laugh1()
return ..()
/obj/item/clothing/mask/gas/cluwne/handle_speech(datum/source, list/speech_args)
if(voicechange)
if(prob(5)) //the brain isn't fully gone yet...
speech_args[SPEECH_MESSAGE] = pick("HELP ME!!","PLEASE KILL ME!!","I WANT TO DIE!!", "END MY SUFFERING", "I CANT TAKE THIS ANYMORE!!" ,"SOMEBODY STOP ME!!")
play_laugh2()
if(prob(3))
speech_args[SPEECH_MESSAGE] = pick("HOOOOINKKKKKKK!!", "HOINK HOINK HOINK HOINK!!","HOINK HOINK!!","HOOOOOOIIINKKKK!!") //but most of the time they cant speak,
play_laugh3()
else
speech_args[SPEECH_MESSAGE] = pick("HEEEENKKKKKK!!", "HONK HONK HONK HONK!!","HONK HONK!!","HOOOOOONKKKK!!") //More sounds,
play_laugh1()
return SPEECH_MESSAGE
/obj/item/clothing/mask/gas/cluwne/equipped(mob/user, slot)
. = ..()
if(!ishuman(user))
return
if(slot == SLOT_WEAR_MASK)
var/mob/living/carbon/human/H = user
H.dna.add_mutation(CLUWNEMUT)
return
/obj/item/clothing/mask/gas/cluwne/happy_cluwne
name = "Happy Cluwne Mask"
desc = "The mask of a poor cluwne that has been scrubbed of its curse by the Nanotrasen supernatural machinations division. Guaranteed to be %99 curse free and %99.9 not haunted. "
item_flags = ABSTRACT
var/can_cluwne = FALSE
var/is_cursed = FALSE //i don't care that this is *slightly* memory wasteful, it's just one more byte and it's not like some madman is going to spawn thousands of these
var/is_very_cursed = FALSE
/obj/item/clothing/mask/gas/cluwne/happy_cluwne/Initialize()
.=..()
if(prob(1)) //this function pre-determines the logic of the cluwne mask. applying and reapplying the mask does not alter or change anything
is_cursed = TRUE
is_very_cursed = FALSE
else if(prob(0.1))
is_cursed = FALSE
is_very_cursed = TRUE
/obj/item/clothing/mask/gas/cluwne/happy_cluwne/attack_self(mob/user)
voicechange = !voicechange
to_chat(user, "<span class='notice'>You turn the voice box [voicechange ? "on" : "off"]!</span>")
if(voicechange)
play_laugh1()
/obj/item/clothing/mask/gas/cluwne/happy_cluwne/equipped(mob/user, slot)
. = ..()
if(!ishuman(user))
return
var/mob/living/carbon/human/H = user
if(slot == SLOT_WEAR_MASK)
if(is_cursed && can_cluwne) //logic predetermined
log_admin("[key_name(H)] was made into a cluwne by [src]")
message_admins("[key_name(H)] got cluwned by [src]")
to_chat(H, "<span class='userdanger'>The masks straps suddenly tighten to your face and your thoughts are erased by a horrible green light!</span>")
H.dropItemToGround(src)
H.cluwneify()
qdel(src)
else if(is_very_cursed && can_cluwne)
var/turf/T = get_turf(src)
var/mob/living/simple_animal/hostile/floor_cluwne/S = new(T)
S.Acquire_Victim(user)
log_admin("[key_name(user)] summoned a floor cluwne using the [src]")
message_admins("[key_name(user)] summoned a floor cluwne using the [src]")
to_chat(H, "<span class='warning'>The mask suddenly slips off your face and... slides under the floor?</span>")
to_chat(H, "<i>...dneirf uoy ot gnoleb ton seod tahT</i>")
+29
View File
@@ -0,0 +1,29 @@
/obj/item/clothing/shoes/clown_shoes/cluwne
desc = "The prankster's standard-issue clowning shoes. Damn, they're huge!"
name = "clown shoes"
icon_state = "cluwne"
item_state = "cluwne"
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
item_flags = DROPDEL
var/footstep = 1
/obj/item/clothing/shoes/clown_shoes/cluwne/Initialize()
.=..()
ADD_TRAIT(src, TRAIT_NODROP, CLOTHING_TRAIT)
ADD_TRAIT(src, CURSED_ITEM_TRAIT, CLOTHING_TRAIT)
/obj/item/clothing/shoes/clown_shoes/cluwne/step_action()
if(footstep > 1)
playsound(src, "clownstep", 50, 1)
footstep = 0
else
footstep++
/obj/item/clothing/shoes/clown_shoes/cluwne/equipped(mob/user, slot)
. = ..()
if(!ishuman(user))
return
if(slot == SLOT_SHOES)
var/mob/living/carbon/human/H = user
H.dna.add_mutation(CLUWNEMUT)
return
+22
View File
@@ -0,0 +1,22 @@
/obj/item/clothing/under/cluwne
name = "clown suit"
desc = "<i>'HONK!'</i>"
icon_state = "greenclown"
item_state = "greenclown"
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
item_flags = DROPDEL
can_adjust = 0
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
/obj/item/clothing/under/cluwne/Initialize()
.=..()
ADD_TRAIT(src, TRAIT_NODROP, CLOTHING_TRAIT)
ADD_TRAIT(src, CURSED_ITEM_TRAIT, CLOTHING_TRAIT)
/obj/item/clothing/under/cluwne/equipped(mob/living/carbon/user, slot)
if(!ishuman(user))
return
if(slot == SLOT_W_UNIFORM)
var/mob/living/carbon/human/H = user
H.dna.add_mutation(CLUWNEMUT)
return ..()
+23
View File
@@ -0,0 +1,23 @@
/datum/round_event_control/floor_cluwne
name = "Floor Cluwne"
typepath = /datum/round_event/floor_cluwne
max_occurrences = 1
min_players = 20
weight = 10
/datum/round_event/floor_cluwne/start()
var/list/spawn_locs = list()
for(var/X in GLOB.xeno_spawn)
spawn_locs += X
if(!spawn_locs.len)
message_admins("No valid spawn locations found, aborting...")
return MAP_ERROR
var/turf/T = get_turf(pick(spawn_locs))
var/mob/living/simple_animal/hostile/floor_cluwne/S = new(T)
playsound(S, 'sound/misc/bikehorn_creepy.ogg', 50, 1, -1)
message_admins("A floor cluwne has been spawned at [COORD(T)][ADMIN_JMP(T)]")
log_game("A floor cluwne has been spawned at [COORD(T)]")
return SUCCESSFUL_SPAWN
@@ -0,0 +1,457 @@
GLOBAL_VAR_INIT(floor_cluwnes, 0)
#define STAGE_HAUNT 1
#define STAGE_SPOOK 2
#define STAGE_TORMENT 3
#define STAGE_ATTACK 4
#define MANIFEST_DELAY 9
/mob/living/simple_animal/hostile/floor_cluwne
name = "???"
desc = "...."
icon = 'icons/obj/clothing/masks.dmi'
icon_state = "cluwne"
icon_living = "cluwne"
icon_gib = "clown_gib"
maxHealth = 250
health = 250
speed = -1
attack_verb_continuous = "attacks"
attack_verb_simple = "attack"
attack_sound = 'sound/items/bikehorn.ogg'
del_on_death = TRUE
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB | LETPASSTHROW | PASSGLASS | PASSBLOB//it's practically a ghost when unmanifested (under the floor)
loot = list(/obj/item/clothing/mask/gas/cluwne)
wander = FALSE
minimum_distance = 2
move_to_delay = 1
movement_type = FLYING
environment_smash = FALSE
lose_patience_timeout = FALSE
pixel_y = 8
pressure_resistance = 200
minbodytemp = 0
maxbodytemp = 1500
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
var/mob/living/carbon/human/current_victim
var/manifested = FALSE
var/switch_stage = 60
var/stage = STAGE_HAUNT
var/interest = 0
var/target_area
var/invalid_area_typecache = list(/area/space, /area/lavaland, /area/centcom, /area/reebe, /area/shuttle/syndicate)
var/eating = FALSE
var/dontkill = FALSE //for if we just wanna curse a fucker
var/obj/effect/dummy/floorcluwne_orbit/poi
var/obj/effect/temp_visual/fcluwne_manifest/cluwnehole
move_resist = INFINITY
hud_type = /datum/hud/ghost
hud_possible = list(ANTAG_HUD)
/mob/living/simple_animal/hostile/floor_cluwne/Initialize()
. = ..()
access_card = new /obj/item/card/id(src)
var/datum/job/captain/C = new /datum/job/captain
access_card.access = C.get_access()
invalid_area_typecache = typecacheof(invalid_area_typecache)
Manifest()
if(!current_victim)
Acquire_Victim()
poi = new(src)
/mob/living/simple_animal/hostile/floor_cluwne/med_hud_set_health()
return //we use a different hud
/mob/living/simple_animal/hostile/floor_cluwne/med_hud_set_status()
return //we use a different hud
/mob/living/simple_animal/hostile/floor_cluwne/Destroy()
QDEL_NULL(poi)
return ..()
/mob/living/simple_animal/hostile/floor_cluwne/attack_hand(mob/living/carbon/human/M)
..()
playsound(src.loc, 'sound/items/bikehorn.ogg', 50, 1)
/mob/living/simple_animal/hostile/floor_cluwne/CanPass(atom/A, turf/target)
return TRUE
/mob/living/simple_animal/hostile/floor_cluwne/Life()
do_jitter_animation(1000)
pixel_y = 8
var/area/A = get_area(src.loc)
if(is_type_in_typecache(A, invalid_area_typecache) || !is_station_level(z))
var/area = pick(GLOB.teleportlocs)
var/area/tp = GLOB.teleportlocs[area]
forceMove(pick(get_area_turfs(tp.type)))
if(!current_victim)
Acquire_Victim()
if(stage && !manifested)
INVOKE_ASYNC(src, .proc/On_Stage)
if(stage == STAGE_ATTACK)
playsound(src, 'sound/misc/cluwne_breathing.ogg', 75, 1)
if(eating)
return
var/turf/T = get_turf(current_victim)
A = get_area(T)
if(prob(5))//checks roughly every 20 ticks
if(current_victim.stat == DEAD || current_victim.dna.check_mutation(CLUWNEMUT) || is_type_in_typecache(A, invalid_area_typecache) || !is_station_level(current_victim.z))
if(!Found_You())
Acquire_Victim()
if(get_dist(src, current_victim) > 9 && !manifested && !is_type_in_typecache(A, invalid_area_typecache))//if cluwne gets stuck he just teleports
do_teleport(src, T)
interest++
if(interest >= switch_stage * 4 && !dontkill)
stage = STAGE_ATTACK
else if(interest >= switch_stage * 2)
stage = STAGE_TORMENT
else if(interest >= switch_stage)
stage = STAGE_SPOOK
else if(interest < switch_stage)
stage = STAGE_HAUNT
..()
/mob/living/simple_animal/hostile/floor_cluwne/Goto(target, delay, minimum_distance)
var/area/A = get_area(current_victim.loc)
if(!manifested && !is_type_in_typecache(A, invalid_area_typecache) && is_station_level(current_victim.z))
walk_to(src, target, minimum_distance, delay)
else
walk_to(src,0)
/mob/living/simple_animal/hostile/floor_cluwne/FindTarget()
return current_victim
/mob/living/simple_animal/hostile/floor_cluwne/CanAttack(atom/the_target)//you will not escape
return TRUE
/mob/living/simple_animal/hostile/floor_cluwne/AttackingTarget()
return
/mob/living/simple_animal/hostile/floor_cluwne/LoseTarget()
return
/mob/living/simple_animal/hostile/floor_cluwne/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)//prevents runtimes with machine fuckery
return FALSE
/mob/living/simple_animal/hostile/floor_cluwne/proc/Found_You()
for(var/obj/structure/closet/hiding_spot in orange(7,src))
if(current_victim.loc == hiding_spot)
hiding_spot.bust_open()
current_victim.Paralyze(40)
to_chat(current_victim, "<span class='warning'>...edih t'nac uoY</span>")
return TRUE
return FALSE
/mob/living/simple_animal/hostile/floor_cluwne/proc/Acquire_Victim(specific)
for(var/I in GLOB.player_list)//better than a potential recursive loop
var/mob/living/carbon/human/H = pick(GLOB.player_list)//so the check is fair
var/area/A
if(specific)
H = specific
A = get_area(H.loc)
if(H.stat != DEAD && H.has_dna() && !H.dna.check_mutation(CLUWNEMUT) && !is_type_in_typecache(A, invalid_area_typecache) && is_station_level(H.z))
return target = current_victim
A = get_area(H.loc)
if(H && ishuman(H) && H.stat != DEAD && H != current_victim && H.has_dna() && !H.dna.check_mutation(CLUWNEMUT) && !is_type_in_typecache(A, invalid_area_typecache) && is_station_level(H.z))
current_victim = H
interest = 0
stage = STAGE_HAUNT
return target = current_victim
message_admins("Floor Cluwne was deleted due to a lack of valid targets, if this was a manually targeted instance please re-evaluate your choice.")
qdel(src)
/mob/living/simple_animal/hostile/floor_cluwne/proc/Manifest()//handles disappearing and appearance anim
if(manifested)
mobility_flags &= ~MOBILITY_MOVE
update_mobility()
cluwnehole = new(src.loc)
addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Appear), MANIFEST_DELAY)
else
layer = GAME_PLANE
invisibility = INVISIBILITY_OBSERVER
density = FALSE
mobility_flags |= MOBILITY_MOVE
update_mobility()
if(cluwnehole)
qdel(cluwnehole)
/mob/living/simple_animal/hostile/floor_cluwne/proc/Appear()//handled in a seperate proc so floor cluwne doesn't appear before the animation finishes
layer = LYING_MOB_LAYER
invisibility = FALSE
density = TRUE
/mob/living/simple_animal/hostile/floor_cluwne/proc/Reset_View(screens, colour, mob/living/carbon/human/H)
if(screens)
for(var/whole_screen in screens)
animate(whole_screen, transform = matrix(), time = 5, easing = QUAD_EASING)
if(colour && H)
H.client.color = colour
/mob/living/simple_animal/hostile/floor_cluwne/proc/On_Stage()
var/mob/living/carbon/human/H = current_victim
switch(stage)
if(STAGE_HAUNT)
if(prob(5))
H.blur_eyes(1)
if(prob(5))
H.playsound_local(src,'sound/voice/cluwnelaugh2_reversed.ogg', 1)
if(prob(5))
H.playsound_local(src,'sound/misc/bikehorn_creepy.ogg', 5)
if(prob(3))
var/obj/item/I = locate() in orange(H, 8)
if(I && !I.anchored)
I.throw_at(H, 4, 3)
to_chat(H, "<span class='warning'>What threw that?</span>")
if(STAGE_SPOOK)
if(prob(4))
var/turf/T = get_turf(H)
T.handle_slip(H, 20)
to_chat(H, "<span class='warning'>The floor shifts underneath you!</span>")
if(prob(5))
H.playsound_local(src,'sound/voice/cluwnelaugh2.ogg', 2)
if(prob(5))
H.playsound_local(src,'sound/voice/cluwnelaugh2_reversed.ogg', 2)
if(prob(5))
H.playsound_local(src,'sound/misc/bikehorn_creepy.ogg', 10)
to_chat(H, "<i>knoh</i>")
if(prob(5))
var/obj/item/I = locate() in orange(H, 8)
if(I && !I.anchored)
I.throw_at(H, 4, 3)
to_chat(H, "<span class='warning'>What threw that?</span>")
if(prob(2))
to_chat(H, "<i>yalp ot tnaw I</i>")
Appear()
manifested = FALSE
addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Manifest), 1)
if(STAGE_TORMENT)
if(prob(5))
var/turf/T = get_turf(H)
T.handle_slip(H, 20)
to_chat(H, "<span class='warning'>The floor shifts underneath you!</span>")
if(prob(3))
playsound(src,pick('sound/spookoween/scary_horn.ogg', 'sound/spookoween/scary_horn2.ogg', 'sound/spookoween/scary_horn3.ogg'), 30, 1)
if(prob(3))
playsound(src,'sound/voice/cluwnelaugh1.ogg', 30, 1)
if(prob(3))
playsound(src,'sound/voice/cluwnelaugh2_reversed.ogg', 30, 1)
if(prob(5))
playsound(src,'sound/misc/bikehorn_creepy.ogg', 30, 1)
if(prob(4))
for(var/obj/item/I in orange(8, H))
if(!I.anchored)
I.throw_at(H, 4, 3)
to_chat(H, "<span class='warning'>What the hell?!</span>")
if(prob(2))
to_chat(H, "<span class='warning'>Something feels very wrong...</span>")
H.playsound_local(src,'sound/hallucinations/behind_you1.ogg', 25)
H.flash_act()
if(prob(2))
to_chat(H, "<i>!?REHTOMKNOH eht esiarp uoy oD</i>")
to_chat(H, "<span class='warning'>Something grabs your foot!</span>")
H.playsound_local(src,'sound/hallucinations/i_see_you1.ogg', 25)
H.Stun(20)
if(prob(3))
to_chat(H, "<i>KNOH ?od nottub siht seod tahW</i>")
for(var/turf/open/O in RANGE_TURFS(6, src))
O.MakeSlippery(TURF_WET_WATER, 10)
playsound(src, 'sound/effects/meteorimpact.ogg', 30, 1)
if(prob(1))
to_chat(H, "<span class='userdanger'>WHAT THE FUCK IS THAT?!</span>")
to_chat(H, "<i>.KNOH !nuf hcum os si uoy htiw gniyalP .KNOH KNOH KNOH</i>")
H.playsound_local(src,'sound/hallucinations/im_here1.ogg', 25)
H.reagents.add_reagent(/datum/reagent/toxin/mindbreaker, 3)
H.reagents.add_reagent(/datum/reagent/consumable/laughter, 5)
H.reagents.add_reagent(/datum/reagent/mercury, 3)
Appear()
manifested = FALSE
addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Manifest), 2)
for(var/obj/machinery/light/L in range(8, H))
L.flicker()
if(STAGE_ATTACK)
if(dontkill)
stage = STAGE_TORMENT
return
if(!eating)
Found_You()
for(var/I in getline(src,H))
var/turf/T = I
if(T.density)
forceMove(H.loc)
for(var/obj/structure/O in T)
if(O.density || istype(O, /obj/machinery/door/airlock))
forceMove(H.loc)
to_chat(H, "<span class='userdanger'>You feel the floor closing in on your feet!</span>")
H.Paralyze(300)
INVOKE_ASYNC(H, /mob.proc/emote, "scream")
H.adjustBruteLoss(10)
manifested = TRUE
Manifest()
if(!eating)
addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Grab, H), 50, TIMER_OVERRIDE|TIMER_UNIQUE)
for(var/turf/open/O in RANGE_TURFS(6, src))
O.MakeSlippery(TURF_WET_LUBE, 20)
playsound(src, 'sound/effects/meteorimpact.ogg', 30, 1)
eating = TRUE
/mob/living/simple_animal/hostile/floor_cluwne/proc/Grab(mob/living/carbon/human/H)
if (H != current_victim)
message_admins("Cluwne tried to grab someone who's not the target. Returning to life stage.")
return
to_chat(H, "<span class='userdanger'>You feel a cold, gloved hand clamp down on your ankle!</span>")
for(var/I in 1 to get_dist(src, H))
if(do_after(src, 5, target = H))
step_towards(H, src)
playsound(H, pick('sound/effects/bodyscrape-01.ogg', 'sound/effects/bodyscrape-02.ogg'), 20, 1, -4)
if(prob(40))
H.emote("scream")
else if(prob(25))
H.say(pick("HELP ME!!","IT'S GOT ME!!","DON'T LET IT TAKE ME!!",";SOMETHING'S KILLING ME!!","HOLY FUCK!!"))
playsound(src, pick('sound/voice/cluwnelaugh1.ogg', 'sound/voice/cluwnelaugh2.ogg', 'sound/voice/cluwnelaugh3.ogg'), 50, 1)
if(get_dist(src,H) <= 1)
visible_message("<span class='danger'>[src] begins dragging [H] under the floor!</span>")
if(do_after(src, 50, target = H) && eating)
H.become_blind()
H.layer = GAME_PLANE
H.invisibility = INVISIBILITY_OBSERVER
H.density = FALSE
H.anchored = TRUE
addtimer(CALLBACK(src, /mob/living/simple_animal/hostile/floor_cluwne/.proc/Kill, H), 100, TIMER_OVERRIDE|TIMER_UNIQUE)
visible_message("<span class='danger'>[src] pulls [H] under!</span>")
to_chat(H, "<span class='userdanger'>[src] drags you underneath the floor!</span>")
else
eating = FALSE
else
eating = FALSE
manifested = FALSE
Manifest()
/mob/living/simple_animal/hostile/floor_cluwne/proc/Kill(mob/living/carbon/human/H)
if (H != current_victim)
message_admins("Cluwne tried to kill someone who's not the target. Returning to life stage.")
H.invisibility = initial(H.invisibility)
return
if(!istype(H) || !H.client)
H.invisibility = initial(H.invisibility)
Acquire_Victim()
return
playsound(H, 'sound/effects/cluwne_feast.ogg', 100, 0, -4)
var/old_color = H.client.color
var/red_splash = list(1,0,0,0.8,0.2,0, 0.8,0,0.2,0.1,0,0)
var/pure_red = list(0,0,0,0,0,0,0,0,0,1,0,0)
H.client.color = pure_red
animate(H.client,color = red_splash, time = 10, easing = SINE_EASING|EASE_OUT)
for(var/turf/T in orange(H, 4))
H.add_splatter_floor(T)
if(do_after(src, 50, target = H))
H.unequip_everything()//more runtime prevention
if(prob(75))
H.gib(FALSE)
else
H.cluwneify()
H.adjustBruteLoss(30)
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 100, 100)
H.cure_blind()
H.layer = initial(H.layer)
H.invisibility = initial(H.invisibility)
H.density = initial(H.density)
H.anchored = initial(H.anchored)
H.blur_eyes(10)
animate(H.client,color = old_color, time = 20)
eating = FALSE
switch_stage = switch_stage * 0.75 //he gets faster after each feast
for(var/mob/M in GLOB.player_list)
M.playsound_local(get_turf(M), 'sound/misc/honk_echo_distant.ogg', 50, 1, pressure_affected = FALSE)
interest = 0
stage = STAGE_HAUNT
Acquire_Victim()
//manifestation animation
/obj/effect/temp_visual/fcluwne_manifest
icon = 'icons/turf/floors.dmi'
icon_state = "fcluwne_open"
layer = TURF_LAYER
duration = 600
randomdir = FALSE
/obj/effect/temp_visual/fcluwne_manifest/Initialize()
. = ..()
playsound(src, 'sound/misc/floor_cluwne_emerge.ogg', 100, 1)
flick("fcluwne_manifest",src)
/obj/effect/dummy/floorcluwne_orbit
name = "floor cluwne"
desc = "If you have this, tell a coder or admin!"
/obj/effect/dummy/floorcluwne_orbit/Initialize()
. = ..()
GLOB.floor_cluwnes++
name += " ([GLOB.floor_cluwnes])"
GLOB.poi_list += src
/obj/effect/dummy/floorcluwne_orbit/Destroy()
. = ..()
GLOB.poi_list -= src
#undef STAGE_HAUNT
#undef STAGE_SPOOK
#undef STAGE_TORMENT
#undef STAGE_ATTACK
#undef MANIFEST_DELAY
@@ -0,0 +1,36 @@
/obj/effect/proc_holder/spell/targeted/cluwnecurse
name = "Curse of the Cluwne"
desc = "This spell dooms the fate of any unlucky soul to the live of a pitiful cluwne, a terrible creature that is hunted for fun."
school = "transmutation"
charge_type = "recharge"
charge_max = 600
charge_counter = 0
clothes_req = SPELL_WIZARD_GARB
stat_allowed = 0
invocation = "CLU WO'NIS CA'TE'BEST'IS MAXIMUS!"
invocation_type = "shout"
range = 3
cooldown_min = 75
selection_type = "range"
var/list/compatible_mobs = list(/mob/living/carbon/human)
action_icon = 'icons/mob/actions/actions_spells.dmi'
action_icon_state = "cluwne"
/obj/effect/proc_holder/spell/targeted/cluwnecurse/cast(list/targets, mob/user = usr)
if(!targets.len)
to_chat(user, "<span class='notice'>No target found in range.</span>")
return
var/mob/living/carbon/target = targets[1]
if(!(target.type in compatible_mobs))
to_chat(user, "<span class='notice'>You are unable to curse [target]!</span>")
return
if(!(target in oview(range)))
to_chat(user, "<span class='notice'>They are too far away!</span>")
return
var/mob/living/carbon/human/H = target
H.cluwneify()
/datum/action/spell_action/New(Target)
..()
var/obj/effect/proc_holder/spell/S = Target
icon_icon = S.action_icon
Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 340 KiB

After

Width:  |  Height:  |  Size: 340 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+7
View File
@@ -682,6 +682,7 @@
#include "code\datums\mutations\antenna.dm"
#include "code\datums\mutations\body.dm"
#include "code\datums\mutations\chameleon.dm"
#include "code\datums\mutations\cluwne.dm"
#include "code\datums\mutations\cold.dm"
#include "code\datums\mutations\combined.dm"
#include "code\datums\mutations\hulk.dm"
@@ -1986,6 +1987,7 @@
#include "code\modules\clothing\masks\_masks.dm"
#include "code\modules\clothing\masks\boxing.dm"
#include "code\modules\clothing\masks\breath.dm"
#include "code\modules\clothing\masks\cluwne.dm"
#include "code\modules\clothing\masks\gasmask.dm"
#include "code\modules\clothing\masks\hailer.dm"
#include "code\modules\clothing\masks\miscellaneous.dm"
@@ -1998,6 +2000,7 @@
#include "code\modules\clothing\outfits\vv_outfit.dm"
#include "code\modules\clothing\shoes\_shoes.dm"
#include "code\modules\clothing\shoes\bananashoes.dm"
#include "code\modules\clothing\shoes\cluwne.dm"
#include "code\modules\clothing\shoes\colour.dm"
#include "code\modules\clothing\shoes\magboots.dm"
#include "code\modules\clothing\shoes\miscellaneous.dm"
@@ -2021,6 +2024,7 @@
#include "code\modules\clothing\suits\wiz_robe.dm"
#include "code\modules\clothing\under\_under.dm"
#include "code\modules\clothing\under\accessories.dm"
#include "code\modules\clothing\under\cluwne.dm"
#include "code\modules\clothing\under\color.dm"
#include "code\modules\clothing\under\costume.dm"
#include "code\modules\clothing\under\miscellaneous.dm"
@@ -2077,6 +2081,7 @@
#include "code\modules\events\electrical_storm.dm"
#include "code\modules\events\fake_virus.dm"
#include "code\modules\events\false_alarm.dm"
#include "code\modules\events\floorcluwne.dm"
#include "code\modules\events\fugitive_spawning.dm"
#include "code\modules\events\ghost_role.dm"
#include "code\modules\events\grid_check.dm"
@@ -2783,6 +2788,7 @@
#include "code\modules\mob\living\simple_animal\hostile\dark_wizard.dm"
#include "code\modules\mob\living\simple_animal\hostile\eyeballs.dm"
#include "code\modules\mob\living\simple_animal\hostile\faithless.dm"
#include "code\modules\mob\living\simple_animal\hostile\floor_cluwne.dm"
#include "code\modules\mob\living\simple_animal\hostile\giant_spider.dm"
#include "code\modules\mob\living\simple_animal\hostile\goose.dm"
#include "code\modules\mob\living\simple_animal\hostile\headcrab.dm"
@@ -3432,6 +3438,7 @@
#include "code\modules\spells\spell_types\area_teleport.dm"
#include "code\modules\spells\spell_types\bloodcrawl.dm"
#include "code\modules\spells\spell_types\charge.dm"
#include "code\modules\spells\spell_types\cluwnecurse.dm"
#include "code\modules\spells\spell_types\cone_spells.dm"
#include "code\modules\spells\spell_types\conjure.dm"
#include "code\modules\spells\spell_types\construct_spells.dm"