This commit is contained in:
Putnam
2021-06-11 16:28:12 -07:00
179 changed files with 2371 additions and 709 deletions

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
))

View File

@@ -104,7 +104,7 @@ GLOBAL_VAR(antag_prototypes)
var/datum/component/activity/activity = current.GetComponent(/datum/component/activity)
if(activity)
out += "Activity level: [activity.activity_level]<br>"
out += "Hasn't changed areas in approximately [activity.not_moved_counter] seconds"
out += "Hasn't changed areas in approximately [activity.not_moved_counter] seconds<br>"
var/special_statuses = get_special_statuses()
if(length(special_statuses))

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.")

View File

@@ -164,14 +164,12 @@ GLOBAL_LIST_EMPTY(antagonists)
/datum/antagonist/proc/remove_blacklisted_quirks()
var/mob/living/L = owner.current
if(istype(L))
var/list/my_quirks = L.client?.prefs.all_quirks.Copy()
SSquirks.filter_quirks(my_quirks,blacklisted_quirks)
for(var/q in L.roundstart_quirks)
var/datum/quirk/Q = q
if(!(SSquirks.quirk_name_by_path(Q.type) in my_quirks))
if(Q.type in blacklisted_quirks)
if(initial(Q.antag_removal_text))
to_chat(L, "<span class='boldannounce'>[initial(Q.antag_removal_text)]</span>")
L.remove_quirk(Q.type)
qdel(Q)
//Returns the team antagonist belongs to if any.
/datum/antagonist/proc/get_team()

View File

@@ -680,6 +680,11 @@
glove_type = /obj/item/clothing/gloves/fingerless/pugilist/cling // just punch his head off dude
glove_name_simple = "bone gauntlets"
/obj/effect/proc_holder/changeling/gloves/gauntlets/sting_action(mob/living/user)
if(HAS_TRAIT(user, TRAIT_NOPUGILIST))
to_chat(user, "<span class='warning'>We would gain nothing by forming our fists into brute-force weapons when we are trained in precision martial arts!</span>")
return
/obj/item/clothing/gloves/fingerless/pugilist/cling // switches between lesser GotNS and Big Punchy Rib Breaky Hands
name = "hewn bone gauntlets"
icon_state = "ling_gauntlets"

View File

@@ -25,7 +25,7 @@
/datum/clockwork_scripture/create_object/stargazer/check_special_requirements()
var/area/A = get_area(invoker)
var/turf/T = get_turf(invoker)
if(!is_station_level(invoker.z) || isspaceturf(T) || !(A.area_flags & VALID_TERRITORY))
if(!is_station_level(invoker.z) || isspaceturf(T) || !(A?.area_flags & CULT_PERMITTED))
to_chat(invoker, "<span class='danger'>Stargazers can't be built off-station.</span>")
return
return ..()

View File

@@ -34,7 +34,7 @@
return FALSE
var/area/A = get_area(invoker)
var/turf/T = get_turf(invoker)
if(!is_station_level(T.z) || isspaceturf(T) || !(A.area_flags & VALID_TERRITORY) || isshuttleturf(T))
if(!is_station_level(T.z) || isspaceturf(T) || !(A?.area_flags & CULT_PERMITTED) || isshuttleturf(T))
to_chat(invoker, "<span class='warning'>You must be on the station to activate the Ark!</span>")
return FALSE
if(GLOB.clockwork_gateway_activated)

View File

@@ -52,7 +52,7 @@
break
if(has_starlight && anchored)
var/area/A = get_area(src)
if(A.outdoors || A.map_name == "Space" || !(A.area_flags & VALID_TERRITORY))
if(A.outdoors || A.map_name == "Space" || !(A?.area_flags & CULT_PERMITTED))
has_starlight = FALSE
if(old_status != has_starlight)
if(has_starlight)

View File

@@ -419,7 +419,7 @@
var/sanity = 0
while(summon_spots.len < SUMMON_POSSIBILITIES && sanity < 100)
var/area/summon = pick(GLOB.sortedAreas - summon_spots)
if(summon && is_station_level(summon.z) && !(summon.area_flags & VALID_TERRITORY))
if(summon && is_station_level(summon.z) && (summon.area_flags & VALID_TERRITORY))
summon_spots += summon
sanity++
update_explanation_text()

View File

@@ -148,7 +148,7 @@ This file contains the cult dagger and rune list code
to_chat(user, "<span class='cult'>There is already a rune here.</span>")
return FALSE
var/area/A = get_area(T)
if((!is_station_level(T.z) && !is_mining_level(T.z)) || !(A?.area_flags & VALID_TERRITORY))
if((!is_station_level(T.z) && !is_mining_level(T.z)) || !(A?.area_flags & CULT_PERMITTED))
to_chat(user, "<span class='warning'>The veil is not weak enough here.</span>")
return FALSE
return TRUE

View File

@@ -89,6 +89,7 @@
var/list/lore = list()
data["charges"] = charge
data["total_sacs"] = cultie.total_sacrifices
for(var/X in to_know)
lore = list()
@@ -96,7 +97,11 @@
lore["type"] = EK.type
lore["name"] = EK.name
lore["cost"] = EK.cost
lore["disabled"] = EK.cost <= charge ? FALSE : TRUE
lore["sacs"] = EK.sacs_needed
if(EK.cost <= charge && cultie.total_sacrifices >= EK.sacs_needed)
lore["disabled"] = FALSE
else
lore["disabled"] = TRUE
lore["path"] = EK.route
lore["state"] = "Research"
lore["flavour"] = EK.gain_text
@@ -108,6 +113,7 @@
var/datum/eldritch_knowledge/EK = known[X]
lore["name"] = EK.name
lore["cost"] = EK.cost
lore["sacs"] = EK.sacs_needed
lore["disabled"] = TRUE
lore["path"] = EK.route
lore["state"] = "Researched"

View File

