Merge branch 'master' into upstream-merge-13731

This commit is contained in:
Nadyr
2022-09-23 19:07:55 -04:00
committed by GitHub
323 changed files with 15807 additions and 16042 deletions
+303 -1
View File
@@ -1,3 +1,51 @@
/datum/modifier
var/effect_color // Allows for coloring of modifiers.
var/coloration_applied = 0 // Tells the game is coloration has been applied already or not.
var/icon_override = 0 // Tells the game if it should use modifer_effects_vr.dmi or not.
// ENERGY CODE. Variables to allow for energy based modifiers.
var/energy_based // Sees if the modifier is based on something electronic based.
var/energy_cost // How much the modifier uses per action/special effect blocked. For base values.
var/damage_cost // How much energy is used when numbers are involed. For values, such as taking damage. Ex: (Damage*damage_cost)
var/obj/item/weapon/cell/energy_source = null // The source of the above.
// RESISTANCES CODE. Variable to enable external damage resistance modifiers. This is not unlike armor.
// 0 = immune || < 0 = heals || 1 = full damage || >1 = increased damage.
// It should never be below zero as it is not intended to do such, but you are free to experiment!
// Ex: Max_brute_resistance = 0. Min_brute resistance = 1. When started, provides 100% resistance to brute. When cell is dying, goes down to 0% resistance.
// Max is the MAXIMUM % multiplier that will be taken at a MAX charge. Min is the MINIMUM % multiplier that will be taken at a MINIMUM charge.
// Think of it like this: Minimum = what happens at minimum charge. Max = what happens at maximum charge.
// Why do I mention this so much? Because even /I/ got confused, and I wrote this thing!
var/min_damage_resistance
var/max_damage_resistance
var/effective_damage_resistance
var/min_brute_resistance
var/max_brute_resistance
var/effective_brute_resistance
var/min_fire_resistance
var/max_fire_resistance
var/effective_fire_resistance
var/min_tox_resistance
var/max_tox_resistance
var/effective_tox_resistance
var/min_oxy_resistance
var/max_oxy_resistance
var/effective_oxy_resistance
var/min_clone_resistance
var/max_clone_resistance
var/effective_clone_resistance
var/min_hal_resistance
var/max_hal_resistance
var/effective_hal_resistance
// Resistances end
/datum/modifier/underwater_stealth
name = "underwater stealth"
desc = "You are currently underwater, rendering it more difficult to see you and enabling you to move quicker, thanks to your aquatic nature."
@@ -30,4 +78,258 @@
if(water_floor.depth < 1) //You're not in deep enough water anymore.
expire(silent = FALSE)
else
expire(silent = FALSE)
expire(silent = FALSE)
/datum/modifier/shield_projection
name = "Shield Projection"
desc = "You are currently protected by a shield, rendering nigh impossible to hit you through conventional means."
on_created_text = "<span class='notice'>Your shield generator buzzes on.</span>"
on_expired_text = "<span class='warning'>Your shield generator buzzes off.</span>"
stacks = MODIFIER_STACK_FORBID //No stacking shields. If you put one one your belt and backpack it won't work.
icon_override = 1
mob_overlay_state = "deflect"
siemens_coefficient = 2 //Stun weapons drain 100% charge per point of damage. They're good at blocking lasers and bullets but not good at blocking stun beams!
energy_based = 1
energy_cost = 99999 //This is changed to the shield_generator's energy_cost.
damage_cost = 50 //This is how much battery is used per damage unit absorbed. Higher damage means higher charge use per damage absorbed. Changed below!
//Not actually in use until effective resistances are set. Just here so it doesn't have to be placed down for all the variants. Less lines.
max_damage_resistance = 1
max_brute_resistance = 1
max_fire_resistance = 1
max_tox_resistance = 1
max_oxy_resistance = 1
max_clone_resistance = 1
max_hal_resistance = 1
min_damage_resistance = 1
min_brute_resistance = 1
min_fire_resistance = 1
min_tox_resistance = 1
min_oxy_resistance = 1
min_clone_resistance = 1
min_hal_resistance = 1
/* // These are not set, but left here as an example. All three (min,max,effective) must be set or BAD THINGS will happen.
min_brute_resistance = 1 // Min = WHAT HAPPENS AT MINIMUM CHARGE
max_brute_resistance = 0 // MAX = WHAT HAPPENS AT MAXIMUM CHARGE
effective_brute_resistance = 1 //Just tells the game that it has vars. Done to use less checks.
min_fire_resistance = 1
max_fire_resistance = 0
effective_fire_resistance = 1
disable_duration_percent = 1 //THIS CAN ALSO BE USED! Don't be too afraid to use this one, but use it sparingly!
*/
var/obj/item/device/personal_shield_generator/shield_generator //This is the shield generator you're wearing!
/datum/modifier/shield_projection/on_applied()
return
/datum/modifier/shield_projection/on_expire() //Don't need to modify this!
return
/datum/modifier/shield_projection/check_if_valid() //Let's check to make sure you got the stuff and set the vars. Don't need to modify this for any subtypes!
if(ishuman(holder)) //Only humans can use this! Other things later down the line might use the same stuff this does, but the shield generator is human only!
var/mob/living/carbon/human/H = holder
if(istype(H.get_equipped_item(slot_back), /obj/item/device/personal_shield_generator))
shield_generator = H.get_equipped_item(slot_back) //Sets the var on the modifier that the shield gen is their back shield gen.
else if(istype(H.get_equipped_item(slot_belt), /obj/item/device/personal_shield_generator))
shield_generator = H.get_equipped_item(slot_belt) //No need for other checks. If they got hit by this, they just turned it on.
else if(istype(H.get_equipped_item(slot_s_store), /obj/item/device/personal_shield_generator) ) //Rigsuits.
shield_generator = H.get_equipped_item(slot_s_store)
else
expire(silent = TRUE)
if(shield_generator) //Sanity.
energy_source = shield_generator.bcell
energy_cost = shield_generator.generator_hit_cost
damage_cost = shield_generator.damage_cost
effect_color = shield_generator.effect_color
if(!coloration_applied) //Does a check if colors have been applied. If not, updates the color.
H.update_modifier_visuals() //This can only happen on the next tick, unfortunately, not the same tick the modifier is applied. Thus, must be done here.
coloration_applied = 1
else
expire(silent = TRUE)
/datum/modifier/shield_projection/tick() //When the shield generator runs out of charge, it'll remove this naturally.
if(holder.stat == DEAD)
expire(silent = TRUE) //If you're dead the generator stops protecting you but keeps running.
if(!shield_generator || !shield_generator.slot_check()) //No shield to begin with/shield is not on them any longer.
expire(silent = FALSE)
var/shield_efficiency = (energy_source.charge/energy_source.maxcharge) //1 = complete resistance. 0 = no resistance. Must be adjusted for subtypes!
if(!isnull(effective_damage_resistance))
effective_damage_resistance = min_damage_resistance + (max_damage_resistance - min_damage_resistance) * shield_efficiency
if(!isnull(effective_brute_resistance))
effective_brute_resistance = min_brute_resistance + (max_brute_resistance - min_brute_resistance) * shield_efficiency
if(!isnull(effective_fire_resistance))
effective_fire_resistance = min_fire_resistance + (max_fire_resistance - min_fire_resistance) * shield_efficiency
if(!isnull(effective_tox_resistance))
effective_tox_resistance = min_tox_resistance + (max_tox_resistance - min_tox_resistance) * shield_efficiency
if(!isnull(effective_oxy_resistance))
effective_oxy_resistance = min_oxy_resistance + (max_oxy_resistance - min_oxy_resistance) * shield_efficiency
if(!isnull(effective_clone_resistance))
effective_clone_resistance = min_clone_resistance + (max_clone_resistance - min_clone_resistance) * shield_efficiency
if(!isnull(effective_hal_resistance))
effective_hal_resistance = min_hal_resistance + (max_hal_resistance - min_hal_resistance) * shield_efficiency
//Shield variants.
//Simple. Goes from 100% resistance to 0% resistance depending on charge. This is mostly an example of a shield variant.
/datum/modifier/shield_projection/bruteburn
max_brute_resistance = 0
effective_brute_resistance = 1
max_fire_resistance = 0
effective_fire_resistance = 1
/datum/modifier/shield_projection/bruteburn/weak
max_brute_resistance = 0.5
max_fire_resistance = 0.5
//SECURITY VARIANTS
/datum/modifier/shield_projection/security // Security backpack. 50% resistance at full charge. 10% resistance for the last shot taken.
max_brute_resistance = 0.50
min_brute_resistance = 0.9
effective_brute_resistance = 1
max_fire_resistance = 0.5
min_fire_resistance = 0.9
effective_fire_resistance = 1
max_hal_resistance = 0.5
min_hal_resistance = 0.9
effective_hal_resistance = 1
disable_duration_percent = 0.75
/datum/modifier/shield_projection/security/weak // Security belt.
max_brute_resistance = 0.75
min_brute_resistance = 0.95
max_fire_resistance = 0.75
min_fire_resistance = 0.95
max_hal_resistance = 0.75
min_hal_resistance = 0.95
/datum/modifier/shield_projection/security/strong // Dunno. Upgraded variant of security backpack?
max_brute_resistance = 0.25
max_fire_resistance = 0.25
max_hal_resistance = 0.25
siemens_coefficient = 1.5 //Not as weak as normal, but still weak.
disable_duration_percent = 0.5
//MINING VARIANTS
/datum/modifier/shield_projection/mining //Base mining belt. 30% resistance that fades to 15% resistance
max_brute_resistance = 0.70
min_brute_resistance = 0.85
effective_brute_resistance = 1
max_fire_resistance = 0.70
min_brute_resistance = 0.85
effective_fire_resistance = 1
max_hal_resistance = 1.5 // No mobs should be shooting you with halloss. If this happens, it means you're using it wrong!!!
min_hal_resistance = 1.5
effective_hal_resistance = 1
disable_duration_percent = 0.75 //Miners often come into contact with things that can stun them.
/datum/modifier/shield_projection/mining/strong // Mining belt, but upgraded. Even weaker to halloss!
max_brute_resistance = 0.55
min_brute_resistance = 0.75
max_fire_resistance = 0.55
min_fire_resistance = 0.75
disable_duration_percent = 0.5
max_hal_resistance = 2
min_hal_resistance = 2
//MISC VARIANTS
/datum/modifier/shield_projection/biohazard //The odd-ball damage types. Provides near-complete immunity while it's up.
min_tox_resistance = 0.25
max_tox_resistance = 0
effective_tox_resistance = 1
min_oxy_resistance = 0.25
max_oxy_resistance = 0
effective_oxy_resistance = 1
min_clone_resistance = 0.25
max_clone_resistance = 0
effective_clone_resistance = 1
/datum/modifier/shield_projection/admin // Adminbus.
on_created_text = "<span class='notice'>Your shield generator activates and you feel the power of the tesla buzzing around you.</span>"
on_expired_text = "<span class='warning'>Your shield generator deactivates, leaving you feeling weak and vulnerable.</span>"
siemens_coefficient = 0
disable_duration_percent = 0
min_damage_resistance = 0
max_damage_resistance = 0
effective_damage_resistance = 0
min_brute_resistance = 0
max_brute_resistance = 0
effective_brute_resistance = 0
min_fire_resistance = 0
max_fire_resistance = 0
effective_fire_resistance = 0
min_tox_resistance = 0
max_tox_resistance = 0
effective_tox_resistance = 0
min_oxy_resistance = 0
max_oxy_resistance = 0
effective_oxy_resistance = 0
min_clone_resistance = 0
max_clone_resistance = 0
effective_clone_resistance = 0
min_hal_resistance = 0
max_hal_resistance = 0
effective_hal_resistance = 0
/datum/modifier/shield_projection/broken //For broken variants. Good if possible randomization is included for packs spawned on PoIs.
max_brute_resistance = 2
min_brute_resistance = 2
effective_brute_resistance = 1
max_fire_resistance = 2
min_fire_resistance = 2
effective_fire_resistance = 1
/datum/modifier/shield_projection/inverted //Becomes stronger the weaker the cell is. Means the last shot taken will be the weakest. Example just to show it can be done.
max_brute_resistance = 1
min_brute_resistance = 0
effective_brute_resistance = 1
max_fire_resistance = 1
min_fire_resistance = 0
effective_fire_resistance = 1
/datum/modifier/shield_projection/parry //Intended for 'parry' shields, which only last for a single second before running out of charge
max_brute_resistance = 0
min_brute_resistance = 0
effective_brute_resistance = 1
max_fire_resistance = 0
min_fire_resistance = 0
effective_fire_resistance = 1
max_hal_resistance = 0
min_hal_resistance = 0
effective_hal_resistance = 1
+1 -1
View File
@@ -18,7 +18,7 @@ var/global/list/prevent_respawns = list()
//Why are you clicking this button?
if(!mind || !mind.assigned_role)
to_chat(src,"<span class='warning'>Either you haven't played this round, or you already used this verb.</span>")
to_chat(src,"<span class='warning'>Either you haven't played this round, you already used this verb or you left round properly already.</span>")
return
//Add them to the nope list
+1 -1
View File
@@ -125,7 +125,7 @@
add_overlay(H.overlays_standing)
default_pixel_x = body.default_pixel_x
default_pixel_y = body.default_pixel_y
if(!T)
if(!T && length(latejoin))
T = pick(latejoin) //Safety in case we cannot find the body's position
if(T)
forceMove(T)
+3 -2
View File
@@ -297,7 +297,8 @@
return
/mob/living/bot/proc/handleFrustrated(var/targ)
obstacle = targ ? target_path[1] : patrol_path[1]
if((targ && LAZYLEN(target_path)) || LAZYLEN(patrol_path))
obstacle = targ ? target_path[1] : patrol_path[1]
target_path = list()
patrol_path = list()
return
@@ -577,4 +578,4 @@
feeding = FALSE
can_be_drop_pred = FALSE
return ..()
return ..()
@@ -25,7 +25,7 @@
//Technically allows metagaming by allowing buddies to turn on digestion for like 2 seconds
// to finish off critically wounded friends to avoid resleeving sickness, but like
// *kill those people* ok?
if(B.digest_mode == DM_DIGEST)
if(B.digest_mode == DM_DIGEST || B.digest_mode == DM_SELECT)
H.mind?.vore_death = TRUE
//Hooks need to return true otherwise they're considered having failed
@@ -115,8 +115,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_brute_damage_percent
if(nif && nif.flag_check(NIF_C_BRUTEARMOR,NIF_FLAGS_COMBAT)){amount *= 0.7} //VOREStation Edit - NIF mod for damage resistance for this type of damage
take_overall_damage(amount, 0)
@@ -133,8 +137,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_fire_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_fire_damage_percent
if(nif && nif.flag_check(NIF_C_BURNARMOR,NIF_FLAGS_COMBAT)){amount *= 0.7} //VOREStation Edit - NIF mod for damage resistance for this type of damage
take_overall_damage(0, amount)
@@ -153,8 +161,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_brute_damage_percent
if(nif && nif.flag_check(NIF_C_BRUTEARMOR,NIF_FLAGS_COMBAT)){amount *= 0.7} //VOREStation Edit - NIF mod for damage resistance for this type of damage
O.take_damage(amount, 0, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
@@ -175,8 +187,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_fire_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_fire_damage_percent
if(nif && nif.flag_check(NIF_C_BURNARMOR,NIF_FLAGS_COMBAT)){amount *= 0.7} //VOREStation Edit - NIF mod for damage resistance for this type of damage
O.take_damage(0, amount, sharp=is_sharp(damage_source), edge=has_edge(damage_source), used_weapon=damage_source)
@@ -485,6 +501,53 @@ This function restores all organs.
if(!def_zone) def_zone = ran_zone(def_zone)
organ = get_organ(check_zone(def_zone))
for(var/datum/modifier/M in modifiers) //MODIFIER STUFF. It's best to do this RIGHT before armor is calculated, so it's done here! This is the 'forcefield' defence.
if(damagetype == BRUTE && (!isnull(M.effective_brute_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_brute_resistance
continue
if((damagetype == BURN || damagetype == ELECTROCUTE) && (!isnull(M.effective_fire_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_fire_resistance
continue
if(damagetype == TOX && (!isnull(M.effective_tox_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_tox_resistance
continue
if(damagetype == OXY && (!isnull(M.effective_oxy_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_oxy_resistance
continue
if(damagetype == CLONE && (!isnull(M.effective_clone_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_clone_resistance
continue
if(damagetype == HALLOSS && (!isnull(M.effective_hal_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_hal_resistance
continue
if(damagetype == SEARING && (!isnull(M.effective_fire_resistance) || !isnull(M.effective_brute_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
var/damage_mitigation = 0//Used for dual calculations.
if(!isnull(M.effective_fire_resistance))
damage_mitigation += round((1/3)*damage * M.effective_fire_resistance)
if(!isnull(M.effective_brute_resistance))
damage_mitigation += round((2/3)*damage * M.effective_brute_resistance)
damage -= damage_mitigation
continue
if(damagetype == BIOACID && (isSynthetic() && (!isnull(M.effective_fire_resistance))) || (!isSynthetic() && M.effective_tox_resistance))
if(isSynthetic())
damage = damage * M.effective_fire_resistance
else
damage = damage * M.effective_tox_resistance
continue
//Handle other types of damage
if((damagetype != BRUTE) && (damagetype != BURN))
if(damagetype == HALLOSS)
@@ -523,8 +586,12 @@ This function restores all organs.
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*damage)
damage *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*damage)
damage *= M.incoming_brute_damage_percent
if(organ.take_damage(damage, 0, sharp, edge, used_weapon))
@@ -536,8 +603,12 @@ This function restores all organs.
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*damage)
damage *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*damage)
damage *= M.incoming_fire_damage_percent
if(organ.take_damage(0, damage, sharp, edge, used_weapon))
@@ -37,6 +37,18 @@ emp_act
var/armor = getarmor_organ(organ, "bullet")
if(!prob(armor/2)) //Even if the armor doesn't stop the bullet from hurting you, it might stop it from embedding.
var/hit_embed_chance = P.embed_chance + (P.damage - armor) //More damage equals more chance to embed
//Modifiers can make bullets less likely to embed! These are the normal modifiers and shouldn't be related to energy stuff, but they can be anyways!
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.energy_cost) //We use energy_cost here for special effects, such as embedding.
hit_embed_chance = hit_embed_chance*M.incoming_damage_percent
if(P.damage_type == BRUTE && (!isnull(M.incoming_brute_damage_percent)))
if(M.energy_based)
M.energy_source.use(M.energy_cost)
hit_embed_chance = hit_embed_chance*M.incoming_brute_damage_percent
if(prob(max(hit_embed_chance, 0)))
var/obj/item/weapon/material/shard/shrapnel/SP = new()
SP.name = (P.name != "shrapnel")? "[P.name] shrapnel" : "shrapnel"
@@ -381,9 +393,28 @@ emp_act
// if(buckled && buckled == AM)
// return // Don't get hit by the thing we're buckled to.
//VORESTATION EDIT START - Allows for thrown vore!
//Throwing a prey into a pred takes priority. After that it checks to see if the person being thrown is a pred.
if(istype(AM, /mob/living))
var/mob/living/thrown_mob = AM
if((can_be_drop_pred && throw_vore) && (thrown_mob.devourable && thrown_mob.throw_vore && thrown_mob.can_be_drop_prey)) //Prey thrown into pred.
vore_selected.nom_mob(thrown_mob) //Eat them!!!
visible_message("<span class='warning'>[thrown_mob] is thrown right into [src]'s [lowertext(vore_selected.name)]!</span>")
if(thrown_mob.loc != vore_selected)
thrown_mob.forceMove(vore_selected) //Double check. Should never happen but...Weirder things have happened!
add_attack_logs(thrown_mob.thrower,src,"Devoured [thrown_mob.name] via throw vore.")
return //We can stop here. We don't need to calculate damage or anything else. They're eaten.
else if((can_be_drop_prey && throw_vore && devourable) && (thrown_mob.can_be_drop_pred && thrown_mob.throw_vore)) //Pred thrown into prey.
visible_message("<span class='warning'>[src] suddenly slips inside of [thrown_mob]'s [lowertext(thrown_mob.vore_selected.name)] as [thrown_mob] flies into them!</span>")
thrown_mob.vore_selected.nom_mob(src) //Eat them!!!
if(src.loc != thrown_mob.vore_selected)
src.forceMove(thrown_mob.vore_selected) //Double check. Should never happen but...Weirder things have happened!
add_attack_logs(thrown_mob.LAssailant,src,"Was Devoured by [thrown_mob.name] via throw vore.")
return
//VORESTATION EDIT END - Allows for thrown vore!
if(istype(AM,/obj/))
var/obj/O = AM
if(in_throw_mode && speed <= THROWFORCE_SPEED_DIVISOR) //empty active hand and we're in throw mode
if(canmove && !restrained())
if(isturf(O.loc))
+185 -23
View File
@@ -248,9 +248,28 @@
to_chat(src, "<span class='danger'>Your legs won't respond properly, you fall down!</span>")
Weaken(10)
// RADIATION! Everyone's favorite thing in the world! So let's get some numbers down off the bat.
// 50 rads = 1Bq. This means 1 rad = 0.02Bq.
// However, unless I am a smoothbrained dumbo, absorbed rads are in Gy. Not Bq.
// So let's just assume that 50 rads = 1Gy. Make life easier!
// ACUTE RADIATION (The stuff that the 'radiation' variable takes care of. Remember, 50radiation=1Gy.):
// Without care: 1-2Gy has a (0-5%) mortality chance. 2-6 (5-95%) 6-8 (95-100)% 8-30 (100%) >30 (100%)
// With care: 1-2Gy (0-5%), 2-6 (5-50%), 6-8 (50-100%), 8-30 (99-100%) >30 (100%)
// So let's make our thresholds based on this! 50-100, 100-300, 300-400, 400-1500, and anything above 1500!
// In reality, however, nobody should ever go above 300 radiation, which is why the cutoff before the really bad effects start to happen being
// 300 radiation is good. For reference: Breaking an artifact deals ~300 rads with no resistance. Getting shot with a lvl 3 PA deals 300 rads with no resistance.
// Nobody outside of engineering should ever have to worry about being irradiated over 300 and start getting organ damage..
/mob/living/carbon/human/handle_mutations_and_radiation()
// CHRONIC RADIATION (The stuff that 'accumulated_rads' takes care of):
// This is more or less for if someone was exposed for a long time to radiation or just finished being treated for extreme ARS.
// These are meant to be annoying effects to nudge someone towards medical, but not lethal or deadly.
// Things such as loss of taste, eye damage, dropping items in your hand, being temporaily weakened, etc. Stuff to annoy them and get them to fix their rads.
// Additionally, RADIATION_SPEED_COEFFICIENT = 0.1
/mob/living/carbon/human/handle_mutations_and_radiation() //Radiation rework! Now with 'accumulated_rads'
if(inStasisNow())
return
@@ -267,12 +286,15 @@
if(gene.is_active(src))
gene.OnMobLife(src)
radiation = CLAMP(radiation,0,250)
radiation = CLAMP(radiation,0,2500) //Max of 50Gy. If you reach that...You're going to wish you were dead. You probably will be dead.
accumulated_rads = CLAMP(accumulated_rads,0,2500) //Max of 50Gy as well. You should never get higher than this. You will be dead before you can reach this.
var/obj/item/organ/internal/I = null //Used for further down below when an organ is picked.
if(!radiation)
if(species.appearance_flags & RADIATION_GLOWS)
set_light(0)
else
if(accumulated_rads)
accumulated_rads -= RADIATION_SPEED_COEFFICIENT //Accumulated rads slowly dissipate very slowly. Get to medical to get it treated!
else if(((life_tick % 5 == 0) && radiation) || (radiation > 600)) //Radiation is a slow, insidious killer. Unless you get a massive dose, then the onset is sudden!
if(species.appearance_flags & RADIATION_GLOWS)
set_light(max(1,min(5,radiation/15)), max(1,min(10,radiation/25)), species.get_flesh_colour(src))
// END DOGSHIT SNOWFLAKE
@@ -299,42 +321,139 @@
return
//VOREStation Addition end: shadekin
var/damage = 0
radiation -= 1 * RADIATION_SPEED_COEFFICIENT
if(radiation > 2.5 && prob(25)) // Safe for a little over 2m at the recommended maximum safe dosage of 0.05Bq
damage = 1
if(reagents.has_reagent("prussian_blue")) //Prussian Blue temporarily stops radiation effects.
return
if (radiation > 50)
var/damage = 0
if (radiation < 50) //Less than 1.0 Gy. No side effects.
radiation -= 10 * RADIATION_SPEED_COEFFICIENT
accumulated_rads += 10 * RADIATION_SPEED_COEFFICIENT //No escape from accumulated rads.
else if (radiation >= 50 && radiation < 100) //Equivalent of 1.0-2.0 Gy. Minimum stage you start seeing effects.
damage = 1
radiation -= 1 * RADIATION_SPEED_COEFFICIENT
radiation -= 10 * RADIATION_SPEED_COEFFICIENT
accumulated_rads += 10 * RADIATION_SPEED_COEFFICIENT
if(!isSynthetic())
if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT))
radiation -= 5 * RADIATION_SPEED_COEFFICIENT
to_chat(src, "<span class='warning'>You feel weak.</span>")
Weaken(3)
if(!lying)
emote("collapse")
if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT) && !weakened)
to_chat(src, "<span class='warning'>You feel exhausted.</span>")
AdjustWeakened(3)
if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT) && species.get_bodytype() == SPECIES_HUMAN) //apes go bald
if((h_style != "Bald" || f_style != "Shaved" ))
to_chat(src, "<span class='warning'>Your hair falls out.</span>")
h_style = "Bald"
f_style = "Shaved"
update_hair()
if(prob(1) && prob(100 * RADIATION_SPEED_COEFFICIENT)) //Rare chance of vomiting.
spawn vomit()
if (radiation > 75)
else if (radiation >= 100 && radiation < 300) //Equivalent of 2.0 to 6.0 Gy. Nobody should ever be above this without extreme negligence.
damage = 3
radiation -= 1 * RADIATION_SPEED_COEFFICIENT
radiation -= 30 * RADIATION_SPEED_COEFFICIENT
accumulated_rads += 30 * RADIATION_SPEED_COEFFICIENT
if(!isSynthetic())
if(prob(5))
take_overall_damage(0, 5 * RADIATION_SPEED_COEFFICIENT, used_weapon = "Radiation Burns")
if(prob(1))
to_chat(src, "<span class='warning'>You feel strange!</span>")
adjustCloneLoss(5 * RADIATION_SPEED_COEFFICIENT)
emote("gasp")
if(prob(5) && prob(100 * RADIATION_SPEED_COEFFICIENT))
spawn vomit()
if(prob(10) && !weakened)
to_chat(src, "<span class='warning'>You feel sick.</span>")
AdjustWeakened(3)
if (radiation > 150)
damage = 6
radiation -= 4 * RADIATION_SPEED_COEFFICIENT
else if (radiation >= 300 && radiation < 400) //Equivalent of 6.0 to 8.0 Gy.
damage = 5
radiation -= 50 * RADIATION_SPEED_COEFFICIENT
accumulated_rads += 50 * RADIATION_SPEED_COEFFICIENT
if(!isSynthetic())
if(prob(15))
take_overall_damage(0, 10 * RADIATION_SPEED_COEFFICIENT, used_weapon = "Radiation Burns")
if(prob(2))
adjustCloneLoss(5 * RADIATION_SPEED_COEFFICIENT)
emote("gasp")
if(prob(10) && prob(100 * RADIATION_SPEED_COEFFICIENT))
spawn vomit()
if(prob(15) && !weakened)
to_chat(src, "<span class='warning'>You feel horribly ill.</span>")
AdjustWeakened(3)
if(prob(5) && internal_organs.len)
I = pick(internal_organs) //Internal organ damage...Not good. Not good at all.
if(istype(I)) I.add_autopsy_data("Radiation Induced Cancerous Growth", damage)
I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
else if (radiation >= 400 && radiation < 1500) //Equivalent of 8.0 to 30 Gy.
damage = 10
radiation -= 100 * RADIATION_SPEED_COEFFICIENT
accumulated_rads += 100 * RADIATION_SPEED_COEFFICIENT
if(!isSynthetic())
if(prob(25))
take_overall_damage(0, 15 * RADIATION_SPEED_COEFFICIENT, used_weapon = "Radiation Burns")
if(prob(5))
I = internal_organs_by_name[O_EYES]
if(I)
if(istype(I)) I.add_autopsy_data("Radiation Burns", damage)
I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
to_chat(src, "<span class='warning'>Your eyes burn!</span>")
eye_blurry += 10
if(prob(4))
adjustCloneLoss(5 * RADIATION_SPEED_COEFFICIENT)
emote("gasp")
if(prob(25) && prob(100 * RADIATION_SPEED_COEFFICIENT))
spawn vomit()
if(prob(20) && !weakened)
to_chat(src, "<span class='critical'>You feel like your insides are burning!</span>")
AdjustWeakened(5)
if(prob(5))
to_chat(src, "<span class='critical'>Your entire body feels like it's on fire!</span>")
adjustHalLoss(5)
if(prob(10) && internal_organs.len)
I = pick(internal_organs) //Internal organ damage...Not good. Not good at all.
if(istype(I)) I.add_autopsy_data("Radiation Induced Cancerous Growth", damage)
I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
else if (radiation >= 1500) //Above 30Gy. You had to get absolutely blasted with rads for this.
damage = 30
radiation -= 300 * RADIATION_SPEED_COEFFICIENT
accumulated_rads += 300 * RADIATION_SPEED_COEFFICIENT
if(!isSynthetic())
take_overall_damage(0, damage * RADIATION_SPEED_COEFFICIENT, used_weapon = "Radiation Burns") //3 burn damage a tick as your body melts.
adjustCloneLoss(15 * RADIATION_SPEED_COEFFICIENT) //1.5 cloneloss a tick as your cells mutate and break down.
I = internal_organs_by_name[O_EYES]
if(I)
I.add_autopsy_data("Radiation Burns", damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT) //3 eye damage a tick as your eyes melt down.
eye_blurry += 10
if(prob(50) && prob(100 * RADIATION_SPEED_COEFFICIENT))
spawn vomit()
if(!paralysis && prob(30) && prob(100 * RADIATION_SPEED_COEFFICIENT)) //CNS is shutting down.
to_chat(src, "<font color='Critical'>You have a seizure!</font>")
Paralyse(10)
make_jittery(1000)
if(!lying)
emote("collapse")
if(get_active_hand() && prob(15)) //CNS is shutting down.
to_chat(src, "<span class='danger'>Your hand won't respond properly, you drop what you're holding!</span>")
drop_item()
if(internal_organs.len)
I = pick(internal_organs) //Internal organ damage...Not good. Not good at all.
if(istype(I)) I.add_autopsy_data("Radiation Induced Cancerous Growth", damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
I.take_damage(damage * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
/* //Not-so-sparkledog code. TODO: Make a pref for 'special game interactions' that allows interactions that align with prefs to occur.
if(radiation >= 250) //Special effect stuff that occurs at certain rad levels.
if(prob(1) && prob(radiation/2 * RADIATION_SPEED_COEFFICIENT) && allow_spontaneous_tf) //If you've got spontaneous TF...well...
scramble(1, src, 3) //I tried to base this on how many rads you took and it was...Hilarious. Sparkledogs everywhere.
//For the most part, 3 strength will simply change colors. If you get really unlucky, it can do more TF's.
//Math: 250 rads = 1/800 chance
//500 rads = 1/400 chance chance. Etc.
*/
if(damage)
damage *= species.radiation_mod
@@ -344,6 +463,47 @@
var/obj/item/organ/external/O = pick(organs)
if(istype(O)) O.add_autopsy_data("Radiation Poisoning", damage)
// Begin long-term radiation effects
// Loss of taste occurs at 100 (2Gy) and is handled in taste.dm
// These are all done one after another, so duplication is not required. Someone at 400rads will have the 100&400 effects.
if(!radiation && accumulated_rads >= 100 && !reagents.has_reagent("prussian_blue")) //Let's not hit them with long term effects when they're actively being hit with rads.
if(!isSynthetic())
I = internal_organs_by_name[O_EYES]
if(I) //Eye stuff
if(prob(5) && prob(accumulated_rads * RADIATION_SPEED_COEFFICIENT))
to_chat(src, "<span class='warning'>Your eyes water.</span>")
eye_blurry += 5
if(accumulated_rads > 300) // (6Gy)
if(prob(2) && prob(accumulated_rads * RADIATION_SPEED_COEFFICIENT))
to_chat(src, "<span class='warning'>Your eyes burn.</span>")
I.add_autopsy_data("Radiation Burns", 1 * species.radiation_mod * RADIATION_SPEED_COEFFICIENT)
I.take_damage(1 * species.radiation_mod * RADIATION_SPEED_COEFFICIENT) //0.1 damage. Not a lot, but enough to tell you to get to medical.
eye_blurry += 10
if(accumulated_rads > 200) // (4Gy)
if(prob(5) && prob(accumulated_rads * RADIATION_SPEED_COEFFICIENT))
to_chat(src, "<span class='warning'>Your feel nauseated.</span>")
spawn vomit()
if(!weakened && prob(2) && prob(accumulated_rads * RADIATION_SPEED_COEFFICIENT))
to_chat(src, "<span class='warning'>Your feel exhausted.</span>")
AdjustWeakened(3)
if(accumulated_rads > 300) // (6Gy)
if(get_active_hand() && prob(15) && prob(100 * RADIATION_SPEED_COEFFICIENT)) //CNS is shutting down.
to_chat(src, "<span class='danger'>Your hand won't respond properly, you drop what you're holding!</span>")
drop_item()
if(accumulated_rads > 700) // (12Gy)
if(!paralysis && prob(1) && prob(100 * RADIATION_SPEED_COEFFICIENT)) //1 in 1000 chance per tick.
to_chat(src, "<font color='Critical'>You have a seizure!</font>")
Paralyse(10)
make_jittery(1000)
if(!lying)
emote("collapse")
else //The synthetic effects!
return //Nothing for now.
/** breathing **/
/mob/living/carbon/human/handle_chemical_smoke(var/datum/gas_mixture/environment)
@@ -1419,7 +1579,9 @@
else
clear_alert("high")
if(!isbelly(loc)) clear_fullscreen("belly") //VOREStation Add - Belly fullscreens safety
if(!isbelly(loc)) //VOREStation Add - Belly fullscreens safety
clear_fullscreen("belly")
//clear_fullscreen("belly2") //For multilayered stomachs. Not currently implemented.
if(config.welder_vision)
var/found_welder
@@ -46,6 +46,7 @@
breath_type = "nitrogen" //CHOMPedit
poison_type = "oxygen"
ideal_air_type = /datum/gas_mixture/belly_air/vox
siemens_coefficient = 0.2
flags = NO_SCAN | NO_DEFIB
@@ -110,6 +111,3 @@
H.internal = locate(/obj/item/weapon/tank) in H.contents
if(istype(H.internal,/obj/item/weapon/tank) && H.internals)
H.internals.icon_state = "internal1"
/datum/species/vox/get_perfect_belly_air_type()
return /datum/gas_mixture/belly_air/vox
@@ -7,4 +7,7 @@
return wing_animation
/datum/species/proc/get_perfect_belly_air_type(var/mob/living/carbon/human/H)
return /datum/gas_mixture/belly_air //Default
if(ideal_air_type)
return ideal_air_type //Whatever we want
else
return /datum/gas_mixture/belly_air //Default
@@ -30,6 +30,8 @@
var/list/copy_vars = list("base_species", "icobase", "deform", "tail", "tail_animation", "icobase_tail", "color_mult", "primitive_form", "appearance_flags", "flesh_color", "base_color", "blood_mask", "damage_mask", "damage_overlays", "move_trail", "has_floating_eyes")
var/trait_points = 0
var/ideal_air_type = null // Set to something else if you breathe something else from default composition. Used for inbelly air.
var/micro_size_mod = 0 // How different is our size for interactions that involve us being small?
var/macro_size_mod = 0 // How different is our size for interactions that involve us being big?
var/digestion_nutrition_modifier = 1
@@ -426,6 +426,7 @@
hazard_low_pressure = 220 // Dangerously low pressure.
safe_pressure = 400
poison_type = "nitrogen" // technically it's a partial pressure thing but IDK if we can emulate that
ideal_air_type = /datum/gas_mixture/belly_air/zaddat
genders = list(FEMALE, PLURAL) //females are polyp-producing, infertile females and males are nigh-identical
@@ -501,9 +502,6 @@
if(!(K in covered))
H.apply_damage(light_amount/4, BURN, K, 0, 0, "Abnormal growths")
/datum/species/zaddat/get_perfect_belly_air_type()
return /datum/gas_mixture/belly_air/zaddat
/datum/species/diona
name = SPECIES_DIONA
name_plural = "Dionaea"
@@ -1154,7 +1154,6 @@
to_chat(src, "<span class='notice'>You successfully drag \the [target] into the water, slipping them into your [vore_selected].</span>")
target.forceMove(src.vore_selected)
/mob/living/carbon/human/proc/toggle_pain_module()
set name = "Toggle pain simulation."
set desc = "Turn on your pain simulation for that organic experience! Or turn it off for repairs, or if it's too much."
@@ -1166,8 +1165,6 @@
to_chat(src, "<span class='danger'> You turn on your pain simulators </span>")
synth_cosmetic_pain = !synth_cosmetic_pain
<<<<<<< HEAD
=======
//This is the 'long vore' ability. Also known as "Grab Prey with appendage" or "Long Predatorial Reach". Or simply "Tongue Vore"
//It involves projectiles (which means it can be VV'd onto a gun for shenanigans)
@@ -1194,12 +1191,14 @@
var/new_color = input(usr, "Choose a color to set your appendage to!", "", appendage_color) as color|null
if(new_color)
appendage_color = new_color
if(choice == "Functionality") //Easy way to set color so we don't bloat up the menu with even more buttons.
var/choice2 = tgui_alert(usr, "Choose if you want to be pulled to the target or pull them to you!", "Functionality Setting", list("Pull target to self", "Pull self to target"))
if(choice2 == "Pull target to self")
appendage_alt_setting = 0
else
appendage_alt_setting = 1
else
var/list/targets = list() //IF IT IS NOT BROKEN. DO NOT FIX IT.
@@ -1378,5 +1377,4 @@
name = "tongue ball"
hitsound = 'sound/vore/sunesound/pred/schlorp.ogg'
hitsound_wall = 'sound/vore/sunesound/pred/schlorp.ogg'
zaptype = /obj/item/projectile/beam/appendage
>>>>>>> 6285a02b37... Merge pull request #13731 from Cameron653/TONGUE_EDIT
zaptype = /obj/item/projectile/beam/appendage
@@ -136,12 +136,12 @@
/datum/trait/negative/breathes/phoron
name = "Phoron Breather"
desc = "You breathe phoron instead of oxygen (which is poisonous to you), much like a Vox."
var_changes = list("breath_type" = "phoron", "poison_type" = "oxygen")
var_changes = list("breath_type" = "phoron", "poison_type" = "oxygen", "ideal_air_type" = /datum/gas_mixture/belly_air/vox)
/datum/trait/negative/breathes/nitrogen
name = "Nitrogen Breather"
desc = "You breathe nitrogen instead of oxygen (which is poisonous to you). Incidentally, phoron isn't poisonous to breathe to you."
var_changes = list("breath_type" = "nitrogen", "poison_type" = "oxygen")
var_changes = list("breath_type" = "nitrogen", "poison_type" = "oxygen", "ideal_air_type" = /datum/gas_mixture/belly_air/nitrogen_breather)
/datum/trait/negative/monolingual
name = "Monolingual"
@@ -122,6 +122,16 @@
H.verbs |= /mob/living/carbon/human/proc/succubus_drain_finalize
H.verbs |= /mob/living/carbon/human/proc/succubus_drain_lethal
/datum/trait/neutral/long_vore
name = "Long Predatorial Reach"
desc = "Makes you able to use your tongue to grab creatures."
cost = 0
custom_only = FALSE
/datum/trait/neutral/long_vore/apply(var/datum/species/S,var/mob/living/carbon/human/H)
..(S,H)
H.verbs |= /mob/living/proc/long_vore
/datum/trait/neutral/feeder
name = "Feeder"
desc = "Allows you to feed your prey using your own body."
@@ -166,11 +176,12 @@
/datum/trait/neutral/synth_chemfurnace
name = "Biofuel Processor"
desc = "You are able to gain energy through consuming and processing normal food. Energy-dense foods such as protein bars and survival food will yield the best results."
desc = "You are able to gain energy through consuming and processing normal food, at the cost of significantly slower recharging via cyborg chargers. Energy-dense foods such as protein bars and survival food will yield the best results."
cost = 0
custom_only = FALSE
can_take = SYNTHETICS
var_changes = list("organic_food_coeff" = 0.75, "synthetic_food_coeff" = 1) //CHOMPEdit: Increase values
excludes = list(/datum/trait/neutral/biofuel_value_down)
/datum/trait/neutral/glowing_eyes
name = "Glowing Eyes"
@@ -608,7 +619,7 @@
/datum/trait/neutral/biofuel_value_down
name = "Discount Biofuel processor"
desc = "You are able to gain energy through consuming and processing normal food. Unfortunately, it is half as effective as premium models."
desc = "You are able to gain energy through consuming and processing normal food. Unfortunately, it is half as effective as premium models. On the plus side, you still recharge from charging stations fairly efficiently."
cost = 0
custom_only = FALSE
can_take = SYNTHETICS
@@ -144,3 +144,13 @@
),
autohiss_exempt = list("Vespinae"))
excludes = list(/datum/trait/neutral/autohiss_tajaran, /datum/trait/neutral/autohiss_unathi)
//End YW edit
/datum/trait/positive/cocoon_tf/xenochimera
sort = TRAIT_SORT_SPECIES
allowed_species = list(SPECIES_XENOCHIMERA)
custom_only = FALSE
name = "Xenochimera: Cocoon Spinner"
desc = "Allows you to build a cocoon around yourself, using it to transform your body if you desire."
cost = 0
category = 0
@@ -1137,8 +1137,14 @@ var/global/list/damage_icon_parts = list() //see UpdateDamageIcon()
var/image/effects = new()
for(var/datum/modifier/M in modifiers)
if(M.mob_overlay_state)
var/image/I = image(icon = 'icons/mob/modifier_effects.dmi', icon_state = M.mob_overlay_state)
effects.overlays += I // Leaving this as overlays +=
if(M.icon_override) //VOREStation Edit. Override for the modifer icon.
var/image/I = image(icon = 'icons/mob/modifier_effects_vr.dmi', icon_state = M.mob_overlay_state)
I.color = M.effect_color
effects.overlays += I // Leaving this as overlays +=
else
var/image/I = image(icon = 'icons/mob/modifier_effects.dmi', icon_state = M.mob_overlay_state)
I.color = M.effect_color
effects.overlays += I // Leaving this as overlays +=
overlays_standing[MODIFIER_EFFECTS_LAYER] = effects
+3
View File
@@ -11,6 +11,9 @@
from.trans_to_holder(temp, amount, multiplier, 1)
var/text_output = temp.generate_taste_message(src)
if(accumulated_rads >= 100) //If you're irradiated, you can't taste!
text_output = "nothing"
if(text_output != last_taste_text || last_taste_time + 100 < world.time) //We dont want to spam the same message over and over again at the person. Give it a bit of a buffer.
to_chat(src, "<span class='notice'>You can taste [text_output].</span>")//no taste means there are too many tastes and not enough flavor.
+48
View File
@@ -13,6 +13,53 @@
to_world_log("## DEBUG: apply_damage() was called on [src], with [damage] damage, and an armor value of [blocked].")
if(!damage || (blocked >= 100))
return 0
for(var/datum/modifier/M in modifiers) //MODIFIER STUFF. It's best to do this RIGHT before armor is calculated, so it's done here! This is the 'forcefield' defence.
if(damagetype == BRUTE && (!isnull(M.effective_brute_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_brute_resistance
continue
if((damagetype == BURN || damagetype == ELECTROCUTE)&& (!isnull(M.effective_fire_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_fire_resistance
continue
if(damagetype == TOX && (!isnull(M.effective_tox_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_tox_resistance
continue
if(damagetype == OXY && (!isnull(M.effective_oxy_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_oxy_resistance
continue
if(damagetype == CLONE && (!isnull(M.effective_clone_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_clone_resistance
continue
if(damagetype == HALLOSS && (!isnull(M.effective_hal_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
damage = damage * M.effective_hal_resistance
continue
if(damagetype == SEARING && (!isnull(M.effective_fire_resistance) || !isnull(M.effective_brute_resistance)))
if(M.energy_based)
M.energy_source.use(M.damage_cost * damage)
var/damage_mitigation = 0//Used for dual calculations.
if(!isnull(M.effective_fire_resistance))
damage_mitigation += round((1/3)*damage * M.effective_fire_resistance)
if(!isnull(M.effective_brute_resistance))
damage_mitigation += round((2/3)*damage * M.effective_brute_resistance)
damage -= damage_mitigation
continue
if(damagetype == BIOACID && (isSynthetic() && (!isnull(M.effective_fire_resistance))) || (!isSynthetic() && M.effective_tox_resistance))
if(isSynthetic())
damage = damage * M.effective_fire_resistance
else
damage = damage * M.effective_tox_resistance
continue
if(soaked)
if(soaked >= round(damage*0.8))
damage -= round(damage*0.8)
@@ -55,6 +102,7 @@
/mob/living/proc/apply_damages(var/brute = 0, var/burn = 0, var/tox = 0, var/oxy = 0, var/clone = 0, var/halloss = 0, var/def_zone = null, var/blocked = 0)
if(blocked >= 100)
return 0
// INSERT MODIFIER CODE HERE... But no, really, only two things in the game use it, quad and viruses. The former is admin-only and the latter wouldn't be affected logically, but would if shield code was inerted here. If you really want, you can copy&paste the above and modify it to adjust brute/burn/etc. I do not advise this however.
if(brute) apply_damage(brute, BRUTE, def_zone, blocked)
if(burn) apply_damage(burn, BURN, def_zone, blocked)
if(tox) apply_damage(tox, TOX, def_zone, blocked)
+24
View File
@@ -192,8 +192,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_brute_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_brute_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
@@ -219,8 +223,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_oxy_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_oxy_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
@@ -243,8 +251,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_tox_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_tox_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
@@ -273,8 +285,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_fire_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_fire_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
@@ -298,8 +314,12 @@
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(!isnull(M.incoming_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_clone_damage_percent))
if(M.energy_based)
M.energy_source.use(M.damage_cost*amount)
amount *= M.incoming_clone_damage_percent
else if(amount < 0)
for(var/datum/modifier/M in modifiers)
@@ -331,6 +351,9 @@
if(status_flags & GODMODE) return 0 //godmode
if(amount > 0)
for(var/datum/modifier/M in modifiers)
if(M.energy_based && (!isnull(M.incoming_hal_damage_percent) || !isnull(M.disable_duration_percent)))
M.energy_source.use(M.damage_cost*amount) // Cost of the Damage absorbed.
M.energy_source.use(M.energy_cost) // Cost of the Effect absorbed.
if(!isnull(M.incoming_damage_percent))
amount *= M.incoming_damage_percent
if(!isnull(M.incoming_hal_damage_percent))
@@ -1088,6 +1111,7 @@
src.inertia_dir = get_dir(target, src)
step(src, inertia_dir)
item.throw_at(target, throw_range, item.throw_speed, src)
item.throwing = 1 //Small edit so thrown interactions actually work!
return TRUE
else
return FALSE
+22
View File
@@ -324,6 +324,28 @@
src.anchored = TRUE
src.pinned += O
//VORESTATION EDIT START - Allows for thrown vore!
//Throwing a prey into a pred takes priority. After that it checks to see if the person being thrown is a pred.
if(istype(AM, /mob/living))
var/mob/living/thrown_mob = AM
if(!client && !thrown_mob.allowmobvore)
return //The mob is AI controlled and the prey doesn't allow for mob vore allowed, don't even bother.
if((can_be_drop_pred && throw_vore) && (thrown_mob.devourable && thrown_mob.throw_vore && thrown_mob.can_be_drop_prey)) //Prey thrown into pred.
vore_selected.nom_mob(thrown_mob) //Eat them!!!
visible_message("<span class='warning'>[thrown_mob] is thrown right into [src]'s [lowertext(vore_selected.name)]!</span>")
if(thrown_mob.loc != vore_selected)
thrown_mob.forceMove(vore_selected) //Double check. Should never happen but...Weirder things have happened!
add_attack_logs(thrown_mob.thrower,src,"Devoured [thrown_mob.name] via throw vore.")
return //We can stop here. We don't need to calculate damage or anything else. They're eaten.
else if((can_be_drop_prey && throw_vore && devourable) && (thrown_mob.can_be_drop_pred && thrown_mob.throw_vore)) //Pred thrown into prey.
visible_message("<span class='warning'>[src] suddenly slips inside of [thrown_mob]'s [lowertext(thrown_mob.vore_selected.name)] as [thrown_mob] flies into them!</span>")
thrown_mob.vore_selected.nom_mob(src) //Eat them!!!
if(src.loc != thrown_mob.vore_selected)
src.forceMove(thrown_mob.vore_selected) //Double check. Should never happen but...Weirder things have happened!
add_attack_logs(thrown_mob.LAssailant,src,"Was Devoured by [thrown_mob.name] via throw vore.")
return
//VORESTATION EDIT END - Allows for thrown vore!
/mob/living/proc/embed(var/obj/O, var/def_zone=null)
O.loc = src
src.embedded += O
@@ -598,9 +598,12 @@
volume = T.reagents.total_volume
if(water)
water.add_charge(volume)
if(T.ckey)
GLOB.prey_digested_roundstat++
if(patient == T)
patient_laststat = null
patient = null
T.mind?.vore_death = TRUE
qdel(T)
//Pick a random item to deal with (if there are any)
@@ -680,7 +680,8 @@ var/global/list/robot_modules = list(
src.emag.reagents = R
R.my_atom = src.emag
R.add_reagent("beer2", 50)
src.emag.name = "Mickey Finn's Special Brew"
src.emag.name = "Auntie Hong's Final Sip"
src.emag.desc = "A bottle of very special mix of alcohol and poison. Some may argue that there's alcohol to die for, but Auntie Hong took it to next level."
/obj/item/weapon/robot_module/robot/clerical/general
name = "clerical robot module"
@@ -1084,13 +1084,7 @@
src.modules += new /obj/item/weapon/tray/robotray(src)
src.modules += new /obj/item/weapon/reagent_containers/borghypo/service(src)
src.emag = new /obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer(src)
var/datum/reagents/N = new/datum/reagents(50)
src.emag.reagents = N
N.my_atom = src.emag
N.add_reagent("beer2", 50)
src.emag.name = "Mickey Finn's Special Brew"
R.icon = 'icons/mob/widerobot_colors_vr.dmi'
R.wideborg_dept = 'icons/mob/widerobot_colors_vr.dmi'
R.hands.icon = 'icons/mob/screen1_robot_vr.dmi'
@@ -1110,9 +1104,6 @@
/obj/item/weapon/robot_module/robot/booze/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
var/obj/item/weapon/reagent_containers/food/condiment/enzyme/E = locate() in src.modules
E.reagents.add_reagent("enzyme", 2 * amount)
if(src.emag)
var/obj/item/weapon/reagent_containers/food/drinks/bottle/small/beer/B = src.emag
B.reagents.add_reagent("beer2", 2 * amount)
//CHOMP addition start BORGHYPO
/obj/item/weapon/reagent_containers/borghypo/service/booze
@@ -1206,4 +1197,3 @@
R.verbs -= /mob/living/proc/shred_limb
R.verbs -= /mob/living/silicon/robot/proc/rest_style
..()
// CH changes - Unity Hound end
@@ -265,6 +265,7 @@
"The juices pooling beneath you sizzle against your sore skin.",
"The churning walls slowly pulverize you into meaty nutrients.",
"The stomach glorps and gurgles as it tries to work you into slop.")
can_be_drop_pred = TRUE // Mobs will eat anyone that decides to drop/slip into them by default.
/mob/living/simple_mob/Bumped(var/atom/movable/AM, yes)
if(tryBumpNom(AM))
@@ -85,7 +85,9 @@ GLOBAL_VAR_INIT(jellyfish_count, 0)
/mob/living/simple_mob/vore/alienanimals/space_jellyfish/init_vore()
..()
if(!voremob_loaded)
return
.=..()
var/obj/belly/B = vore_selected
B.name = "internal chamber"
B.desc = "It's smooth and translucent. You can see the world around you distort and wobble with the movement of the space jellyfish. It floats casually, while the delicate flesh seems to form to you. It's surprisingly cool, and flickers with its own light. You're on display for all to see, trapped within the confines of this strange space alien!"
@@ -208,7 +208,8 @@
/mob/living/simple_mob/vore/alienanimals/spooky_ghost/apply_melee_effects(var/atom/A)
var/mob/living/L = A
L.hallucination += rand(1,50)
if(L && istype(L))
L.hallucination += rand(1,50)
/mob/living/simple_mob/vore/alienanimals/spooky_ghost/Life()
. = ..()
@@ -110,12 +110,13 @@
violent_breakthrough = TRUE
/mob/living/simple_mob/vore/alienanimals/startreader/apply_melee_effects(mob/living/L)
if(!isliving(L))
return
if(L.weakened) //Don't stun people while they're already stunned! That's SILLY!
return
if(prob(15))
if(isliving(L))
visible_message("<span class='danger'>\The [src] trips \the [L]!</span>!")
L.weakened += rand(1,10)
visible_message("<span class='danger'>\The [src] trips \the [L]!</span>!")
L.weakened += rand(1,10)
/mob/living/simple_mob/vore/alienanimals/startreader/Life()
. = ..()
@@ -0,0 +1,347 @@
#define GA_ADS 0
#define GA_CALLDOWN 1
#define GA_SPEEDUP 2
#define GA_ILLUSION 3
#define GA_BULLETHELL 4
#define GA_LINES 5
#define GA_CONFUSION 6
/mob/living/simple_mob/glitch_boss
name = "CLICK ME!!!"
desc = "WELCOME TO %location_data% THIS IS YOUR HOME NOW PLEASE INPUT CREDIT CARD CREDENTIALS BELOW"
tt_desc = "BEST TOOLBAR PROVIDER SINCE 2098"
icon = 'icons/mob/unknown_boss.dmi'
icon_state = "glitch_boss"
icon_living = "glitch_boss"
icon_dead = "glitch_boss_dead"
faction = "MATH"
maxHealth = 2000
health = 2000
evasion = -75 // Its hitbox is broken ;_;
melee_damage_lower = 20
melee_damage_upper = 40
attack_armor_pen = 20
base_attack_cooldown = 2.5 SECONDS
projectiletype = /obj/item/projectile/energy/slow_orb
projectilesound = 'sound/effects/uncloak.ogg'
special_attack_min_range = 0
special_attack_max_range = 10
special_attack_cooldown = 20 SECONDS
ai_holder_type = /datum/ai_holder/simple_mob/ranged/aggressive/bossmob_glitch
var/next_special_attack = GA_ADS
var/recently_used_attack = GA_SPEEDUP
var/all_special_attacks = list(GA_ADS, GA_CALLDOWN, GA_LINES, GA_BULLETHELL, GA_ILLUSION, GA_CONFUSION, GA_SPEEDUP)
loot_list = list(/obj/item/device/nif/glitch = 100)
/obj/item/projectile/energy/slow_orb
name = "TROJAN"
icon_state = "glitch"
damage = 50
speed = 6
damage_type = ELECTROCUTE
agony = 15
check_armour = "energy"
armor_penetration = 40
fire_sound = 'sound/effects/uncloak.ogg'
combustion = TRUE
/mob/living/simple_mob/glitch_boss/death(gibbed, deathmessage="suddenly %runtime error in unknown.dm, line 56%")
. = ..()
new /obj/effect/temp_visual/glitch(get_turf(src))
qdel(src)
/mob/living/simple_mob/glitch_boss/updatehealth()
. = ..()
if(health < maxHealth*0.25)
special_attack_cooldown = 5 SECONDS
icon_state = "glitch_boss_25"
icon_living = "glitch_boss_25"
else if(health < maxHealth*0.5)
special_attack_cooldown = 10 SECONDS
icon_state = "glitch_boss_50"
icon_living = "glitch_boss_50"
else if (health < maxHealth*0.75)
special_attack_cooldown = 15 SECONDS
icon_state = "glitch_boss_75"
icon_living = "glitch_boss_75"
/mob/living/simple_mob/glitch_boss/proc/create_illusions(atom/A)
var/list/possible_turfs = list()
for(var/turf/T in view(4, src))
if(T.density || T == get_turf(src)) // Our turf is always eligible
continue
var/blocked = FALSE
for(var/atom/movable/AM in T)
if(AM.density)
blocked = TRUE
break
if(!blocked)
possible_turfs += T
if(possible_turfs.len <= 1)
return
var/illusion_amount = min(possible_turfs.len, 4) // Not including our spot
var/list/actual_turfs = list()
actual_turfs += get_turf(src)
for(var/i = 0, i < illusion_amount, i++)
var/turf_to_add = pick(possible_turfs)
actual_turfs += turf_to_add
possible_turfs -= turf_to_add
for(var/i = 0, i < illusion_amount, i++)
var/chosen_turf = pick(actual_turfs)
var/type_to_spawn = prob(15) ? /mob/living/simple_mob/glitch_boss_fake/strong : /mob/living/simple_mob/glitch_boss_fake
var/mob/living/simple_mob/newmob = new type_to_spawn(chosen_turf)
newmob.icon_living = src.icon_living
newmob.icon_state = src.icon_state
new /obj/effect/temp_visual/glitch(chosen_turf)
actual_turfs -= chosen_turf
var/move_turf = pick(actual_turfs)
src.forceMove(move_turf)
new /obj/effect/temp_visual/glitch(move_turf)
/mob/living/simple_mob/glitch_boss/proc/make_ads(atom/A)
var/list/potential_targets = list()
for(var/mob/living/mob in view(7, src))
if(mob.client && mob.faction != faction)
potential_targets += mob
if(potential_targets.len)
var/iteration = clamp(potential_targets.len, 1, 4)
for(var/i = 0, i < iteration, i++)
if(!(potential_targets.len))
break
var/mob/target = pick(potential_targets)
potential_targets -= target
if(target.client)
target.client.create_fake_ad_popup_multiple(/obj/screen/popup/default, 5)
/mob/living/simple_mob/glitch_boss/proc/bombardment(atom/A)
var/list/potential_targets = ai_holder.list_targets()
for(var/atom/entry in potential_targets)
if(istype(entry, /mob/living/simple_mob/glitch_boss_fake))
potential_targets -= entry
if(potential_targets.len)
var/iteration = clamp(potential_targets.len, 1, 3)
for(var/i = 0, i < iteration, i++)
if(!(potential_targets.len))
break
var/mob/target = pick(potential_targets)
potential_targets -= target
spawn_bombardments(target)
/mob/living/simple_mob/glitch_boss/proc/spawn_bombardments(atom/target)
var/list/bomb_range = block(locate(target.x-1, target.y-1, target.z), locate(target.x+1, target.y+1, target.z))
new /obj/effect/calldown_attack(get_turf(target))
bomb_range -= get_turf(target)
for(var/i = 0, i < 4, i++)
var/turf/T = pick(bomb_range)
new /obj/effect/calldown_attack(T)
bomb_range -= T
/mob/living/simple_mob/glitch_boss/proc/bomb_lines(atom/A)
var/list/potential_targets = ai_holder.list_targets()
for(var/atom/entry in potential_targets)
if(istype(entry, /mob/living/simple_mob/glitch_boss_fake))
potential_targets -= entry
if(potential_targets.len)
var/iteration = clamp(potential_targets.len, 1, 3)
for(var/i = 0, i < iteration, i++)
if(!(potential_targets.len))
break
var/mob/target = pick(potential_targets)
potential_targets -= target
spawn_lines(target)
/mob/living/simple_mob/glitch_boss/proc/spawn_lines(atom/target)
var/alignment = rand(1,2) // 1 for vertical, 2 for horizontal
var/list/line_range = list()
var/turf/T = get_turf(target)
line_range += T
for(var/i = 1, i <= 7, i++)
switch(alignment)
if(1)
if(T.x-i > 0)
line_range += locate(T.x-i, T.y, T.z)
if(T.x+i <= world.maxx)
line_range += locate(T.x+i, T.y, T.z)
if(2)
if(T.y-i > 0)
line_range += locate(T.x, T.y-i, T.z)
if(T.y+i <= world.maxy)
line_range += locate(T.x, T.y+i, T.z)
for(var/turf/dropspot in line_range)
new /obj/effect/calldown_attack(dropspot)
/mob/living/simple_mob/glitch_boss/proc/confuse_inflict(atom/A)
var/list/potential_targets = ai_holder.list_targets()
for(var/atom/entry in potential_targets)
if(istype(entry, /mob/living/simple_mob/glitch_boss_fake))
potential_targets -= entry
if(potential_targets.len < 2)
return
potential_targets -= A
var/mob/living/target
while(!target && potential_targets.len)
var/candidate = pick(potential_targets)
if(isliving(candidate))
target = candidate
break
else
potential_targets -= candidate
if(target && istype(target))
if(target.client)
to_chat(target, "<span class='critical'>You feel as though you are losing your sense of direction! Brace yourself!</span>")
new /obj/effect/temp_visual/pre_confuse(get_turf(target))
spawn(5 SECONDS)
if(target)
target.Confuse(3)
if(target.client)
to_chat(target, "<span class='critical'>You feel confused!</span>")
new /obj/effect/temp_visual/confuse(get_turf(target))
/mob/living/simple_mob/glitch_boss/proc/bullethell(atom/A)
set waitfor = FALSE
var/sd = dir2angle(dir)
var/list/offsets = list(45, 45, 20, 10)
for(var/i = 0, i<4, i++)
for(var/j = 0, j <4, j++)
var/obj/item/projectile/energy/slow_orb/shot = new(get_turf(src))
shot.firer = src
shot.fire(sd)
sd += 90
sd += pick(offsets)
sleep(20)
/mob/living/simple_mob/glitch_boss/proc/speed_up_boost(atom/A)
if(base_attack_cooldown == initial(base_attack_cooldown))
base_attack_cooldown = 1 SECOND
var/duration = (special_attack_cooldown == 5 SECONDS) ? 5 SECONDS : 10 SECONDS
spawn(duration)
base_attack_cooldown = initial(base_attack_cooldown)
/mob/living/simple_mob/glitch_boss/do_special_attack(atom/A)
. = TRUE
recently_used_attack = next_special_attack
switch(next_special_attack)
if(GA_ADS)
make_ads(A)
if(GA_CALLDOWN)
bombardment(A)
if(GA_LINES)
bomb_lines(A)
if(GA_BULLETHELL)
bullethell(A)
if(GA_ILLUSION)
create_illusions(A)
if(GA_CONFUSION)
confuse_inflict(A)
if(GA_SPEEDUP)
speed_up_boost(A)
/datum/ai_holder/simple_mob/ranged/aggressive/bossmob_glitch
wander = TRUE
pointblank = TRUE
intelligence_level = AI_SMART
vision_range = 10
closest_distance = 4
/datum/ai_holder/simple_mob/ranged/bossmob_glitch/pre_special_attack(atom/A)
var/mob/living/simple_mob/glitch_boss/GB
if(istype(holder, /mob/living/simple_mob/glitch_boss))
GB = holder
if(GB)
if(isliving(A) || ismecha(A))
var/list/possible_attacks = list()
possible_attacks += GB.all_special_attacks - GB.recently_used_attack
var/illusion_count = 0
var/list/potential_targets = list_targets()
for(var/atom/illusion_maybe in potential_targets)
if(istype(illusion_maybe, /mob/living/simple_mob/glitch_boss_fake))
illusion_count++
potential_targets -= illusion_maybe
if(potential_targets.len < 2)
possible_attacks -= GA_CONFUSION
possible_attacks += GA_SPEEDUP // Double chance when fighting single target
if(illusion_count > 4)
possible_attacks -= GA_ILLUSION
if(!(possible_attacks.len))
GB.next_special_attack = GA_BULLETHELL
else
GB.next_special_attack = pick(possible_attacks)
else
GB.next_special_attack = GA_BULLETHELL
/mob/living/simple_mob/glitch_boss_fake
name = "CLICK ME!!!"
desc = "WELCOME TO %location_data% THIS IS YOUR HOME NOW PLEASE INPUT CREDIT CARD CREDENTIALS BELOW"
tt_desc = "BEST TOOLBAR PROVIDER SINCE 2098"
icon = 'icons/mob/unknown_boss.dmi'
icon_state = "glitch_boss"
icon_living = "glitch_boss"
icon_dead = "glitch_boss_dead"
faction = "MATH"
maxHealth = 20
health = 20
evasion = -75
melee_damage_lower = 0
melee_damage_upper = 0
attack_armor_pen = 0
base_attack_cooldown = 2.5 SECONDS
projectiletype = /obj/item/projectile/energy/slow_orb_fake
projectilesound = 'sound/effects/uncloak.ogg'
var/prob_respawn = 15
ai_holder_type = /datum/ai_holder/simple_mob/ranged/aggressive/bossmob_glitch_fake
/mob/living/simple_mob/glitch_boss_fake/strong
maxHealth = 100
health = 100
prob_respawn = 60
/mob/living/simple_mob/glitch_boss_fake/death(gibbed, deathmessage="disappears in cloud of static.")
new /obj/effect/temp_visual/glitch(get_turf(src))
if(prob(prob_respawn))
new /mob/living/simple_mob/glitch_boss_fake(get_turf(src))
qdel(src)
/obj/item/projectile/energy/slow_orb_fake
name = "TROJAN"
icon_state = "glitch"
damage = 0
speed = 6
damage_type = ELECTROCUTE
agony = 0
check_armour = "energy"
armor_penetration = 0
fire_sound = 'sound/effects/uncloak.ogg'
combustion = TRUE
/datum/ai_holder/simple_mob/ranged/aggressive/bossmob_glitch_fake //Same AI, but without special attack calculation stuff
wander = TRUE
pointblank = TRUE
intelligence_level = AI_SMART
vision_range = 9
closest_distance = 4
@@ -29,6 +29,7 @@
icon = 'icons/mob/vore.dmi'
movement_cooldown = 4 //fast as fucc boie.
can_be_drop_pred = 1 //They can tongue vore.
meat_amount = 4
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
@@ -39,6 +40,10 @@
ai_holder_type = /datum/ai_holder/simple_mob/melee
special_attack_min_range = 1
special_attack_max_range = 5
special_attack_cooldown = 100
// Pepe is love, not hate.
/mob/living/simple_mob/vore/aggressive/frog/New()
if(rand(1,1000000) == 1)
@@ -46,6 +51,21 @@
desc = "You found a rare Pepe. Screenshot for good luck."
..()
/mob/living/simple_mob/vore/aggressive/frog/do_special_attack(atom/A)
set_AI_busy(TRUE)
do_windup_animation(A, 20)
addtimer(CALLBACK(src, .proc/chargeend, A), 20)
/mob/living/simple_mob/vore/aggressive/frog/proc/chargeend(atom/A)
if(stat) //you are dead
set_AI_busy(FALSE)
return
playsound(src, 'sound/vore/sunesound/pred/schlorp.ogg', 25)
var/obj/item/projectile/beam/appendage/appendage_attack = new /obj/item/projectile/beam/appendage(get_turf(loc))
appendage_attack.old_style_target(A, src)
appendage_attack.launch_projectile(A, BP_TORSO, src)
set_AI_busy(FALSE)
// Activate Noms!
/mob/living/simple_mob/vore/aggressive/frog
vore_active = 1
@@ -17,19 +17,19 @@
var/mycolour = COLOR_BLUE //Variable Lighting colours
var/original_temp = null //Value to remember temp
var/set_temperature = T0C + 450 //Sets the target point of 450 degrees celsius
var/heating_power = 100000 //This controls the strength at which it heats the environment. // The number seems ridiculous but this is actually pretty reasonable - Lunar
var/set_temperature = T0C + 10000 //Sets the target point of 10k degrees celsius
var/heating_power = 100000 //This controls the strength at which it heats the environment.
var/emp_heavy = 2
var/emp_med = 4
var/emp_light = 7
var/emp_long = 10
faction = "grubs"
maxHealth = 200 // Tanky fuckers.
health = 200 // Tanky fuckers.
maxHealth = 400 // Tanky fuckers.
health = 400 // Tanky fuckers.
melee_damage_lower = 5
melee_damage_upper = 10
melee_damage_lower = 1
melee_damage_upper = 5
movement_cooldown = 5
@@ -59,18 +59,18 @@
minbodytemp = 0
heat_damage_per_tick = 0 //Even if the atmos stuff doesn't work, at least it won't take any damage.
armor = list(
"melee" = -50,
"bullet" = 0,
"laser" = 50,
"energy" = 50,
"bomb" = 25,
armor = list(
"melee" = 0,
"bullet" = 90,
"laser" = 100,
"energy" = 100,
"bomb" = 100,
"bio" = 100,
"rad" = 100)
/datum/say_list/solarmoth
emote_see = list("flutters")
/mob/living/simple_mob/vore/solarmoth/apply_melee_effects(var/atom/A)
if(isliving(A))
var/mob/living/L = A
@@ -106,17 +106,17 @@
if(heat_transfer > 0 && env.temperature < T0C + 200) //This should start heating the room at a moderate pace up to 200 degrees celsius.
heat_transfer = min(heat_transfer , heating_power) //limit by the power rating of the heater
removed.add_thermal_energy(heat_transfer)
else if(heat_transfer > 0 && env.temperature < set_temperature) //Set temperature is 450 degrees celsius. Heating rate should increase between 200 and 450 C.
heating_power = original_temp*100
else if(heat_transfer > 0 && env.temperature < set_temperature) //Set temperature is 10,000 degrees celsius. So this thing will start cooking crazy hot between the temperatures of 200C and 10,000C.
heating_power = original_temp*100 //Changed to work variable -shark //FLAME ON! This will make the moth heat up the room at an incredible rate.
heat_transfer = min(heat_transfer , heating_power) //limit by the power rating of the heater. Except it's hot, so yeah.
removed.add_thermal_energy(heat_transfer)
else
return
env.merge(removed)
//Since I'm changing hyper mode to be variable we need to store old power
@@ -132,10 +132,11 @@
/mob/living/simple_mob/vore/solarmoth/death()
explode()
..()
/mob/living/simple_mob/vore/solarmoth/gib() //This baby will explode no matter what you do to it.
explode()
..()
/mob/living/simple_mob/vore/solarmoth/handle_light()
@@ -156,7 +157,9 @@
/mob/living/simple_mob/vore/solarmoth/lunarmoth
name = "lunarmoth"
desc = "A majestic sparkling lunarmoth. Also a slight engineering hazard."
var/nospampls = 0
cold_damage_per_tick = 0
//ATMOS
set_temperature = T0C - 10000
@@ -169,7 +172,7 @@
if(prob(25))
for(var/obj/machinery/light/light in range(5, src))
if(prob(50))
light.broken()
light.broken()
if(prob(10))
for(var/obj/structure/window/window in range(5, src))
if(prob(50))
@@ -180,7 +183,7 @@
visible_message("<span class='danger'>Emergency Shutter malfunction!</span>")
door.blocked = 0
door.open(1)
spawn(100)
nospampls = 0
@@ -188,5 +191,4 @@
..()
if(!nospampls)
chilltheglass() //shatter and broken calls for glass and lights. Also some special thing.
@@ -1,6 +1,7 @@
/mob/living/simple_mob/vore
mob_class = MOB_CLASS_ANIMAL
mob_bump_flag = 0
can_be_drop_pred = 1
/mob/living/simple_mob
var/nameset
@@ -19,17 +20,15 @@
can_be_drop_prey = client.prefs_vr.can_be_drop_prey
can_be_drop_pred = client.prefs_vr.can_be_drop_pred
latejoin_vore = client.prefs_vr.latejoin_vore //CHOMPedit
throw_vore = client.prefs_vr.throw_vore
allow_spontaneous_tf = client.prefs_vr.allow_spontaneous_tf
digest_leave_remains = client.prefs_vr.digest_leave_remains
allowmobvore = client.prefs_vr.allowmobvore
permit_healbelly = client.prefs_vr.permit_healbelly
noisy = client.prefs_vr.noisy
selective_preference = client.prefs_vr.selective_preference
<<<<<<< HEAD
=======
appendage_color = client.prefs_vr.appendage_color
appendage_alt_setting = client.prefs_vr.appendage_alt_setting
>>>>>>> 6285a02b37... Merge pull request #13731 from Cameron653/TONGUE_EDIT
drop_vore = client.prefs_vr.drop_vore
stumble_vore = client.prefs_vr.stumble_vore
+1
View File
@@ -8,6 +8,7 @@
var/obj/screen/xenochimera/danger_level/xenochimera_danger_display = null
var/size_multiplier = 1 //multiplier for the mob's icon size
var/accumulated_rads = 0 // For radiation stuff.
/mob/drop_location()
if(temporary_form)
+2 -2
View File
@@ -408,7 +408,7 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HURT)
return // Can't talk in deadchat if you can't see it.
for(var/mob/M in player_list)
if(M.client && ((!istype(M, /mob/new_player) && M.stat == DEAD) || (M.client.holder && M.client.holder.rights)) && M.is_preference_enabled(/datum/client_preference/show_dsay))
if(M.client && ((!istype(M, /mob/new_player) && M.stat == DEAD) || (M.client.holder && M.client.holder.rights && M.is_preference_enabled(/datum/client_preference/holder/show_staff_dsay))) && M.is_preference_enabled(/datum/client_preference/show_dsay))
var/follow
var/lname
if(M.forbid_seeing_deadchat && !M.client.holder)
@@ -438,7 +438,7 @@ var/list/intents = list(I_HELP,I_DISARM,I_GRAB,I_HURT)
/proc/say_dead_object(var/message, var/obj/subject = null)
for(var/mob/M in player_list)
if(M.client && ((!istype(M, /mob/new_player) && M.stat == DEAD) || (M.client.holder && M.client.holder.rights)) && M.is_preference_enabled(/datum/client_preference/show_dsay))
if(M.client && ((!istype(M, /mob/new_player) && M.stat == DEAD) || (M.client.holder && M.client.holder.rights && M.is_preference_enabled(/datum/client_preference/holder/show_staff_dsay))) && M.is_preference_enabled(/datum/client_preference/show_dsay))
var/follow
var/lname = "Game Master"
if(M.forbid_seeing_deadchat && !M.client.holder)
@@ -1605,27 +1605,27 @@ shaved
icon_state = "facial_dwarf"
/datum/sprite_accessory/facial_hair/threeOclock
name = "3 O'clock Shadow"
name = "3 O-clock Shadow"
icon_state = "facial_3oclock"
/datum/sprite_accessory/facial_hair/threeOclockstache
name = "3 O'clock Shadow and Moustache"
name = "3 O-clock Shadow and Moustache"
icon_state = "facial_3oclockmoustache"
/datum/sprite_accessory/facial_hair/fiveOclock
name = "5 O'clock Shadow"
name = "5 O-clock Shadow"
icon_state = "facial_5oclock"
/datum/sprite_accessory/facial_hair/fiveOclockstache
name = "5 O'clock Shadow and Moustache"
name = "5 O-clock Shadow and Moustache"
icon_state = "facial_5oclockmoustache"
/datum/sprite_accessory/facial_hair/sevenOclock
name = "7 O'clock Shadow"
name = "7 O-clock Shadow"
icon_state = "facial_7oclock"
/datum/sprite_accessory/facial_hair/sevenOclockstache
name = "7 O'clock Shadow and Moustache"
name = "7 O-clock Shadow and Moustache"
icon_state = "facial_7oclockmoustache"
/datum/sprite_accessory/facial_hair/mutton
@@ -569,7 +569,7 @@
var/desc = "You should not see this..."
/datum/sprite_accessory/hair_accessory/verie_hair_glow
name = "verie's hair glow"
name = "veries hair glow"
desc = ""
icon_state = "verie_hair_glow"
ignores_lighting = 1