Merge branch 'master' into upstream-merge-5335

This commit is contained in:
Aronai Sieyes
2018-06-16 17:43:55 -04:00
committed by GitHub
70 changed files with 1834 additions and 471 deletions
+3 -1
View File
@@ -659,11 +659,13 @@ var/list/admin_verbs_event_manager = list(
set desc = "Cause an explosion of varying strength at your location."
var/turf/epicenter = mob.loc
var/list/choices = list("Small Bomb", "Medium Bomb", "Big Bomb", "Custom Bomb")
var/list/choices = list("Small Bomb", "Medium Bomb", "Big Bomb", "Custom Bomb", "Cancel")
var/choice = input("What size explosion would you like to produce?") in choices
switch(choice)
if(null)
return 0
if("Cancel")
return 0
if("Small Bomb")
explosion(epicenter, 1, 2, 3, 3)
if("Medium Bomb")
+2 -2
View File
@@ -637,7 +637,7 @@
if(!check_rights(R_DEBUG))
return
var/datum/planet/planet = input(usr, "Which planet do you want to modify the weather on?", "Change Weather") in planet_controller.planets
var/datum/planet/planet = input(usr, "Which planet do you want to modify the weather on?", "Change Weather") in SSplanets.planets
var/datum/weather/new_weather = input(usr, "What weather do you want to change to?", "Change Weather") as null|anything in planet.weather_holder.allowed_weather_types
if(new_weather)
planet.weather_holder.change_weather(new_weather)
@@ -653,7 +653,7 @@
if(!check_rights(R_DEBUG))
return
var/datum/planet/planet = input(usr, "Which planet do you want to modify time on?", "Change Time") in planet_controller.planets
var/datum/planet/planet = input(usr, "Which planet do you want to modify time on?", "Change Time") in SSplanets.planets
var/datum/time/current_time_datum = planet.current_time
var/new_hour = input(usr, "What hour do you want to change to?", "Change Time", text2num(current_time_datum.show_time("hh"))) as null|num
@@ -0,0 +1,7 @@
//Minimum limit is 18
/datum/category_item/player_setup_item/get_min_age()
var/min_age = 18
var/datum/species/S = all_species[pref.species ? pref.species : "Human"]
if(!is_FBP() && S.min_age > 18)
min_age = S.min_age
return min_age
-11
View File
@@ -51,17 +51,6 @@
kill()
return
/** Checks if any living humans are in a given area! */
/datum/event/atmos_leak/proc/is_area_occupied(var/area/myarea)
// Testing suggests looping over human_mob_list is quicker than looping over area contents
for(var/mob/living/carbon/human/H in human_mob_list)
if(H.stat >= DEAD) //Conditions for exclusion here, like if disconnected people start blocking it.
continue
var/area/A = get_area(H)
if(A == myarea) //The loc of a turf is the area it is in.
return 1
return 0
/datum/event/atmos_leak/announce()
command_announcement.Announce("Warning, hazardous [gas_data.name[gas_type]] gas leak detected in \the [target_area], evacuate the area and contain the damage!", "Hazard Alert")
+1 -1
View File
@@ -33,7 +33,7 @@
/datum/event/escaped_slimes/start()
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines)
if(temp_vent.network && temp_vent.loc.z in using_map.station_levels) //borrowed from spiders event, but it works. Distribute the slimes only in rooms with vents
if(temp_vent.network && temp_vent.loc.z in using_map.station_levels && !is_area_occupied(temp_vent.loc.loc)) //borrowed from spiders event, but it works. Distribute the slimes only in rooms with vents
vents += temp_vent
while((spawncount > 0) && vents.len)
+2 -3
View File
@@ -6,9 +6,8 @@
endWhen = rand(15, 60)
// Setup which levels we will disrupt gravit on.
zLevels = using_map.station_levels.Copy()
if (planet_controller)
for(var/datum/planet/P in planet_controller.planets)
zLevels -= P.expected_z_levels
for(var/datum/planet/P in SSplanets.planets)
zLevels -= P.expected_z_levels
/datum/event/gravity/announce()
command_announcement.Announce("Feedback surge detected in mass-distributions systems. Artificial gravity has been disabled whilst the system \
+1 -1
View File
@@ -50,7 +50,7 @@
new /obj/structure/meteorite(current)
var/datum/planet/impacted
for(var/datum/planet/P in planet_controller.planets)
for(var/datum/planet/P in SSplanets.planets)
if(current.z in P.expected_z_levels)
impacted = P
break
@@ -25,3 +25,7 @@
/mob/living/carbon/human/protean/New(var/new_loc)
..(new_loc, "Protean")
/mob/living/carbon/human/alraune/New(var/new_loc)
..(new_loc, "Alraune")
@@ -0,0 +1,336 @@
/datum/species/alraune
name = SPECIES_ALRAUNE
name_plural = "Alraunes"
unarmed_types = list(/datum/unarmed_attack/stomp, /datum/unarmed_attack/kick, /datum/unarmed_attack/punch, /datum/unarmed_attack/bite)
num_alternate_languages = 2
language = LANGUAGE_ROOTLOCAL
slowdown = 1 //slow, they're plants. Not as slow as full diona.
total_health = 100 //standard
brute_mod = 1 //nothing special
burn_mod = 1.5 //plants don't like fire
metabolic_rate = 0.75 // slow metabolism
item_slowdown_mod = 0.25 //while they start slow, they don't get much slower
bloodloss_rate = 0.1 //While they do bleed, they bleed out VERY slowly
min_age = 18
max_age = 250
health_hud_intensity = 1.5
body_temperature = T20C
breath_type = "carbon_dioxide"
poison_type = "phoron"
exhale_type = "oxygen"
// Heat and cold resistances are 20 degrees broader on the level 1 range, level 2 is default, level 3 is much weaker, halfway between L2 and normal L3.
// Essentially, they can tolerate a broader range of comfortable temperatures, but suffer more at extremes.
cold_level_1 = 240 //Default 260 - Lower is better
cold_level_2 = 200 //Default 200
cold_level_3 = 160 //Default 120
cold_discomfort_level = 260 //they start feeling uncomfortable around the point where humans take damage
heat_level_1 = 380 //Default 360 - Higher is better
heat_level_2 = 400 //Default 400
heat_level_3 = 700 //Default 1000
heat_discomfort_level = 360
breath_cold_level_1 = 240 //They don't have lungs, they breathe through their skin
breath_cold_level_2 = 180 //sadly for them, their breath tolerance is no better than anyone else's.
breath_cold_level_3 = 140 //mainly 'cause breath tolerance is more generous than body temp tolerance.
breath_heat_level_1 = 400 //slightly better heat tolerance in air though. Slightly.
breath_heat_level_2 = 450
breath_heat_level_3 = 800 //lower incineration threshold though
spawn_flags = SPECIES_CAN_JOIN | SPECIES_IS_WHITELISTED // whitelist only while WIP
flags = NO_SCAN | IS_PLANT | NO_MINOR_CUT
appearance_flags = HAS_HAIR_COLOR | HAS_LIPS | HAS_UNDERWEAR | HAS_SKIN_COLOR | HAS_EYE_COLOR
inherent_verbs = list(
/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
color_mult = 1
icobase = 'icons/mob/human_races/r_human_vr.dmi'
deform = 'icons/mob/human_races/r_def_human_vr.dmi'
flesh_color = "#9ee02c"
blood_color = "#edf4d0" //sap!
base_color = "#1a5600"
blurb = "Alraunes are a rare sight in space. Their bodies are reminiscent of that of plants, and yet they share many\
traits with other humanoid beings.\
\
Most Alraunes are not interested in traversing space, their heavy preference for natural environments and general\
disinterest in things outside it keeps them as a species at a rather primal stage.\
\
However, after their discovery by the angels of Sanctum, many alraunes succumbed to their curiosity, and took the offer\
to learn of the world and venture out, whether it's to Sanctum, or elsewhere in the galaxy."
has_limbs = list(
BP_TORSO = list("path" = /obj/item/organ/external/chest),
BP_GROIN = list("path" = /obj/item/organ/external/groin),
BP_HEAD = list("path" = /obj/item/organ/external/head),
BP_L_ARM = list("path" = /obj/item/organ/external/arm),
BP_R_ARM = list("path" = /obj/item/organ/external/arm/right),
BP_L_LEG = list("path" = /obj/item/organ/external/leg),
BP_R_LEG = list("path" = /obj/item/organ/external/leg/right),
BP_L_HAND = list("path" = /obj/item/organ/external/hand),
BP_R_HAND = list("path" = /obj/item/organ/external/hand/right),
BP_L_FOOT = list("path" = /obj/item/organ/external/foot),
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right)
)
// limited organs, 'cause they're simple
has_organ = list(
O_LIVER = /obj/item/organ/internal/liver/alraune,
O_KIDNEYS = /obj/item/organ/internal/kidneys/alraune,
O_BRAIN = /obj/item/organ/internal/brain/alraune,
O_EYES = /obj/item/organ/internal/eyes/alraune,
)
/datum/species/alraune/can_breathe_water()
return TRUE //eh, why not? Aquatic plants are a thing.
/datum/species/alraune/handle_environment_special(var/mob/living/carbon/human/H)
if(H.inStasisNow()) // if they're in stasis, they won't need this stuff.
return
//setting these here 'cause ugh the defines for life are in the wrong place to compile properly
//set them back to HUMAN_MAX_OXYLOSS if we move the life defines to the defines folder at any point
var/ALRAUNE_MAX_OXYLOSS = 1 //Defines how much oxyloss humans can get per tick. A tile with no air at all (such as space) applies this value, otherwise it's a percentage of it.
var/ALRAUNE_CRIT_MAX_OXYLOSS = ( 2.0 / 6) //The amount of damage you'll get when in critical condition. We want this to be a 5 minute deal = 300s. There are 50HP to get through, so (1/6)*last_tick_duration per second. Breaths however only happen every 4 ticks. last_tick_duration = ~2.0 on average
//They don't have lungs so breathe() will just return. Instead, they breathe through their skin.
//This is mostly normal breath code with some tweaks that apply to their particular biology.
var/datum/gas_mixture/breath = null
var/fullysealed = FALSE //if they're wearing a fully sealed suit, their internals take priority.
var/environmentalair = FALSE //if no sealed suit, internals take priority in low pressure environements
if(H.wear_suit && (H.wear_suit.item_flags & STOPPRESSUREDAMAGE) && H.head && (H.head.item_flags & STOPPRESSUREDAMAGE))
fullysealed = TRUE
else // find out if local gas mixture is enough to override use of internals
var/datum/gas_mixture/environment = H.loc.return_air()
var/envpressure = environment.return_pressure()
if(envpressure >= hazard_low_pressure)
environmentalair = TRUE
if(fullysealed || !environmentalair)
breath = H.get_breath_from_internal()
if(!breath) //No breath from internals so let's try to get air from our location
// cut-down version of get_breath_from_environment - notably, gas masks provide no benefit
var/datum/gas_mixture/environment2
if(H.loc)
environment2 = H.loc.return_air_for_internal_lifeform(H)
if(environment2)
breath = environment2.remove_volume(BREATH_VOLUME)
H.handle_chemical_smoke(environment2) //handle chemical smoke while we're at it
// NOW a crude copypasta of handle_breath. Leaving some things out that don't apply to plants.
if(H.does_not_breathe)
H.failed_last_breath = 0
H.adjustOxyLoss(-5)
return // if somehow they don't breathe, abort breathing.
if(!breath || (breath.total_moles == 0))
H.failed_last_breath = 1
if(H.health > config.health_threshold_crit)
H.adjustOxyLoss(ALRAUNE_MAX_OXYLOSS)
else
H.adjustOxyLoss(ALRAUNE_CRIT_MAX_OXYLOSS)
H.oxygen_alert = max(H.oxygen_alert, 1)
return // skip air processing if there's no air
// now into the good stuff
//var/safe_pressure_min = species.minimum_breath_pressure // Minimum safe partial pressure of breathable gas in kPa
//just replace safe_pressure_min with minimum_breath_pressure, no need to declare a new var
var/safe_exhaled_max = 10
var/safe_toxins_max = 0.2
var/SA_para_min = 1
var/SA_sleep_min = 5
var/inhaled_gas_used = 0
var/breath_pressure = (breath.total_moles*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
var/inhaling
var/poison
var/exhaling
var/failed_inhale = 0
var/failed_exhale = 0
inhaling = breath.gas[breath_type]
poison = breath.gas[poison_type]
exhaling = breath.gas[exhale_type]
var/inhale_pp = (inhaling/breath.total_moles)*breath_pressure
var/toxins_pp = (poison/breath.total_moles)*breath_pressure
var/exhaled_pp = (exhaling/breath.total_moles)*breath_pressure
// Not enough to breathe
if((inhale_pp + exhaled_pp) < minimum_breath_pressure) //they can breathe either oxygen OR CO2
if(prob(20))
spawn(0) H.emote("gasp")
var/ratio = (inhale_pp + exhaled_pp)/minimum_breath_pressure
// Don't fuck them up too fast (space only does HUMAN_MAX_OXYLOSS (1) after all!)
H.adjustOxyLoss(max(ALRAUNE_MAX_OXYLOSS*(1-ratio), 0))
failed_inhale = 1
H.oxygen_alert = max(H.oxygen_alert, 1)
else
// We're in safe limits
H.oxygen_alert = 0
inhaled_gas_used = inhaling/6
breath.adjust_gas(breath_type, -inhaled_gas_used, update = 0) //update afterwards
breath.adjust_gas_temp(exhale_type, inhaled_gas_used, H.bodytemperature, update = 0) //update afterwards
//Now we handle CO2.
if(inhale_pp > safe_exhaled_max * 0.7) // For a human, this would be too much exhaled gas in the air. But plants don't care.
H.co2_alert = 1 // Give them the alert on the HUD. They'll be aware when the good stuff is present.
else
H.co2_alert = 0
//do the CO2 buff stuff here
var/co2buff = 0
if(inhaling)
co2buff = (Clamp(inhale_pp, 0, minimum_breath_pressure))/minimum_breath_pressure //returns a value between 0 and 1.
var/light_amount = fullysealed ? H.getlightlevel() : H.getlightlevel()/5 // if they're covered, they're not going to get much light on them.
if(co2buff && !H.toxloss && light_amount >= 0.1) //if there's enough light and CO2 and you're not poisoned, heal. Note if you're wearing a sealed suit your heal rate will suck.
H.adjustBruteLoss(-(light_amount * co2buff * 2)) //at a full partial pressure of CO2 and full light, you'll only heal half as fast as diona.
H.adjustFireLoss(-(light_amount * co2buff)) //this won't let you tank environmental damage from fire. MAYBE cold until your body temp drops.
if(H.nutrition < (200 + 400*co2buff)) //if no CO2, a fully lit tile gives them 1/tick up to 200. With CO2, potentially up to 600.
H.nutrition += (light_amount*(1+co2buff*5))
// Too much poison in the air.
if(toxins_pp > safe_toxins_max)
var/ratio = (poison/safe_toxins_max) * 10
if(H.reagents)
H.reagents.add_reagent("toxin", Clamp(ratio, MIN_TOXIN_DAMAGE, MAX_TOXIN_DAMAGE))
breath.adjust_gas(poison_type, -poison/6, update = 0) //update after
H.phoron_alert = max(H.phoron_alert, 1)
else
H.phoron_alert = 0
// If there's some other shit in the air lets deal with it here.
if(breath.gas["sleeping_agent"])
var/SA_pp = (breath.gas["sleeping_agent"] / breath.total_moles) * breath_pressure
// Enough to make us paralysed for a bit
if(SA_pp > SA_para_min)
// 3 gives them one second to wake up and run away a bit!
H.Paralyse(3)
// Enough to make us sleep as well
if(SA_pp > SA_sleep_min)
H.Sleeping(5)
// There is sleeping gas in their lungs, but only a little, so give them a bit of a warning
else if(SA_pp > 0.15)
if(prob(20))
spawn(0) H.emote(pick("giggle", "laugh"))
breath.adjust_gas("sleeping_agent", -breath.gas["sleeping_agent"]/6, update = 0) //update after
// Were we able to breathe?
if (failed_inhale || failed_exhale)
H.failed_last_breath = 1
else
H.failed_last_breath = 0
H.adjustOxyLoss(-5)
// Hot air hurts :(
if((breath.temperature < breath_cold_level_1 || breath.temperature > breath_heat_level_1) && !(COLD_RESISTANCE in H.mutations))
if(breath.temperature <= breath_cold_level_1)
if(prob(20))
to_chat(H, "<span class='danger'>You feel icicles forming on your skin!</span>")
else if(breath.temperature >= breath_heat_level_1)
if(prob(20))
to_chat(H, "<span class='danger'>You feel yourself smouldering in the heat!</span>")
var/bodypart = pick(BP_L_FOOT,BP_R_FOOT,BP_L_LEG,BP_R_LEG,BP_L_ARM,BP_R_ARM,BP_L_HAND,BP_R_HAND,BP_TORSO,BP_GROIN,BP_HEAD)
if(breath.temperature >= breath_heat_level_1)
if(breath.temperature < breath_heat_level_2)
H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_1, BURN, bodypart, used_weapon = "Excessive Heat")
H.fire_alert = max(H.fire_alert, 2)
else if(breath.temperature < breath_heat_level_3)
H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_2, BURN, bodypart, used_weapon = "Excessive Heat")
H.fire_alert = max(H.fire_alert, 2)
else
H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_3, BURN, bodypart, used_weapon = "Excessive Heat")
H.fire_alert = max(H.fire_alert, 2)
else if(breath.temperature <= breath_cold_level_1)
if(breath.temperature > breath_cold_level_2)
H.apply_damage(COLD_GAS_DAMAGE_LEVEL_1, BURN, bodypart, used_weapon = "Excessive Cold")
H.fire_alert = max(H.fire_alert, 1)
else if(breath.temperature > breath_cold_level_3)
H.apply_damage(COLD_GAS_DAMAGE_LEVEL_2, BURN, bodypart, used_weapon = "Excessive Cold")
H.fire_alert = max(H.fire_alert, 1)
else
H.apply_damage(COLD_GAS_DAMAGE_LEVEL_3, BURN, bodypart, used_weapon = "Excessive Cold")
H.fire_alert = max(H.fire_alert, 1)
//breathing in hot/cold air also heats/cools you a bit
var/temp_adj = breath.temperature - H.bodytemperature
if (temp_adj < 0)
temp_adj /= (BODYTEMP_COLD_DIVISOR * 5) //don't raise temperature as much as if we were directly exposed
else
temp_adj /= (BODYTEMP_HEAT_DIVISOR * 5) //don't raise temperature as much as if we were directly exposed
var/relative_density = breath.total_moles / (MOLES_CELLSTANDARD * BREATH_PERCENTAGE)
temp_adj *= relative_density
if (temp_adj > BODYTEMP_HEATING_MAX) temp_adj = BODYTEMP_HEATING_MAX
if (temp_adj < BODYTEMP_COOLING_MAX) temp_adj = BODYTEMP_COOLING_MAX
//world << "Breath: [breath.temperature], [src]: [bodytemperature], Adjusting: [temp_adj]"
H.bodytemperature += temp_adj
else if(breath.temperature >= heat_discomfort_level)
get_environment_discomfort(src,"heat")
else if(breath.temperature <= cold_discomfort_level)
get_environment_discomfort(src,"cold")
breath.update_values()
return 1
/obj/item/organ/internal/brain/alraune
icon = 'icons/mob/species/alraune/organs.dmi'
icon_state = "neurostroma"
name = "neuro-stroma"
desc = "A knot of fibrous plant matter."
parent_organ = BP_TORSO // brains in their core
/obj/item/organ/internal/eyes/alraune
icon = 'icons/mob/species/alraune/organs.dmi'
icon_state = "photoreceptors"
name = "photoreceptors"
desc = "Bulbous and fleshy plant matter."
/obj/item/organ/internal/kidneys/alraune
icon = 'icons/mob/species/alraune/organs.dmi'
icon_state = "rhyzofilter"
name = "rhyzofilter"
desc = "A tangle of root nodules."
/obj/item/organ/internal/liver/alraune
icon = 'icons/mob/species/alraune/organs.dmi'
icon_state = "phytoextractor"
name = "phytoextractor"
desc = "A bulbous gourd-like structure."
+2 -1
View File
@@ -1,10 +1,11 @@
/mob/living/carbon/proc/ingest(var/datum/reagents/from, var/datum/reagents/target, var/amount = 1, var/multiplier = 1, var/copy = 0) //we kind of 'sneak' a proc in here for ingesting stuff so we can play with it.
/* VOREStation Removal - Synths should be able to taste because... reasons
if(ishuman(src))
var/mob/living/carbon/human/H = src
var/braintype = H.get_FBP_type()
if(braintype == FBP_DRONE || braintype == FBP_POSI)
return from.trans_to_holder(target,amount,multiplier,copy) //skip the taste, complete transfer
*/
if(last_taste_time + 50 < world.time)
var/datum/reagents/temp = new(amount) //temporary holder used to analyse what gets transfered.
from.trans_to_holder(temp, amount, multiplier, 1)
+3
View File
@@ -693,6 +693,9 @@ var/list/ai_verbs_default = list(
card.grab_ai(src, user)
else if(istype(W, /obj/item/weapon/wrench))
if(user == controlling_drone)
to_chat(user, "<span class='notice'>The drone's subsystems resist your efforts to tamper with your bolts.</span>")
return
if(anchored)
playsound(src, W.usesound, 50, 1)
user.visible_message("<font color='blue'>\The [user] starts to unbolt \the [src] from the plating...</font>")
@@ -3,6 +3,10 @@
if(stat == DEAD)
return
if(controlling_drone)
controlling_drone.release_ai_control("<b>WARNING: Primary control loop failure.</b> Session terminated.")
. = ..(gibbed)
if(src.eyeobj)
src.eyeobj.setLoc(get_turf(src))
@@ -8,6 +8,8 @@
if (src.stat!=CONSCIOUS)
src.cameraFollow = null
src.reset_view(null)
if(controlling_drone)
controlling_drone.release_ai_control("<b>WARNING: Primary control loop failure.</b> Session terminated.")
src.updatehealth()
@@ -19,7 +19,7 @@ var/list/mob_hat_cache = list()
return mob_hat_cache[key]
/mob/living/silicon/robot/drone
name = "drone"
name = "maintenance drone"
real_name = "drone"
icon = 'icons/mob/robots.dmi'
icon_state = "repairbot"
@@ -57,6 +57,8 @@ var/list/mob_hat_cache = list()
var/obj/item/hat
var/hat_x_offset = 0
var/hat_y_offset = -13
var/serial_number = 0
var/name_override = 0
holder_type = /obj/item/weapon/holder/drone
@@ -71,6 +73,7 @@ var/list/mob_hat_cache = list()
return FALSE
/mob/living/silicon/robot/drone/construction
name = "construction drone"
icon_state = "constructiondrone"
law_type = /datum/ai_laws/construction_drone
module_type = /obj/item/weapon/robot_module/drone/construction
@@ -95,6 +98,7 @@ var/list/mob_hat_cache = list()
remove_language("Robot Talk")
add_language("Robot Talk", 0)
add_language("Drone Talk", 1)
serial_number = rand(0,999)
//They are unable to be upgraded, so let's give them a bit of a better battery.
cell.maxcharge = 10000
@@ -127,14 +131,22 @@ var/list/mob_hat_cache = list()
name = real_name
/mob/living/silicon/robot/drone/updatename()
real_name = "maintenance drone ([rand(100,999)])"
if(name_override)
return
if(controlling_ai)
real_name = "remote drone ([controlling_ai])"
else
real_name = "[initial(name)] ([serial_number])"
name = real_name
/mob/living/silicon/robot/drone/updateicon()
overlays.Cut()
if(stat == 0)
overlays += "eyes-[icon_state]"
if(controlling_ai)
overlays += "eyes-[icon_state]-ai"
else
overlays += "eyes-[icon_state]"
else
overlays -= "eyes"
if(hat) // Let the drones wear hats.
@@ -213,15 +225,18 @@ var/list/mob_hat_cache = list()
return
if(emagged)
to_chat(user, "<span class='danger'>\The [user] attempts to load subversive software into you, but your hacked subroutines ignore the attempt.</span>")
to_chat(src, "<span class='danger'>\The [user] attempts to load subversive software into you, but your hacked subroutines ignore the attempt.</span>")
to_chat(user, "<span class='danger'>You attempt to subvert [src], but the sequencer has no effect.</span>")
return
to_chat(user, "<span class='danger'>You swipe the sequencer across [src]'s interface and watch its eyes flicker.</span>")
to_chat(user, "<span class='danger'>You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script.</span>")
message_admins("[key_name_admin(user)] emagged drone [key_name_admin(src)]. Laws overridden.")
log_game("[key_name(user)] emagged drone [key_name(src)]. Laws overridden.")
if(controlling_ai)
to_chat(src, "<span class='danger'>\The [user] loads some kind of subversive software into the remote drone, corrupting its lawset but luckily sparing yours.</span>")
else
to_chat(src, "<span class='danger'>You feel a sudden burst of malware loaded into your execute-as-root buffer. Your tiny brain methodically parses, loads and executes the script.</span>")
log_game("[key_name(user)] emagged drone [key_name(src)][controlling_ai ? " but AI [key_name(controlling_ai)] is in remote control" : " Laws overridden"].")
var/time = time2text(world.realtime,"hh:mm:ss")
lawchanges.Add("[time] <B>:</B> [user.name]([user.key]) emagged [name]([key])")
@@ -234,9 +249,10 @@ var/list/mob_hat_cache = list()
var/datum/gender/TU = gender_datums[user.get_visible_gender()]
set_zeroth_law("Only [user.real_name] and people [TU.he] designate[TU.s] as being such are operatives.")
src << "<b>Obey these laws:</b>"
laws.show_laws(src)
src << "<span class='danger'>ALERT: [user.real_name] [TU.is] your new master. Obey your new laws and [TU.his] commands.</span>"
if(!controlling_ai)
to_chat(src, "<b>Obey these laws:</b>")
laws.show_laws(src)
to_chat(src, "<span class='danger'>ALERT: [user.real_name] is your new master. Obey your new laws and \his commands.</span>")
return 1
//DRONE LIFE/DEATH
@@ -262,26 +278,41 @@ var/list/mob_hat_cache = list()
return
..()
/mob/living/silicon/robot/drone/death(gibbed)
if(controlling_ai)
release_ai_control("<b>WARNING: remote system failure.</b> Connection timed out.")
. = ..(gibbed)
//DRONE MOVEMENT.
/mob/living/silicon/robot/drone/Process_Spaceslipping(var/prob_slip)
return 0
//CONSOLE PROCS
/mob/living/silicon/robot/drone/proc/law_resync()
if(controlling_ai)
to_chat(src, "<span class='warning'>Someone issues a remote law reset order for this unit, but you disregard it.</span>")
return
if(stat != 2)
if(emagged)
src << "<span class='danger'>You feel something attempting to modify your programming, but your hacked subroutines are unaffected.</span>"
to_chat(src, "<span class='danger'>You feel something attempting to modify your programming, but your hacked subroutines are unaffected.</span>")
else
src << "<span class='danger'>A reset-to-factory directive packet filters through your data connection, and you obediently modify your programming to suit it.</span>"
to_chat(src, "<span class='danger'>A reset-to-factory directive packet filters through your data connection, and you obediently modify your programming to suit it.</span>")
full_law_reset()
show_laws()
/mob/living/silicon/robot/drone/proc/shut_down()
if(controlling_ai && mind.special_role)
to_chat(src, "<span class='warning'>Someone issued a remote kill order for this unit, but you disregard it.</span>")
return
if(stat != 2)
if(emagged)
src << "<span class='danger'>You feel a system kill order percolate through your tiny brain, but it doesn't seem like a good idea to you.</span>"
to_chat(src, "<span class='danger'>You feel a system kill order percolate through [controlling_ai ? "the drones" : "your"] tiny brain, but it doesn't seem like a good idea to [controlling_ai ? "it" : "you"].</span>")
else
src << "<span class='danger'>You feel a system kill order percolate through your tiny brain, and you obediently destroy yourself.</span>"
to_chat(src, "<span class='danger'>You feel a system kill order percolate through [controlling_ai ? "the drones" : "your"] tiny brain, and [controlling_ai ? "it" : "you"] obediently destroy[controlling_ai ? "s itself" : " yourself"].</span>")
death()
/mob/living/silicon/robot/drone/proc/full_law_reset()
@@ -290,6 +321,21 @@ var/list/mob_hat_cache = list()
clear_ion_laws(1)
laws = new law_type
/mob/living/silicon/robot/drone/show_laws(var/everyone = 0)
if(!controlling_ai)
return..()
to_chat(src, "<b>Obey these laws:</b>")
controlling_ai.laws_sanity_check()
controlling_ai.laws.show_laws(src)
/mob/living/silicon/robot/drone/robot_checklaws()
set category = "Silicon Commands"
set name = "State Laws"
if(!controlling_ai)
return ..()
controlling_ai.subsystem_law_manager()
//Reboot procs.
/mob/living/silicon/robot/drone/proc/request_player()
@@ -347,14 +393,6 @@ var/list/mob_hat_cache = list()
..()
flavor_text = "It's a bulky construction drone stamped with a Sol Central glyph."
/mob/living/silicon/robot/drone/construction/updatename()
real_name = "construction drone ([rand(100,999)])"
name = real_name
/mob/living/silicon/robot/drone/mining/init()
..()
flavor_text = "It's a bulky mining drone stamped with a Grayson logo."
/mob/living/silicon/robot/drone/mining/updatename()
real_name = "mining drone ([rand(100,999)])"
name = real_name
@@ -75,20 +75,22 @@
if(!produce_drones || !config.allow_drone_spawn || count_drones() >= config.max_maint_drones)
return
if(!player || !istype(player.mob,/mob/observer/dead))
if(player && !istype(player.mob,/mob/observer/dead))
return
announce_ghost_joinleave(player, 0, "They have taken control over a maintenance drone.")
visible_message("\The [src] churns and grinds as it lurches into motion, disgorging a shiny new drone after a few moments.")
flick("h_lathe_leave",src)
drone_progress = 0
time_last_drone = world.time
if(player.mob && player.mob.mind) player.mob.mind.reset()
var/mob/living/silicon/robot/drone/new_drone = new drone_type(get_turf(src))
new_drone.transfer_personality(player)
new_drone.master_fabricator = src
drone_progress = 0
var/mob/living/silicon/robot/drone/new_drone = new drone_type(get_turf(src))
if(player)
announce_ghost_joinleave(player, 0, "They have taken control over a maintenance drone.")
if(player.mob && player.mob.mind) player.mob.mind.reset()
new_drone.transfer_personality(player)
return new_drone
/mob/observer/dead/verb/join_as_drone()
@@ -0,0 +1,104 @@
/mob/living/silicon/ai
var/mob/living/silicon/robot/drone/controlling_drone
/mob/living/silicon/robot/drone
var/mob/living/silicon/ai/controlling_ai
/mob/living/silicon/robot/drone/attack_ai(var/mob/living/silicon/ai/user)
if(!istype(user) || controlling_ai || !config.allow_drone_spawn || !config.allow_ai_drones)
return
if(client || key)
to_chat(user, "<span class='warning'>You cannot take control of an autonomous, active drone.</span>")
return
if(health < -35 || emagged)
to_chat(user, "<span class='notice'><b>WARNING:</b> connection timed out.</span>")
return
user.controlling_drone = src
user.teleop = src
radio.channels = user.aiRadio.keyslot2.channels
controlling_ai = user
verbs += /mob/living/silicon/robot/drone/proc/release_ai_control_verb
local_transmit = FALSE
languages = controlling_ai.languages.Copy()
speech_synthesizer_langs = controlling_ai.speech_synthesizer_langs.Copy()
stat = CONSCIOUS
if(user.mind)
user.mind.transfer_to(src)
else
key = user.key
updatename()
to_chat(src, "<span class='notice'><b>You have shunted your primary control loop into \a [initial(name)].</b> Use the <b>Release Control</b> verb to return to your core.</span>")
/obj/machinery/drone_fabricator/attack_ai(var/mob/living/silicon/ai/user as mob)
if(!istype(user) || user.controlling_drone || !config.allow_drone_spawn || !config.allow_ai_drones)
return
if(stat & NOPOWER)
to_chat(user, "<span class='warning'>\The [src] is unpowered.</span>")
return
if(!produce_drones)
to_chat(user, "<span class='warning'>\The [src] is disabled.</span>")
return
if(drone_progress < 100)
to_chat(user, "<span class='warning'>\The [src] is not ready to produce a new drone.</span>")
return
if(count_drones() >= config.max_maint_drones)
to_chat(user, "<span class='warning'>The drone control subsystems are tasked to capacity; they cannot support any more drones.</span>")
return
var/mob/living/silicon/robot/drone/new_drone = create_drone()
user.controlling_drone = new_drone
user.teleop = new_drone
new_drone.radio.channels = user.aiRadio.keyslot2.channels
new_drone.controlling_ai = user
new_drone.verbs += /mob/living/silicon/robot/drone/proc/release_ai_control_verb
new_drone.local_transmit = FALSE
new_drone.languages = new_drone.controlling_ai.languages.Copy()
new_drone.speech_synthesizer_langs = new_drone.controlling_ai.speech_synthesizer_langs.Copy()
if(user.mind)
user.mind.transfer_to(new_drone)
else
new_drone.key = user.key
new_drone.updatename()
to_chat(new_drone, "<span class='notice'><b>You have shunted your primary control loop into \a [initial(new_drone.name)].</b> Use the <b>Release Control</b> verb to return to your core.</span>")
/mob/living/silicon/robot/drone/proc/release_ai_control_verb()
set name = "Release Control"
set desc = "Release control of a remote drone."
set category = "Silicon Commands"
release_ai_control("Remote session terminated.")
/mob/living/silicon/robot/drone/proc/release_ai_control(var/message = "Connection terminated.")
if(controlling_ai)
if(mind)
mind.transfer_to(controlling_ai)
else
controlling_ai.key = key
to_chat(controlling_ai, "<span class='notice'>[message]</span>")
controlling_ai.controlling_drone = null
controlling_ai.teleop = null
controlling_ai = null
radio.channels = module.channels
verbs -= /mob/living/silicon/robot/drone/proc/release_ai_control_verb
languages = initial(languages)
speech_synthesizer_langs = initial(speech_synthesizer_langs)
remove_language("Robot Talk")
add_language("Robot Talk", 0)
add_language("Drone Talk", 1)
local_transmit = TRUE
full_law_reset()
updatename()
death()
@@ -114,6 +114,8 @@
var/obj/structure/closet/crate/C = new(get_turf(src))
// Put loot in crate
for(var/obj/O in src)
if(isbelly(O)) //VOREStation edit
continue
O.forceMove(C)
..()
@@ -146,6 +148,8 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca
/mob/living/simple_animal/hostile/mimic/copy/death()
for(var/atom/movable/M in src)
if(isbelly(M)) //VOREStation edit
continue
M.forceMove(get_turf(src))
..()
+1 -1
View File
@@ -451,7 +451,7 @@
if(!silent)
if(planetary)
visible_message("<span class='danger'><font size='3'>\A [src] falls out of the sky and crashes into \the [landing]!</font></span>", \
"<span class='danger'><font size='3'> You fall out of the skiy and crash into \the [landing]!</font></span>", \
"<span class='danger'><font size='3'> You fall out of the sky and crash into \the [landing]!</font></span>", \
"You hear something slam into \the [landing].")
var/turf/T = get_turf(landing)
explosion(T, 0, 1, 2)
+1 -1
View File
@@ -50,7 +50,7 @@
// Now sync the organ's eye_colour list.
update_colour()
// Finally, update the eye icon on the mob.
owner.update_eyes()
owner.regenerate_icons()
/obj/item/organ/internal/eyes/replaced(var/mob/living/carbon/human/target)
+2
View File
@@ -1105,6 +1105,8 @@ Note that amputating the affected organ does in fact remove the infection from t
R = basic_robolimb
if(R)
force_icon = R.icon
brute_mod *= R.robo_brute_mod
burn_mod *= R.robo_burn_mod
if(R.lifelike)
robotic = ORGAN_LIFELIKE
name = "[initial(name)]"
+7 -7
View File
@@ -4,13 +4,13 @@ var/global/list/limb_icon_cache = list()
return
/obj/item/organ/external/proc/compile_icon()
overlays.Cut()
cut_overlays()
// This is a kludge, only one icon has more than one generation of children though.
for(var/obj/item/organ/external/organ in contents)
if(organ.children && organ.children.len)
for(var/obj/item/organ/external/child in organ.children)
overlays += child.mob_icon
overlays += organ.mob_icon
add_overlay(organ.mob_icon)
/obj/item/organ/external/proc/sync_colour_to_human(var/mob/living/carbon/human/human)
s_tone = null
@@ -94,7 +94,7 @@ var/global/list/limb_icon_cache = list()
mob_icon.Blend(mark_s, ICON_OVERLAY) //So when it's on your body, it has icons
icon_cache_key += "[M][markings[M]["color"]]"
overlays |= get_hair_icon()
add_overlay(get_hair_icon())
return mob_icon
@@ -107,7 +107,7 @@ var/global/list/limb_icon_cache = list()
var/icon/facial_s = new/icon("icon" = facial_hair_style.icon, "icon_state" = "[facial_hair_style.icon_state]_s")
if(facial_hair_style.do_colouration)
facial_s.Blend(rgb(owner.r_facial, owner.g_facial, owner.b_facial), ICON_MULTIPLY) // VOREStation edit
add_overlay(facial_s)
res.add_overlay(facial_s)
//Head hair
if(owner.h_style && !(owner.head && (owner.head.flags_inv & BLOCKHEADHAIR)))
@@ -122,7 +122,7 @@ var/global/list/limb_icon_cache = list()
if(hair_style.do_colouration && islist(h_col) && h_col.len >= 3)
hair_s.Blend(rgb(h_col[1], h_col[2], h_col[3]), ICON_MULTIPLY)
hair_s.Blend(hair_s_add, ICON_ADD)
res.overlays |= hair_s
res.add_overlay(hair_s)
return res
@@ -164,7 +164,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"]]"
@@ -280,7 +280,7 @@ var/list/robot_hud_colours = list("#CFCFCF","#AFAFAF","#8F8F8F","#6F6F6F","#4F4F
var/b = 0.11 * R.health_hud_intensity
temp.color = list(r, r, r, g, g, g, b, b, b)
hud_damage_image = image(null)
hud_damage_image.overlays += temp
hud_damage_image.add_overlay(temp)
// Calculate the required color index.
var/dam_state = min(1,((brute_dam+burn_dam)/max_damage))
+5
View File
@@ -49,6 +49,9 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\
var/suggested_species = "Human" //If it should make the torso a species
var/speech_bubble_appearance = "synthetic" // What icon_state to use for speech bubbles when talking. Check talk.dmi for all the icons.
var/robo_brute_mod = 1 // Multiplier for incoming brute damage.
var/robo_burn_mod = 1 // As above for burn.
/datum/robolimb/unbranded_monitor
company = "Unbranded Monitor"
desc = "A generic unbranded interpretation of a popular prosthetic head model. It looks rudimentary and cheaply constructed."
@@ -214,6 +217,8 @@ var/const/standard_monitor_styles = "blank=ipc_blank;\
skin_tone = 1
blood_color = "#CCCCCC"
speech_bubble_appearance = "normal"
//robo_brute_mod = 1.1 //VOREStation Edit
//robo_burn_mod = 1.1 //VOREStation Edit
/datum/robolimb/wardtakahashi
company = "Ward-Takahashi"
+3 -2
View File
@@ -30,9 +30,10 @@
current_time = current_time.make_random_time()
update_sun()
/datum/planet/proc/process(amount)
/datum/planet/proc/process(last_fire)
if(current_time)
current_time = current_time.add_seconds(amount)
var/difference = world.time - last_fire
current_time = current_time.add_seconds(difference SECONDS)
update_weather() // We update this first, because some weather types decease the brightness of the sun.
if(sun_last_process <= world.time - sun_process_interval)
update_sun()
+29 -9
View File
@@ -184,7 +184,8 @@ datum/weather/sif
)
/datum/weather/sif/snow/process_effects()
for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs)
..()
for(var/turf/simulated/floor/outdoors/snow/S in SSplanets.new_outdoor_turfs) //This didn't make any sense before SSplanets, either
if(S.z in holder.our_planet.expected_z_levels)
for(var/dir_checked in cardinal)
var/turf/simulated/floor/T = get_step(S, dir_checked)
@@ -207,7 +208,8 @@ datum/weather/sif
)
/datum/weather/sif/blizzard/process_effects()
for(var/turf/simulated/floor/outdoors/snow/S in outdoor_turfs)
..()
for(var/turf/simulated/floor/outdoors/snow/S in SSplanets.new_outdoor_turfs) //This didn't make any sense before SSplanets, either
if(S.z in holder.our_planet.expected_z_levels)
for(var/dir_checked in cardinal)
var/turf/simulated/floor/T = get_step(S, dir_checked)
@@ -219,6 +221,8 @@ datum/weather/sif
name = "rain"
icon_state = "rain"
light_modifier = 0.5
effect_message = "<span class='warning'>Rain falls on you.</span>"
transition_chances = list(
WEATHER_OVERCAST = 25,
WEATHER_LIGHT_SNOW = 10,
@@ -228,6 +232,7 @@ datum/weather/sif
)
/datum/weather/sif/rain/process_effects()
..()
for(var/mob/living/L in living_mob_list)
if(L.z in holder.our_planet.expected_z_levels)
var/turf/T = get_turf(L)
@@ -238,16 +243,19 @@ datum/weather/sif
if(istype(L.get_active_hand(), /obj/item/weapon/melee/umbrella))
var/obj/item/weapon/melee/umbrella/U = L.get_active_hand()
if(U.open)
to_chat(L, "<span class='notice'>Rain patters softly onto your umbrella</span>")
if(show_message)
to_chat(L, "<span class='notice'>Rain patters softly onto your umbrella</span>")
continue
else if(istype(L.get_inactive_hand(), /obj/item/weapon/melee/umbrella))
var/obj/item/weapon/melee/umbrella/U = L.get_inactive_hand()
if(U.open)
to_chat(L, "<span class='notice'>Rain patters softly onto your umbrella</span>")
if(show_message)
to_chat(L, "<span class='notice'>Rain patters softly onto your umbrella</span>")
continue
L.water_act(1)
to_chat(L, "<span class='warning'>Rain falls on you.</span>")
if(show_message)
to_chat(L, effect_message)
/datum/weather/sif/storm
name = "storm"
@@ -256,6 +264,8 @@ datum/weather/sif
temp_low = 233.15 // -40c
light_modifier = 0.3
flight_failure_modifier = 10
transition_chances = list(
WEATHER_RAIN = 45,
WEATHER_STORM = 40,
@@ -264,6 +274,7 @@ datum/weather/sif
)
/datum/weather/sif/storm/process_effects()
..()
for(var/mob/living/L in living_mob_list)
if(L.z in holder.our_planet.expected_z_levels)
var/turf/T = get_turf(L)
@@ -294,6 +305,10 @@ datum/weather/sif
temp_low = 243.15 // -30c
light_modifier = 0.3
flight_failure_modifier = 15
timer_low_bound = 2
timer_high_bound = 5
effect_message = "<span class='warning'>The hail smacks into you!</span>"
transition_chances = list(
WEATHER_RAIN = 45,
WEATHER_STORM = 40,
@@ -302,6 +317,7 @@ datum/weather/sif
)
/datum/weather/sif/hail/process_effects()
..()
for(var/mob/living/carbon/human/H in living_mob_list)
if(H.z in holder.our_planet.expected_z_levels)
var/turf/T = get_turf(H)
@@ -309,15 +325,18 @@ datum/weather/sif
continue // They're indoors, so no need to pelt them with ice.
// If they have an open umbrella, it'll guard from rain
// Message plays every time the umbrella gets stolen, just so they're especially aware of what's happening
if(istype(H.get_active_hand(), /obj/item/weapon/melee/umbrella))
var/obj/item/weapon/melee/umbrella/U = H.get_active_hand()
if(U.open)
to_chat(H, "<span class='notice'>Hail patters gently onto your umbrella.</span>")
if(show_message)
to_chat(H, "<span class='notice'>Hail patters gently onto your umbrella.</span>")
continue
else if(istype(H.get_inactive_hand(), /obj/item/weapon/melee/umbrella))
var/obj/item/weapon/melee/umbrella/U = H.get_inactive_hand()
if(U.open)
to_chat(H, "<span class='notice'>Hail patters gently onto your umbrella.</span>")
if(show_message)
to_chat(H, "<span class='notice'>Hail patters gently onto your umbrella.</span>")
continue
var/target_zone = pick(BP_ALL)
@@ -330,8 +349,9 @@ datum/weather/sif
if(amount_soaked >= 10)
continue // No need to apply damage.
H.apply_damage(rand(5, 10), BRUTE, target_zone, amount_blocked, amount_soaked, used_weapon = "hail")
to_chat(H, "<span class='warning'>The hail smacks into you!</span>")
H.apply_damage(rand(1, 3), BRUTE, target_zone, amount_blocked, amount_soaked, used_weapon = "hail")
if(show_message)
to_chat(H, effect_message)
/datum/weather/sif/blood_moon
name = "blood moon"
+13 -1
View File
@@ -25,7 +25,7 @@
if(current_weather)
old_light_modifier = current_weather.light_modifier // We store the old one, so we can determine if recalculating the sun is needed.
current_weather = allowed_weather_types[new_weather]
next_weather_shift = world.time + rand(20, 30) MINUTES
next_weather_shift = world.time + rand(current_weather.timer_low_bound, current_weather.timer_high_bound) MINUTES
update_icon_effects()
update_temperature()
@@ -66,8 +66,20 @@
var/flight_failure_modifier = 0 // Some types of weather make flying harder, and therefore make crashes more likely.
var/transition_chances = list() // Assoc list
var/datum/weather_holder/holder = null
var/timer_low_bound = 5 // How long this weather must run before it tries to change, in minutes
var/timer_high_bound = 10 // How long this weather can run before it tries to change, in minutes
var/effect_message = null // Should be a string, this is what is shown to a mob caught in the weather
var/last_message = 0 // Keeps track of when the weather last tells EVERY player it's hitting them
var/message_delay = 10 SECONDS // Delay in between weather hit messages
var/show_message = FALSE // Is set to TRUE and plays the messsage every [message_delay]
/datum/weather/proc/process_effects()
show_message = FALSE // Need to reset the show_message var, just in case
if(effect_message) // Only bother with the code below if we actually need to display something
if(world.time >= last_message + message_delay)
last_message = world.time // Reset the timer
show_message = TRUE // Tell the rest of the process that we need to make a message
return
// All this does is hold the weather icon.
@@ -909,9 +909,9 @@
cup_icon_state = "cup_coffee"
cup_name = "cup of coffee"
cup_desc = "Don't drop it, or you'll send scalding liquid and porcelain shards everywhere."
cup_desc = "Don't drop it, or you'll send scalding liquid and ceramic shards everywhere."
glass_name = "cup of coffee"
glass_name = "coffee"
glass_desc = "Don't drop it, or you'll send scalding liquid and glass shards everywhere."
+1 -2
View File
@@ -5,8 +5,7 @@
desc = "..."
icon = 'icons/obj/objects.dmi'
icon_state = "watertank"
plane = TURF_PLANE
layer = TABLE_LAYER // Above catwalks, hopefully below other things
layer = TABLE_LAYER
density = 1
anchored = 0
pressure_resistance = 2*ONE_ATMOSPHERE
@@ -88,16 +88,58 @@
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/ears/curly_bug
name = "curly antennae, colorable"
desc = ""
icon_state = "curly_bug"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/ears/dual_robot
name = "synth antennae, colorable"
desc = ""
icon_state = "dual_robot_antennae"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/ears/right_robot
name = "right synth, colorable"
desc = ""
icon_state = "right_robot_antennae"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/ears/left_robot
name = "left synth, colorable"
desc = ""
icon_state = "left_robot_antennae"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/ears/oni_h1
name = "oni horns"
desc = ""
icon_state = "oni-h1"
/datum/sprite_accessory/ears/oni_h1_c
name = "oni horns, colorable"
desc = ""
icon_state = "oni-h1_c"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/ears/demon_horns1
name = "demon horns"
desc = ""
icon_state = "demon-horns1"
/datum/sprite_accessory/ears/demon_horns1_c
name = "demon horns, colorable"
desc = ""
icon_state = "demon-horns1_c"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/ears/demon_horns2
name = "demon horns, colorable(outward)"
desc = ""
@@ -105,6 +147,13 @@
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/ears/dragon_horns
name = "dragon horns, colorable"
desc = ""
icon_state = "dragon-horns"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/ears/foxears
name = "highlander zorren ears"
desc = ""
@@ -413,6 +462,7 @@
desc = ""
icon_state = "spider-legs"
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/wing/moth
name = "moth wings"
desc = ""
@@ -682,12 +732,14 @@
icon_state = "fantail"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/tail/wagtail
name = "avian wagtail, colorable"
desc = ""
icon_state = "wagtail"
do_colouration = 1
color_blend_mode = ICON_MULTIPLY
/datum/sprite_accessory/tail/crossfox
name = "cross fox"
desc = ""
+5
View File
@@ -578,6 +578,11 @@
if(!(content in src) || !istype(target))
return
content.forceMove(target)
if(isitem(content))
var/obj/item/I = content
if(I.gurgled && (target.mode_flags & DM_FLAG_ITEMWEAK))
I.decontaminate()
I.gurgle_contaminate(target.contents, target.cont_flavor)
items_preserved -= content
if(!silent && target.vore_sound && !recent_sound)
var/soundfile = vore_sounds[target.vore_sound]
@@ -217,6 +217,13 @@
/obj/item/clothing/gloves/fluff/morsleeves,
/obj/item/clothing/under/fluff/morunder)
// Mewchild: Phi Vietsi
/obj/item/weapon/storage/box/fluff/vietsi
name = "Phi's Personal Items"
desc = "A small box containing Phi's small things"
has_items = list(
/obj/item/clothing/accessory/medal/bronze_heart,
/obj/item/clothing/gloves/ring/seal/signet/fluff/vietsi)
/*
Swimsuits, for general use, to avoid arriving to work with your swimsuit.
@@ -1680,9 +1680,10 @@ Departamental Swimsuits, for general use
//Mewchild: Phi Vietsi
/obj/item/clothing/gloves/ring/seal/signet/fluff/vietsi
name = "signet ring"
desc = "A signet ring carved from the bones of something long extinct, as a ward against bad luck."
name = "Phi Vietsi's Bone Signet Ring"
desc = "A signet ring belonging to Phi Vietsi, carved from the bones of something long extinct, as a ward against bad luck."
var/signet_name = "Phi Vietsi"
icon = 'icons/vore/custom_clothes_vr.dmi'
icon_state = "vietsi_ring"