@@ -165,6 +165,25 @@
new /obj/effect/reality_smash(chosen_location)
ReworkNetwork()
/**
*CIT CHANGE
*
*Creates a singular reality smash
*Credit to slimelust
*/
/datum/reality_smash_tracker/proc/RandomSpawnSmash(var/deferred = FALSE)
var/turf/chosen_location = get_safe_random_station_turf()
//we also dont want them close to each other, at least 1 tile of separation
var/obj/effect/reality_smash/what_if_i_have_one = locate() in range(1, chosen_location)
var/obj/effect/broken_illusion/what_if_i_had_one_but_got_used = locate() in range(1, chosen_location)
var/tries = 10
while((what_if_i_have_one || what_if_i_had_one_but_got_used) && tries-- > 0)
chosen_location = get_safe_random_station_turf()
new /obj/effect/reality_smash(chosen_location)
if(!deferred)
ReworkNetwork()
/**
* Adds a mind to the list of people that can see the reality smashes
*
@@ -200,15 +219,23 @@
/obj/effect/broken_illusion/Initialize()
. = ..()
addtimer(CALLBACK(src,.proc/show_presence),15 SECONDS)
addtimer(CALLBACK(src,.proc/remove_presence),195 SECONDS)
var/image/I = image('icons/effects/eldritch.dmi',src,null,OBJ_LAYER)
I.override = TRUE
add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/silicons, "pierced_reality", I)
/obj/effect/broken_illusion/Destroy()
GLOB.reality_smash_track.RandomSpawnSmash()
return ..()
///Makes this obj appear out of nothing
/obj/effect/broken_illusion/proc/show_presence()
animate(src,alpha = 255,time = 15 SECONDS)
/obj/effect/broken_illusion/proc/remove_presence()
qdel(src)
/obj/effect/broken_illusion/attack_hand(mob/living/user, list/modifiers)
if(!ishuman(user))
return ..()

View File

@@ -44,46 +44,6 @@
if(target.stat == DEAD)
to_chat(user,"<span class='warning'>[target.real_name] is dead. Bring them onto a transmutation rune!</span>")
/datum/action/innate/heretic_shatter
name = "Shattering Offer"
desc = "After a brief delay, you will be granted salvation from a dire situation at the cost of your blade. (Teleports you to a random safe turf on your current z level after a windup, but destroys your blade.)"
background_icon_state = "bg_ecult"
button_icon_state = "shatter"
icon_icon = 'icons/mob/actions/actions_ecult.dmi'
check_flags = MOBILITY_HOLD|MOBILITY_MOVE|MOBILITY_USE
var/mob/living/carbon/human/holder
var/obj/item/melee/sickly_blade/sword
/datum/action/innate/heretic_shatter/Grant(mob/user, obj/object)
sword = object
holder = user
//i know what im doing
return ..()
/datum/action/innate/heretic_shatter/IsAvailable()
if(IS_HERETIC(holder) || IS_HERETIC_MONSTER(holder))
return ..()
else
return FALSE
/datum/action/innate/heretic_shatter/Activate()
if(do_after(holder,10, target = holder))
if(!sword || QDELETED(sword))
return
if(!IsAvailable()) //Never trust the user.
return
var/swordz = (get_turf(sword))?.z //SHOULD usually have a turf but if it doesn't better be prepared.
if(!swordz)
to_chat(holder, "<span class='warning'>[sword] flickers but remains in place, as do you...</span>")
return
var/turf/safe_turf = find_safe_turf(zlevels = swordz, extended_safety_checks = TRUE)
if(!safe_turf)
to_chat(holder, "<span class='warning'>[sword] flickers but remains in place, as do you...</span>")
return
do_teleport(holder,safe_turf,forceMove = TRUE,channel=TELEPORT_CHANNEL_MAGIC)
to_chat(holder,"<span class='warning'>You feel a gust of energy flow through your body... the Rusted Hills heard your call...</span>")
qdel(sword)
/obj/item/melee/sickly_blade
name = "sickly blade"
desc = "A sickly green crescent blade, decorated with an ornamental eye. You feel like you're being watched..."
@@ -101,11 +61,6 @@
throwforce = 10
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "tore", "lacerated", "ripped", "diced", "rended")
var/datum/action/innate/heretic_shatter/linked_action
/obj/item/melee/sickly_blade/Initialize()
. = ..()
linked_action = new(src)
/obj/item/melee/sickly_blade/attack(mob/living/target, mob/living/user)
if(!(IS_HERETIC(user) || IS_HERETIC_MONSTER(user)))
@@ -120,13 +75,17 @@
return
return ..()
/obj/item/melee/sickly_blade/pickup(mob/user)
. = ..()
linked_action.Grant(user, src)
/obj/item/melee/sickly_blade/dropped(mob/user, silent)
. = ..()
linked_action.Remove(user, src)
/obj/item/melee/sickly_blade/attack_self(mob/user)
var/turf/safe_turf = find_safe_turf(zlevels = z, extended_safety_checks = TRUE)
if(IS_HERETIC(user) || IS_HERETIC_MONSTER(user))
if(do_teleport(user, safe_turf, forceMove = TRUE, channel = TELEPORT_CHANNEL_MAGIC))
to_chat(user,"<span class='warning'>As you shatter [src], you feel a gust of energy flow through your body. The Rusted Hills heard your call...</span>")
else
to_chat(user,"<span class='warning'>You shatter [src], but your plea goes unanswered.</span>")
else
to_chat(user,"<span class='warning'>You shatter [src].</span>")
playsound(src, "shatter", 70, TRUE) //copied from the code for smashing a glass sheet onto the ground to turn it into a shard
qdel(src)
/obj/item/melee/sickly_blade/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
. = ..()
@@ -141,6 +100,11 @@
else
eldritch_knowledge_datum.on_ranged_attack_eldritch_blade(target,user,click_parameters)
/obj/item/melee/sickly_blade/examine(mob/user)
. = ..()
if(IS_HERETIC(user) || IS_HERETIC_MONSTER(user))
. += "<span class='notice'><B>A heretic (or a servant of one) can shatter this blade to teleport to a random, mostly safe location by activating it in-hand.</B></span>"
/obj/item/melee/sickly_blade/rust
name = "rusted blade"
desc = "This crescent blade is decrepit, wasting to rust. Yet still it bites, ripping flesh and bone with jagged, rotten teeth."
@@ -243,6 +207,7 @@
// slightly worse than normal cult robes
armor = list("melee" = 30, "bullet" = 30, "laser" = 30,"energy" = 30, "bomb" = 15, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0)
pocket_storage_component_path = /datum/component/storage/concrete/pockets/void_cloak
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
/obj/item/clothing/suit/hooded/cultrobes/void/ToggleHood()
if(!iscarbon(loc))

View File

@@ -15,6 +15,8 @@
var/gain_text = ""
///Cost of knowledge in souls
var/cost = 0
///Required sacrifices to unlock
var/sacs_needed = 0
///Next knowledge in the research tree
var/list/next_knowledge = list()
///What knowledge is incompatible with this. This will simply make it impossible to research knowledges that are in banned_knowledge once this gets researched.
@@ -230,7 +232,6 @@
atoms -= H
H.gib()
///////////////
///Base lore///
///////////////

View File

@@ -50,7 +50,7 @@
/obj/item/melee/touch_attack/mansus_fist/afterattack(atom/target, mob/user, proximity_flag, click_parameters)
if(!proximity_flag | target == user)
if(!proximity_flag || (target == user))
return
playsound(user, 'sound/items/welder.ogg', 75, TRUE)
if(ishuman(target))

View File

@@ -109,10 +109,15 @@
gain_text = "When the Glory of the Lantern scorches and sears their skin, nothing will protect them from the ashes."
desc = "Fire off five streams of fire from your hand, each setting ablaze targets hit and scorching them upon contact."
cost = 2
sacs_needed = 3
spell_to_add = /obj/effect/proc_holder/spell/pointed/nightwatchers_rite
next_knowledge = list(/datum/eldritch_knowledge/final/ash_final)
route = PATH_ASH
/datum/eldritch_knowledge/spell/nightwatchers_rite/on_gain(mob/user)
. = ..()
priority_announce("Large heat signatures discovered! A swelling fiery horror is coming..", sound = 'sound/misc/notice1.ogg')
/datum/eldritch_knowledge/ash_blade_upgrade
name = "Fiery Blade"
gain_text = "Blade in hand, he swung and swung as the ash fell from the skies. His city, his people... all burnt to cinders, and yet life still remained in his charred body."
@@ -181,6 +186,7 @@
desc = "Bring 3 corpses onto a transmutation rune, you will become immune to fire, the vacuum of space, cold and other enviromental hazards and become overall sturdier to all other damages. You will gain a spell that passively creates ring of fire around you as well ,as you will gain a powerful ability that lets you create a wave of flames all around you."
required_atoms = list(/mob/living/carbon/human)
cost = 5
sacs_needed = 8
route = PATH_ASH
var/list/trait_list = list(TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE)

View File

@@ -170,7 +170,7 @@
gain_text = "The Uncanny Man, who walks alone in the valley between the worlds... I was able to summon his aid."
desc = "You can now summon a Raw Prophet by transmutating a pair of eyes, a left arm and a pool of blood. Raw prophets have increased seeing range, as well as X-Ray vision, but they are very fragile."
cost = 1
required_atoms = list(/obj/item/organ/eyes,/obj/item/bodypart/l_arm,/obj/item/bodypart/r_arm,/obj/effect/decal/cleanable/blood)
required_atoms = list(/obj/item/organ/eyes,/obj/item/bodypart/l_arm,/obj/effect/decal/cleanable/blood)
mob_to_summon = /mob/living/simple_animal/hostile/eldritch/raw_prophet
next_knowledge = list(/datum/eldritch_knowledge/flesh_blade_upgrade,/datum/eldritch_knowledge/rune_carver,/datum/eldritch_knowledge/curse/paralysis)
route = PATH_FLESH
@@ -217,6 +217,7 @@
desc = "Bring 3 bodies onto a transmutation rune to shed your human form and ascend to untold power."
required_atoms = list(/mob/living/carbon/human)
cost = 5
sacs_needed = 8
route = PATH_FLESH
/datum/eldritch_knowledge/final/flesh_final/on_finished_recipe(mob/living/user, list/atoms, loc)
@@ -257,6 +258,11 @@
gain_text = "The ignorant mind that inhabits their feeble bodies will crumble when they acknowledge - willingly or not, the truth."
desc = "By forcing the knowledge of the Mansus upon my foes, I can show them things that would drive any normal man insane."
cost = 2
sacs_needed = 3
spell_to_add = /obj/effect/proc_holder/spell/targeted/touch/mad_touch
next_knowledge = list(/datum/eldritch_knowledge/final/flesh_final)
route = PATH_FLESH
/datum/eldritch_knowledge/spell/touch_of_madness/on_gain(mob/user)
. = ..()
priority_announce("The stench of rotting flesh fills the air... An approaching abomination has been detected!", sound = 'sound/misc/notice1.ogg')

View File

@@ -24,7 +24,7 @@
var/check = FALSE
if(ismob(target))
var/mob/living/mobster = target
if(!mobster.mob_biotypes & MOB_ROBOTIC)
if(!(mobster.mob_biotypes & MOB_ROBOTIC))
return FALSE
else
check = TRUE
@@ -159,15 +159,21 @@
desc = "Applying your knowledge of rust to the human body, a knowledge that could decay your foes from the inside out, resulting in organ failure, vomiting, or eventual death through the peeling of rotting flesh."
gain_text = "Rust, decay, it's all the same. All that remains is application."
cost = 2
sacs_needed = 3
spell_to_add = /obj/effect/proc_holder/spell/targeted/touch/grasp_of_decay
next_knowledge = list(/datum/eldritch_knowledge/final/rust_final)
route = PATH_RUST
/datum/eldritch_knowledge/spell/grasp_of_decay/on_gain(mob/user)
. = ..()
priority_announce("A foul wind is blowing... The floor creaks with rust as something sinister approaches!", sound = 'sound/misc/notice1.ogg')
/datum/eldritch_knowledge/final/rust_final
name = "Rustbringer's Oath"
desc = "Bring three corpses onto a transmutation rune. After you finish the ritual, rust will now automatically spread from the rune. Your healing on rust is also tripled, while you become more resilient overall."
gain_text = "Champion of rust. Corruptor of steel. Fear the dark for the Rustbringer has come! Rusted Hills, CALL MY NAME!"
cost = 5
sacs_needed = 8
required_atoms = list(/mob/living/carbon/human)
route = PATH_RUST

View File

@@ -160,15 +160,21 @@
gain_text = "This world will be my stage, and nothing will be out of my reach."
desc = "Gain the ability to mark a 7x7 area as your domain after a short delay. Creatures in your domain are slowed and branded with a void mark, allowing you to quickly teleport to them and slash them, further inhibiting their ability to move."
cost = 2
sacs_needed = 3
spell_to_add = /obj/effect/proc_holder/spell/aoe_turf/domain_expansion
next_knowledge = list(/datum/eldritch_knowledge/final/void_final)
route = PATH_VOID
/datum/eldritch_knowledge/spell/domain_expansion/on_gain(mob/user)
. = ..()
priority_announce("Echos of the lost in space are heard... An ominous presence is being detected! ", sound = 'sound/misc/notice1.ogg')
/datum/eldritch_knowledge/final/void_final
name = "Waltz at the End of Time"
desc = "Bring 3 corpses onto the transmutation rune. After you finish the ritual you will automatically silence people around you and will summon a snow storm around you."
gain_text = "The world falls into darkness. I stand in an empty plane, small flakes of ice fall from the sky. The Aristocrat stands before me, he motions to me. We will play a waltz to the whispers of dying reality, as the world is destroyed before our eyes."
cost = 5
sacs_needed = 8
required_atoms = list(/mob/living/carbon/human)
route = PATH_VOID
///soundloop for the void theme

View File

@@ -492,7 +492,7 @@
var/targetAmount = 100
/datum/objective/revenant/New()
targetAmount = rand(350,600)
targetAmount = rand(150,300)
explanation_text = "Absorb [targetAmount] points of essence from humans."
..()

View File

@@ -84,6 +84,9 @@
if(slam_cooldown + slam_cooldown_time > world.time)
to_chat(src, "<span class='warning'>Your slam ability is still on cooldown!</span>")
return
if(!isopenturf(loc))
to_chat(src, "<span class='warning'>You need to be on open flooring to do that!")
return
face_atom(A)
var/mob/living/victim = A

View File

@@ -145,7 +145,7 @@
if("VICTIM")
var/mob/living/carbon/human/T = target
var/datum/antagonist/cult/C = user.mind.has_antag_datum(/datum/antagonist/cult,TRUE)
if(C?.cult_team.is_sacrifice_target(T.mind))
if(C && C.cult_team.is_sacrifice_target(T.mind))
if(iscultist(user))
to_chat(user, "<span class='cult'><b>\"This soul is mine.</b></span> <span class='cultlarge'>SACRIFICE THEM!\"</span>")
else

View File

@@ -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

View File

@@ -37,14 +37,19 @@
/obj/item/clothing/gloves/fingerless/pugilist/equipped(mob/user, slot)
. = ..()
if(slot == SLOT_GLOVES)
use_buffs(user, TRUE)
wornonce = TRUE
if((HAS_TRAIT(user, TRAIT_NOPUGILIST)))
to_chat(user, "<span class='danger'>What purpose is there to don the weapons of pugilism if you're already well-practiced in martial arts? Mixing arts is blasphemous!</span>")
return
use_buffs(user, TRUE)
/obj/item/clothing/gloves/fingerless/pugilist/dropped(mob/user)
. = ..()
if(wornonce)
use_buffs(user, FALSE)
wornonce = FALSE
if((HAS_TRAIT(user, TRAIT_NOPUGILIST)))
return
use_buffs(user, FALSE)
/obj/item/clothing/gloves/fingerless/pugilist/proc/use_buffs(mob/user, buff)
if(buff) // tarukaja
@@ -67,6 +72,7 @@
H.dna.species.punchdamagehigh -= enhancement
H.dna.species.punchdamagelow -= enhancement
H.dna.species.punchwoundbonus -= wound_enhancement
H.dna?.species?.attack_sound_override = null
if(!silent)
to_chat(user, "<span class='warning'>With [src] off of your arms, you feel less ready to punch things.</span>")
@@ -223,6 +229,50 @@
parry_cooldown = 0
parry_failed_clickcd_duration = 0
/obj/item/clothing/gloves/fingerless/pugilist/mauler
name = "mauler gauntlets"
desc = "Plastitanium gauntlets coated in a thick nano-weave carbon material and implanted with nanite injectors that boost the wielder's strength six-fold."
icon_state = "mauler_gauntlets"
item_state = "mauler_gauntlets"
transfer_prints = FALSE
body_parts_covered = ARMS|HANDS
cold_protection = ARMS|HANDS
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
max_heat_protection_temperature = GLOVES_MAX_TEMP_PROTECT
armor = list("melee" = 30, "bullet" = 30, "laser" = 10, "energy" = 10, "bomb" = 55, "bio" = 15, "rad" = 15, "fire" = 80, "acid" = 50)
siemens_coefficient = 0
permeability_coefficient = 0.05
strip_delay = 80
enhancement = 12 // same as the changeling gauntlets but without changeling utility
wound_enhancement = 12
silent = TRUE
inherited_trait = TRAIT_CHUNKYFINGERS // your fingers are fat because the gloves are
secondary_trait = TRAIT_MAULER // commit table slam
/obj/item/clothing/gloves/fingerless/pugilist/mauler/equipped(mob/user, slot)
. = ..()
if(slot == SLOT_GLOVES)
wornonce = TRUE
if((HAS_TRAIT(user, TRAIT_NOPUGILIST)))
return
use_mauls(user, TRUE)
/obj/item/clothing/gloves/fingerless/pugilist/mauler/dropped(mob/user)
. = ..()
if(wornonce)
wornonce = FALSE
if((HAS_TRAIT(user, TRAIT_NOPUGILIST)))
return
use_mauls(user, FALSE)
/obj/item/clothing/gloves/fingerless/pugilist/mauler/proc/use_mauls(mob/user, maul)
if(maul)
if(ishuman(user))
var/mob/living/carbon/human/H = user
H.dna?.species?.attack_sound_override = 'sound/weapons/mauler_punch.ogg'
if(silent)
to_chat(H, "<span class='danger'>You feel prickles around your wrists as [src] cling to them - strength courses through your veins!</span>")
/obj/item/clothing/gloves/botanic_leather
name = "botanist's leather gloves"
desc = "These leather gloves protect against thorns, barbs, prickles, spikes and other harmful objects of floral origin. They're also quite warm."
@@ -253,7 +303,6 @@
armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 80, "acid" = 50)
strip_mod = 1.5
/obj/item/clothing/gloves/bracer
name = "bone bracers"
desc = "For when you're expecting to get slapped on the wrist. Offers modest protection to your arms."

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>")

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

View File

@@ -535,3 +535,9 @@
to_chat(user, "<span class='notice'>You insert [I] into [src].</span>")
B.use(10)
icon_state = initial(icon_state)
/obj/item/clothing/shoes/swagshoes
name = "swag shoes"
desc = "They got me for my foams!"
icon_state = "SwagShoes"
item_state = "SwagShoes"

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 ..()

View File

@@ -355,3 +355,10 @@
name = "Sakura Kimono'"
icon_state = "sakura_kimono"
item_state = "sakura_kimono"
/obj/item/clothing/under/costume/swagoutfit
name = "Swag outfit"
desc = "Why don't you go secure some bitches?"
icon_state = "SwagOutfit"
item_state = "SwagOutfit"
can_adjust = FALSE

View File

@@ -102,9 +102,14 @@
desc = "An uniform worn by command officers since 2420s."
icon_state = "orv_com"
/obj/item/clothing/under/trek/engsec/orv
/obj/item/clothing/under/trek/eng/orv
desc = "An uniform worn by operations officers since 2420s."
icon_state = "orv_ops"
icon_state = "orv_eng"
/obj/item/clothing/under/trek/sec/orv
desc = "An uniform worn by security officers since 2420s."
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 30, "acid" = 30, "wound" = 10)
icon_state = "orv_sec"
/obj/item/clothing/under/trek/medsci/orv
desc = "An uniform worn by medsci officers since 2420s."
@@ -114,13 +119,20 @@
//honestly no idea why i added specified comm. uniforms but w/e
/obj/item/clothing/under/trek/command/orv/captain
name = "captain uniform"
desc = "An uniform worn by captains since 2550s."
desc = "An uniform worn by captains and commanders since 2550s."
icon_state = "orv_com_capt"
/obj/item/clothing/under/trek/command/orv/engsec
name = "operations command uniform"
desc = "An uniform worn by operations command officers since 2550s."
icon_state = "orv_com_ops"
/obj/item/clothing/under/trek/command/orv/eng
name = "engineering command uniform"
desc = "An uniform worn by Chief Engineers since 2550s."
icon_state = "orv_com_eng"
/obj/item/clothing/under/trek/command/orv/sec
name = "security command uniform"
armor = list("melee" = 10, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 50, "acid" = 50, "wound" = 10)
desc = "An uniform worn by Heads of Security since 2550s."
icon_state = "orv_com_sec"
/obj/item/clothing/under/trek/command/orv/medsci
name = "medsci command uniform"
@@ -131,13 +143,11 @@
name = "adjutant uniform"
desc = "An uniform worn by adjutants <i>(assistants)</i> since 2550s."
icon_state = "orv_ass"
item_state = "gy_suit"
/obj/item/clothing/under/trek/orv/service
name = "service uniform"
desc = "An uniform worn by service officers since 2550s."
icon_state = "orv_srv"
item_state = "g_suit"
//The Motion Picture
/obj/item/clothing/under/trek/fedutil

View File

@@ -61,7 +61,7 @@
originMachine.visible_message("[originMachine] beeps and seems lifeless.")
kill()
return
vendingMachines = listclearnulls(vendingMachines)
listclearnulls(vendingMachines)
if(!vendingMachines.len) //if every machine is infected
for(var/obj/machinery/vending/upriser in infectedMachines)
if(prob(70) && !QDELETED(upriser))

View File

@@ -0,0 +1,22 @@
/datum/round_event_control/cat_surgeon
name = "Cat Surgeon"
typepath = /datum/round_event/cat_surgeon
max_occurrences = 1
weight = 10
/datum/round_event/cat_surgeon/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/cat_butcherer/S = new(T)
playsound(S, 'sound/misc/catscream.ogg', 50, 1, -1)
message_admins("A cat surgeon has been spawned at [COORD(T)][ADMIN_JMP(T)]")
log_game("A cat surgeon has been spawned at [COORD(T)]")
return SUCCESSFUL_SPAWN

View File

@@ -0,0 +1,11 @@
/datum/round_event_control/meteor_wave/cat
name = "Meteor Wave: CATastrophic"
typepath = /datum/round_event/meteor_wave/cat
weight = 10
max_occurrences = 1
/datum/round_event/meteor_wave/cat
wave_name = "cat"
/datum/round_event/meteor_wave/cat/announce(fake)
priority_announce("Unknown biological entities have been detected near [station_name()], please stand-by.", "Lifesign Alert", "meteors")

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

View File

@@ -56,6 +56,8 @@
wave_type = GLOB.meteorsC
if("halloween")
wave_type = GLOB.meteorsSPOOKY
if("cat")
wave_type = GLOB.meteorsCat
else
WARNING("Wave name of [wave_name] not recognised.")
kill()

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

View File

@@ -391,6 +391,15 @@
bonus_reagents = list(/datum/reagent/consumable/nutriment = 1, /datum/reagent/consumable/nutriment/vitamin = 1)
tastes = list("meat" = 3, "smokey sauce" = 1)
foodtype = MEAT
/obj/item/reagent_containers/food/snacks/goliathcalamari
name = "goliath calamari"
desc = "ACKCHYUALLY, this isn't calamari, guys!"
icon_state = "goliathcalamari"
bonus_reagents = list(/datum/reagent/consumable/nutriment/vitamin = 3, /datum/reagent/consumable/capsaicin = 1)
list_reagents = list(/datum/reagent/consumable/nutriment = 5, /datum/reagent/consumable/nutriment/vitamin = 5, /datum/reagent/consumable/capsaicin = 2)
tastes = list("rock" = 1, "meat" = 1)
foodtype = MEAT
////////////// Cubes //////////

View File

@@ -213,3 +213,12 @@
)
result = /obj/item/reagent_containers/food/snacks/salad/gumbo
subcategory = CAT_MEAT
/datum/crafting_recipe/food/goliathcalamari
name = "Goliath Calamari"
reqs = list(
/obj/item/reagent_containers/food/snacks/meat/slab/goliath = 2,
/datum/reagent/consumable/cooking_oil = 10
)
result = /obj/item/reagent_containers/food/snacks/goliathcalamari
subcategory = CAT_MEAT

View File

@@ -101,6 +101,13 @@
matrixed_sections = MATRIX_RED
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
/datum/sprite_accessory/ears/lablight
name = "Dog, Floppy (Light)"
icon_state = "lablight"
color_src = MATRIXED
matrixed_sections = MATRIX_RED
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
/datum/sprite_accessory/ears/human/eevee
name = "Eevee"
icon_state = "eevee"
@@ -162,12 +169,19 @@
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
/datum/sprite_accessory/ears/human/rabbit
name = "Rabbit"
name = "Rabbit (Lop-eared)"
icon_state = "rabbit"
color_src = MATRIXED
matrixed_sections = MATRIX_RED_GREEN
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
/datum/sprite_accessory/ears/human/rabbitalt
name = "Rabbit (Straight-eared)"
icon_state = "rabbitalt"
color_src = MATRIXED
matrixed_sections = MATRIX_ALL
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
/datum/sprite_accessory/ears/human/pede
name = "Scolipede"
icon_state = "pede"
@@ -296,7 +310,7 @@
/datum/sprite_accessory/ears/mam_ears/deer
name = "Deer"
icon_state = "deer"
color_src = MUTCOLORS3
matrixed_sections = MATRIX_RED_GREEN
/datum/sprite_accessory/ears/mam_ears/eevee
name = "Eevee"
@@ -344,10 +358,15 @@
matrixed_sections = MATRIX_RED_GREEN
/datum/sprite_accessory/ears/mam_ears/lab
name = "Dog, Long"
name = "Dog, Floppy"
icon_state = "lab"
matrixed_sections = MATRIX_RED
/datum/sprite_accessory/ears/mam_ears/lablight
name = "Dog, Floppy (Light)"
icon_state = "lablight"
matrixed_sections = MATRIX_RED
/datum/sprite_accessory/ears/mam_ears/murid
name = "Murid"
icon_state = "murid"
@@ -359,10 +378,15 @@
matrixed_sections = MATRIX_RED_GREEN
/datum/sprite_accessory/ears/mam_ears/rabbit
name = "Rabbit"
name = "Rabbit (Lop-eared)"
icon_state = "rabbit"
matrixed_sections = MATRIX_RED_GREEN
/datum/sprite_accessory/ears/mam_ears/rabbitalt
name = "Rabbit (Straight-eared)"
icon_state = "rabbitalt"
matrixed_sections = MATRIX_ALL
/datum/sprite_accessory/ears/mam_ears/pede
name = "Scolipede"
icon_state = "pede"

View File

@@ -17,6 +17,10 @@
name = "Adhara"
icon_state = "hair_adhara"
/datum/sprite_accessory/hair/africanpigtails
name = "African Pig Tails"
icon_state = "hair_africanpigtails"
/datum/sprite_accessory/hair/afro
name = "Afro"
icon_state = "hair_afro"
@@ -25,10 +29,26 @@
name = "Afro 2"
icon_state = "hair_afro2"
/datum/sprite_accessory/hair/afro2alt
name = "Afro 2 (Alt)"
icon_state = "hair_afro2alt"
/datum/sprite_accessory/hair/afro_large
name = "Afro (Large)"
icon_state = "hair_bigafro"
/datum/sprite_accessory/hair/afropuffdouble
name = "Afropuff (Double)"
icon_state = "hair_afropuffdouble"
/datum/sprite_accessory/hair/afropuffleft
name = "Afropuff (Left)"
icon_state = "hair_afropuffleft"
/datum/sprite_accessory/hair/afropuffright
name = "Afropuff (Right)"
icon_state = "hair_afropuffright"
/datum/sprite_accessory/hair/antenna
name = "Ahoge"
icon_state = "hair_antenna"
@@ -41,10 +61,18 @@
name = "Anita"
icon_state = "hair_anita"
/datum/sprite_accessory/hair/astolfo
name = "Astolfo"
icon_state = "hair_astolfo"
/datum/sprite_accessory/hair/balding
name = "Balding Hair"
icon_state = "hair_e"
/datum/sprite_accessory/hair/baum
name = "Baum"
icon_state = "hair_baum"
/datum/sprite_accessory/hair/bedhead
name = "Bedhead"
icon_state = "hair_bedhead"
@@ -85,6 +113,14 @@
name = "Belle"
icon_state = "hair_belle"
/datum/sprite_accessory/hair/bluntbangs
name = "Bluntbangs"
icon_state = "hair_bluntbangs"
/datum/sprite_accessory/hair/bluntbangsalt
name = "Bluntbangs (Alt)"
icon_state = "hair_bluntbangsalt"
/datum/sprite_accessory/hair/bob
name = "Bob Hair"
icon_state = "hair_bob"
@@ -109,6 +145,10 @@
name = "Bobcut (Alt)"
icon_state = "hair_bobcutalt"
/datum/sprite_accessory/hair/bobcutalt2
name = "Bobcut (Alt) 2"
icon_state = "hair_bobcutalt2"
/datum/sprite_accessory/hair/boddicker
name = "Boddicker"
icon_state = "hair_boddicker"
@@ -205,6 +245,14 @@
name = "CIA"
icon_state = "hair_cia"
/datum/sprite_accessory/hair/combedback
name = "Combed Back"
icon_state = "hair_combedback"
/datum/sprite_accessory/hair/combedbob
name = "Combed Bob"
icon_state = "hair_combedbob"
/datum/sprite_accessory/hair/combover
name = "Combover"
icon_state = "hair_combover"
@@ -233,6 +281,14 @@
name = "Cornrow Tail"
icon_state = "hair_cornrowtail"
/datum/sprite_accessory/hair/cotton
name = "Cotton"
icon_state = "hair_cotton"
/datum/sprite_accessory/hair/cottonalt
name = "Cotton (Alt)"
icon_state = "hair_cottonalt"
/datum/sprite_accessory/hair/country
name = "Country"
icon_state = "hair_country"
@@ -261,6 +317,10 @@
name = "Devil Lock"
icon_state = "hair_devillock"
/datum/sprite_accessory/hair/diagonalbangs
name = "Diagonal Bangs"
icon_state = "hair_diagonalbangs"
/datum/sprite_accessory/hair/dreadlocks
name = "Dreadlocks"
icon_state = "hair_dreads"
@@ -337,10 +397,22 @@
name = "Fluffy"
icon_state = "hair_fluffy"
/datum/sprite_accessory/hair/fortuneteller
name = "Fortune Teller"
icon_state = "hair_fortuneteller"
/datum/sprite_accessory/hair/fringetail
name = "Fringe Tail"
icon_state = "hair_fringetail"
/datum/sprite_accessory/hair/froofy
name = "Froofy"
icon_state = "hair_froofy"
/datum/sprite_accessory/hair/geisha
name = "Geisha"
icon_state = "hair_geisha"
/datum/sprite_accessory/hair/gelled
name = "Gelled Back"
icon_state = "hair_gelled"
@@ -349,6 +421,26 @@
name = "Gentle"
icon_state = "hair_gentle"
/datum/sprite_accessory/hair/glammetal
name = "Glam Metal"
icon_state = "hair_glammetal"
/datum/sprite_accessory/hair/gloomy
name = "Gloomy"
icon_state = "hair_gloomy"
/datum/sprite_accessory/hair/gloomylong
name = "Gloomy (Long)"
icon_state = "hair_gloomylong"
/datum/sprite_accessory/hair/hajime
name = "Hajime"
icon_state = "hair_hajime"
/datum/sprite_accessory/hair/hajimealt
name = "Hajime (Alt)"
icon_state = "hair_hajimealt"
/datum/sprite_accessory/hair/halfbang
name = "Half-banged Hair"
icon_state = "hair_halfbang"
@@ -365,6 +457,10 @@
name = "Half-shaved Hair"
icon_state = "hair_halfshaved"
/datum/sprite_accessory/hair/harold
name = "Harold"
icon_state = "hair_harold"
/datum/sprite_accessory/hair/hedgehog
name = "Hedgehog Hair"
icon_state = "hair_hedgehog"
@@ -393,6 +489,10 @@
name = "Hitop"
icon_state = "hair_hitop"
/datum/sprite_accessory/hair/inari
name = "Inari"
icon_state = "hair_inari"
/datum/sprite_accessory/hair/inkling
name = "Inkling"
icon_state = "hair_inkling"
@@ -421,14 +521,18 @@
name = "Keanu"
icon_state = "hair_keanu"
/datum/sprite_accessory/hair/kusangi
name = "Kusanagi"
icon_state = "hair_kusanagi"
/datum/sprite_accessory/hair/kisaragi
name = "Kisaragi"
icon_state = "hair_kisaragi"
/datum/sprite_accessory/hair/kleeia
name = "Kleeia"
icon_state = "hair_kleeia"
/datum/sprite_accessory/hair/kusangi
name = "Kusanagi"
icon_state = "hair_kusanagi"
/datum/sprite_accessory/hair/long
name = "Long Hair 1"
icon_state = "hair_long"
@@ -449,6 +553,10 @@
name = "Long Over Eye"
icon_state = "hair_longovereye"
/datum/sprite_accessory/hair/long_over_eyealt
name = "Long Over Eye (Alt)"
icon_state = "hair_longovereyealt"
/datum/sprite_accessory/hair/longbangs
name = "Long Bangs"
icon_state = "hair_lbangs"
@@ -489,10 +597,6 @@
name = "Mohawk"
icon_state = "hair_d"
/datum/sprite_accessory/hair/newyou
name = "New You"
icon_state = "hair_newyou"
/datum/sprite_accessory/hair/reversemohawk
name = "Mohawk (Reverse)"
icon_state = "hair_reversemohawk"
@@ -509,6 +613,10 @@
name = "Mulder"
icon_state = "hair_mulder"
/datum/sprite_accessory/hair/newyou
name = "New You"
icon_state = "hair_newyou"
/datum/sprite_accessory/hair/nia
name = "Nia"
icon_state = "hair_nia"
@@ -579,10 +687,18 @@
name = "Pompadour (Big)"
icon_state = "hair_bigpompadour"
/datum/sprite_accessory/hair/bigpompadouralt
name = "Pompadour (Big) (Alt)"
icon_state = "hair_bigpompadouralt"
/datum/sprite_accessory/hair/ponytail1
name = "Ponytail"
icon_state = "hair_ponytail"
/datum/sprite_accessory/hair/ponytail1alt
name = "Ponytail (Alt)"
icon_state = "hair_ponytailalt"
/datum/sprite_accessory/hair/ponytail2
name = "Ponytail 2"
icon_state = "hair_ponytail2"
@@ -591,14 +707,26 @@
name = "Ponytail 3"
icon_state = "hair_ponytail3"
/datum/sprite_accessory/hair/ponytail3alt
name = "Ponytail 3 (Alt)"
icon_state = "hair_ponytail3alt"
/datum/sprite_accessory/hair/ponytail4
name = "Ponytail 4"
icon_state = "hair_ponytail4"
/datum/sprite_accessory/hair/ponytail4alt
name = "Ponytail 4 (Alt)"
icon_state = "hair_ponytail4alt"
/datum/sprite_accessory/hair/ponytail5
name = "Ponytail 5"
icon_state = "hair_ponytail5"
/datum/sprite_accessory/hair/ponytail6
name = "Ponytail 6"
icon_state = "hair_ponytail6"
/datum/sprite_accessory/hair/highponytail
name = "Ponytail (High)"
icon_state = "hair_highponytail"
@@ -623,6 +751,10 @@
name = "Ponytail (Side) 4"
icon_state = "hair_sidetail4"
/datum/sprite_accessory/hair/sidetail5
name = "Ponytail (Side) 5"
icon_state = "hair_sidetail5"
/datum/sprite_accessory/hair/sharptail
name = "Ponytail (Sharp)"
icon_state = "hair_sharptail"
@@ -639,10 +771,18 @@
name = "Poofy 2"
icon_state = "hair_poofy2"
/datum/sprite_accessory/hair/quadcurls
name = "Quad Curls"
icon_state = "hair_quadcurls"
/datum/sprite_accessory/hair/quiff
name = "Quiff"
icon_state = "hair_quiff"
/datum/sprite_accessory/hair/rockstar
name = "Rockstar"
icon_state = "hair_rockstar"
/datum/sprite_accessory/hair/ronin
name = "Ronin"
icon_state = "hair_ronin"
@@ -759,6 +899,10 @@
name = "Slightly Long Hair"
icon_state = "hair_protagonist"
/datum/sprite_accessory/hair/slightlymessy
name = "Slightly Messy Hair"
icon_state = "hair_slightlymessy"
/datum/sprite_accessory/hair/spiky
name = "Spiky"
icon_state = "hair_spikey"
@@ -771,6 +915,26 @@
name = "Spiky 3"
icon_state = "hair_spiky2"
/datum/sprite_accessory/hair/slimedroplet
name = "Slime Droplet"
icon_state = "hair_slimedroplet"
/datum/sprite_accessory/hair/slimedropletalt
name = "Slime Droplet (Alt)"
icon_state = "hair_slimedropletalt"
/datum/sprite_accessory/hair/slimespikes
name = "Slime Spikes"
icon_state = "hair_slimespikes"
/datum/sprite_accessory/hair/slimetendrils
name = "Slime Tendrils"
icon_state = "hair_slimetendrils"
/datum/sprite_accessory/hair/slimetendrilsalt
name = "Slime Tendrils (Alt)"
icon_state = "hair_slimetendrilsalt"
/datum/sprite_accessory/hair/supernova
name = "Supernova"
icon_state = "hair_supernova"
@@ -851,6 +1015,10 @@
name = "Very Long Hair 2"
icon_state = "hair_longest"
/datum/sprite_accessory/hair/longestalt
name = "Very Long Hair 2 (Alt)"
icon_state = "hair_longestalt"
/datum/sprite_accessory/hair/longest2
name = "Very Long Over Eye"
icon_state = "hair_longest2"
@@ -886,3 +1054,7 @@
/datum/sprite_accessory/hair/ziegler
name = "Ziegler"
icon_state = "hair_ziegler"
/datum/sprite_accessory/hair/zone
name = "Zone"
icon_state = "hair_zone"

View File

@@ -83,7 +83,8 @@
for (var/_A in mind.antag_datums)
var/datum/antagonist/A = _A
if (A.show_to_ghosts)
var/mob/dead/observer/O = user
if (A?.show_to_ghosts || !O?.can_reenter_corpse)
was_antagonist = TRUE
serialized["antag"] = A.name
antagonists += list(serialized)

View File

@@ -28,7 +28,7 @@
if(skipface || get_visible_name() == "Unknown")
. += "You can't make out what species they are."
else
. += "[t_He] [t_is] a [dna.custom_species ? dna.custom_species : dna.species.name]!"
. += "[t_He] [t_is] a [spec_trait_examine_font()][dna.custom_species ? dna.custom_species : dna.species.name]</font>!"
//uniform
if(w_uniform && !(SLOT_W_UNIFORM in obscured))

View File

@@ -1083,6 +1083,30 @@
. = ..()
set_species(race)
/**
* # `spec_trait_examine_font()`
*
* This gets a humanoid's special examine font, which is used to color their species name during examine / health analyzing.
* The first of these that applies is returned.
* Returns:
* * Metallic font if robotic
* * Cyan if a toxinlover
* * Purple if plasmaperson
* * Rock / Brownish if a golem
* * Green if none of the others apply (aka, generic organic)
*/
/mob/living/carbon/human/proc/spec_trait_examine_font()
if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
return "<font color='#aaa9ad'>"
if(HAS_TRAIT(src, TRAIT_TOXINLOVER))
return "<font color='#00ffff'>"
if(isplasmaman(src))
return "<font color='#800080'"
if(isgolem(src))
return "<font color='#8b4513'"
return "<font color='#18d855'>"
/mob/living/carbon/human/get_tooltip_data()
var/t_He = p_they(TRUE)
var/t_is = p_are()
@@ -1091,7 +1115,7 @@
if(skipface || get_visible_name() == "Unknown")
. += "You can't make out what species they are."
else
. += "[t_He] [t_is] a [dna.custom_species ? dna.custom_species : dna.species.name]"
. += "[t_He] [t_is] a [spec_trait_examine_font()][dna.custom_species ? dna.custom_species : dna.species.name]</font>"
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, usr, .)
/mob/living/carbon/human/species/abductor

