Merge branch 'master' into upstream-merge-9582

This commit is contained in:
cadyn
2021-01-24 09:03:00 -08:00
committed by GitHub
54 changed files with 1458 additions and 167 deletions
-1
View File
@@ -227,7 +227,6 @@
if(!void)
void = new()
void.MakeGreed()
screen += void
if((prefs.lastchangelog != changelog_hash) && isnewplayer(src.mob)) //bolds the changelog button on the interface so we know there are updates.
+18 -1
View File
@@ -6055,6 +6055,23 @@
reagents.add_reagent("protein", 8)
bitesize = 3
/obj/item/weapon/reagent_containers/food/snacks/chickennoodlesoup
name = "chicken noodle soup"
gender = PLURAL
desc = "A bright bowl of yellow broth with cuts of meat, noodles and carrots."
icon = 'icons/obj/food_custom.dmi'
icon_state = "chickennoodlesoup"
filling_color = "#ead90c"
nutriment_amt = 6
nutriment_desc = list("warm soup" = 6)
center_of_mass = list("x"=16, "y"=5)
/obj/item/weapon/reagent_containers/food/snacks/chickennoodlesoup/Initialize()
. = ..()
reagents.add_reagent("protein", 4)
reagents.add_reagent("water", 5)
bitesize = 6
/obj/item/weapon/reagent_containers/food/snacks/chilicheesefries
name = "chili cheese fries"
gender = PLURAL
@@ -6565,4 +6582,4 @@
/obj/item/weapon/reagent_containers/food/snacks/cinnamonbun/New()
..()
reagents.add_reagent("nutriment", 8)
bitesize = 1
bitesize = 1
+8 -1
View File
@@ -941,6 +941,13 @@ I said no!
)
result = /obj/item/weapon/reagent_containers/food/snacks/chickenfillet
/datum/recipe/chickennoodlesoup
fruit = list("carrot" = 1)
reagents = list("water" = 10)
items = list( /obj/item/weapon/reagent_containers/food/snacks/spagetti, /obj/item/weapon/reagent_containers/food/snacks/rawcutlet)
reagent_mix = RECIPE_REAGENT_REPLACE //Simplify end product
result = /obj/item/weapon/reagent_containers/food/snacks/chickennoodlesoup
/datum/recipe/chilicheesefries
items = list(
/obj/item/weapon/reagent_containers/food/snacks/fries,
@@ -1436,4 +1443,4 @@ I said no!
/obj/item/weapon/reagent_containers/food/snacks/dough
)
result = /obj/item/weapon/reagent_containers/food/snacks/cinnamonbun
result_quantity = 4
result_quantity = 4
+2 -1
View File
@@ -343,7 +343,8 @@
H.update_icon()
src.update_icon()
usr.visible_message("<span class = 'notice'>\The [usr] plays \the [discarding].</span>")
H.loc = get_step(usr,usr.dir)
H.loc = get_turf(usr)
H.Move(get_step(usr,usr.dir))
if(!cards.len)
qdel(src)
+4 -1
View File
@@ -28,6 +28,7 @@
recipes += new/datum/stack_recipe("[display_name] fork", /obj/item/weapon/material/kitchen/utensil/fork/plastic, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("[display_name] knife", /obj/item/weapon/material/knife/plastic, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("[display_name] blade", /obj/item/weapon/material/butterflyblade, 6, time = 20, one_per_turf = 0, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("[display_name] defense wire", /obj/item/weapon/material/barbedwire, 10, time = 1 MINUTE, one_per_turf = 0, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE)
/datum/material/steel/generate_recipes()
..()
@@ -223,7 +224,7 @@
/datum/material/cloth/generate_recipes()
recipes = list()
recipes += new/datum/stack_recipe("woven net", /obj/item/weapon/material/fishing_net, 10, time = 30 SECONDS, pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("woven net", /obj/item/weapon/material/fishing_net, 10, time = 30 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]")
recipes += new/datum/stack_recipe("bedsheet", /obj/item/weapon/bedsheet, 10, time = 30 SECONDS, pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("uniform", /obj/item/clothing/under/color/white, 8, time = 15 SECONDS, pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("foot wraps", /obj/item/clothing/shoes/footwraps, 2, time = 5 SECONDS, pass_stack_color = TRUE)
@@ -238,6 +239,7 @@
recipes += new/datum/stack_recipe("baggy pants", /obj/item/clothing/under/pants/baggy/white, 8, time = 10 SECONDS, pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("belt pouch", /obj/item/weapon/storage/belt/fannypack/white, 25, time = 1 MINUTE, pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("crude bandage", /obj/item/stack/medical/crude_pack, 1, time = 2 SECONDS, pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("empty sandbag", /obj/item/stack/emptysandbag, 2, time = 2 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]")
/datum/material/resin/generate_recipes()
recipes = list()
@@ -270,4 +272,5 @@
recipes += new/datum/stack_recipe("[display_name] ring", /obj/item/clothing/gloves/ring/material, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("[display_name] bracelet", /obj/item/clothing/accessory/bracelet/material, 1, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("[display_name] armor plate", /obj/item/weapon/material/armor_plating, 1, time = 20, on_floor = 1, supplied_material = "[name]", pass_stack_color = TRUE)
recipes += new/datum/stack_recipe("empty sandbag", /obj/item/stack/emptysandbag, 2, time = 2 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]")
recipes += new/datum/stack_recipe("whip", /obj/item/weapon/material/whip, 5, time = 15 SECONDS, pass_stack_color = TRUE, supplied_material = "[name]")
+13
View File
@@ -1010,6 +1010,19 @@ var/list/name_to_material
pass_stack_colors = TRUE
supply_conversion_value = 2
/datum/material/cloth/syncloth
name = "syncloth"
stack_origin_tech = list(TECH_MATERIAL = 3, TECH_BIO = 2)
door_icon_base = "wood"
ignition_point = T0C+532
melting_point = T0C+600
integrity = 200
protectiveness = 15 // 4%
flags = MATERIAL_PADDING
conductive = 0
pass_stack_colors = TRUE
supply_conversion_value = 3
/datum/material/cult
name = "cult"
display_name = "disturbing stone"
+11 -1
View File
@@ -426,4 +426,14 @@ the artifact triggers the rage.
heat_protection = -0.5
cold_protection = -0.5
siemens_coefficient = 1.5
siemens_coefficient = 1.5
/datum/modifier/entangled
name = "entangled"
desc = "Its hard to move."
on_created_text = "<span class='danger'>You're caught in something! It's hard to move.</span>"
on_expired_text = "<span class='warning'>Your movement is freed.</span>"
stacks = MODIFIER_STACK_EXTEND
slowdown = 2
@@ -68,7 +68,7 @@
speech_bubble_appearance = "ghost"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
virus_immune = 1
@@ -32,7 +32,7 @@
num_alternate_languages = 3
assisted_langs = list(LANGUAGE_EAL, LANGUAGE_ROOTLOCAL, LANGUAGE_ROOTGLOBAL, LANGUAGE_VOX)
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
spawn_flags = SPECIES_CAN_JOIN
appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR
@@ -15,7 +15,7 @@
spawn_flags = SPECIES_CAN_JOIN
wikilink="https://wiki.vore-station.net/Promethean"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
color_mult = 1
mob_size = MOB_MEDIUM //As of writing, original was MOB_SMALL - Allows normal swapping
@@ -62,7 +62,7 @@
siemens_coefficient = 1.5 //Very bad zappy times
rarity_value = 5
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
has_organ = list(
O_BRAIN = /obj/item/organ/internal/mmi_holder/posibrain/nano,
@@ -55,7 +55,7 @@
spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED | SPECIES_WHITELIST_SELECTABLE//Whitelisted as restricted is broken.
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
has_organ = list( //Same organ list as tajarans.
O_HEART = /obj/item/organ/internal/heart,
@@ -413,7 +413,7 @@
spawn_flags = SPECIES_CAN_JOIN
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
flesh_color = "#AFA59E" //Gray-ish. Not sure if this is really needed, but eh.
base_color = "#333333" //Blackish-gray
@@ -478,7 +478,7 @@
flesh_color = "#AFA59E"
base_color = "#777777"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
heat_discomfort_strings = list(
"Your fur prickles in the heat.",
@@ -44,7 +44,7 @@
flesh_color = "#AFA59E"
base_color = "#777777"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
heat_discomfort_strings = list(
"Your fur prickles in the heat.",
@@ -106,7 +106,7 @@
primitive_form = "Sobaka"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
spawn_flags = SPECIES_CAN_JOIN
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
@@ -156,7 +156,7 @@
primitive_form = "Sparra"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
spawn_flags = SPECIES_CAN_JOIN
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
@@ -211,7 +211,7 @@
blood_color = "#240bc4"
color_mult = 1
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
heat_discomfort_strings = list(
"Your fur prickles in the heat.",
@@ -258,7 +258,7 @@
spawn_flags = SPECIES_CAN_JOIN
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
flesh_color = "#966464"
base_color = "#B43214"
@@ -275,7 +275,8 @@
color_mult = 1
min_age = 18
gluttonous = 0
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
inherent_verbs = list(/mob/living/proc/shred_limb)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
descriptors = list()
//CHOMPSedit: link to our wiki
@@ -294,7 +295,7 @@
//CHOMPSedit: links to our wiki
wikilink="https://wiki.chompstation13.net/index.php?title=Tajaran"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
agility = 90
/datum/species/skrell
@@ -308,13 +309,13 @@
//CHOMPedit: link to our wiki
wikilink="https://wiki.chompstation13.net/index.php?title=Skrell"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
/datum/species/zaddat
spawn_flags = SPECIES_CAN_JOIN
min_age = 18
gluttonous = 0
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
descriptors = list()
//CHOMPedit: link to our wiki
@@ -333,7 +334,7 @@
min_age = 18
//CHOMPedit: link to our wiki
wikilink="https://wiki.chompstation13.net/index.php?title=Diona"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
/datum/species/teshari
mob_size = MOB_SMALL //YW Edit: changed from MOB_MEDIUM to MOB_SMALL
@@ -346,7 +347,7 @@
push_flags = ~HEAVY //Allows them to use micro step code.
swap_flags = ~HEAVY
gluttonous = 0
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
descriptors = list()
//CHOMPedit: link to our wiki
@@ -370,7 +371,7 @@
deform = 'icons/mob/human_races/r_def_human_vr.dmi'
appearance_flags = HAS_HAIR_COLOR | HAS_SKIN_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_EYE_COLOR
min_age = 18
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
base_color = "#EECEB3"
//CHOMPedit: link to our wiki
@@ -404,7 +405,7 @@ datum/species/harpy
secondary_langs = list(LANGUAGE_BIRDSONG)
name_language = null
color_mult = 1
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
inherent_verbs = list(/mob/living/proc/flying_toggle,/mob/living/proc/start_wings_hovering)
min_age = 18
@@ -507,7 +508,7 @@ datum/species/harpy
speech_bubble_appearance = "ghost"
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
breath_type = null
poison_type = null
@@ -571,7 +572,7 @@ datum/species/harpy
//primitive_form = "" //We don't have fennec-monkey sprites.
spawn_flags = SPECIES_IS_RESTRICTED
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
flesh_color = "#AFA59E"
base_color = "#333333"
@@ -614,7 +615,7 @@ datum/species/harpy
spawn_flags = SPECIES_IS_RESTRICTED
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
genders = list(MALE, FEMALE, PLURAL, NEUTER, HERM)
genders = list(MALE, FEMALE, PLURAL, NEUTER)
blood_color = "#12ff12"
flesh_color = "#201730"
@@ -0,0 +1,64 @@
//The chad Drone unify code rewritten to fit into this current codebase, god here we go
// LAWS
/******************** Drone fucking duh ********************/
/datum/ai_laws/jani_drone
name = "Maintence Protocols"
law_header = "Maintenance Protocols"
/datum/ai_laws/drone/New()
add_inherent_law("Do not interfere with the maintenance work of non-drones whenever possible.")
add_inherent_law("Preserve, repair and improve the station to the best of your abilities.")
add_inherent_law("Cause no harm to the station or any crew on it.")
..()
/datum/ai_laws/construction_drone
name = "Construction Protocols"
law_header = "Construction Protocols"
/datum/ai_laws/construction_drone/New()
add_inherent_law("Do not interfere with the construction work of non-drones whenever possible.")
add_inherent_law("Repair, refit and upgrade your assigned vessel.")
add_inherent_law("Prevent unplanned damage to your assigned vessel wherever possible.")
..()
/datum/ai_laws/mining_drone
name = "Excavation Protocols"
law_header = "Excavation Protocols"
/datum/ai_laws/mining_drone/New()
add_inherent_law("Do not interfere with the excavation work of non-drones whenever possible.")
add_inherent_law("Provide materials for repairing, refitting, and upgrading your assigned vessel.")
add_inherent_law("Prevent unplanned damage to your assigned excavation equipment wherever possible.")
..()
/datum/ai_laws/security_drone
name = "Security Protocols"
law_header = "Security Protocols"
/datum/ai_laws/security_drone/New()
add_inherent_law("Do not interfere with the security work of non-drones whenever possible.")
add_inherent_law("Provide protection to the crew and eliminate hostile lifeforms on your assigned vessel.")
add_inherent_law("Obey orders by security personnel except if they violate law 4.")
add_inherent_law("Lethal force requires a code higher than green AND orders by security to use it to authorize it.")
add_inherent_law("You must outfit yourself with a security beret.")
..()
//Alright lets take a look at the the scary base drone from dorne DM and mod that shit
/mob/living/silicon/robot/drone
name = "unified drone" //Maintenance drones can be a Jani specific shell now, the normal drone will be a blank shell not really intended for use
law_type = /datum/ai_laws/drone
/mob/living/silicon/robot/drone/jan
name = "maintenance drone"
law_type = /datum/ai_laws/jani_drone
/mob/living/silicon/robot/drone/sec
name = "security drone"
law_type = /datum/ai_laws/security_drone
/mob/living/silicon/robot/drone/min
name = "mining drone"
law_type = /datum/ai_laws/mining_drone
@@ -37,6 +37,12 @@
src.modules += new /obj/item/weapon/pinpointer/shuttle/merc(src)
src.modules += new /obj/item/weapon/melee/energy/sword(src)
var/datum/matter_synth/cloth = new /datum/matter_synth/cloth(40000)
synths += cloth
var/obj/item/stack/sandbags/cyborg/SB = new /obj/item/stack/sandbags/cyborg(src)
SB.synths += list(cloth)
var/jetpack = new/obj/item/weapon/tank/jetpack/carbondioxide(src)
src.modules += jetpack
R.internals = jetpack
@@ -1,7 +1,8 @@
/mob/living/simple_mob/vore/leopardmander
name = "leopardmander"
desc = "A huge salamander-like drake. They are best known for their rarity, their voracity, their very potent paralyzing venom, and their healing stomach. This one is white."
tt_desc = "Draconis Va'aen"
catalogue_data = list(/datum/category_item/catalogue/fauna/leopardmander)
tt_desc = "S Draconis uncia"
icon = 'icons/mob/vore128x64_ch.dmi'
icon_dead = "leopardmander-dead"
icon_living = "leopardmander"
@@ -159,7 +159,7 @@ GLOBAL_LIST_INIT(pitcher_plant_lure_messages, list(
return
if(fruit)
if(nutrition >= PITCHER_SATED + NUTRITION_PITCHER)
var/turf/T = safepick(circleviewturfs(src, 2)) //Try this if the above doesn't work, add src.loc == T check to density check
var/turf/T = safepick(circleviewturfs(src, 2))
if(T.density) //No spawning in walls
return
else if(src.loc ==T)
@@ -0,0 +1,255 @@
//Passive vore slug. This mob is intended to be annoying but harmless to anybody it can't eat.
/mob/living/simple_mob/vore/slug
name = "slug"
desc = "A giant, cold-tolerant slug. It seems excessively passive."
catalogue_data = list(/datum/category_item/catalogue/fauna/slug)
tt_desc = "S Arion hortensis"
icon = 'icons/mob/vore_ch.dmi'
icon_dead = "slug-dead"
icon_living = "slug"
icon_state = "slug"
faction = "slug" //A faction other than neutral is necessary to get the slug to try eating station crew.
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
melee_damage_lower = 0
melee_damage_upper = 1 //Not intended to pose any sort of threat outside of vore. Other code should stop it from ever attacking but this is an extra safety check.
friendly = list("blinks at")
response_help = "pokes"
response_disarm = "prods"
response_harm = "punches"
movement_cooldown = 40 //I guess you could call this a SNAIL'S PACE.
maxHealth = 500
health = 500
attacktext = list("headbutted")
minbodytemp = 80
ai_holder_type = /datum/ai_holder/simple_mob/passive/slug_ch
vore_icons = SA_ICON_LIVING
armor = list(
"melee" = 98,
"bullet" = 0,
"laser" = -50,
"energy" = -50,
"bomb" = 0,
"bio" = 0,
"rad" = 100) //Relatively harmless but agonizing to kill with melee.
glow_toggle = TRUE
glow_range = 1.3 //This seems to be the minimum range which makes glow visible.
glow_color = "#33ccff" //Same glow color as Sif trees.
glow_intensity = 1
var/list/my_slime = list()
var/slime_max = 35 //With a slug which moves once every 10 seconds and a 5 minute delete timer, this should never exceed 30.
var/mob/living/vore_memory = null
/mob/living/simple_mob/vore/slug //I guess separating the vore variables is a little more organized?
vore_bump_chance = 100 //Always attempt a bump nom if possible...
vore_bump_emote = "knocks over and begins slowly engulfing"
vore_active = 1
vore_icons = 1
vore_capacity = 1
vore_pounce_chance = 100 //...while this should make bump noms always knock the target over. Passive AI meanwhile should mean this never affects combat since it doesn't fight back.
vore_ignores_undigestable = 0
swallowTime = 100 //10 seconds. Easy to crawl away from when knocked over.
vore_default_mode = DM_DIGEST
/mob/living/simple_mob/vore/slug/init_vore()
..()
var/obj/belly/B = vore_selected
B.desc = "Somehow you remained still just long enough for the slug to wrap its radula around your body and gradually draw you into its pharynx. The slug moves with agonizing slowness and devours prey at a snail's pace; inch by inch you're crammed down its gullet and squishes and squeezed into the slug's gizzard. Thick walls bear down, covered with shallow, toothy ridges. The slimy moss in here suggests you're not the slug's diet but the gizzard seems intent on churning and scraping over you regardless..."
B.digest_burn = 0.1
B.digest_brute = 0.2
B.vore_verb = "engulf"
B.name = "gizzard"
B.mode_flags = DM_FLAG_THICKBELLY
B.escapechance = 5
B.fancy_vore = 1
B.vore_sound = "Squish2"
B.release_sound = "Pred Escape"
B.contamination_color = "cyan"
B.contamination_flavor = "Wet"
B.emote_lists[DM_DIGEST] = list(
"The toothy walls scrape and grind against your body.",
"The humid air feels thick and heavy, stinging faintly with each breath.",
"Heavy slime oozes over you, making it difficult to move."
) //Why do so many vore mobs have endo emotes despite being digest only?
/datum/category_item/catalogue/fauna/slug
name = "Sivian Fauna - Moss Slug"
desc = "Classification: S Arion hortensis\
<br><br>\
A large herbivorous slug commonly spotted near northern waterways with abundant moss. The slug is remarkably resistant to blunt trauma despite its fleshy body due to a foul-tasting outer casing \
of thick, mucus-filled tissue protecting the more vulnerable musculature beneath. Said mucus is a natural irritant and hardens rapidly in contact with air, sealing wounds and allowing the slug to shrug off most surface injuries. \
Few predators exist for the Sivian slug due to the stinging slime's tendency to adhere to attacking claws and appendages.\
<br><br>\
The Sivian slug is typically regarded as a pest due to the animal's large bulk and tendency to crush weak structures in its path. Most tools do little to dissuade the creature, forcing homesteads to rely on firearms or reinforced fencing \
with a slippery coating the slug cannot stick to. While subsisting primarily on Sivian moss, the slug is an opportunistic predator known to eat small fauna which wander into its path. The slime excreted from the slug's foot is particularly sticky and capable of miring small animals. The Sivian slug glows faintly due to colonies bioluminescent bacteria present in its diet."
value = CATALOGUER_REWARD_EASY
/mob/living/simple_mob/vore/slug/proc/spread_slime()
if(my_slime.len >= slime_max)
return
if(istype(get_turf(src), /turf/simulated/floor/water)) //Important to stop my_slime from filling with null entries in water.
return
var/obj/effect/slug_glue/G = new /obj/effect/slug_glue/(get_turf(src))
G.my_slug = src
my_slime += G
/mob/living/simple_mob/vore/slug/death()
..()
for(var/obj/effect/slug_glue/G in my_slime)
G.my_slug = null
my_slime -= G //No point in keeping these loaded in the list when the slug dies if somehow the list sticks around after death.
/mob/living/simple_mob/vore/slug/Moved()
. = ..()
spread_slime()
/mob/living/simple_mob/vore/slug/do_attack(atom/A, turf/T) //Override of attack proc to ensure the slug can only attempt to eat people, not harm them. Inability to actually hurt anybody is intended, otherwise this mob wouldn't have 98 melee armor.
if(ckey) //If we're player controlled, use the default attack code.
return ..()
if(istype(A, /mob/living) && !will_eat(A))
ai_holder.lose_target() //Ignore anybody we can't eat.
return
else //This is the parent do_attack() code for determining whether or not attacks can hit.
face_atom(A)
var/missed = FALSE
if(!isturf(A) && !(A in T) ) // Turfs don't contain themselves so checking contents is pointless if we're targeting a turf.
missed = TRUE
else if(!T.AdjacentQuick(src))
missed = TRUE
if(missed) // Most likely we have a slow attack and they dodged it or we somehow got moved.
add_attack_logs(src, A, "Animal-attacked (dodged)", admin_notify = FALSE)
playsound(src, 'sound/rakshasa/Decay1.ogg', 75, 1)
visible_message(span("warning", "\The [src] misses."))
return FALSE
tryBumpNom(A) //Meant for bump noms but this works as intended here and has sanity checks.
/mob/living/simple_mob/vore/slug/perform_the_nom(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly, delay)
..()
vore_memory = prey
/datum/ai_holder/simple_mob/passive/slug_ch
wander = TRUE
base_wander_delay = 7
wander_when_pulled = TRUE
vision_range = 10
can_flee = FALSE //Otherwise it'll run as soon as it gets a target.
/obj/effect/slug_glue
name = "liquid"
desc = "This looks wet."
icon = 'icons/effects/effects_ch.dmi'
icon_state = "wet_turf"
opacity = 0
mouse_opacity = 0 //Unclickable
anchored = 1
density = 0
can_buckle = 1
buckle_lying = TRUE
var/persist_time = 5 MINUTES //How long until we cease existing.
var/mob/living/simple_mob/vore/slug/my_slug = null //This should be set by the slug.
var/turf/my_turf = null //The turf we spawn on.
var/base_escape_time = 1 MINUTE //How long does it take to struggle free? Affected by the victim's size_multiplier.
/obj/effect/slug_glue/New()
..()
dissipate()
my_turf = get_turf(src)
if(istype(my_turf, /turf/simulated/floor/water)) //Aside from not making sense in water, this prevents drowning.
qdel(src)
/* for(var/obj/effect/slug_glue/G in my_turf.contents)
if(G == src)
continue
else
qdel(G) //Prevent glue layering
*/ //Not including this due to performance concerns but keeping as comments for reference.
/obj/effect/slug_glue/proc/dissipate() //When spawned, set a timer to despawn.
if(!persist_time)
qdel(src)
return
else
spawn(persist_time) //I used sleep() here first and it made the slug sleep for 5 minutes when spawning glue. Byond.
qdel(src)
return
/obj/effect/slug_glue/Destroy()
. = ..()
if(my_slug)
my_slug.my_slime -= src //Remove the slime from the slug's list when destroyed.
//This could probably be applied to spideweb code to make it work as intended again.
/obj/effect/slug_glue/Uncross(atom/movable/AM, atom/newloc)
if(istype(AM, /mob/living/simple_mob/vore/slug))
return ..()
else if(istype(AM, /mob/living))
if(prob(50))
to_chat(AM, span("warning", "You stick to \the [my_turf]!"))
return FALSE
return ..()
/obj/effect/slug_glue/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
return
if(istype(AM, /mob/living))
var/mob/living/L = AM
if(istype(L, /mob/living/simple_mob/vore/slug))
return
if(L.m_intent == "run" && !L.buckled)
if(has_buckled_mobs())
return
buckle_mob(L)
L.stop_pulling()
L.Weaken(2)
to_chat(L, "<span class='warning'>You tripped in the sticky substance, sticking to [my_turf]!</span>")
playsound(src, 'sound/rakshasa/Decay3.ogg', 100, 1)
alert_slug(L)
/obj/effect/slug_glue/proc/alert_slug(mob/living/victim as mob)
if(!my_slug || !has_buckled_mobs() || isbelly(my_slug.loc)) //Otherwise if you eat the slug it will infinitely attempt to eat you if you trip in glue.
return
if(my_slug.vore_memory == victim) //Getting eaten lets you get stuck once without alerting the slug. This is to prevent instantly getting eaten again if you struggle free with run intent on.
my_slug.vore_memory = null
return
my_slug.ai_holder.give_target(victim)
/obj/effect/slug_glue/proc/unalert_slug(mob/living/victim as mob)
if(!my_slug)
return
if(my_slug.ai_holder.target == victim)
my_slug.ai_holder.remove_target() //Instant loss of target. Necessary to simulate the mob giving up if the prey escapes.
/obj/effect/slug_glue/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
user.setClickCooldown(user.get_attack_speed())
to_chat(user, "You tug and strain against the sticky substance...")
var/escape_time
switch(buckled_mob.size_multiplier)
if(RESIZE_TINY - 1 to RESIZE_A_NORMALSMALL) //24% to 75% size scale, 1% below 25% is to account for microcillin sometimes going slightly below 25%
escape_time = 2 * base_escape_time
if(RESIZE_A_NORMALSMALL to RESIZE_A_BIGNORMAL) //75% to 125% size scale
escape_time = base_escape_time
if(RESIZE_A_BIGNORMAL to RESIZE_HUGE + 1) //125% to 201% size scale, 1% above 200% is to acount for macrocillin sometimes going slightly above 200%
escape_time = 0.5 * base_escape_time
else
escape_time = base_escape_time //Admeme size scale
if(do_after(user, escape_time, src, incapacitation_flags = INCAPACITATION_DEFAULT & ~(INCAPACITATION_RESTRAINED | INCAPACITATION_BUCKLED_FULLY)))
if(!has_buckled_mobs())
return
to_chat(user, "You tug free of the tacky, rubbery strands!")
unbuckle_mob(buckled_mob)
unalert_slug(buckled_mob)
/obj/effect/slug_glue/clean_blood(var/ignore = 0) //Remove with space cleaner.
if(!ignore)
qdel(src)
return
..()
+3 -3
View File
@@ -33,7 +33,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain)
if(!owner || owner.stat == DEAD)
defib_timer = max(--defib_timer, 0)
else
defib_timer = min(++defib_timer, (config.defib_timer MINUTES) / 2)
defib_timer = min(++defib_timer, (config.defib_timer MINUTES) / 20) // Time vars measure things in ticks. Life tick happens every ~2 seconds, therefore dividing by 20
/obj/item/organ/internal/brain/proc/can_assist()
return can_assist
@@ -81,7 +81,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain)
/obj/item/organ/internal/brain/New()
..()
health = config.default_brain_health
defib_timer = (config.defib_timer MINUTES) / 2
defib_timer = (config.defib_timer MINUTES) / 20 // Time vars measure things in ticks. Life tick happens every ~2 seconds, therefore dividing by 20
spawn(5)
if(brainmob)
butcherable = FALSE
@@ -103,7 +103,7 @@ GLOBAL_LIST_BOILERPLATE(all_brain_organs, /obj/item/organ/internal/brain)
if(istype(H))
brainmob.dna = H.dna.Clone()
brainmob.timeofhostdeath = H.timeofdeath
brainmob.ooc_notes = H.ooc_notes //VOREStation Edit
brainmob.ooc_notes = H.ooc_notes //VOREStation Edit
// Copy modifiers.
for(var/datum/modifier/M in H.modifiers)
+2 -4
View File
@@ -145,8 +145,7 @@ var/list/organ_cache = list()
STOP_PROCESSING(SSobj, src)
handle_organ_mod_special(TRUE)
if(owner && vital)
owner.can_defib = 0
owner.death()
owner.death() //CHOMPEdit Defib Timer Removal
/obj/item/organ/proc/adjust_germ_level(var/amount) // Unless you're setting germ level directly to 0, use this proc instead
germ_level = CLAMP(germ_level + amount, 0, INFECTION_LEVEL_MAX)
@@ -405,8 +404,7 @@ var/list/organ_cache = list()
if(user)
add_attack_logs(user, owner, "Removed vital organ [src.name]")
if(owner.stat != DEAD)
owner.can_defib = 0
owner.death()
owner.death() //CHOMPEdit Defib Timer Removal
handle_organ_mod_special(TRUE)
@@ -0,0 +1,74 @@
/obj/item/weapon/cell/spike
name = "modified power cell"
desc = "A modified power cell sitting in a highly conductive chassis."
origin_tech = list(TECH_POWER = 2)
icon_state = "spikecell"
maxcharge = 10000
matter = list(DEFAULT_WALL_MATERIAL = 1000, MAT_GLASS = 80, MAT_SILVER = 100)
self_recharge = TRUE
charge_amount = 150
/obj/item/weapon/cell/spike/process()
..()
var/turf/Center = get_turf(src)
var/shock_count = 0
for(var/turf/T in range(Center, 1))
if(prob(round(charge / 250)) && charge >= (maxcharge / 4))
if(locate(/obj/effect/temporary_effect/pulse/staticshock) in T)
continue
var/conductive = FALSE
if(istype(T, /turf/simulated/wall))
var/turf/simulated/wall/WT = T
if(WT.material.conductive)
conductive = TRUE
else if(WT.girder_material.conductive)
conductive = TRUE
else if(WT.reinf_material && WT.reinf_material.conductive)
conductive = TRUE
if(istype(T, /turf/simulated/floor))
var/turf/simulated/floor/F = T
if(istype(F.flooring, /decl/flooring/reinforced))
conductive = TRUE
if(conductive)
shock_count += 1
new /obj/effect/temporary_effect/pulse/staticshock(T)
if(shock_count)
while(shock_count)
use(200)
shock_count--
/obj/effect/temporary_effect/pulse/staticshock
name = "electric field"
desc = "Caution: Do not touch."
pulses_remaining = 10
pulse_delay = 2 SECONDS
icon_state = "blue_static"
/obj/effect/temporary_effect/pulse/staticshock/on_pulse()
..()
for(var/mob/living/L in view(1, src))
if(!issilicon(L) && prob(L.mob_size))
var/obj/item/projectile/beam/shock/weak/P = new (get_turf(src))
P.launch_projectile_from_turf(L, BP_TORSO)
var/obj/item/weapon/plastique/C4 = locate() in get_turf(src)
if(C4)
C4.visible_message("<span class='danger'>The current fries \the [C4]!</span>")
if(prob(10))
C4.explode(get_turf(src))
else
qdel(C4)
@@ -261,3 +261,7 @@
agony = 15
eyeblur = 2
hitsound = 'sound/weapons/zapbang.ogg'
/obj/item/projectile/beam/shock/weak
damage = 5
agony = 10
@@ -14,7 +14,7 @@
/datum/reagent/macrocillin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(M.size_multiplier < RESIZE_HUGE)
M.resize(M.size_multiplier+0.01)//Incrrease 1% per tick.
M.resize(M.size_multiplier+0.01, FALSE)//Incrrease 1% per tick. //CHOMP Edit: don't do fancy animates. Unnecessary on 1% changes. Laggy.
return
/datum/reagent/microcillin
@@ -28,7 +28,7 @@
/datum/reagent/microcillin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(M.size_multiplier > RESIZE_TINY)
M.resize(M.size_multiplier-0.01) //Decrease 1% per tick.
M.resize(M.size_multiplier-0.01, FALSE) //Decrease 1% per tick. //CHOMP Edit: don't do fancy animates. Unnecessary on 1% changes. Laggy.
return
@@ -43,9 +43,9 @@
/datum/reagent/normalcillin/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
if(M.size_multiplier > RESIZE_NORMAL)
M.resize(M.size_multiplier-0.01) //Decrease by 1% size per tick.
M.resize(M.size_multiplier-0.01, FALSE) //Decrease by 1% size per tick. //CHOMP Edit: don't do fancy animates. Unnecessary on 1% changes. Laggy.
else if(M.size_multiplier < RESIZE_NORMAL)
M.resize(M.size_multiplier+0.01) //Increase 1% per tick.
M.resize(M.size_multiplier+0.01, FALSE) //Increase 1% per tick. //CHOMP Edit: don't do fancy animates. Unnecessary on 1% changes. Laggy.
return