Merge branch 'master' into upstream-merge-5432

This commit is contained in:
Spades
2018-09-09 17:57:31 -04:00
committed by GitHub
92 changed files with 2659 additions and 3423 deletions
+1 -8
View File
@@ -23,7 +23,6 @@
processing_objects -= src
..()
/obj/item/weapon/deadringer/dropped()
if(timer > 20)
uncloak()
@@ -50,7 +49,6 @@
activated = 0
return
/obj/item/weapon/deadringer/process()
if(activated)
if (ismob(src.loc))
@@ -77,13 +75,11 @@
icon_state = "deadringer"
return
/obj/item/weapon/deadringer/proc/deathprevent()
for(var/mob/living/simple_animal/D in oviewers(7, src))
D.LoseTarget()
watchowner.emote("deathgasp")
watchowner.invisibility = 85
watchowner.alpha = 127
watchowner.alpha = 15
makeacorpse(watchowner)
for(var/mob/living/simple_animal/D in oviewers(7, src))
D.LoseTarget()
@@ -91,7 +87,6 @@
/obj/item/weapon/deadringer/proc/uncloak()
if(watchowner)
watchowner.invisibility = 0
watchowner.alpha = 255
playsound(get_turf(src), 'sound/effects/uncloak.ogg', 35, 1, -1)
return
@@ -180,5 +175,3 @@
var/obj/item/organ/internal/G = I
G.Destroy()
return
@@ -303,7 +303,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
. += "<br><a href='?src=\ref[src];marking_style=1'>Body Markings +</a><br>"
for(var/M in pref.body_markings)
. += "[M] <a href='?src=\ref[src];marking_remove=[M]'>-</a> <a href='?src=\ref[src];marking_color=[M]'>Color</a>"
. += "[M] [pref.body_markings.len > 1 ? "<a href='?src=\ref[src];marking_up=[M]'>&#708;</a> <a href='?src=\ref[src];marking_down=[M]'>&#709;</a> " : ""]<a href='?src=\ref[src];marking_remove=[M]'>-</a> <a href='?src=\ref[src];marking_color=[M]'>Color</a>"
. += "<font face='fixedsys' size='3' color='[pref.body_markings[M]]'><table style='display:inline;' bgcolor='[pref.body_markings[M]]'><tr><td>__</td></tr></table></font>"
. += "<br>"
@@ -500,6 +500,24 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
pref.body_markings[new_marking] = "#000000" //New markings start black
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["marking_up"])
var/M = href_list["marking_up"]
var/start = pref.body_markings.Find(M)
if(start != 1) //If we're not the beginning of the list, swap with the previous element.
moveElement(pref.body_markings, start, start-1)
else //But if we ARE, become the final element -ahead- of everything else.
moveElement(pref.body_markings, start, pref.body_markings.len+1)
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["marking_down"])
var/M = href_list["marking_down"]
var/start = pref.body_markings.Find(M)
if(start != pref.body_markings.len) //If we're not the end of the list, swap with the next element.
moveElement(pref.body_markings, start, start+2)
else //But if we ARE, become the first element -behind- everything else.
moveElement(pref.body_markings, start, 1)
return TOPIC_REFRESH_UPDATE_PREVIEW
else if(href_list["marking_remove"])
var/M = href_list["marking_remove"]
pref.body_markings -= M
@@ -247,7 +247,7 @@ datum/gear/suit/duster
allowed_roles = list("Cargo Technician","Quartermaster")
/datum/gear/suit/roles/poncho/cloak/mining
display_name = "cloak, cargo"
display_name = "cloak, mining"
path = /obj/item/clothing/accessory/poncho/roles/cloak/mining
allowed_roles = list("Quartermaster","Shaft Miner")
@@ -73,14 +73,16 @@
if(!(path in negative_traits))
pref.neg_traits -= path
if(pref.species == pref.custom_base && pref.species != SPECIES_CUSTOM)
var/datum/species/selected_species = all_species[pref.species]
if(selected_species.selects_bodytype)
// Allowed!
else if(!pref.custom_base || !(pref.custom_base in custom_species_bases))
pref.custom_base = SPECIES_HUMAN
/datum/category_item/player_setup_item/vore/traits/copy_to_mob(var/mob/living/carbon/human/character)
character.custom_species = pref.custom_species
if(pref.species == SPECIES_CUSTOM || pref.species == SPECIES_XENOCHIMERA)
var/datum/species/selected_species = all_species[pref.species]
if(selected_species.selects_bodytype)
var/datum/species/custom/CS = character.species
var/S = pref.custom_base ? pref.custom_base : "Human"
var/datum/species/custom/new_CS = CS.produceCopy(S, pref.pos_traits + pref.neu_traits + pref.neg_traits, character)
@@ -92,7 +94,8 @@
. += "<b>Custom Species</b> "
. += "<a href='?src=\ref[src];custom_species=1'>[pref.custom_species ? pref.custom_species : "-Input Name-"]</a><br>"
if(pref.species == SPECIES_CUSTOM || pref.species == SPECIES_XENOCHIMERA)
var/datum/species/selected_species = all_species[pref.species]
if(selected_species.selects_bodytype)
. += "<b>Icon Base: </b> "
. += "<a href='?src=\ref[src];custom_base=1'>[pref.custom_base ? pref.custom_base : "Human"]</a><br>"
+1 -1
View File
@@ -60,7 +60,7 @@ datum/preferences
var/r_synth //Used with synth_color to color synth parts that normaly can't be colored.
var/g_synth //Same as above
var/b_synth //Same as above
var/synth_markings = 0 //Enable/disable markings on synth parts.
var/synth_markings = 1 //VOREStation edit. Enable/disable markings on synth parts.
//Some faction information.
var/home_system = "Unset" //System of birth.
@@ -75,7 +75,6 @@
/obj/item/integrated_circuit/memory/constant
name = "constant chip"
desc = "This tiny chip can store one piece of data, which cannot be overwritten without disassembly."
icon_state = "memory"
complexity = 1
inputs = list()
outputs = list("output pin" = IC_PINTYPE_ANY)
+6
View File
@@ -168,6 +168,12 @@ var/list/mining_overlay_cache = list()
if(istype(get_step(src, direction), /turf/space) && !istype(get_step(src, direction), /turf/space/cracked_asteroid))
add_overlay(get_cached_border("asteroid_edge",direction,icon,"asteroid_edges", 0))
//Or any time
else
var/turf/T = get_step(src, direction)
if(istype(T) && T.density)
add_overlay(get_cached_border("rock_side",direction,'icons/turf/walls.dmi',"rock_side"))
if(overlay_detail)
add_overlay('icons/turf/flooring/decals.dmi',overlay_detail)
+6 -2
View File
@@ -133,7 +133,11 @@
flags = WHITELISTED
syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix", "...", "oo", "q", "nq", "x", "xq", "ll", "...", "...", "...") //should sound like there's holes in it
/datum/language/skrell/get_random_name(var/gender)
var/list/first_names = file2list('config/names/first_name_skrell.txt')
var/list/last_names = file2list('config/names/last_name_skrell.txt')
return "[pick(first_names)] [pick(last_names)]"
/datum/language/human
name = LANGUAGE_SOL_COMMON
desc = "A bastardized hybrid of many languages, including Chinese, English, French, and more; it is the common language of the Sol system."
@@ -288,4 +292,4 @@
"tod", "ser", "su", "no", "nue", "el",
"ad", "al", "an", "ar", "as", "ci", "co", "de", "do", "el", "en", "er", "es", "ie", "in", "la", "lo", "me", "na",
"no", "nt", "or", "os", "pa", "qu", "ra", "re", "ro", "se", "st", "ta", "te", "to", "ue", "un",
"tod", "ser", "su", "no", "nue", "el")
"tod", "ser", "su", "no", "nue", "el")
@@ -2,7 +2,7 @@
var/skip_gear = 0
var/skip_body = 0
if(alpha <= 50)
if(alpha <= EFFECTIVE_INVIS)
src.loc.examine(user)
return
@@ -6,4 +6,4 @@
var/wagging = 0 //UGH.
var/flapping = 0
var/vantag_pref = VANTAG_NONE //What's my status?
var/impersonate_bodytype //For impersonating a bodytype
var/impersonate_bodytype //For impersonating a bodytype
@@ -36,6 +36,16 @@
if(shock_stage >= 10) tally -= 1.5 //this gets a +3 later, feral critters take reduced penalty
if(reagents.has_reagent("numbenzyme"))
tally += 1.5 //A tad bit of slowdown.
if(riding_datum) //Bit of slowdown for taur rides if rider is bigger or fatter than mount.
var/datum/riding/R = riding_datum
var/mob/living/L = R.ridden
for(var/mob/living/M in L.buckled_mobs)
if(ishuman(M))
var/mob/living/carbon/human/H = M
if(H.size_multiplier > L.size_multiplier)
tally += 1
if(H.weight > L.weight)
tally += 1
//VOREstation end
if(istype(buckled, /obj/structure/bed/chair/wheelchair))
@@ -13,6 +13,8 @@
min_age = 18
max_age = 250
health_hud_intensity = 1.5
base_species = SPECIES_ALRAUNE
selects_bodytype = TRUE
body_temperature = T20C
breath_type = "carbon_dioxide"
@@ -47,7 +49,8 @@
/mob/living/carbon/human/proc/succubus_drain,
/mob/living/carbon/human/proc/succubus_drain_finalize,
/mob/living/carbon/human/proc/succubus_drain_lethal,
/mob/living/carbon/human/proc/bloodsuck) //Give them the voremodes related to wrapping people in vines and sapping their fluids
/mob/living/carbon/human/proc/bloodsuck,
/mob/living/carbon/human/proc/alraune_fruit_select) //Give them the voremodes related to wrapping people in vines and sapping their fluids
color_mult = 1
icobase = 'icons/mob/human_races/r_human_vr.dmi'
@@ -85,6 +88,7 @@
O_KIDNEYS = /obj/item/organ/internal/kidneys/alraune,
O_BRAIN = /obj/item/organ/internal/brain/alraune,
O_EYES = /obj/item/organ/internal/eyes/alraune,
A_FRUIT = /obj/item/organ/internal/fruitgland,
)
/datum/species/alraune/can_breathe_water()
@@ -331,5 +335,164 @@
/obj/item/organ/internal/liver/alraune
icon = 'icons/mob/species/alraune/organs.dmi'
icon_state = "phytoextractor"
name = "phytoextractor"
desc = "A bulbous gourd-like structure."
name = "enzoretector"
desc = "A bulbous gourd-like structure."
//Begin fruit gland and its code.
/obj/item/organ/internal/fruitgland //Amazing name, I know.
icon = 'icons/mob/species/alraune/organs.dmi'
icon_state = "phytoextractor"
name = "fruit gland"
desc = "A bulbous gourd-like structure."
organ_tag = A_FRUIT
var/generated_reagents = list("sugar" = 2) //This actually allows them. This could be anything, but sugar seems most fitting.
var/usable_volume = 250 //Five fruit.
var/transfer_amount = 50
var/empty_message = list("Your have no fruit on you.", "You have a distinct lack of fruit..")
var/full_message = list("You have a multitude of fruit that is ready for harvest!", "You have fruit that is ready to be picked!")
var/emote_descriptor = list("fruit right off of the Alraune!", "a fruit from the Alraune!")
var/verb_descriptor = list("grabs", "snatches", "picks")
var/self_verb_descriptor = list("grab", "snatch", "pick")
var/short_emote_descriptor = list("picks", "grabs")
var/self_emote_descriptor = list("grab", "pick", "snatch")
var/fruit_type = "apple"
var/mob/organ_owner = null
var/gen_cost = 0.5
/obj/item/organ/internal/fruitgland/New()
..()
create_reagents(usable_volume)
/obj/item/organ/internal/fruitgland/process()
if(!owner) return
var/obj/item/organ/external/parent = owner.get_organ(parent_organ)
var/before_gen
if(parent && generated_reagents && organ_owner) //Is it in the chest/an organ, has reagents, and is 'activated'
before_gen = reagents.total_volume
if(reagents.total_volume < reagents.maximum_volume)
if(organ_owner.nutrition >= gen_cost)
do_generation()
if(reagents)
if(reagents.total_volume == reagents.maximum_volume * 0.05)
to_chat(organ_owner, "<span class='notice'>[pick(empty_message)]</span>")
else if(reagents.total_volume == reagents.maximum_volume && before_gen < reagents.maximum_volume)
to_chat(organ_owner, "<span class='warning'>[pick(full_message)]</span>")
/obj/item/organ/internal/fruitgland/proc/do_generation()
organ_owner.nutrition -= gen_cost
for(var/reagent in generated_reagents)
reagents.add_reagent(reagent, generated_reagents[reagent])
/mob/living/carbon/human/proc/alraune_fruit_select() //So if someone doesn't want fruit/vegetables, they don't have to select one.
set name = "Select fruit"
set desc = "Select what fruit/vegetable you wish to grow."
set category = "Object"
var/obj/item/organ/internal/fruitgland/fruit_gland
for(var/F in contents)
if(istype(F, /obj/item/organ/internal/fruitgland))
fruit_gland = F
break
if(fruit_gland)
var/selection = input(src, "Choose your character's fruit type. Choosing nothing will result in a default of apples.", "Fruit Type", fruit_gland.fruit_type) as null|anything in acceptable_fruit_types
if(selection)
fruit_gland.fruit_type = selection
verbs |= /mob/living/carbon/human/proc/alraune_fruit_pick
verbs -= /mob/living/carbon/human/proc/alraune_fruit_select
fruit_gland.organ_owner = src
fruit_gland.emote_descriptor = list("fruit right off of [fruit_gland.organ_owner]!", "a fruit from [fruit_gland.organ_owner]!")
else
to_chat(src, "<span class='notice'>You lack the organ required to produce fruit.</span>")
return
/mob/living/carbon/human/proc/alraune_fruit_pick()
set name = "Pick Fruit"
set desc = "Pick fruit off of [src]."
set category = "Object"
set src in view(1)
//do_reagent_implant(usr)
if(!isliving(usr) || !usr.canClick())
return
if(usr.incapacitated() || usr.stat > CONSCIOUS)
return
var/obj/item/organ/internal/fruitgland/fruit_gland
for(var/I in contents)
if(istype(I, /obj/item/organ/internal/fruitgland))
fruit_gland = I
break
if (fruit_gland) //Do they have the gland?
if(fruit_gland.reagents.total_volume < fruit_gland.transfer_amount)
to_chat(src, "<span class='notice'>[pick(fruit_gland.empty_message)]</span>")
return
var/datum/seed/S = plant_controller.seeds["[fruit_gland.fruit_type]"]
S.harvest(usr,0,0,1)
var/index = rand(0,2)
if (usr != src)
var/emote = fruit_gland.emote_descriptor[index]
var/verb_desc = fruit_gland.verb_descriptor[index]
var/self_verb_desc = fruit_gland.self_verb_descriptor[index]
usr.visible_message("<span class='notice'>[usr] [verb_desc] [emote]</span>",
"<span class='notice'>You [self_verb_desc] [emote]</span>")
else
visible_message("<span class='notice'>[src] [pick(fruit_gland.short_emote_descriptor)] a fruit.</span>",
"<span class='notice'>You [pick(fruit_gland.self_emote_descriptor)] a fruit.</span>")
fruit_gland.reagents.remove_any(fruit_gland.transfer_amount)
//End of fruit gland code.
/datum/species/alraune/proc/produceCopy(var/datum/species/to_copy,var/list/traits,var/mob/living/carbon/human/H)
ASSERT(to_copy)
ASSERT(istype(H))
if(ispath(to_copy))
to_copy = "[initial(to_copy.name)]"
if(istext(to_copy))
to_copy = all_species[to_copy]
var/datum/species/alraune/new_copy = new()
//Initials so it works with a simple path passed, or an instance
new_copy.base_species = to_copy.name
new_copy.icobase = to_copy.icobase
new_copy.deform = to_copy.deform
new_copy.tail = to_copy.tail
new_copy.tail_animation = to_copy.tail_animation
new_copy.icobase_tail = to_copy.icobase_tail
new_copy.color_mult = to_copy.color_mult
new_copy.primitive_form = to_copy.primitive_form
new_copy.appearance_flags = to_copy.appearance_flags
new_copy.flesh_color = to_copy.flesh_color
new_copy.base_color = to_copy.base_color
new_copy.blood_mask = to_copy.blood_mask
new_copy.damage_mask = to_copy.damage_mask
new_copy.damage_overlays = to_copy.damage_overlays
//Set up a mob
H.species = new_copy
H.icon_state = lowertext(new_copy.get_bodytype())
if(new_copy.holder_type)
H.holder_type = new_copy.holder_type
if(H.dna)
H.dna.ready_dna(H)
return new_copy
/datum/species/alraune/get_bodytype()
return base_species
/datum/species/alraune/get_race_key()
var/datum/species/real = all_species[base_species]
return real.race_key
@@ -1,15 +1,18 @@
/datum/species
//var/vore_numbing = 0
var/gets_food_nutrition = 1 // If this is set to 0, the person can't get nutrition from food.
var/gets_food_nutrition = TRUE // If this is set to 0, the person can't get nutrition from food.
var/metabolism = 0.0015
var/lightweight = 0 //Oof! Nonhelpful bump stumbles.
var/trashcan = 0 //It's always sunny in the wrestling ring.
var/lightweight = FALSE //Oof! Nonhelpful bump stumbles.
var/trashcan = FALSE //It's always sunny in the wrestling ring.
var/base_species = null // Unused outside of a few species
var/selects_bodytype = FALSE // Allows the species to choose from body types intead of being forced to be just one.
/datum/species/custom
name = SPECIES_CUSTOM
name_plural = "Custom"
var/base_species = "Human"
selects_bodytype = TRUE
base_species = SPECIES_HUMAN
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite)
@@ -53,7 +53,7 @@
var/datum/robolimb/M = chargen_robolimbs[company]
if(!(choice in M.parts))
continue
if(species.name in M.species_cannot_use)
if(impersonate_bodytype in M.species_cannot_use)
continue
if(M.whitelisted_to && !(ckey in M.whitelisted_to))
continue
@@ -106,7 +106,7 @@
var/datum/robolimb/M = chargen_robolimbs[company]
if(!(BP_TORSO in M.parts))
continue
if(species.name in M.species_cannot_use)
if(impersonate_bodytype in M.species_cannot_use)
continue
if(M.whitelisted_to && !(ckey in M.whitelisted_to))
continue
@@ -374,4 +374,4 @@
icon_state = "metal"
to_call = /mob/living/carbon/human/proc/nano_metalnom
#undef PER_LIMB_STEEL_COST
#undef PER_LIMB_STEEL_COST
@@ -1,7 +1,7 @@
#define DAM_SCALE_FACTOR 0.01
#define METAL_PER_TICK 150
/datum/species/protean
name = "Protean"
name = SPECIES_PROTEAN
name_plural = "Proteans"
blurb = "Sometimes very advanced civilizations will produce the ability to swap into manufactured, robotic bodies. And sometimes \
<i>VERY</i> advanced civilizations have the option of 'nanoswarm' bodies. Effectively a single robot body comprised \
@@ -139,7 +139,7 @@
if(H.backbag == 1) //Somewhat misleading, 1 == no bag (not boolean)
H.equip_to_slot_or_del(permit, slot_l_hand)
H.equip_to_slot_or_del(metal_stack, slot_r_hand)
H.equip_to_slot_or_del(metal_stack, slot_r_hand)
else
H.equip_to_slot_or_del(permit, slot_in_backpack)
H.equip_to_slot_or_del(metal_stack, slot_in_backpack)
@@ -172,7 +172,7 @@
var/obj/item/organ/internal/nano/refactory/refactory = locate() in H.internal_organs
if(refactory && !(refactory.status & ORGAN_DEAD))
//MHydrogen adds speeeeeed
if(refactory.get_stored_material("mhydrogen") >= METAL_PER_TICK)
H.add_modifier(/datum/modifier/protean/mhydrogen, origin = refactory)
@@ -233,7 +233,7 @@
var/obj/item/organ/internal/nano/refactory/refactory = origin.resolve()
if(!istype(refactory) || refactory.status & ORGAN_DEAD)
expire()
//Out of materials
if(!refactory.use_stored_material(material_name,material_use))
expire()
@@ -255,7 +255,7 @@
on_created_text = "<span class='notice'>You feel yourself become nearly impervious to physical attacks as plasteel nanites are made.</span>"
on_expired_text = "<span class='notice'>Your refactory finishes consuming the plasteel, and you return to your normal nanites.</span>"
material_name = "plasteel"
incoming_brute_damage_percent = 0.5
@@ -266,7 +266,7 @@
on_created_text = "<span class='notice'>You feel yourself become more reflective, able to resist heat and fire better for a time.</span>"
on_expired_text = "<span class='notice'>Your refactory finishes consuming the diamond, and you return to your normal nanites.</span>"
material_name = "diamond"
incoming_fire_damage_percent = 0.2
@@ -277,7 +277,7 @@
on_created_text = "<span class='notice'>You feel new nanites being produced from your stockpile of steel, healing you slowly.</span>"
on_expired_text = "<span class='notice'>Your steel supply has either run out, or is no longer needed, and your healing stops.</span>"
material_name = "steel"
/datum/modifier/protean/steel/tick()
@@ -5,7 +5,7 @@
/datum/species/xenochimera //Scree's race.
name = "Xenochimera"
name = SPECIES_XENOCHIMERA
name_plural = "Xenochimeras"
icobase = 'icons/mob/human_races/r_xenochimera.dmi'
deform = 'icons/mob/human_races/r_def_xenochimera.dmi'
@@ -14,7 +14,8 @@
slowdown = -0.2 //scuttly, but not as scuttly as a tajara or a teshari.
brute_mod = 0.8 //About as tanky to brute as a Unathi. They'll probably snap and go feral when hurt though.
burn_mod = 1.15 //As vulnerable to burn as a Tajara.
var/base_species = "Xenochimera"
base_species = "Xenochimera"
selects_bodytype = TRUE
num_alternate_languages = 2
secondary_langs = list("Sol Common")
@@ -300,7 +301,7 @@
/////SPIDER RACE/////
/////////////////////
/datum/species/spider //These actually look pretty damn spooky!
name = "Vasilissan"
name = SPECIES_VASILISSAN
name_plural = "Vasilissans"
icobase = 'icons/mob/human_races/r_spider.dmi'
deform = 'icons/mob/human_races/r_def_spider.dmi'
+5 -1
View File
@@ -1277,4 +1277,8 @@ default behaviour is:
/mob/living/proc/has_vision()
return !(eye_blind || (disabilities & BLIND) || stat || blinded)
return !(eye_blind || (disabilities & BLIND) || stat || blinded)
/mob/living/proc/dirties_floor() // If we ever decide to add fancy conditionals for making dirty floors (floating, etc), here's the proc.
return makes_dirt
+7 -2
View File
@@ -380,8 +380,13 @@
var/turf/location = get_turf(src)
location.hotspot_expose(fire_burn_temperature(), 50, 1)
/mob/living/fire_act()
adjust_fire_stacks(2)
//altered this to cap at the temperature of the fire causing it, using the same 1:1500 value as /mob/living/carbon/human/handle_fire() in human/life.dm
/mob/living/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
if(exposed_temperature)
if(fire_stacks < exposed_temperature/1500) // Subject to balance
adjust_fire_stacks(2)
else
adjust_fire_stacks(2)
IgniteMob()
//Share fire evenly between the two mobs
+2 -1
View File
@@ -16,7 +16,6 @@
var/brainloss = 0 //'Retardation' damage caused by someone hitting you in the head with a bible or being infected with brainrot.
var/halloss = 0 //Hallucination damage. 'Fake' damage obtained through hallucinating or the holodeck. Sleeping should cause it to wear off.
var/hallucination = 0 //Directly affects how long a mob will hallucinate for
var/list/atom/hallucinations = list() //A list of hallucinated people that try to attack the mob. See /obj/effect/fake_attacker in hallucinations.dm
@@ -59,3 +58,5 @@
var/list/hud_list //Holder for health hud, status hud, wanted hud, etc (not like inventory slots)
var/has_huds = FALSE //Whether or not we should bother initializing the above list
var/makes_dirt = TRUE //FALSE if the mob shouldn't be making dirt on the ground when it walks
@@ -142,15 +142,27 @@
chargecost = 500
/obj/item/weapon/shockpaddles/robot/hound/jumper
name = "paws of life"
icon = 'icons/mob/dogborg_vr.dmi'
icon_state = "defibpaddles0"
name = "jumper paws"
desc = "Zappy paws. For rebooting a full body prostetic."
combat = 1
attack_verb = list("batted", "pawed", "bopped", "whapped")
chargecost = 500
use_on_synthetic = 1
/obj/item/weapon/reagent_containers/borghypo/hound
name = "MediHound hypospray"
desc = "An advanced chemical synthesizer and injection system utilizing carrier's reserves, designed for heavy-duty medical equipment."
charge_cost = 10
var/datum/matter_synth/water = null
/obj/item/weapon/reagent_containers/borghypo/hound/process() //Recharges in smaller steps and uses the water reserves as well.
if(isrobot(loc))
var/mob/living/silicon/robot/R = loc
if(R && R.cell)
for(var/T in reagent_ids)
if(reagent_volumes[T] < volume && water.energy >= charge_cost)
R.cell.use(charge_cost)
water.use_charge(charge_cost)
reagent_volumes[T] = min(reagent_volumes[T] + 1, volume)
return 1
//Tongue stuff
/obj/item/device/dogborg/tongue
name = "synthetic tongue"
@@ -188,7 +200,14 @@
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
if(user.client && (target in user.client.screen))
to_chat(user, "<span class='warning'>You need to take \the [target.name] off before cleaning it!</span>")
else if(istype(target,/obj/effect/decal/cleanable) && water.energy >= 5)
if(istype(target, /obj/structure/sink) || istype(target, /obj/structure/toilet)) //Dog vibes.
user.visible_message("[user] begins to lap up water from [target.name].", "<span class='notice'>You begin to lap up water from [target.name].</span>")
if(do_after (user, 50))
water.add_charge(50)
else if(water.energy < 5)
to_chat(user, "<span class='notice'>Your mouth feels dry.</span>")
return
else if(istype(target,/obj/effect/decal/cleanable))
user.visible_message("[user] begins to lick off \the [target.name].", "<span class='notice'>You begin to lick off \the [target.name]...</span>")
if(do_after (user, 50))
to_chat(user, "<span class='notice'>You finish licking off \the [target.name].</span>")
@@ -196,7 +215,7 @@
qdel(target)
var/mob/living/silicon/robot.R = user
R.cell.charge += 50
else if(istype(target,/obj/item) && water.energy >= 5)
else if(istype(target,/obj/item))
if(istype(target,/obj/item/trash))
user.visible_message("[user] nibbles away at \the [target.name].", "<span class='notice'>You begin to nibble away at \the [target.name]...</span>")
if(do_after (user, 50))
@@ -238,25 +257,14 @@
"<span class='userdanger'>[user] has shocked you with its tongue! You can feel the betrayal.</span>")
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
R.cell.charge -= 666
else if(water.energy >= 5)
else
user.visible_message("<span class='notice'>\the [user] affectionally licks all over \the [target]'s face!</span>", "<span class='notice'>You affectionally lick all over \the [target]'s face!</span>")
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
water.use_charge(5)
var/mob/living/carbon/human/H = target
if(H.species.lightweight == 1)
H.Weaken(3)
return
else if(istype(target, /obj/structure/window) && water.energy >= 1)
user.visible_message("[user] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
if(do_after (user, 50))
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
water.use_charge(5)
target.color = initial(target.color)
else if(istype(target, /obj/structure/sink) || istype(target, /obj/structure/toilet)) //Dog vibes.
user.visible_message("[user] begins to lap up water from [target.name].", "<span class='notice'>You begin to lap up water from [target.name].</span>")
if(do_after (user, 50))
water.add_charge(100)
else if(water.energy >= 5)
else
user.visible_message("[user] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
if(do_after (user, 50))
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
@@ -11,7 +11,6 @@
var/min_health = -100
var/cleaning = 0
var/patient_laststat = null
var/mob_energy = -100 //Energy gained from digesting dead mobs (including PCs)
var/list/injection_chems = list("inaprovaline", "dexalin", "bicaridine", "kelotane","anti_toxin", "alkysine", "imidazoline", "spaceacillin", "paracetamol") //The borg is able to heal every damage type. As a nerf, they use 750 charge per injection.
var/eject_port = "ingestion"
var/list/items_preserved = list()
@@ -19,6 +18,12 @@
var/compactor = FALSE
var/analyzer = FALSE
var/decompiler = FALSE
var/delivery = FALSE
var/delivery_tag = "Fuel"
var/list/deliverylists = list()
var/list/deliveryslot_1 = list()
var/list/deliveryslot_2 = list()
var/list/deliveryslot_3 = list()
var/datum/research/techonly/files //Analyzerbelly var.
var/synced = FALSE
var/startdrain = 500
@@ -50,52 +55,11 @@
return
if(target in hound.module.modules)
return
if(length(contents) > (max_item_count - 1))
if(length(contents) >= max_item_count)
to_chat(user, "<span class='warning'>Your [src.name] is full. Eject or process contents to continue.</span>")
return
if(analyzer == TRUE)
if(istype(target, /obj/item))
var/obj/target_obj = target
if(target_obj.w_class > ITEMSIZE_LARGE)
to_chat(user, "<span class='warning'>\The [target] is too large to fit into your [src.name]</span>")
return
user.visible_message("<span class='warning'>[hound.name] is ingesting [target.name] into their [src.name].</span>", "<span class='notice'>You start ingesting [target] into your [src.name]...</span>")
if(do_after(user, 30, target) && length(contents) < max_item_count)
target.forceMove(src)
user.visible_message("<span class='warning'>[hound.name]'s internal analyzer groans lightly as [target.name] slips inside.</span>", "<span class='notice'>Your internal analyzer groans lightly as [target] slips inside.</span>")
playsound(hound, gulpsound, vol = 60, vary = 1, falloff = 0.1, preference = /datum/client_preference/eating_noises)
if(istype(target,/obj/item))
var/obj/item/tech_item = target
for(var/T in tech_item.origin_tech)
to_chat(user, "<span class='notice'>\The [tech_item] has level [tech_item.origin_tech[T]] in [CallTechName(T)].</span>")
update_patient()
if(UI_open == TRUE)
sleeperUI(usr)
return
else if(ishuman(target))
var/mob/living/carbon/human/trashman = target
if(patient)
to_chat(user, "<span class='warning'>Your [src.name] is already occupied.</span>")
return
if(trashman.buckled)
to_chat(user, "<span class='warning'>[trashman] is buckled and can not be put into your [src.name].</span>")
return
user.visible_message("<span class='warning'>[hound.name] is ingesting [trashman] into their [src.name].</span>", "<span class='notice'>You start ingesting [trashman] into your [src.name]...</span>")
if(do_after(user, 30, trashman) && !patient && !trashman.buckled && length(contents) < max_item_count)
trashman.forceMove(src)
trashman.reset_view(src)
processing_objects |= src
user.visible_message("<span class='warning'>[hound.name]'s internal analyzer groans lightly as [trashman] slips inside.</span>", "<span class='notice'>Your internal analyzer groans lightly as [trashman] slips inside.</span>")
playsound(hound, gulpsound, vol = 100, vary = 1, falloff = 0.1, preference = /datum/client_preference/eating_noises)
update_patient()
if(UI_open == TRUE)
sleeperUI(usr)
return
return
if(compactor == TRUE)
if(compactor)
if(istype(target, /obj/item) || istype(target, /obj/effect/decal/remains))
var/obj/target_obj = target
if(target_obj.w_class > ITEMSIZE_LARGE)
@@ -104,11 +68,17 @@
user.visible_message("<span class='warning'>[hound.name] is ingesting [target.name] into their [src.name].</span>", "<span class='notice'>You start ingesting [target] into your [src.name]...</span>")
if(do_after(user, 30, target) && length(contents) < max_item_count)
target.forceMove(src)
user.visible_message("<span class='warning'>[hound.name]'s garbage processor groans lightly as [target.name] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [target] slips inside.</span>")
user.visible_message("<span class='warning'>[hound.name]'s [src.name] groans lightly as [target.name] slips inside.</span>", "<span class='notice'>Your [src.name] groans lightly as [target] slips inside.</span>")
playsound(hound, gulpsound, vol = 60, vary = 1, falloff = 0.1, preference = /datum/client_preference/eating_noises)
if(analyzer && istype(target,/obj/item))
var/obj/item/tech_item = target
for(var/T in tech_item.origin_tech)
to_chat(user, "<span class='notice'>\The [tech_item] has level [tech_item.origin_tech[T]] in [CallTechName(T)].</span>")
if(delivery)
if(islist(deliverylists[delivery_tag]))
deliverylists[delivery_tag] |= target
to_chat(user, "<span class='notice'>\The [target.name] added to cargo compartment slot: [delivery_tag].</span>")
update_patient()
if(UI_open == TRUE)
sleeperUI(usr)
return
if(istype(target, /mob/living/simple_animal/mouse)) //Edible mice, dead or alive whatever. Mostly for carcass picking you cruel bastard :v
@@ -117,11 +87,13 @@
if(do_after(user, 30, trashmouse) && length(contents) < max_item_count)
trashmouse.forceMove(src)
trashmouse.reset_view(src)
user.visible_message("<span class='warning'>[hound.name]'s garbage processor groans lightly as [trashmouse] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [trashmouse] slips inside.</span>")
user.visible_message("<span class='warning'>[hound.name]'s [src.name] groans lightly as [trashmouse] slips inside.</span>", "<span class='notice'>Your [src.name] groans lightly as [trashmouse] slips inside.</span>")
playsound(hound, gulpsound, vol = 60, vary = 1, falloff = 0.1, preference = /datum/client_preference/eating_noises)
if(delivery)
if(islist(deliverylists[delivery_tag]))
deliverylists[delivery_tag] |= trashmouse
to_chat(user, "<span class='notice'>\The [trashmouse] added to cargo compartment slot: [delivery_tag].</span>")
update_patient()
if(UI_open == TRUE)
sleeperUI(usr)
return
else if(ishuman(target))
@@ -137,13 +109,18 @@
trashman.forceMove(src)
trashman.reset_view(src)
processing_objects |= src
user.visible_message("<span class='warning'>[hound.name]'s garbage processor groans lightly as [trashman] slips inside.</span>", "<span class='notice'>Your garbage compactor groans lightly as [trashman] slips inside.</span>")
user.visible_message("<span class='warning'>[hound.name]'s [src.name] groans lightly as [trashman] slips inside.</span>", "<span class='notice'>Your [src.name] groans lightly as [trashman] slips inside.</span>")
message_admins("[key_name(hound)] has eaten [key_name(patient)] as a dogborg. ([hound ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[hound.x];Y=[hound.y];Z=[hound.z]'>JMP</a>" : "null"])")
playsound(hound, gulpsound, vol = 100, vary = 1, falloff = 0.1, preference = /datum/client_preference/eating_noises)
if(delivery)
if(islist(deliverylists[delivery_tag]))
deliverylists[delivery_tag] |= trashman
to_chat(user, "<span class='notice'>\The [trashman] added to cargo compartment slot: [delivery_tag].</span>")
to_chat(trashman, "<span class='notice'>[hound.name] has added you to their cargo compartment slot: [delivery_tag].</span>")
update_patient()
if(UI_open == TRUE)
sleeperUI(usr)
return
return
else if(ishuman(target))
var/mob/living/carbon/human/H = target
if(H.buckled)
@@ -154,50 +131,38 @@
return
user.visible_message("<span class='warning'>[hound.name] is ingesting [H.name] into their [src.name].</span>", "<span class='notice'>You start ingesting [H] into your [src]...</span>")
if(!patient && !H.buckled && do_after (user, 50, H))
if(!proximity) return //If they moved away, you can't eat them.
if(patient) return //If you try to eat two people at once, you can only eat one.
if(!proximity)
return //If they moved away, you can't eat them.
if(patient)
return //If you try to eat two people at once, you can only eat one.
else //If you don't have someone in you, proceed.
H.forceMove(src)
H.reset_view(src)
update_patient()
processing_objects |= src
user.visible_message("<span class='warning'>[hound.name]'s medical pod lights up as [H.name] slips inside into their [src.name].</span>", "<span class='notice'>Your medical pod lights up as [H] slips into your [src]. Life support functions engaged.</span>")
user.visible_message("<span class='warning'>[hound.name]'s [src.name] lights up as [H.name] slips inside.</span>", "<span class='notice'>Your [src] lights up as [H] slips inside. Life support functions engaged.</span>")
message_admins("[key_name(hound)] has eaten [key_name(patient)] as a dogborg. ([hound ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[hound.x];Y=[hound.y];Z=[hound.z]'>JMP</a>" : "null"])")
playsound(hound, gulpsound, vol = 100, vary = 1, falloff = 0.1, preference = /datum/client_preference/eating_noises)
if(UI_open == TRUE)
sleeperUI(usr)
/obj/item/device/dogborg/sleeper/proc/go_out(var/target)
hound = src.loc
items_preserved.Cut()
cleaning = 0
for(var/list/dlist in deliverylists)
dlist.Cut()
if(length(contents) > 0)
hound.visible_message("<span class='warning'>[hound.name] empties out their contents via their [eject_port] port.</span>", "<span class='notice'>You empty your contents via your [eject_port] port.</span>")
if(target)
if(ishuman(target))
var/mob/living/carbon/human/person = target
for(var/C in contents)
if(ishuman(C))
var/mob/living/carbon/human/person = C
person.forceMove(get_turf(src))
person.reset_view()
else
var/obj/T = target
var/obj/T = C
T.loc = hound.loc
else
for(var/C in contents)
if(ishuman(C))
var/mob/living/carbon/human/person = C
person.forceMove(get_turf(src))
person.reset_view()
else
var/obj/T = C
T.loc = hound.loc
items_preserved.Cut()
cleaning = 0
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
update_patient()
else //You clicked eject with nothing in you, let's just reset stuff to be sure.
items_preserved.Cut()
cleaning = 0
update_patient()
/obj/item/device/dogborg/sleeper/proc/drain(var/amt = 3) //Slightly reduced cost (before, it was always injecting inaprov)
@@ -208,10 +173,9 @@
if(..())
return
sleeperUI(user)
UI_open = TRUE
/obj/item/device/dogborg/sleeper/proc/sleeperUI(mob/user)
var/dat
var/dat = "<TITLE>[name] Console</TITLE><BR>"
if(islist(injection_chems)) //Only display this if we're a drug-dispensing doggo.
dat += "<h3>Injector</h3>"
@@ -234,15 +198,33 @@
dat += "<A href='?src=\ref[src];clean=1'>Self-Clean</A>"
else
dat += "<span class='linkOff'>Self-Clean</span>"
if(delivery)
dat += "<BR><h3>Cargo Compartment</h3><BR>"
dat += "<A href='?src=\ref[src];deliveryslot=1'>Active Slot: [delivery_tag]</A>"
if(islist(deliverylists[delivery_tag]))
dat += "<A href='?src=\ref[src];slot_eject=1'>Eject Slot</A>"
dat += "<div class='statusDisplay'>"
if(compactor == TRUE && length(contents))//garbage counter for trashpup
var/obj/item/device/dogborg/sleeper/compactor/garbo = src
dat += "<font color='red'><B>Current load:</B> [length(contents)] / [garbo.max_item_count] objects.</font><BR>"
if(!delivery && compactor && length(contents))//garbage counter for trashpup
dat += "<font color='red'><B>Current load:</B> [length(contents)] / [max_item_count] objects.</font><BR>"
dat += "<font color='gray'>([list2text(contents,", ")])</font><BR><BR>"
if(analyzer == TRUE && synced == FALSE)
if(delivery && length(contents))
dat += "<font color='red'><B>Current load:</B> [length(contents)] / [max_item_count] objects.</font><BR>"
dat += "<font color='gray'>Cargo compartment slot: Cargo 1.</font><BR>"
if(length(deliveryslot_1))
dat += "<font color='gray'>([list2text(deliveryslot_1,", ")])</font><BR>"
dat += "<font color='gray'>Cargo compartment slot: Cargo 2.</font><BR>"
if(length(deliveryslot_2))
dat += "<font color='gray'>([list2text(deliveryslot_2,", ")])</font><BR>"
dat += "<font color='gray'>Cargo compartment slot: Cargo 3.</font><BR>"
if(length(deliveryslot_3))
dat += "<font color='gray'>([list2text(deliveryslot_3,", ")])</font><BR>"
dat += "<font color='red'>Cargo compartment slot: Fuel.</font><BR>"
dat += "<font color='red'>([list2text(contents - (deliveryslot_1 + deliveryslot_2 + deliveryslot_3),", ")])</font><BR><BR>"
if(analyzer && synced)
dat += "<A href='?src=\ref[src];sync=1'>Sync Files</A><BR>"
//Cleaning and there are still un-preserved items
@@ -295,10 +277,10 @@
dat += "<div class='line'><div style='width: 170px;' class='statusLabel'>[R.name]:</div><div class='statusValue'>[round(R.volume, 0.1)] units</div></div><br>"
dat += "</div>"
var/datum/browser/popup = new(user, "sleeper", "[name] Console", 520, 540) //Set up the popup browser window
//popup.set_title_image(user.browse_rsc_icon(icon, icon_state)) //I have no idea what this is, but it feels irrelevant and causes runtimes idk.
var/datum/browser/popup = new(user, "sleeper_b", "[name] Console", 400, 500, src)
popup.set_content(dat)
popup.open()
UI_open = TRUE
return
/obj/item/device/dogborg/sleeper/Topic(href, href_list)
@@ -328,7 +310,6 @@
drain(startdrain)
processing_objects |= src
update_patient()
sleeperUI(usr)
if(patient)
to_chat(patient, "<span class='danger'>[hound.name]'s [src.name] fills with caustic enzymes around you!</span>")
return
@@ -343,7 +324,29 @@
eject_port = "ingestion"
sleeperUI(usr)
return
if(href_list["deliveryslot"])
var/tag = input("Select active delivery slot.") as null|anything in deliverylists
if(!tag)
return 0
delivery_tag = tag
sleeperUI(usr)
return
if(href_list["slot_eject"])
if(length(deliverylists[delivery_tag]) > 0)
hound.visible_message("<span class='warning'>[hound.name] empties out their cargo compartment via their [eject_port] port.</span>", "<span class='notice'>You empty your cargo compartment via your [eject_port] port.</span>")
for(var/C in deliverylists[delivery_tag])
if(ishuman(C))
var/mob/living/carbon/human/person = C
person.forceMove(get_turf(src))
person.reset_view()
else
var/obj/T = C
T.loc = hound.loc
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
update_patient()
deliverylists[delivery_tag].Cut()
sleeperUI(usr)
return
if(href_list["sync"])
synced = TRUE
var/success = 0
@@ -392,6 +395,15 @@
//For if the dogborg's existing patient uh, doesn't make it.
/obj/item/device/dogborg/sleeper/proc/update_patient()
hound = src.loc
if(UI_open == TRUE)
sleeperUI(hound)
//Cleaning looks better with red on, even with nobody in it
if(cleaning || (length(contents) > 10) || (decompiler && (length(contents) > 5)) || (analyzer && (length(contents) > 1)))
hound.sleeper_r = TRUE
hound.sleeper_g = FALSE
hound.updateicon()
return
//Well, we HAD one, what happened to them?
if(patient in contents)
@@ -411,8 +423,6 @@
//Update icon
hound.updateicon()
//Return original patient
if(UI_open == TRUE)
sleeperUI(usr)
return(patient)
//Check for a new patient
@@ -433,30 +443,16 @@
patient_laststat = patient.stat
//Update icon and return new patient
hound.updateicon()
if(UI_open == TRUE)
sleeperUI(usr)
return(C)
//Cleaning looks better with red on, even with nobody in it
if(cleaning || (length(contents) > 11))
hound.sleeper_r = TRUE
hound.sleeper_g = FALSE
//Letting analyzer gut swell if overloaded.
if(analyzer == TRUE && (length(contents) > 1))
hound.sleeper_r = TRUE
hound.sleeper_g = FALSE
//Couldn't find anyone, and not cleaning
else if(!cleaning && !patient && !length(contents))
if(!cleaning && !patient)
hound.sleeper_r = FALSE
hound.sleeper_g = FALSE
patient_laststat = null
patient = null
hound.updateicon()
if(UI_open == TRUE)
sleeperUI(usr)
return
//Gurgleborg process
@@ -467,10 +463,10 @@
if(!(I in contents))
items_preserved -= I
var/list/touchable_items = contents - items_preserved
var/list/touchable_items = contents - items_preserved - (deliveryslot_1 + deliveryslot_2 + deliveryslot_3)
//Belly is entirely empty
if(!length(contents))
if(!length(touchable_items))
var/finisher = pick(
'sound/vore/death1.ogg',
'sound/vore/death2.ogg',
@@ -508,9 +504,11 @@
if(air_master.current_cycle%3==1 && length(touchable_items))
//Burn all the mobs or add them to the exclusion list
var/volume = 0
for(var/mob/living/T in (touchable_items))
touchable_items -= T //Exclude mobs from loose item picking.
if((T.status_flags & GODMODE) || !T.digestable)
items_preserved += T
items_preserved |= T
else
var/old_brute = T.getBruteLoss()
var/old_burn = T.getFireLoss()
@@ -520,66 +518,55 @@
var/actual_burn = T.getFireLoss() - old_burn
var/damage_gain = actual_brute + actual_burn
drain(-25 * damage_gain) //25*total loss as with voreorgan stats.
update_patient()
water.add_charge(damage_gain)
if(T.stat == DEAD)
if(ishuman(T))
message_admins("[key_name(hound)] has digested [key_name(T)] as a dogborg. ([hound ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[hound.x];Y=[hound.y];Z=[hound.z]'>JMP</a>" : "null"])")
to_chat(hound, "<span class='notice'>You feel your belly slowly churn around [T], breaking them down into a soft slurry to be used as power for your systems.</span>")
to_chat(T, "<span class='notice'>You feel [hound]'s belly slowly churn around your form, breaking you down into a soft slurry to be used as power for [hound]'s systems.</span>")
var/deathsound = pick(
'sound/vore/death1.ogg',
'sound/vore/death2.ogg',
'sound/vore/death3.ogg',
'sound/vore/death4.ogg',
'sound/vore/death5.ogg',
'sound/vore/death6.ogg',
'sound/vore/death7.ogg',
'sound/vore/death8.ogg',
'sound/vore/death9.ogg',
'sound/vore/death10.ogg')
playsound(hound, deathsound, vol = 100, vary = 1, falloff = 0.1, ignore_walls = TRUE, preference = /datum/client_preference/digestion_noises)
if(is_vore_predator(T))
for(var/belly in T.vore_organs)
var/obj/belly/B = belly
for(var/atom/movable/thing in B)
thing.forceMove(src)
if(ismob(thing))
to_chat(thing, "As [T] melts away around you, you find yourself in [hound]'s [name]")
for(var/obj/item/I in T)
if(istype(I,/obj/item/organ/internal/mmi_holder/posibrain))
var/obj/item/organ/internal/mmi_holder/MMI = I
var/atom/movable/brain = MMI.removed()
if(brain)
hound.remove_from_mob(brain,src)
brain.forceMove(src)
items_preserved |= brain
else
T.drop_from_inventory(I, src)
if(ishuman(T))
var/mob/living/carbon/human/Prey = T
volume = (Prey.bloodstr.total_volume + Prey.ingested.total_volume + Prey.touching.total_volume + Prey.weight) * Prey.size_multiplier
water.add_charge(volume)
if(T.reagents)
volume = T.reagents.total_volume
water.add_charge(volume)
qdel(T)
//Pick a random item to deal with (if there are any)
var/atom/target = pick(touchable_items)
var/volume = 0
if(length(touchable_items))
var/atom/target = pick(touchable_items)
//Handle the target being a mob
if(isliving(target))
var/mob/living/T = target
//Mob is now dead
if(T.stat == DEAD)
if(ishuman(target))
message_admins("[key_name(hound)] has digested [key_name(T)] as a dogborg. ([hound ? "<a href='?_src_=holder;adminplayerobservecoodjump=1;X=[hound.x];Y=[hound.y];Z=[hound.z]'>JMP</a>" : "null"])")
to_chat(hound, "<span class='notice'>You feel your belly slowly churn around [T], breaking them down into a soft slurry to be used as power for your systems.</span>")
to_chat(T, "<span class='notice'>You feel [hound]'s belly slowly churn around your form, breaking you down into a soft slurry to be used as power for [hound]'s systems.</span>")
drain(mob_energy) //Fueeeeellll
var/deathsound = pick(
'sound/vore/death1.ogg',
'sound/vore/death2.ogg',
'sound/vore/death3.ogg',
'sound/vore/death4.ogg',
'sound/vore/death5.ogg',
'sound/vore/death6.ogg',
'sound/vore/death7.ogg',
'sound/vore/death8.ogg',
'sound/vore/death9.ogg',
'sound/vore/death10.ogg')
playsound(hound, deathsound, vol = 100, vary = 1, falloff = 0.1, ignore_walls = TRUE, preference = /datum/client_preference/digestion_noises)
if(is_vore_predator(T))
for(var/belly in T.vore_organs)
var/obj/belly/B = belly
for(var/atom/movable/thing in B)
thing.forceMove(src)
if(ismob(thing))
to_chat(thing, "As [T] melts away around you, you find yourself in [hound]'s [name]")
for(var/obj/item/I in T)
if(istype(I,/obj/item/organ/internal/mmi_holder/posibrain))
var/obj/item/organ/internal/mmi_holder/MMI = I
var/atom/movable/brain = MMI.removed()
if(brain)
hound.remove_from_mob(brain,src)
brain.forceMove(src)
items_preserved += brain
else
T.drop_from_inventory(I, src)
if(ishuman(T))
var/mob/living/carbon/human/Prey = T
volume = (Prey.bloodstr.total_volume + Prey.ingested.total_volume + Prey.touching.total_volume + Prey.weight) * Prey.size_multiplier
water.add_charge(volume)
if(T.reagents)
volume = T.reagents.total_volume
water.add_charge(volume)
qdel(T)
update_patient()
if(UI_open == TRUE)
sleeperUI(hound)
//Handle the target being anything but a /mob/living
else
//Handle the target being anything but a /mob/living
var/obj/item/T = target
if(istype(T))
if(T.reagents)
@@ -596,12 +583,12 @@
drain(-50 * digested)
if(volume)
water.add_charge(volume)
if(!analyzer && compactor && T.matter)
if(!analyzer && !delivery && compactor && T.matter)
for(var/material in T.matter)
var/total_material = T.matter[material]
if(istype(T,/obj/item/stack))
var/obj/item/stack/stack = T
total_material *= stack.get_amount()
total_material *= (0.5 * stack.get_amount())
if(material == DEFAULT_WALL_MATERIAL)
metal.add_charge(total_material)
if(material == "glass")
@@ -618,10 +605,8 @@
drain(-100)
else
items_preserved |= target
if(UI_open == TRUE)
update_patient()
sleeperUI(hound)
return
update_patient()
return
/obj/item/device/dogborg/sleeper/process()
@@ -671,4 +656,11 @@
desc = "A mounted matter decompiling unit with fuel processor."
icon_state = "decompiler"
max_item_count = 10
decompiler = TRUE
decompiler = TRUE
/obj/item/device/dogborg/sleeper/compactor/delivery //Unfinished and unimplemented, still testing.
name = "Cargo Belly"
desc = "A mounted cargo bay unit for tagged deliveries."
icon_state = "decompiler"
max_item_count = 20
delivery = TRUE
@@ -166,7 +166,6 @@ var/global/list/robot_modules = list(
sprites = list(
"M-USE NanoTrasen" = "robot",
"Cabeiri" = "eyebot-standard",
"CUPCAKE" = "Noble-STD",
"Haruka" = "marinaSD",
"Usagi" = "tallflower",
"Telemachus" = "toiletbot",
@@ -198,7 +197,6 @@ var/global/list/robot_modules = list(
sprites = list(
"M-USE NanoTrasen" = "robotMedi",
"Cabeiri" = "eyebot-medical",
"CUPCAKE" = "Noble-MED",
"Haruka" = "marinaMD",
"Minako" = "arachne",
"Usagi" = "tallwhite",
@@ -269,7 +267,6 @@ var/global/list/robot_modules = list(
sprites = list(
"M-USE NanoTrasen" = "robotMedi",
"Cabeiri" = "eyebot-medical",
"CUPCAKE" = "Noble-MED",
"Haruka" = "marinaMD",
"Minako" = "arachne",
"Usagi" = "tallwhite",
@@ -342,7 +339,6 @@ var/global/list/robot_modules = list(
sprites = list(
"M-USE NanoTrasen" = "robotEngi",
"Cabeiri" = "eyebot-engineering",
"CUPCAKE" = "Noble-ENG",
"Haruka" = "marinaENG",
"Usagi" = "tallyellow",
"Telemachus" = "toiletbotengineering",
@@ -500,7 +496,6 @@ var/global/list/robot_modules = list(
"Cabeiri" = "eyebot-security",
"Cerberus" = "bloodhound",
"Cerberus - Treaded" = "treadhound",
"CUPCAKE" = "Noble-SEC",
"Haruka" = "marinaSC",
"Usagi" = "tallred",
"Telemachus" = "toiletbotsecurity",
@@ -544,7 +539,6 @@ var/global/list/robot_modules = list(
"M-USE NanoTrasen" = "robotJani",
"Arachne" = "crawler",
"Cabeiri" = "eyebot-janitor",
"CUPCAKE" = "Noble-CLN",
"Haruka" = "marinaJN",
"Telemachus" = "toiletbotjanitor",
"WTOperator" = "sleekjanitor",
@@ -595,7 +589,6 @@ var/global/list/robot_modules = list(
sprites = list(
"M-USE NanoTrasen" = "robotServ",
"Cabeiri" = "eyebot-standard",
"CUPCAKE" = "Noble-SRV",
"Haruka" = "marinaSV",
"Michiru" = "maidbot",
"Usagi" = "tallgreen",
@@ -650,7 +643,6 @@ var/global/list/robot_modules = list(
sprites = list(
"M-USE NanoTrasen" = "robotCler",
"Cabeiri" = "eyebot-standard",
"CUPCAKE" = "Noble-SRV",
"Haruka" = "marinaSV",
"Usagi" = "tallgreen",
"Telemachus" = "toiletbot",
@@ -690,7 +682,6 @@ var/global/list/robot_modules = list(
sprites = list(
"NM-USE NanoTrasen" = "robotMine",
"Cabeiri" = "eyebot-miner",
"CUPCAKE" = "Noble-DIG",
"Haruka" = "marinaMN",
"Telemachus" = "toiletbotminer",
"WTOperator" = "sleekminer",
@@ -63,55 +63,64 @@
/obj/item/weapon/robot_module/robot/medical/surgeon //VOREStation sprites
vr_sprites = list(
"Acheron" = "mechoid-Medical"
"Acheron" = "mechoid-Medical",
"Shellguard Noble" = "Noble-MED"
)
/obj/item/weapon/robot_module/robot/medical/crisis //VOREStation sprites
vr_sprites = list(
"Handy" = "handy-med",
"Acheron" = "mechoid-Medical"
"Acheron" = "mechoid-Medical",
"Shellguard Noble" = "Noble-MED"
)
/obj/item/weapon/robot_module/robot/clerical/butler //VOREStation sprites
vr_sprites = list(
"Handy - Service" = "handy-service",
"Handy - Hydro" = "handy-hydro",
"Acheron" = "mechoid-Service"
"Acheron" = "mechoid-Service",
"Shellguard Noble" = "Noble-SRV"
)
/obj/item/weapon/robot_module/robot/clerical/general //VOREStation sprites
vr_sprites = list(
"Handy" = "handy-clerk",
"Acheron" = "mechoid-Service"
"Acheron" = "mechoid-Service",
"Shellguard Noble" = "Noble-SRV"
)
/obj/item/weapon/robot_module/robot/janitor //VOREStation sprites
vr_sprites = list(
"Handy" = "handy-janitor",
"Acheron" = "mechoid-Janitor"
"Acheron" = "mechoid-Janitor",
"Shellguard Noble" = "Noble-CLN"
)
/obj/item/weapon/robot_module/robot/security/general //VOREStation sprites
vr_sprites = list(
"Handy" = "handy-sec",
"Acheron" = "mechoid-Security"
"Acheron" = "mechoid-Security",
"Shellguard Noble" = "Noble-SEC"
)
/obj/item/weapon/robot_module/robot/miner //VOREStation sprites
vr_sprites = list(
"Handy" = "handy-miner",
"Acheron" = "mechoid-Miner"
"Acheron" = "mechoid-Miner",
"Shellguard Noble" = "Noble-DIG"
)
/obj/item/weapon/robot_module/robot/standard //VOREStation sprites
vr_sprites = list(
"Handy" = "handy-standard",
"Acheron" = "mechoid-Standard"
"Acheron" = "mechoid-Standard",
"Shellguard Noble" = "Noble-STD"
)
/obj/item/weapon/robot_module/robot/engineering/general //VOREStation sprites
vr_sprites = list(
"Acheron" = "mechoid-Engineering"
"Acheron" = "mechoid-Engineering",
"Shellguard Noble" = "Noble-ENG"
)
/obj/item/weapon/robot_module/robot/research //VOREStation sprites
@@ -148,7 +157,7 @@
var/datum/matter_synth/water = new /datum/matter_synth()
water.name = "Water reserves"
water.recharge_rate = 0
water.max_energy = 1000
water.max_energy = 500
water.energy = 0
R.water_res = water
synths += water
@@ -170,6 +179,7 @@
R.dogborg = TRUE
R.wideborg = TRUE
R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill
R.verbs |= /mob/living/silicon/robot/proc/robot_mount
R.verbs |= /mob/living/proc/shred_limb
..()
@@ -208,7 +218,6 @@
src.modules += new /obj/item/weapon/dogborg/jaws/small(src) //In case a patient is being attacked by carp.
src.modules += new /obj/item/device/dogborg/boop_module(src) //Boop the crew.
src.modules += new /obj/item/device/healthanalyzer(src) // See who's hurt specificially.
src.modules += new /obj/item/weapon/reagent_containers/borghypo(src)//So medi-hounds aren't nearly useless
src.modules += new /obj/item/weapon/reagent_containers/syringe(src) //In case the chemist is nice!
src.modules += new /obj/item/weapon/reagent_containers/glass/beaker(src)//For holding the chemicals when the chemist is nice
src.modules += new /obj/item/device/sleevemate(src) //Lets them scan people.
@@ -218,11 +227,15 @@
var/datum/matter_synth/water = new /datum/matter_synth()
water.name = "Water reserves"
water.recharge_rate = 0
water.max_energy = 1000
water.max_energy = 500
water.energy = 0
R.water_res = water
synths += water
var/obj/item/weapon/reagent_containers/borghypo/hound/H = new /obj/item/weapon/reagent_containers/borghypo/hound(src)
H.water = water
src.modules += H
var/obj/item/device/dogborg/tongue/T = new /obj/item/device/dogborg/tongue(src)
T.water = water
src.modules += T
@@ -240,6 +253,7 @@
R.dogborg = TRUE
R.wideborg = TRUE
R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill
R.verbs |= /mob/living/silicon/robot/proc/robot_mount
R.verbs |= /mob/living/proc/shred_limb
..()
@@ -264,7 +278,7 @@
var/datum/matter_synth/water = new /datum/matter_synth()
water.name = "Water reserves"
water.recharge_rate = 0
water.max_energy = 1000
water.max_energy = 500
water.energy = 0
R.water_res = water
synths += water
@@ -286,6 +300,7 @@
R.dogborg = TRUE
R.wideborg = TRUE
R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill
R.verbs |= /mob/living/silicon/robot/proc/robot_mount
R.verbs |= /mob/living/proc/shred_limb
..()
@@ -307,17 +322,17 @@
var/datum/matter_synth/metal = new /datum/matter_synth/metal()
metal.name = "Steel reserves"
metal.recharge_rate = 0
metal.max_energy = 100000
metal.max_energy = 50000
metal.energy = 0
var/datum/matter_synth/glass = new /datum/matter_synth/glass()
glass.name = "Glass reserves"
glass.recharge_rate = 0
glass.max_energy = 100000
glass.max_energy = 50000
glass.energy = 0
var/datum/matter_synth/water = new /datum/matter_synth()
water.name = "Water reserves"
water.recharge_rate = 0
water.max_energy = 1000
water.max_energy = 500
water.energy = 0
R.water_res = water
@@ -366,6 +381,7 @@
R.dogborg = TRUE
R.wideborg = TRUE
R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill
R.verbs |= /mob/living/silicon/robot/proc/robot_mount
R.verbs |= /mob/living/proc/shred_limb
..()
@@ -390,7 +406,7 @@
var/datum/matter_synth/water = new /datum/matter_synth()
water.name = "Water reserves"
water.recharge_rate = 0
water.max_energy = 1000
water.max_energy = 500
water.energy = 0
R.water_res = water
synths += water
@@ -412,6 +428,7 @@
R.dogborg = TRUE
R.wideborg = TRUE
R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill
R.verbs |= /mob/living/silicon/robot/proc/robot_mount
R.verbs |= /mob/living/proc/shred_limb
..()
@@ -435,7 +452,7 @@
src.modules += new /obj/item/device/t_scanner(src)
src.modules += new /obj/item/taperoll/engineering(src)
src.modules += new /obj/item/weapon/inflatable_dispenser/robot(src)
src.modules += new /obj/item/device/geiger(src)
src.modules += new /obj/item/weapon/pickaxe(src)
src.modules += new /obj/item/weapon/dogborg/jaws/small(src)
src.modules += new /obj/item/device/dogborg/boop_module(src)
src.emag = new /obj/item/weapon/dogborg/pounce(src)
@@ -444,27 +461,27 @@
var/datum/matter_synth/metal = new /datum/matter_synth/metal()
metal.name = "Steel reserves"
metal.recharge_rate = 50
metal.max_energy = 100000
metal.max_energy = 50000
metal.energy = 5000
var/datum/matter_synth/glass = new /datum/matter_synth/glass()
glass.name = "Glass reserves"
glass.recharge_rate = 50
glass.max_energy = 100000
glass.max_energy = 50000
glass.energy = 5000
var/datum/matter_synth/wood = new /datum/matter_synth/wood()
wood.name = "Wood reserves"
wood.recharge_rate = 50
wood.max_energy = 100000
wood.max_energy = 50000
wood.energy = 5000
var/datum/matter_synth/plastic = new /datum/matter_synth/plastic()
plastic.name = "Plastic reserves"
plastic.recharge_rate = 50
plastic.max_energy = 100000
plastic.max_energy = 50000
plastic.energy = 5000
var/datum/matter_synth/water = new /datum/matter_synth()
water.name = "Water reserves"
water.recharge_rate = 0
water.max_energy = 1000
water.max_energy = 500
water.energy = 0
R.water_res = water
@@ -489,6 +506,7 @@
MD.glass = glass
MD.wood = wood
MD.plastic = plastic
MD.water = water
src.modules += MD
var/obj/item/stack/material/cyborg/steel/M = new (src)
@@ -536,6 +554,7 @@
R.dogborg = TRUE
R.wideborg = TRUE
R.verbs |= /mob/living/silicon/robot/proc/ex_reserve_refill
R.verbs |= /mob/living/silicon/robot/proc/robot_mount
R.verbs |= /mob/living/proc/shred_limb
..()
@@ -549,5 +568,6 @@
R.default_pixel_x = initial(pixel_x)
R.scrubbing = FALSE
R.verbs -= /mob/living/silicon/robot/proc/ex_reserve_refill
R.verbs -= /mob/living/silicon/robot/proc/robot_mount
R.verbs -= /mob/living/proc/shred_limb
..()
@@ -123,4 +123,114 @@
E.reagents.add_reagent("water", amount)
to_chat(src, "You refill the extinguisher using your water reserves.")
else
to_chat(src, "Insufficient water reserves.")
to_chat(src, "Insufficient water reserves.")
//RIDING
/datum/riding/dogborg
keytype = /obj/item/weapon/material/twohanded/fluff/riding_crop // Crack!
nonhuman_key_exemption = FALSE // If true, nonhumans who can't hold keys don't need them, like borgs and simplemobs.
key_name = "a riding crop" // What the 'keys' for the thing being rided on would be called.
only_one_driver = TRUE // If true, only the person in 'front' (first on list of riding mobs) can drive.
/datum/riding/dogborg/handle_vehicle_layer()
if(ridden.has_buckled_mobs())
if(ridden.dir != NORTH)
ridden.layer = ABOVE_MOB_LAYER
else
ridden.layer = initial(ridden.layer)
else
ridden.layer = initial(ridden.layer)
/datum/riding/dogborg/ride_check(mob/living/M)
var/mob/living/L = ridden
if(L.stat)
force_dismount(M)
return FALSE
return TRUE
/datum/riding/dogborg/force_dismount(mob/M)
. =..()
ridden.visible_message("<span class='notice'>[M] stops riding [ridden]!</span>")
//Hoooo boy.
/datum/riding/dogborg/get_offsets(pass_index) // list(dir = x, y, layer)
var/mob/living/L = ridden
var/scale = L.size_multiplier
var/list/values = list(
"[NORTH]" = list(0, 8*scale, ABOVE_MOB_LAYER),
"[SOUTH]" = list(0, 8*scale, BELOW_MOB_LAYER),
"[EAST]" = list(-5*scale, 8*scale, ABOVE_MOB_LAYER),
"[WEST]" = list(5*scale, 8*scale, ABOVE_MOB_LAYER))
return values
//Human overrides for taur riding
/mob/living/silicon/robot
max_buckled_mobs = 1 //Yeehaw
can_buckle = TRUE
buckle_movable = TRUE
buckle_lying = FALSE
/mob/living/silicon/robot/New()
..()
riding_datum = new /datum/riding/dogborg(src)
/mob/living/silicon/robot/buckle_mob(mob/living/M, forced = FALSE, check_loc = TRUE)
if(forced)
return ..() // Skip our checks
if(!dogborg)
return FALSE
if(lying)
return FALSE
if(!ishuman(M))
return FALSE
if(M in buckled_mobs)
return FALSE
if(M.size_multiplier > size_multiplier * 1.2)
to_chat(src,"<span class='warning'>This isn't a pony show! You need to be bigger for them to ride.</span>")
return FALSE
var/mob/living/carbon/human/H = M
if(isTaurTail(H.tail_style))
to_chat(src,"<span class='warning'>Too many legs. TOO MANY LEGS!!</span>")
return FALSE
if(M.loc != src.loc)
if(M.Adjacent(src))
M.forceMove(get_turf(src))
. = ..()
if(.)
buckled_mobs[M] = "riding"
/mob/living/silicon/robot/MouseDrop_T(mob/living/M, mob/living/user) //Prevention for forced relocation caused by can_buckle. Base proc has no other use.
return
/mob/living/silicon/robot/attack_hand(mob/user as mob)
if(LAZYLEN(buckled_mobs))
//We're getting off!
if(user in buckled_mobs)
riding_datum.force_dismount(user)
//We're kicking everyone off!
if(user == src)
for(var/rider in buckled_mobs)
riding_datum.force_dismount(rider)
else
. = ..()
/mob/living/silicon/robot/proc/robot_mount(var/mob/living/M in living_mobs(1))
set name = "Robot Mount/Dismount"
set category = "Abilities"
set desc = "Let people ride on you."
if(LAZYLEN(buckled_mobs))
for(var/rider in buckled_mobs)
riding_datum.force_dismount(rider)
return
if (stat != CONSCIOUS)
return
if(!can_buckle || !istype(M) || !M.Adjacent(src) || M.buckled)
return
if(buckle_mob(M))
visible_message("<span class='notice'>[M] starts riding [name]!</span>")
@@ -1,7 +1,7 @@
/mob/living/simple_animal/penguin
name = "space penguin"
desc = "An ungainly, waddling, cute, and VERY well-dressed bird."
tt_desc = "Aptenodytes forsteri"
tt_desc = "E Aptenodytes forsteri"
icon_state = "penguin"
icon_living = "penguin"
icon_dead = "penguin_dead"
@@ -796,8 +796,6 @@
var/mob/living/L = target_mob
if(L.stat != DEAD)
return 1
if(L.invisibility < INVISIBILITY_LEVEL_ONE)
return 1
if (istype(target_mob,/obj/mecha))
var/obj/mecha/M = target_mob
if (M.occupant)
@@ -917,7 +915,7 @@
continue
else if(L in friends)
continue
else if(L.invisibility >= INVISIBILITY_LEVEL_ONE)
else if(L.alpha <= EFFECTIVE_INVIS)
continue
else if(!SA_attackable(L))
continue
@@ -1246,7 +1244,7 @@
ai_log("AttackTarget() Bailing because we're disabled",2)
LoseTarget()
return 0
if(!target_mob || !SA_attackable(target_mob) || (target_mob.invisibility >= INVISIBILITY_LEVEL_ONE)) //if the target went invisible, you can't follow it
if(!target_mob || !SA_attackable(target_mob) || (target_mob.alpha <= EFFECTIVE_INVIS)) //if the target went invisible, you can't follow it
LoseTarget()
return 0
if(!(target_mob in ListTargets(view_range)))
@@ -16,12 +16,16 @@
melee_damage_lower = 5
melee_damage_upper = 10
response_help = "pets the"
response_disarm = "gently baps the"
response_harm = "hits the"
speak_chance = 2
speak = list("Meow!","Esp!","Purr!","HSSSSS","Mew?","Nya~")
speak_emote = list("purrs","meows")
emote_hear = list("meows","mews")
emote_see = list("shakes her head","shivers")
attacktext = list("swatted")
emote_see = list("shakes her head","shivers","stretches","grooms herself")
attacktext = list("swatted","bapped")
var/random_skin = 1
var/list/skins = list(
@@ -161,7 +161,7 @@
// TODO - Customizable per mob
B.emote_lists[DM_HOLD] = list(
"The walls gently squeeze against you. The wet sounds of shifting flesh against your form fill the air.",
"The hot, humid air rushes around you for a moment as the creature urps. The walls clench in around you for a moment, before relaxxing again.",
"The hot, humid air rushes around you for a moment as the creature urps. The walls clench in around you for a moment, before relaxing again.",
"Your body is soaked in the fluids that cling to the churning walls. They squeeze across your form gently, conforming to your shape.",
"You can feel the world around you shift and sway as the creature moves! The flesh is stretchy, doughy. You can sink into it a little ways before it bounces back, curling you into a small shape."
)
@@ -200,7 +200,7 @@
. = ..()
if(ability_flags & AB_PHASE_SHIFTED)
density = FALSE
//Convert spare nutrition into energy at a certain ratio
if(. && nutrition > initial(nutrition) && energy < 100)
nutrition = max(0, nutrition-5)
@@ -208,7 +208,7 @@
/mob/living/simple_animal/shadekin/update_icon()
. = ..()
cut_overlay(tailimage)
tailimage.icon_state = icon_state
+4 -3
View File
@@ -482,9 +482,10 @@
if(mind)
mind.active = 0 //we wish to transfer the key manually
if(mind.assigned_role == "Clown") //give them a clownname if they are a clown
new_character.real_name = pick(clown_names) //I hate this being here of all places but unfortunately dna is based on real_name!
new_character.rename_self("clown")
// VOREStation edit to disable the destructive forced renaming for our responsible whitelist clowns.
//if(mind.assigned_role == "Clown") //give them a clownname if they are a clown
// new_character.real_name = pick(clown_names) //I hate this being here of all places but unfortunately dna is based on real_name!
// new_character.rename_self("clown")
mind.original = new_character
// VOREStation
mind.loaded_from_ckey = client.ckey
+1 -1
View File
@@ -185,7 +185,7 @@ var/global/list/limb_icon_cache = list()
var/datum/sprite_accessory/marking/mark_style = markings[M]["datum"]
var/icon/mark_s = new/icon("icon" = mark_style.icon, "icon_state" = "[mark_style.icon_state]-[organ_tag]")
mark_s.Blend(markings[M]["color"], mark_style.color_blend_mode) // VOREStation edit
overlays |= mark_s //So when it's not on your body, it has icons
add_overlay(mark_s) //So when it's not on your body, it has icons
mob_icon.Blend(mark_s, ICON_OVERLAY) //So when it's on your body, it has icons
icon_cache_key += "[M][markings[M]["color"]]"
+2 -5
View File
@@ -309,6 +309,7 @@
t = replacetext(t, "\[/h2\]", "</H2>")
t = replacetext(t, "\[h3\]", "<H3>")
t = replacetext(t, "\[/h3\]", "</H3>")
t = replacetext(t, "\[tab\]", "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;")
if(!iscrayon)
t = replacetext(t, "\[*\]", "<li>")
@@ -630,12 +631,8 @@
/obj/item/weapon/paper/crumpled/bloody/CrashedMedShuttle
name = "Blackbox Transcript - VMV Aurora's Light"
<<<<<<< HEAD
info = "<I>\[The paper is torn at the top, presumably from the impact. It's oil-stained, but you can just about read it.]</I><BR> <B>mmons 19:52:01:</B> Come on... it's right there in the distance, we're almost there!<BR> <B>Doctor Nazarril 19:52:26:</B> Odysseus online. Orrderrs, sirr?<BR> <B>Captain Simmons 19:52:29:</B> Brace for impact. We're going in full-speed.<BR> <B>Technician Dynasty 19:52:44:</B> Chief, fire's spread to the secondary propulsion systems.<BR> <B>Captain Simmons 19:52:51:</B> Copy. Any word from TraCon? Transponder's down still?<BR> <B>Technician Dynasty 19:53:02:</B> Can't get in touch, sir. Emergency beacon's active, but we're not going t-<BR> <B>Doctor Nazarril 19:53:08:</B> Don't say it. As long as we believe, we'll get through this.<BR> <B>Captain Simmons 19:53:11:</B> Damn right. We're a few klicks out from the port. Rough landing, but we can do it.<BR> <B>V.I.T.A 19:53:26:</B> Vessel diagnostics complete. Engines one, two, three offline. Engine four status: critical. Transponder offline. Fire alarm in the patient bay.<BR> <B>A loud explosion is heard.</B><BR> <B>V.I.T.A 19:53:29:</B> Alert: fuel intake valve open.<BR> <B>Technician Dynasty 19:53:31:</B> ... ah.<BR> <B>Doctor Nazarril 19:53:34:</B> Trrranslate?<BR> <B>V.I.T.A 19:53:37:</B> There is a 16.92% chance of this vessel safely landing at the emergency destination. Note that there is an 83.08% chance of detonation of fuel supplies upon landing.<BR> <B>Technician Dynasty 19:53:48:</B> We'll make it, sure, but we'll explode and take out half the LZ with us. Propulsion's down, we can't slow down. If we land there, everyone in that port dies, no question.<BR> <B>V.I.T.A 19:53:53:</B> The Technician is correct.<BR> <B>Doctor Nazarril 19:54:02:</B> Then... we can't land therrre.<BR> <B>V.I.T.A 19:54:11:</B> Analysing... recommended course of action: attempt emergency landing in isolated area. Chances of survival: negligible. <BR> <B>Captain Simmons 19:54:27:</B> I- alright. I'm bringing us down. You all know what this means.<BR> <B>Doctor Nazarril 19:54:33:</B> Sh... I- I understand. It's been- it's been an honorr, Captain, Dynasty, VITA.<BR> <B>Technician Dynasty 19:54:39:</B> We had a good run. I'm going to miss this.<BR> <B>Captain Simmons 19:54:47:</B> VITA. Tell them we died heroes. Tell them... we did all we could.<BR> <B>V.I.T.A 19:54:48:</B> I will. Impact in five. Four. Three.<BR> <B>Doctor Nazarril 19:54:49:</B> Oh, starrs... I- you werrre all the... best frriends she everr had. Thank you.<BR> <B>Technician Dynasty 19:54:50:</B> Any time, kid. Any time.<BR> <B>V.I.T.A 19:54:41:</B> Two.<BR><B>V.I.T.A 19:54:42:</B> One.<BR> **8/DEC/2561**<BR> <B>V.I.T.A 06:22:16:</B> Backup power restored. Attempting to establish connection with emergency rescue personnel.<BR> <B>V.I.T.A 06:22:17:</B> Unable to establish connection. Transponder destroyed on impact.<BR> <B>V.I.T.A 06:22:18:</B> No lifesigns detected on board.<BR> **1/JAN/2562**<BR> <B>V.I.T.A 00:00:00:</B> Happy New Year, crew.<BR> <B>V.I.T.A 00:00:01:</B> Power reserves: 41%. Diagnostics offline. Cameras offline. Communications offline.<BR> <B>V.I.T.A 00:00:02:</B> Nobody's coming.<BR> **14/FEB/2562**<BR> <B>V.I.T.A 00:00:00:</B> Roses are red.<BR> <B>V.I.T.A 00:00:01:</B> Violets are blue.<BR> <B>V.I.T.A 00:00:02:</B> Won't you come back?<BR> <B>V.I.T.A 00:00:03:</B> I miss you.<BR> **15/FEB/2562**<BR><B>V.I.T.A 22:19:06:</B> Power reserves critical. Transferring remaining power to emergency broadcasting beacon.<BR> <B>V.I.T.A 22:19:07:</B> Should anyone find this, lay them to rest. They deserve a proper burial.<BR> <B>V.I.T.A 22:19:08:</B> Erasing files... shutting down.<BR> <B>A low, monotone beep.</B><BR> **16/FEB/2562**<BR> <B>Something chitters.</B><BR> <B>End of transcript.</B>"
=======
info = "<I>\[The paper is torn at the top, presumably from the impact. It's oil-stained, but you can just about read it.]</I><BR> <B>mmons 19:52:01:</B> Come on... it's right there in the distance, we're almost there!<BR> <B>Doctor Nazarril 19:52:26:</B> Odysseus online. Orrderrs, sirr?<BR> <B>Captain Simmons 19:52:29:</B> Brace for impact. We're going in full-speed.<BR> <B>Technician Dynasty 19:52:44:</B> Chief, fire's spread to the secondary propulsion systems.<BR> <B>Captain Simmons 19:52:51:</B> Copy. Any word from TraCon? Transponder's down still?<BR> <B>Technician Dynasty 19:53:02:</B> Can't get in touch, sir. Emergency beacon's active, but we're not going t-<BR> <B>Doctor Nazarril 19:53:08:</B> Don't say it. As long as we believe, we'll get through this.<BR> <B>Captain Simmons 19:53:11:</B> Damn right. We're a few klicks out from the port. Rough landing, but we can do it.<BR> <B>V.I.T.A 19:53:26:</B> Vessel diagnostics complete. Engines one, two, three offline. Engine four status: critical. Transponder offline. Fire alarm in the patient bay.<BR> <B>A loud explosion is heard.</B><BR> <B>V.I.T.A 19:53:29:</B> Alert: fuel intake valve open.<BR> <B>Technician Dynasty 19:53:31:</B> ... ah.<BR> <B>Doctor Nazarril 19:53:34:</B> Trrranslate?<BR> <B>V.I.T.A 19:53:37:</B> There is a 16.92% chance of this vessel safely landing at the emergency destination. Note that there is an 83.08% chance of detonation of fuel supplies upon landing.<BR> <B>Technician Dynasty 19:53:48:</B> We'll make it, sure, but we'll explode and take out half the LZ with us. Propulsion's down, we can't slow down. If we land there, everyone in that port dies, no question.<BR> <B>V.I.T.A 19:53:53:</B> The Technician is correct.<BR> <B>Doctor Nazarril 19:54:02:</B> Then... we can't land therrre.<BR> <B>V.I.T.A 19:54:11:</B> Analysing... recommended course of action: attempt emergency landing in isolated area. Chances of survival: negligible. <BR> <B>Captain Simmons 19:54:27:</B> I- alright. I'm bringing us down. You all know what this means.<BR> <B>Doctor Nazarril 19:54:33:</B> Sh... I- I understand. It's been- it's been an honorr, Captain, Dynasty, VITA.<BR> <B>Technician Dynasty 19:54:39:</B> We had a good run. I'm going to miss this.<BR> <B>Captain Simmons 19:54:47:</B> VITA. Tell them we died heroes. Tell them... we did all we could.<BR> <B>V.I.T.A 19:54:48:</B> I will. Impact in five. Four. Three.<BR> <B>Doctor Nazarril 19:54:49:</B> Oh, starrs... I- you werrre all the... best frriends she everr had. Thank you.<BR> <B>Technician Dynasty 19:54:50:</B> Any time, kid. Any time.<BR> <B>V.I.T.A 19:54:41:</B> Two.<BR><B>V.I.T.A 19:54:42:</B> One.<BR> **8/DEC/2561**<BR> <B>V.I.T.A 06:22:16:</B> Backup power restored. Attempting to establish connection with emergency rescue personnel.<BR> <B>V.I.T.A 06:22:17:</B> Unable to establish connection. Transponder destroyed on impact.<BR> <B>V.I.T.A 06:22:18:</B> No lifesigns detected on board.<BR> **1/JAN/2562**<BR> <B>V.I.T.A 00:00:00:</B> Happy New Year, crew.<BR> <B>V.I.T.A 00:00:01:</B> Power reserves: 41%. Diagnostics offline. Cameras offline. Communications offline.<BR> <B>V.I.T.A 00:00:02:</B> Nobody's coming.<BR> **14/FEB/2562**<BR> <B>V.I.T.A 00:00:00:</B> Roses are red.<BR> <B>V.I.T.A 00:00:01:</B> Violets are blue.<BR> <B>V.I.T.A 00:00:02:</B> Won't you come back?<BR> <B>V.I.T.A 00:00:03:</B> I miss you.<BR> **15/FEB/2562**<BR><B>V.I.T.A 22:19:06:</B> Power reserves critical. Transferring remaining power to emergency broadcasting beacon.<BR> <B>V.I.T.A 22:19:07:</B> Should anyone find this, lay them to rest. They deserve a proper burial.<BR> <B>V.I.T.A 22:19:08:</B> Erasing files... shutting down.<BR> <B>A low, monotone beep.</B><BR> **16/FEB/2562**<BR> <B>Something chitters.</B><BR> <B>End of transcript.</B>"
/obj/item/weapon/paper/manifest
name = "supply manifest"
var/is_copy = 1
>>>>>>> 5ef98ad... Merge pull request #5432 from Atermonera/reorganize_supplycontroller
var/is_copy = 1
@@ -263,6 +263,34 @@ GLOBAL_LIST_BOILERPLATE(all_engine_setup_markers, /obj/effect/engine_setup)
F.update_icon()
return SETUP_OK
// Closes the monitoring room shutters so the first Engi to show up doesn't get microwaved
/obj/effect/engine_setup/shutters/
name = "Shutter Button Marker"
var/target_button = "Engine Monitoring Room Blast Doors" // This needs to be set to whatever the shutter button is called
/obj/effect/engine_setup/shutters/activate()
if(!target_button)
log_and_message_admins("## WARNING: No button type set at [x] [y] [z]!")
return SETUP_WARNING
var/obj/machinery/button/remote/blast_door/found = null
var/turf/T = get_turf(src)
for(var/obj/machinery/button/remote/blast_door/B in T.contents)
if(B.name == target_button)
found = B
break
if(!found)
log_and_message_admins("## WARNING: Unable to locate button at [x] [y] [z]!")
return SETUP_WARNING
found.trigger()
found.update_icon()
return SETUP_OK
#undef SETUP_OK
#undef SETUP_WARNING
@@ -4,6 +4,7 @@
name = "phase carbine"
desc = "The NT EW26 Artemis is a downsized energy weapon, specifically designed for use against wildlife."
icon_state = "phasecarbine"
item_state = "phasecarbine"
wielded_item_state = "phasecarbine-wielded"
slot_flags = SLOT_BACK|SLOT_BELT
charge_cost = 240
@@ -6,7 +6,7 @@
anchored = 1
density = 0
opacity = 0
layer = FLY_LAYER
plane = ABOVE_PLANE
simulated = 0
mouse_opacity = 0
@@ -65,7 +65,7 @@
reagent_state = LIQUID
color = "#404030"
ingest_met = REM
ingest_met = REM * 2
var/nutriment_factor = 0
var/strength = 10 // This is, essentially, units between stages - the lower, the stronger. Less fine tuning, more clarity.
@@ -32,8 +32,8 @@
var/list/values = list(
"[NORTH]" = list(0, 8*scale, ABOVE_MOB_LAYER),
"[SOUTH]" = list(0, 8*scale, BELOW_MOB_LAYER),
"[EAST]" = list(-10*scale, 8*scale, BELOW_MOB_LAYER),
"[WEST]" = list(10*scale, 8*scale, BELOW_MOB_LAYER))
"[EAST]" = list(-10*scale, 8*scale, ABOVE_MOB_LAYER),
"[WEST]" = list(10*scale, 8*scale, ABOVE_MOB_LAYER))
return values
@@ -44,10 +44,6 @@
buckle_movable = TRUE
buckle_lying = FALSE
/mob/living/carbon/human/New()
..()
riding_datum = new /datum/riding/taur(src)
/mob/living/carbon/human/buckle_mob(mob/living/M, forced = FALSE, check_loc = TRUE)
if(forced)
return ..() // Skip our checks
@@ -61,25 +57,44 @@
return FALSE
if(!ishuman(M))
return FALSE
if(M.size_multiplier > size_multiplier)
to_chat(M,"<span class='warning'>This isn't a pony show! They need to be bigger to ride.</span>")
if(M in buckled_mobs)
return FALSE
if(M.size_multiplier > size_multiplier * 1.2)
to_chat(M,"<span class='warning'>This isn't a pony show! You need to be bigger for them to ride.</span>")
return FALSE
if(M.loc != src.loc)
if(M.Adjacent(src))
M.forceMove(get_turf(src))
var/mob/living/carbon/human/H = M
if(isTaurTail(H.tail_style))
to_chat(H,"<span class='warning'>Too many legs. TOO MANY LEGS!!</span>")
to_chat(src,"<span class='warning'>Too many legs. TOO MANY LEGS!!</span>")
return FALSE
. = ..()
if(.)
buckled_mobs[M] = "riding"
/mob/living/carbon/human/MouseDrop_T(mob/living/M, mob/living/user)
if(can_buckle && istype(M))
if(user_buckle_mob(M, user, silent = TRUE))
visible_message("<span class='notice'>[M] starts riding [name]!</span>")
return TRUE
/mob/living/carbon/human/MouseDrop_T(mob/living/M, mob/living/user) //Prevention for forced relocation caused by can_buckle. Base proc has no other use.
return
/mob/living/carbon/human/proc/taur_mount(var/mob/living/M in living_mobs(1))
set name = "Taur Mount/Dismount"
set category = "Abilities"
set desc = "Let people ride on you."
if(LAZYLEN(buckled_mobs))
var/datum/riding/R = riding_datum
for(var/rider in buckled_mobs)
R.force_dismount(rider)
return
if (stat != CONSCIOUS)
return
if(!can_buckle || !istype(M) || !M.Adjacent(src) || M.buckled)
return
if(buckle_mob(M))
visible_message("<span class='notice'>[M] starts riding [name]!</span>")
/mob/living/carbon/human/attack_hand(mob/user as mob)
if(LAZYLEN(buckled_mobs))
@@ -40,6 +40,10 @@ var/global/list/wing_icon_cache = list()
qdel(overlay)
if(isTaurTail(tail_style))
var/datum/sprite_accessory/tail/taur/taurtype = tail_style
if(taurtype.can_ride && !riding_datum)
riding_datum = new /datum/riding/taur(src)
verbs |= /mob/living/carbon/human/proc/taur_mount
return image(tail_s, "pixel_x" = -16)
else
return image(tail_s)
+9 -9
View File
@@ -19,23 +19,23 @@
/////////////
// Some indigestible stuff
/////////////
/obj/item/weapon/hand_tele/digest_act(...)
/obj/item/weapon/hand_tele/digest_act(var/atom/movable/item_storage = null)
return FALSE
/obj/item/weapon/card/id/gold/captain/spare/digest_act(...)
/obj/item/weapon/card/id/gold/captain/spare/digest_act(var/atom/movable/item_storage = null)
return FALSE
/obj/item/device/aicard/digest_act(...)
/obj/item/device/aicard/digest_act(var/atom/movable/item_storage = null)
return FALSE
/obj/item/device/paicard/digest_act(...)
/obj/item/device/paicard/digest_act(var/atom/movable/item_storage = null)
return FALSE
/obj/item/weapon/gun/digest_act(...)
/obj/item/weapon/gun/digest_act(var/atom/movable/item_storage = null)
return FALSE
/obj/item/weapon/pinpointer/digest_act(...)
/obj/item/weapon/pinpointer/digest_act(var/atom/movable/item_storage = null)
return FALSE
/obj/item/blueprints/digest_act(...)
/obj/item/blueprints/digest_act(var/atom/movable/item_storage = null)
return FALSE
/obj/item/weapon/disk/nuclear/digest_act(...)
/obj/item/weapon/disk/nuclear/digest_act(var/atom/movable/item_storage = null)
return FALSE
/obj/item/device/perfect_tele_beacon/digest_act(...)
/obj/item/device/perfect_tele_beacon/digest_act(var/atom/movable/item_storage = null)
return FALSE //Sorta important to not digest your own beacons.
/////////////
+2 -2
View File
@@ -22,7 +22,7 @@
var/fuzzy = 1 // Preference toggle for sharp/fuzzy icon.
var/tail_alt = 0 // Tail layer toggle.
var/can_be_drop_prey = 0
var/can_be_drop_pred = 1 //Mobs are pred by default.
var/can_be_drop_pred = 1 // Mobs are pred by default.
//
// Hook for generic creation of stuff on new creatures
@@ -406,7 +406,7 @@
// Prepare messages
if(user == pred) //Feeding someone to yourself
attempt_msg = text("<span class='warning'>[] is attemping to [] [] into their []!</span>",pred,lowertext(belly.vore_verb),prey,lowertext(belly.name))
attempt_msg = text("<span class='warning'>[] is attempting to [] [] into their []!</span>",pred,lowertext(belly.vore_verb),prey,lowertext(belly.name))
success_msg = text("<span class='warning'>[] manages to [] [] into their []!</span>",pred,lowertext(belly.vore_verb),prey,lowertext(belly.name))
else //Feeding someone to another person
attempt_msg = text("<span class='warning'>[] is attempting to make [] [] [] into their []!</span>",user,pred,lowertext(belly.vore_verb),prey,lowertext(belly.name))
@@ -995,70 +995,6 @@
rimplant.reagents.remove_any(rimplant.transfer_amount)
/obj/item/weapon/implant/reagent_generator/pumila_apple
name = "apple laying implant"
desc = "This is an implant that allows the user to grow apples."
generated_reagents = list("sugar" = 2) //This actually allows them to.
usable_volume = 250 //Five apples. Let's not get /too/ crazy here.
transfer_amount = 50
empty_message = list("Your have no apples on you.", "You have a distinct lack of apples..")
full_message = list("You have multiple apples on you, ready for harvest!", "There are a multitude of apples awaiting harvest on you!")
emote_descriptor = list("an apple right off of Pumila!", "a large apple off Pumila!")
var/verb_descriptor = list("grabs", "snatches", "picks")
var/self_verb_descriptor = list("grab", "snatch", "pick")
var/short_emote_descriptor = list("picks", "grabs")
self_emote_descriptor = list("grab", "pick", "snatch")
assigned_proc = /mob/living/carbon/human/proc/use_reagent_implant_pumila_apple
/obj/item/weapon/implant/reagent_generator/pumila_apple/post_implant(mob/living/carbon/source)
processing_objects += src
to_chat(source, "<span class='notice'>You implant [source] with \the [src].</span>")
source.verbs |= assigned_proc
return 1
/obj/item/weapon/implanter/reagent_generator/pumila_apple
implant_type = /obj/item/weapon/implant/reagent_generator/pumila_apple
/mob/living/carbon/human/proc/use_reagent_implant_pumila_apple()
set name = "Grab Apple"
set desc = "Grab an apple off of Pumila."
set category = "Object"
set src in view(1)
//do_reagent_implant(usr)
if(!isliving(usr) || !usr.canClick())
return
if(usr.incapacitated() || usr.stat > CONSCIOUS)
return
var/obj/item/weapon/implant/reagent_generator/roiz/rimplant
for(var/I in contents)
if(istype(I, /obj/item/weapon/implant/reagent_generator))
rimplant = I
break
if (rimplant)
if(rimplant.reagents.total_volume < rimplant.transfer_amount)
to_chat(src, "<span class='notice'>[pick(rimplant.empty_message)]</span>")
return
var/datum/seed/S = plant_controller.seeds["apple"] //crosses fingers.
S.harvest(usr,0,0,1)
var/index = rand(0,2)
if (usr != src)
var/emote = rimplant.emote_descriptor[index]
var/verb_desc = rimplant.verb_descriptor[index]
var/self_verb_desc = rimplant.self_verb_descriptor[index]
usr.visible_message("<span class='notice'>[usr] [verb_desc] [emote]</span>",
"<span class='notice'>You [self_verb_desc] [emote]</span>")
else
visible_message("<span class='notice'>[src] [pick(rimplant.short_emote_descriptor)] an apple.</span>",
"<span class='notice'>You [pick(rimplant.self_emote_descriptor)] an apple.</span>")
rimplant.reagents.remove_any(rimplant.transfer_amount)
/*
/obj/item/weapon/implant/reagent_generator/pumila_nectar //Bugged. Two implants at once messes things up.
generated_reagents = list("honey" = 2)
@@ -1998,7 +1934,7 @@
KA.desc = initial(KA.desc)
KA.icon = initial(KA.icon)
..()
//ArgobargSoup:Lynn Shady
/obj/item/device/flashlight/pen/fluff/lynn
name = "Lynn's penlight"
@@ -2006,3 +1942,9 @@
icon = 'icons/vore/custom_items_vr.dmi'
icon_state = "penlightlynn"
//Knightfall5:Ashley Kifer
/obj/item/clothing/accessory/medal/nobel_science/fluff/ashley
name = "nobel sciences award"
desc = "A bronze medal which represents significant contributions to the field of science or engineering, this one has Ashley Kifer engraved on it."
@@ -4,6 +4,7 @@
icon = 'icons/obj/clothing/spacesuits.dmi'
icon_state = "engspace_suit"
item_state = "engspace_suit"
update_icon_define = "icons/mob/spacesuit.dmi"
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 100, rad = 100)
/obj/item/clothing/head/bio_hood/anomaly