View File

@@ -149,6 +149,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
///
var/sound/attack_sound = 'sound/weapons/punch1.ogg'
var/sound/miss_sound = 'sound/weapons/punchmiss.ogg'
var/attack_sound_override = null
var/list/mob/living/ignored_by = list() // list of mobs that will ignore this species
//Breathing!
@@ -569,12 +570,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
/datum/species/proc/remove_blacklisted_quirks(mob/living/carbon/C)
var/mob/living/L = C.mind?.current
if(istype(L))
var/list/my_quirks = L.client?.prefs.all_quirks.Copy()
SSquirks.filter_quirks(my_quirks, blacklisted_quirks)
for(var/q in L.roundstart_quirks)
var/datum/quirk/Q = q
if(!(SSquirks.quirk_name_by_path(Q.type) in my_quirks))
L.remove_quirk(Q.type)
if(Q.type in blacklisted_quirks)
qdel(Q)
removed_quirks += Q.type
// restore any quirks that we removed
@@ -1615,7 +1614,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/armor_block = target.run_armor_check(affecting, "melee")
playsound(target.loc, user.dna.species.attack_sound, 25, 1, -1)
playsound(target.loc, user.dna.species.attack_sound_override || attack_sound, 25, 1, -1)
target.visible_message("<span class='danger'>[user] [atk_verb]ed [target]!</span>", \
"<span class='userdanger'>[user] [atk_verb]ed you!</span>", null, COMBAT_MESSAGE_RANGE, null, \
user, "<span class='danger'>You [atk_verb]ed [target]!</span>")
@@ -2003,6 +2002,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/turf/target_shove_turf = get_step(target.loc, shove_dir)
var/mob/living/carbon/human/target_collateral_human
var/shove_blocked = FALSE //Used to check if a shove is blocked so that if it is knockdown logic can be applied
var/targetatrest = !CHECK_MOBILITY(target, MOBILITY_STAND)
//Thank you based whoneedsspace
target_collateral_human = locate(/mob/living/carbon/human) in target_shove_turf.contents
@@ -2017,7 +2017,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/append_message = ""
if(shove_blocked && !target.buckled)
var/directional_blocked = !target.Adjacent(target_shove_turf)
var/targetatrest = !CHECK_MOBILITY(target, MOBILITY_STAND)
if((directional_blocked || !(target_collateral_human || target_shove_turf.shove_act(target, user))) && !targetatrest)
target.DefaultCombatKnockdown(SHOVE_KNOCKDOWN_SOLID)
target.visible_message("<span class='danger'>[user.name] shoves [target.name], knocking them down!</span>",
@@ -2046,11 +2045,15 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
append_message += ", loosening their grip on [target_held_item]"
else
append_message += ", but couldn't loose their grip on [target_held_item]"
else if(target_held_item)
if(target.dropItemToGround(target_held_item))
target.visible_message("<span class='danger'>[target.name] drops \the [target_held_item]!!</span>",
"<span class='danger'>You drop \the [target_held_item]!!</span>", null, COMBAT_MESSAGE_RANGE)
append_message += ", causing them to drop [target_held_item]"
else if(target.has_status_effect(STATUS_EFFECT_OFF_BALANCE))
if(target_held_item)
if(shove_blocked)
if (target.buckled)
return
else if(target.dropItemToGround(target_held_item))
target.visible_message("<span class='danger'>[target.name] drops \the [target_held_item]!!</span>",
"<span class='danger'>You drop \the [target_held_item]!!</span>", null, COMBAT_MESSAGE_RANGE)
append_message += ", causing them to drop [target_held_item]"
target.ShoveOffBalance(SHOVE_OFFBALANCE_DURATION)
log_combat(user, target, "shoved", append_message)

View File

@@ -542,8 +542,48 @@
update_stat()
med_hud_set_health()
med_hud_set_status()
update_health_hud()
//proc used to ressuscitate a mob
/mob/living/update_health_hud()
var/severity = 0
var/healthpercent = (health/maxHealth) * 100
if(hud_used?.healthdoll) //to really put you in the boots of a simplemob
var/obj/screen/healthdoll/living/livingdoll = hud_used.healthdoll
switch(healthpercent)
if(100 to INFINITY)
livingdoll.icon_state = "living0"
if(80 to 100)
livingdoll.icon_state = "living1"
severity = 1
if(60 to 80)
livingdoll.icon_state = "living2"
severity = 2
if(40 to 60)
livingdoll.icon_state = "living3"
severity = 3
if(20 to 40)
livingdoll.icon_state = "living4"
severity = 4
if(1 to 20)
livingdoll.icon_state = "living5"
severity = 5
else
livingdoll.icon_state = "living6"
severity = 6
if(!livingdoll.filtered)
livingdoll.filtered = TRUE
var/icon/mob_mask = icon(icon, icon_state)
if(mob_mask.Height() > world.icon_size || mob_mask.Width() > world.icon_size)
var/health_doll_icon_state = health_doll_icon ? health_doll_icon : "megasprite"
mob_mask = icon('icons/mob/screen_gen.dmi', health_doll_icon_state) //swap to something generic if they have no special doll
UNLINT(livingdoll.filters += filter(type="alpha", icon = mob_mask))
livingdoll.filters += filter(type="drop_shadow", size = -1)
if(severity > 0)
overlay_fullscreen("brute", /obj/screen/fullscreen/brute, severity)
else
clear_fullscreen("brute")
//Proc used to resuscitate a mob, for full_heal see fully_heal()
/mob/living/proc/revive(full_heal = FALSE, admin_revive = FALSE)
SEND_SIGNAL(src, COMSIG_LIVING_REVIVE, full_heal, admin_revive)
if(full_heal)

View File

@@ -94,6 +94,7 @@
var/smoke_delay = 0 //used to prevent spam with smoke reagent reaction on mob.
var/bubble_icon = "default" //what icon the mob uses for speechbubbles
var/health_doll_icon //if this exists AND the normal sprite is bigger than 32x32, this is the replacement icon state (because health doll size limitations). the icon will always be screen_gen.dmi
var/last_bumped = 0
var/unique_name = 0 //if a mob's name should be appended with an id when created e.g. Mob (666)

View File

@@ -231,8 +231,11 @@
R.update_module_innate()
RM.rebuild_modules()
INVOKE_ASYNC(RM, .proc/do_transform_animation)
if(RM.dogborg)
if(RM.dogborg || R.dogborg)
RM.dogborg_equip()
R.typing_indicator_state = /obj/effect/overlay/typing_indicator/machine/dogborg
else
R.typing_indicator_state = /obj/effect/overlay/typing_indicator/machine
R.maxHealth = borghealth
R.health = min(borghealth, R.health)
qdel(src)

View File

@@ -48,6 +48,8 @@
var/hack_software = FALSE //Will be able to use hacking actions
var/interaction_range = 7 //wireless control range
typing_indicator_state = /obj/effect/overlay/typing_indicator/machine
/mob/living/silicon/Initialize()
. = ..()
GLOB.silicon_mobs += src

View File

@@ -149,6 +149,7 @@
icon_state = "alienq"
icon_living = "alienq"
icon_dead = "alienq_dead"
health_doll_icon = "alienq"
bubble_icon = "alienroyal"
move_to_delay = 4
maxHealth = 400

View File

@@ -73,6 +73,7 @@
icon_living = "megacarp"
icon_dead = "megacarp_dead"
icon_gib = "megacarp_gib"
health_doll_icon = "megacarp"
regen_amount = 6
maxHealth = 30

View File

@@ -6,37 +6,108 @@
icon_living = "cat_butcher"
icon_dead = "syndicate_dead"
icon_gib = "syndicate_gib"
projectiletype = /obj/item/projectile/bullet/dart/catranq
projectilesound = 'sound/items/syringeproj.ogg'
ranged = 1
ranged_message = "fires the syringe gun at"
ranged_cooldown_time = 30
speak_chance = 0
turns_per_move = 5
response_help_continuous = "pokes"
response_harm_continuous = "hits"
speed = 0
stat_attack = UNCONSCIOUS
robust_searching = 1
maxHealth = 100
health = 100
harm_intent_damage = 5
melee_damage_lower = 15
melee_damage_upper = 15
attack_verb_continuous = "slashes at"
attack_verb_simple = "slash at"
attack_sound = 'sound/weapons/circsawhit.ogg'
a_intent = INTENT_HARM
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
loot = list(/obj/effect/mob_spawn/human/corpse/cat_butcher, /obj/item/circular_saw)
mob_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
loot = list(/obj/effect/mob_spawn/human/corpse/cat_butcher, /obj/item/circular_saw, /obj/item/gun/syringe)
atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 1, "min_co2" = 0, "max_co2" = 5, "min_n2" = 0, "max_n2" = 0)
unsuitable_atmos_damage = 15
faction = list("hostile")
check_friendly_fire = 1
status_flags = CANPUSH
del_on_death = 1
del_on_death = TRUE
var/impatience = 0
rapid_melee = 2 //this lets him attack nearly as fast as a normal player, instead of half as fast as one. Without this, due to mood differences, a greytider in melee can actually facetank and beat him to death with only fists
dodging = TRUE
/mob/living/simple_animal/hostile/cat_butcherer/Life()
. = ..()
if(prob(10) && health <= maxHealth && !target) //heal himself when not in combat
var/healamount = min(maxHealth-health, 20)
visible_message("[src] medicates themself.", "<span class='notice'>You medicate yourself.</span>")
health += healamount
/mob/living/simple_animal/hostile/cat_butcherer/CanAttack(atom/the_target)
if(iscarbon(target))
var/mob/living/carbon/human/C = target
if(C.getorgan(/obj/item/organ/ears/cat) && C.getorgan(/obj/item/organ/tail/cat) && C.has_trauma_type(/datum/brain_trauma/severe/pacifism))//he wont attack his creations
if(C.stat && !istype(C.dna.species, /datum/species/ipc))//unless they need healing
return ..()
else
return FALSE
return ..()
/mob/living/simple_animal/hostile/cat_butcherer/AttackingTarget()
. = ..()
if(. && prob(35) && iscarbon(target))
if(iscarbon(target))
var/mob/living/carbon/human/L = target
var/obj/item/organ/tail/cat/tail = L.getorgan(/obj/item/organ/tail/cat)
if(!QDELETED(tail))
visible_message("[src] severs [L]'s tail in one swift swipe!", "<span class='notice'>You sever [L]'s tail in one swift swipe.</span>")
tail.Remove()
var/obj/item/organ/tail/cat/dropped_tail = new(target.drop_location())
dropped_tail.color = L.hair_color
return 1
if(!L.getorgan(/obj/item/organ/ears/cat) && L.stat) //target doesnt have cat ears
if(L.getorgan(/obj/item/organ/ears)) //slice off the old ears
var/obj/item/organ/ears/ears = L.getorgan(/obj/item/organ/ears)
visible_message("[src] slices off [L]'s ears!", "<span class='notice'>You slice [L]'s ears off.</span>")
ears.Remove(L)
ears.forceMove(get_turf(L))
else //implant new ears
visible_message("[src] attaches a pair of cat ears to [L]!", "<span class='notice'>You attach a pair of cat ears to [L].</span>")
var/obj/item/organ/ears/cat/newears = new
newears.Insert(L, drop_if_replaced = FALSE)
return
else if(!L.getorgan(/obj/item/organ/tail/cat) && L.stat)
if(L.getorgan(/obj/item/organ/tail)) //cut off the tail if they have one already
var/obj/item/organ/tail/tail = L.getorgan(/obj/item/organ/tail)
visible_message("[src] severs [L]'s tail in one swift swipe!", "<span class='notice'>You sever [L]'s tail in one swift swipe.</span>")
tail.Remove(L)
tail.forceMove(get_turf(L))
else //put a cat tail on
visible_message("[src] attaches a cat tail to [L]!", "<span class='notice'>You attach a tail to [L].</span>")
var/obj/item/organ/tail/cat/newtail = new
newtail.Insert(L, drop_if_replaced = FALSE)
return
else if(!L.has_trauma_type(/datum/brain_trauma/severe/pacifism) && L.getorgan(/obj/item/organ/ears/cat) && L.getorgan(/obj/item/organ/tail/cat)) //still does damage. This also lacks a Stat check- felinids beware.
visible_message("[src] drills a hole in [L]'s skull!", "<span class='notice'>You pacify [L]. Another successful creation.</span>")
if(L.stat == CONSCIOUS)
L.emote("scream")
L.gain_trauma(/datum/brain_trauma/severe/pacifism, TRAUMA_RESILIENCE_BASIC)
say("Such a GOOD KITTY!!")
if(L.mind && maxHealth <= 300) //if he robusts a tider, he becomes stronger
maxHealth += 20
adjustHealth(-(maxHealth)) //he heals whenever he finishes
else if(L.stat) //quickly heal them up and move on to our next target!
visible_message("[src] injects [L] with an unknown medicine!", "<span class='notice'>You inject [L] with medicine.</span>")
L.SetSleeping(0, FALSE)
L.SetUnconscious(0, FALSE)
L.adjustOxyLoss(-50)// do CPR first
if(L.blood_volume <= 500) //bandage them up and give em some blood if they're bleeding
L.blood_volume += 30
L.bleedsuppress = 0
if(L.getBruteLoss() >= 50)// first, did we beat them into crit? if so, heal that
var/healing = min(L.getBruteLoss(), 120)
L.adjustBruteLoss(-healing)
L.bleedsuppress = 0 //bandage their ass
return
else if(L.getFireLoss() >= 50) // are they still down from other damage? fix it, but not as fast as the burns
var/healing = min(L.getFireLoss(), 50)
L.adjustFireLoss(-healing)
impatience += 50
if(prob(impatience))
FindTarget()//so we don't focus on some unconscious dude when we could get our eyes on the prize
impatience = 0
say("Bah!!")
return
return ..()

View File

@@ -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

View File

@@ -9,6 +9,7 @@
icon_state = "crawling"
icon_living = "crawling"
icon_dead = "dead"
health_doll_icon = "crawling"
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
speak_chance = 80
maxHealth = 220

View File

@@ -28,6 +28,7 @@ Difficulty: Medium
icon_state = "miner"
icon_living = "miner"
icon = 'icons/mob/broadMobs.dmi'
health_doll_icon = "miner"
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
light_color = "#E4C7C5"
movement_type = GROUND

View File

@@ -33,6 +33,7 @@ Difficulty: Hard
icon_state = "bubblegum"
icon_living = "bubblegum"
icon_dead = ""
health_doll_icon = "bubblegum"
friendly_verb_continuous = "stares down"
friendly_verb_simple = "stare down"
icon = 'icons/mob/lavaland/96x96megafauna.dmi'

View File

@@ -32,6 +32,7 @@ Difficulty: Very Hard
icon_state = "eva"
icon_living = "eva"
icon_dead = "dragon_dead"
health_doll_icon = "eva"
friendly_verb_continuous = "stares down"
friendly_verb_simple = "stare down"
icon = 'icons/mob/lavaland/96x96megafauna.dmi'

View File

@@ -48,6 +48,7 @@ Difficulty: Medium
icon_state = "dragon"
icon_living = "dragon"
icon_dead = "dragon_dead"
health_doll_icon = "dragon"
friendly_verb_continuous = "stares down"
friendly_verb_simple = "stare down"
speak_emote = list("roars")

View File

@@ -44,6 +44,7 @@ Difficulty: Normal
attack_sound = 'sound/weapons/sonic_jackhammer.ogg'
icon_state = "hierophant"
icon_living = "hierophant"
health_doll_icon = "hierophant"
friendly_verb_continuous = "stares down"
friendly_verb_simple = "stare down"
icon = 'icons/mob/lavaland/hierophant_new.dmi'

View File

@@ -26,6 +26,7 @@ SHITCODE AHEAD. BE ADVISED. Also comment extravaganza
spacewalk = TRUE
icon_state = "mega_legion"
icon_living = "mega_legion"
health_doll_icon = "mega_legion"
desc = "One of many."
icon = 'icons/mob/lavaland/96x96megafauna.dmi'
attack_verb_continuous = "chomps"

View File

@@ -75,6 +75,7 @@
icon_living = "watcher"
icon_aggro = "watcher"
icon_dead = "watcher_dead"
health_doll_icon = "watcher"
pixel_x = -10
throw_message = "bounces harmlessly off of"
melee_damage_lower = 15

View File

@@ -25,6 +25,7 @@
icon_aggro = "broodmother"
icon_dead = "egg_sac"
icon_gib = "syndicate_gib"
health_doll_icon = "broodmother"
maxHealth = 800
health = 800
melee_damage_lower = 30

View File

@@ -24,6 +24,7 @@
icon_aggro = "herald"
icon_dead = "herald_dying"
icon_gib = "syndicate_gib"
health_doll_icon = "herald"
maxHealth = 800
health = 800
melee_damage_lower = 20

View File

@@ -24,6 +24,7 @@
icon_aggro = "legionnaire"
icon_dead = "legionnaire_dead"
icon_gib = "syndicate_gib"
health_doll_icon = "legionnaire"
maxHealth = 800
health = 800
melee_damage_lower = 30

View File

@@ -24,6 +24,7 @@
icon_aggro = "pandora"
icon_dead = "pandora_dead"
icon_gib = "syndicate_gib"
health_doll_icon = "pandora"
maxHealth = 800
health = 800
melee_damage_lower = 15

View File

@@ -253,6 +253,7 @@
icon_state = "legion"
icon_living = "legion"
icon_dead = "legion"
health_doll_icon = "legion"
health = 450
maxHealth = 450
melee_damage_lower = 20

View File

@@ -6,6 +6,7 @@
icon_living = "clown"
icon_dead = "clown_dead"
icon_gib = "clown_gib"
health_doll_icon = "clown" //if >32x32, it will use this generic. for all the huge clown mobs that subtype from this
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
turns_per_move = 5
response_disarm_continuous = "gently pushes aside"

View File

@@ -6,6 +6,7 @@
icon_living = "pine_1"
icon_dead = "pine_1"
icon_gib = "pine_1"
health_doll_icon = "pine_1"
gender = NEUTER
speak_chance = 0
turns_per_move = 5
@@ -72,5 +73,6 @@
icon_living = "festivus_pole"
icon_dead = "festivus_pole"
icon_gib = "festivus_pole"
health_doll_icon = "festivus_pole"
loot = list(/obj/item/stack/rods)
speak_emote = list("polls")

View File

@@ -8,6 +8,7 @@
icon_aggro = "Fugu0"
icon_dead = "Fugu_dead"
icon_gib = "syndicate_gib"
health_doll_icon = "Fugu0"
mob_biotypes = MOB_ORGANIC|MOB_BEAST
mouse_opacity = MOUSE_OPACITY_ICON
move_to_delay = 5

View File

@@ -7,6 +7,7 @@
///How much blud it has for bloodsucking
blood_volume = 550
rad_flags = RAD_NO_CONTAMINATE
hud_type = /datum/hud/living/simple_animal
status_flags = CANPUSH

View File

@@ -6,6 +6,7 @@
var/Discipline = 0 // if a slime has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while
var/SStun = 0 // stun variable
typing_indicator_state = /obj/effect/overlay/typing_indicator/slime
/mob/living/simple_animal/slime/BiologicalLife(seconds, times_fired)
if(!(. = ..()))

View File

@@ -55,3 +55,12 @@ GLOBAL_LIST_EMPTY(typing_indicator_overlays)
icon_state = "normal_typing"
appearance_flags = RESET_COLOR | TILE_BOUND | PIXEL_SCALE
layer = ABOVE_FLY_LAYER
/obj/effect/overlay/typing_indicator/machine
icon_state = "machine_typing"
/obj/effect/overlay/typing_indicator/machine/dogborg
icon = 'icons/mob/talk_64x64.dmi'
/obj/effect/overlay/typing_indicator/slime
icon_state = "slime_typing"

View File

@@ -158,12 +158,12 @@
return FALSE
size_x = clamp(size_x, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT)
size_y = clamp(size_y, 0, CAMERA_PICTURE_SIZE_HARD_LIMIT)
var/list/desc = list("This is a photo of an area of [size_x+1] meters by [size_y+1] meters.")
var/list/desc = list("This is a photo of an area of [size_x*2 + 1] meters by [size_y*2 + 1] meters.")
var/ai_user = isAI(user)
var/list/seen
var/list/viewlist = (user && user.client)? getviewsize(user.client.view) : getviewsize(world.view)
var/list/viewlist = user?.client? getviewsize(user.client.view) : getviewsize(world.view)
var/viewr = max(viewlist[1], viewlist[2]) + max(size_x, size_y)
var/viewc = user.client? user.client.eye : target
var/viewc = user?.client? user.client.eye : target
seen = get_hear(viewr, viewc)
var/list/turfs = list()
var/list/mobs = list()
@@ -184,7 +184,7 @@
var/psize_y = (size_y * 2 + 1) * world.icon_size
var/get_icon = camera_get_icon(turfs, target_turf, psize_x, psize_y, clone_area, size_x, size_y, (size_x * 2 + 1), (size_y * 2 + 1))
qdel(clone_area)
var/icon/temp = icon('icons/effects/96x96.dmi',"")
var/icon/temp = icon('icons/effects/camera_image_base.dmi',"")
temp.Blend("#000", ICON_OVERLAY)
temp.Scale(psize_x, psize_y)
temp.Blend(get_icon, ICON_OVERLAY)

View File

@@ -47,7 +47,7 @@
atoms += A
CHECK_TICK
var/icon/res = icon('icons/effects/96x96.dmi', "")
var/icon/res = icon('icons/effects/camera_image_base.dmi', "")
res.Scale(psize_x, psize_y)
var/list/sorted = list()
@@ -64,7 +64,6 @@
var/xcomp = FLOOR(psize_x / 2, 1) - 15
var/ycomp = FLOOR(psize_y / 2, 1) - 15
for(var/atom/A in sorted)
var/xo = (A.x - center.x) * world.icon_size + A.pixel_x + xcomp
var/yo = (A.y - center.y) * world.icon_size + A.pixel_y + ycomp

View File

@@ -235,10 +235,10 @@
if(POOL_SCALDING) //Scalding
M.adjust_bodytemperature(50,0,500)
if(POOL_WARM) //Warm
M.adjust_bodytemperature(20,0,360) //Heats up mobs till the termometer shows up
M.adjust_bodytemperature(20,0,360) //Heats up mobs till the thermometer shows up
//Normal temp does nothing, because it's just room temperature water.
if(POOL_COOL)
M.adjust_bodytemperature(-20,250) //Cools mobs till the termometer shows up
M.adjust_bodytemperature(-20,250) //Cools mobs till the thermometer shows up
if(POOL_FRIGID) //Freezing
M.adjust_bodytemperature(-60) //cool mob at -35k per cycle, less would not affect the mob enough.
if(M.bodytemperature <= 50 && !M.stat)
@@ -290,10 +290,10 @@
/obj/machinery/pool/controller/proc/update_temp()
if(mist_state)
if(temperature < POOL_SCALDING)
if(temperature < POOL_WARM)
mist_off()
else
if(temperature == POOL_SCALDING)
if(temperature >= POOL_WARM)
mist_on()
update_icon()

View File

@@ -35,6 +35,9 @@
/obj/item/ammo_casing/magic/spellblade
projectile_type = /obj/item/projectile/magic/spellblade
/obj/item/ammo_casing/magic/judgement_cut
projectile_type = /obj/item/projectile/judgement_cut
/obj/item/ammo_casing/magic/arcane_barrage
projectile_type = /obj/item/projectile/magic/arcane_barrage

View File

@@ -568,12 +568,18 @@
/datum/action/item_action/toggle_scope_zoom/IsAvailable(silent = FALSE)
. = ..()
if(!.)
var/obj/item/gun/G = target
G.zoom(owner, owner.dir, FALSE)
/datum/action/item_action/toggle_scope_zoom/Trigger()
. = ..()
if(.)
var/obj/item/gun/G = target
G.zoom(owner, owner.dir)
/datum/action/item_action/toggle_scope_zoom/Remove(mob/living/L)
var/obj/item/gun/G = target
G.zoom(L, L.dir)
G.zoom(L, L.dir, FALSE)
return ..()
/obj/item/gun/proc/rotate(atom/thing, old_dir, new_dir)

View File

@@ -0,0 +1,91 @@
/obj/item/gun/magic/staff/motivation
name = "Motivation"
desc = "Rumored to have the ability to open up a portal the depths of Lavaland."
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "motivation"
item_state = "motivation"
lefthand_file = 'icons/mob/inhands/weapons/swords_lefthand.dmi'
righthand_file = 'icons/mob/inhands/weapons/swords_righthand.dmi'
fire_sound = 'sound/weapons/judgementhit.ogg'
ammo_type = /obj/item/ammo_casing/magic/judgement_cut
force = 20 //so it's worth that 20 tc
armour_penetration = 50
w_class = WEIGHT_CLASS_NORMAL
slot_flags = ITEM_SLOT_BELT
hitsound = 'sound/weapons/bladeslice.ogg'
attack_verb = list("attacked", "slashed", "stabbed", "sliced", "torn", "ripped", "diced", "cut")
sharpness = SHARP_EDGED
max_integrity = 200
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
max_charges = 3
recharge_rate = 5
var/datum/action/judgement_cut/judgementcut = new/datum/action/judgement_cut()
block_parry_data = /datum/block_parry_data/motivation
//to get this to toggle correctly
/obj/item/gun/magic/staff/motivation/Initialize()
. = ..()
judgementcut = new(src)
//lets the user know that their judgment cuts are recharging
/obj/item/gun/magic/staff/motivation/shoot_with_empty_chamber(mob/living/user as mob|obj)
to_chat(user, "<span class='warning'>Judgment Cut is recharging.</span>")
//action button to toggle judgement cuts on/off
/datum/action/judgement_cut
name = "Judgement Cut - Allows Motivation to slash at a longer distance."
icon_icon = 'icons/obj/projectiles.dmi'
button_icon_state = "judgement_fire"
var/judgement_toggled = TRUE
//lets the user know that you toggled them on/off
/datum/action/judgement_cut/Trigger()
judgement_toggled = !judgement_toggled
to_chat(owner, "<span class='notice'>You [judgement_toggled ? "enable" : "disable"] Judgement Cuts with Motivation.</span>")
//Prevents "firing" the judgement cuts if toggled off and lets the user know
/obj/item/gun/magic/staff/motivation/can_trigger_gun(mob/living/user)
. = ..()
if(!judgementcut.judgement_toggled)
to_chat(user, "<span class='notice'> Judgment Cut is disabled.</span>")
return FALSE
//adds/removes judgement cut and judgement cut end upon pickup/drop
/obj/item/gun/magic/staff/motivation/pickup(mob/living/user)
. = ..()
judgementcut.Grant(user, src)
user.update_icons()
playsound(src, 'sound/items/unsheath.ogg', 25, 1)
/obj/item/gun/magic/staff/motivation/dropped(mob/user)
. = ..()
judgementcut.Remove(user)
user.update_icons()
//A parry tight enough to stagger, but not to counter attack
/datum/block_parry_data/motivation
parry_time_windup = 0.5
parry_time_active = 5
parry_time_spindown = 0
parry_attack_types = ALL
parry_time_active_visual_override = 3
parry_time_spindown_visual_override = 2
parry_flags = PARRY_DEFAULT_HANDLE_FEEDBACK | PARRY_LOCK_ATTACKING
parry_time_perfect = 0
parry_time_perfect_leeway = 3
parry_time_perfect_leeway_override = list(
TEXT_ATTACK_TYPE_PROJECTILE = 1
)
parry_imperfect_falloff_percent_override = list(
TEXT_ATTACK_TYPE_PROJECTILE = 50 // useless after 3rd decisecond
)
parry_imperfect_falloff_percent = 30
parry_efficiency_to_counterattack = 100
parry_efficiency_considered_successful = 1
parry_efficiency_perfect = 100
parry_data = list(
PARRY_STAGGER_ATTACKER = 10
)
parry_failed_stagger_duration = 2 SECONDS
parry_failed_clickcd_duration = CLICK_CD_RANGE
parry_cooldown = 0

View File

@@ -38,6 +38,10 @@
reagents.add_reagent(/datum/reagent/foaming_agent, 5)
reagents.add_reagent(/datum/reagent/toxin/acid, 5)
/obj/item/projectile/bullet/dart/catranq/Initialize()
. = ..()
reagents.add_reagent(/datum/reagent/fermi/furranium, 5) // Turns out I don't even need to give this guy actual tranquilizer chems.
/obj/item/projectile/bullet/dart/syringe
name = "syringe"
icon_state = "syringeproj"

View File

@@ -0,0 +1,15 @@
/obj/item/projectile/judgement_cut
name = "judgement cut"
icon_state = "judgement_fire"
hitsound = 'sound/weapons/judgementfire.ogg'
damage = 10
damage_type = BRUTE
range = 30
is_reflectable = FALSE
sharpness = SHARP_EDGED
impact_effect_type = /obj/effect/temp_visual/impact_effect/judgement_cut
/obj/item/projectile/judgement_cut/on_hit(atom/target, blocked = FALSE)
. = ..()
if(ishuman(target))
new /obj/effect/temp_visual/impact_effect/judgement_cut(src)

View File

@@ -741,6 +741,13 @@
required_reagents = list(/datum/reagent/liquid_dark_matter = 5, /datum/reagent/medicine/synaptizine = 10, /datum/reagent/medicine/oculine = 10, /datum/reagent/mutationtoxin = 1)
required_temp = 600
/datum/chemical_reaction/slimejelly
name = "slimejelly"
results = list(/datum/reagent/toxin/slimejelly = 5)
required_reagents = list(/datum/reagent/oil = 3, /datum/reagent/radium = 2, /datum/reagent/consumable/tinlux = 1)
required_container = /obj/item/reagent_containers/food/snacks/grown/mushroom/glowshroom
mix_message = "The mushroom's insides bubble and pop and it becomes very limp."
/datum/chemical_reaction/slime_extractification
required_reagents = list(/datum/reagent/toxin/slimejelly = 30, /datum/reagent/consumable/frostoil = 5, /datum/reagent/toxin/plasma = 5)
mix_message = "The mixture condenses into a ball."

View File

@@ -254,14 +254,14 @@
software_error()
/datum/nanite_program/proc/on_shock(shock_damage)
if(!program_flags & NANITE_SHOCK_IMMUNE)
if(!(program_flags & NANITE_SHOCK_IMMUNE))
if(prob(10))
software_error()
else if(prob(33))
self_destruct()
/datum/nanite_program/proc/on_minor_shock()
if(!program_flags & NANITE_SHOCK_IMMUNE)
if(!(program_flags & NANITE_SHOCK_IMMUNE))
if(prob(10))
software_error()

View File

@@ -27,8 +27,6 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
/obj/machinery/syndicatebomb,
/obj/item/hilbertshotel,
/obj/machinery/launchpad,
/obj/machinery/disposal,
/obj/structure/disposalpipe,
/obj/item/hilbertshotel,
/obj/machinery/camera,
/obj/item/gps,

View File

@@ -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

View File

@@ -214,6 +214,7 @@
switch(animal_origin)
if(ALIEN_BODYPART,LARVA_BODYPART) //aliens take some additional burn //nothing can burn with so much snowflake code around
burn *= 1.2
stamina = 0
/*
// START WOUND HANDLING

View File

@@ -0,0 +1,7 @@
/datum/unit_test/crafting_recipes/Run()
for(var/i in GLOB.crafting_recipes)
var/datum/crafting_recipe/R = i
if(!R.subcategory)
Fail("Invalid subcategory on [R] ([R.type]).")
if(!R.category && (R.cateogry != CAT_NONE))
Fail("Invalid category on [R] ([R.type])")

View File

@@ -38,7 +38,7 @@
specialised contractor baton, and three randomly selected low cost items. Can include otherwise unobtainable items."
item = /obj/item/storage/box/syndie_kit/contract_kit
cost = 20
player_minimum = 30
player_minimum = 25
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops)
restricted = TRUE

View File

@@ -104,7 +104,7 @@
name = "Mechanical Eyepatch"
desc = "An eyepatch that connects itself to your eye socket, enhancing your shooting to an impossible degree, allowing your bullets to ricochet far more often than usual."
item = /obj/item/clothing/glasses/eyepatch/syndicate
cost = 8
cost = 4
/datum/uplink_item/device_tools/ablative_armwraps
name = "Ablative Armwraps"

View File

@@ -189,7 +189,7 @@
desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an \
organic host as a home base and source of fuel. Holoparasites come in various types and share damage with their host."
item = /obj/item/storage/box/syndie_kit/guardian
cost = 15
cost = 12
limited_stock = 1 // you can only have one holopara apparently?
refundable = TRUE
cant_discount = TRUE
@@ -204,7 +204,7 @@
desc = "Though capable of near sorcerous feats via use of hardlight holograms and nanomachines, they require an \
organic host as a home base and source of fuel. Holoparasites come in various types and share damage with their host."
item = /obj/item/storage/box/syndie_kit/nukieguardian
cost = 15
cost = 8
refundable = TRUE
surplus = 50
refund_path = /obj/item/guardiancreator/tech/choose/nukie
@@ -228,6 +228,15 @@
surplus = 50
include_modes = list(/datum/game_mode/nuclear)
/datum/uplink_item/dangerous/maulergauntlets
name = "Mauler Gauntlets"
desc = "Mauler gauntlets are a pair of high-tech plastitanium gauntlets fused with illegal nanite auto-injectors designed \
to grant the wearer sextuple the strength of an average human being. Wearing these, you will punch harder, inflict more injuries \
with your fists, and be able to slam people through tables with immense force. \
Unfortunately, due to the size of the gloves you will be unable to wield firearms with them equipped."
item = /obj/item/clothing/gloves/fingerless/pugilist/mauler
cost = 8
/datum/uplink_item/dangerous/powerfist
name = "Power Fist"
desc = "The power-fist is a metal gauntlet with a built-in piston-ram powered by an external gas supply.\
@@ -277,3 +286,13 @@
item = /obj/item/gun/ballistic/automatic/toy/pistol/riot
cost = 3
surplus = 10
/datum/uplink_item/dangerous/motivation
name = "Motivation"
desc = "An ancient blade said to have ties with Lavaland's most inner demons. \
Allows you to cut from a far distance!"
item = /obj/item/gun/magic/staff/motivation
cost = 20
player_minimum = 20
exclude_modes = list(/datum/game_mode/nuclear, /datum/game_mode/nuclear/clown_ops, /datum/game_mode/traitor/internal_affairs)
cant_discount = TRUE

View File

@@ -76,11 +76,15 @@
return FALSE
if(occupant_amount() >= max_occupants)
return FALSE
if(do_mob(forcer, get_enter_delay(M), target = src))
var/atom/old_loc = loc
if(do_mob(forcer, M, get_enter_delay(M), extra_checks=CALLBACK(src, /obj/vehicle/sealed/car/proc/is_car_stationary, old_loc)))
mob_forced_enter(M, silent)
return TRUE
return FALSE
/obj/vehicle/sealed/car/proc/is_car_stationary(atom/old_loc)
return (old_loc == loc)
/obj/vehicle/sealed/car/proc/mob_forced_enter(mob/M, silent = FALSE)
if(!silent)
M.visible_message("<span class='warning'>[M] is forced into \the [src]!</span>")

View File

@@ -212,6 +212,8 @@
/obj/item/clothing/suit/jacket/leather/overcoat = 4,
/obj/item/clothing/under/pants/mustangjeans = 3,
/obj/item/clothing/neck/necklace/dope = 5,
/obj/item/clothing/under/costume/swagoutfit = 5,
/obj/item/clothing/shoes/swagshoes = 5,
/obj/item/clothing/suit/jacket/letterman_nanotrasen = 5,
/obj/item/clothing/under/misc/corporateuniform = 5,
/obj/item/clothing/suit/hooded/wintercoat/polychromic = 5,