Merge remote-tracking branch 'citadel/master' into combat_rework

This commit is contained in:
kevinz000
2020-05-24 15:03:06 -07:00
1045 changed files with 21989 additions and 11144 deletions
@@ -133,6 +133,7 @@
/datum/sprite_accessory/antenna
icon = 'modular_citadel/icons/mob/ipc_antennas.dmi'
color_src = MUTCOLORS2
relevant_layers = list(BODY_ADJ_LAYER)
recommended_species = list("ipc")
/datum/sprite_accessory/antenna/none
@@ -64,6 +64,7 @@
taur_mode = STYLE_HOOF_TAURIC
alt_taur_mode = STYLE_PAW_TAURIC
color_src = MUTCOLORS
extra = TRUE
/datum/sprite_accessory/taur/drake
name = "Drake"
@@ -72,6 +73,12 @@
color_src = MUTCOLORS
extra = TRUE
/datum/sprite_accessory/taur/drake/old
name = "Drake (Old)"
icon_state = "drake_old"
color_src = MATRIXED
extra = FALSE
/datum/sprite_accessory/taur/drider
name = "Drider"
icon_state = "drider"
@@ -450,6 +450,18 @@
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails/human/tamamo_kitsune
name = "Tamamo Kitsune Tails" //Tamamo-no-Tiro, let it be known!
icon_state = "9sune"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails_animated/human/tamamo_kitsune
name = "Tamamo Kitsune Tails"
icon_state = "9sune"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
/datum/sprite_accessory/tails/human/tentacle
name = "Tentacle"
icon_state = "tentacle"
@@ -816,6 +828,14 @@ datum/sprite_accessory/mam_tails/insect
name = "Squirrel"
icon_state = "squirrel"
/datum/sprite_accessory/mam_tails/tamamo_kitsune
name = "Tamamo Kitsune Tails"
icon_state = "9sune"
/datum/sprite_accessory/mam_tails_animated/tamamo_kitsune
name = "Tamamo Kitsune Tails"
icon_state = "9sune"
/datum/sprite_accessory/mam_tails/tentacle
name = "Tentacle"
icon_state = "tentacle"
+1 -1
View File
@@ -707,7 +707,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
//this is a mob verb instead of atom for performance reasons
//see /mob/verb/examinate() in mob.dm for more info
//overridden here and in /mob/living for different point span classes and sanity checks
/mob/dead/observer/pointed(atom/A as mob|obj|turf in view())
/mob/dead/observer/pointed(atom/A as mob|obj|turf in fov_view())
if(!..())
return 0
usr.visible_message("<span class='deadsay'><b>[src]</b> points to [A].</span>")
+1 -1
View File
@@ -59,7 +59,7 @@
nutrition_ratio *= 1.2
if(satiety > 80)
nutrition_ratio *= 1.25
nutrition = max(0, nutrition - nutrition_ratio * HUNGER_FACTOR)
adjust_nutrition(-nutrition_ratio * HUNGER_FACTOR)
blood_volume = min((BLOOD_VOLUME_NORMAL * blood_ratio), blood_volume + 0.5 * nutrition_ratio)
//Effects of bloodloss
+1 -1
View File
@@ -164,7 +164,7 @@
if(!B)
return
forceMove(B.loc)
src.client.eye = src
reset_perspective(src)
src.visible_message("<span class='warning'><B>[src] rises out of the pool of blood!</B></span>")
exit_blood_effect(B)
if(iscarbon(src))
+1
View File
@@ -4,6 +4,7 @@
var/emp_damage = 0//Handles a type of MMI damage
var/datum/dna/stored/stored_dna // dna var for brain. Used to store dna, brain dna is not considered like actual dna, brain.has_dna() returns FALSE.
stat = DEAD //we start dead by default
has_field_of_vision = FALSE //Not really worth it.
see_invisible = SEE_INVISIBLE_LIVING
possible_a_intents = list(INTENT_HELP, INTENT_HARM) //for mechas
speech_span = SPAN_ROBOT
+29 -36
View File
@@ -51,6 +51,12 @@
var/datum/brain_trauma/BT = X
BT.owner = owner
BT.on_gain()
if(damage > BRAIN_DAMAGE_MILD)
var/datum/skill_modifier/S
ADD_SKILL_MODIFIER_BODY(/datum/skill_modifier/brain_damage, null, C, S)
if(damage > BRAIN_DAMAGE_SEVERE)
var/datum/skill_modifier/S
ADD_SKILL_MODIFIER_BODY(/datum/skill_modifier/heavy_brain_damage, null, C, S)
//Update the body's icon so it doesnt appear debrained anymore
C.update_hair()
@@ -66,6 +72,8 @@
if((!QDELETED(src) || C) && !no_id_transfer)
transfer_identity(C)
if(C)
REMOVE_SKILL_MODIFIER_BODY(/datum/skill_modifier/brain_damage, null, C)
REMOVE_SKILL_MODIFIER_BODY(/datum/skill_modifier/heavy_brain_damage, null, C)
C.update_hair()
/obj/item/organ/brain/prepare_eat()
@@ -129,11 +137,11 @@
if(cached_Bdamage <= HEALTH_THRESHOLD_DEAD) //Fixing dead brains yeilds a trauma
if((cached_Bdamage <= HEALTH_THRESHOLD_DEAD) && (brainmob.health > HEALTH_THRESHOLD_DEAD))
if(prob(80))
gain_trauma_type(BRAIN_TRAUMA_MILD)
gain_trauma_type(BRAIN_TRAUMA_MILD, natural_gain = TRUE)
else if(prob(50))
gain_trauma_type(BRAIN_TRAUMA_SEVERE)
gain_trauma_type(BRAIN_TRAUMA_SEVERE, natural_gain = TRUE)
else
gain_trauma_type(BRAIN_TRAUMA_SPECIAL)
gain_trauma_type(BRAIN_TRAUMA_SPECIAL, natural_gain = TRUE)
return
if((organ_flags & ORGAN_FAILING) && O.is_drainable() && O.reagents.has_reagent(/datum/reagent/medicine/mannitol)) //attempt to heal the brain
@@ -219,31 +227,6 @@
Insert(C)
else
..()
/* TO BE REMOVED, KEPT IN CASE OF BUGS
/obj/item/organ/brain/proc/get_brain_damage()
var/brain_damage_threshold = max_integrity * BRAIN_DAMAGE_INTEGRITY_MULTIPLIER
var/offset_integrity = obj_integrity - (max_integrity - brain_damage_threshold)
. = round((1 - (offset_integrity / brain_damage_threshold)) * BRAIN_DAMAGE_DEATH, DAMAGE_PRECISION)
/obj/item/organ/brain/proc/adjust_brain_damage(amount, maximum)
var/adjusted_amount
if(amount >= 0 && maximum)
var/brainloss = get_brain_damage()
var/new_brainloss = clamp(brainloss + amount, 0, maximum)
if(brainloss > new_brainloss) //brainloss is over the cap already
return 0
adjusted_amount = new_brainloss - brainloss
else
adjusted_amount = amount
adjusted_amount = round(adjusted_amount * BRAIN_DAMAGE_INTEGRITY_MULTIPLIER, DAMAGE_PRECISION)
if(adjusted_amount)
if(adjusted_amount >= DAMAGE_PRECISION)
take_damage(adjusted_amount)
else if(adjusted_amount <= -DAMAGE_PRECISION)
obj_integrity = min(max_integrity, obj_integrity-adjusted_amount)
. = adjusted_amount
*/
/obj/item/organ/brain/applyOrganDamage(var/d, var/maximum = maxHealth)
. = ..()
@@ -261,18 +244,28 @@
. = ..()
//if we're not more injured than before, return without gambling for a trauma
if(damage <= prev_damage)
if(damage < prev_damage && owner)
if(prev_damage > BRAIN_DAMAGE_MILD && damage <= BRAIN_DAMAGE_MILD)
REMOVE_SKILL_MODIFIER_BODY(/datum/skill_modifier/brain_damage, null, owner)
if(prev_damage > BRAIN_DAMAGE_SEVERE && damage <= BRAIN_DAMAGE_SEVERE)
REMOVE_SKILL_MODIFIER_BODY(/datum/skill_modifier/heavy_brain_damage, null, owner)
return
damage_delta = damage - prev_damage
if(damage > BRAIN_DAMAGE_MILD)
if(prob(damage_delta * (1 + max(0, (damage - BRAIN_DAMAGE_MILD)/100)))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 1% //learn how to do your bloody math properly goddamnit
gain_trauma_type(BRAIN_TRAUMA_MILD)
gain_trauma_type(BRAIN_TRAUMA_MILD, natural_gain = TRUE)
if(prev_damage <= BRAIN_DAMAGE_MILD && owner)
var/datum/skill_modifier/S
ADD_SKILL_MODIFIER_BODY(/datum/skill_modifier/brain_damage, null, owner, S)
if(damage > BRAIN_DAMAGE_SEVERE)
if(prob(damage_delta * (1 + max(0, (damage - BRAIN_DAMAGE_SEVERE)/100)))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 1%
if(prob(20))
gain_trauma_type(BRAIN_TRAUMA_SPECIAL)
gain_trauma_type(BRAIN_TRAUMA_SPECIAL, natural_gain = TRUE)
else
gain_trauma_type(BRAIN_TRAUMA_SEVERE)
gain_trauma_type(BRAIN_TRAUMA_SEVERE, natural_gain = TRUE)
if(prev_damage <= BRAIN_DAMAGE_SEVERE && owner)
var/datum/skill_modifier/S
ADD_SKILL_MODIFIER_BODY(/datum/skill_modifier/heavy_brain_damage, null, owner, S)
if (owner)
if(owner.stat < UNCONSCIOUS) //conscious or soft-crit
var/brain_message
@@ -315,7 +308,7 @@
if(istype(BT, brain_trauma_type) && (BT.resilience <= resilience))
. += BT
/obj/item/organ/brain/proc/can_gain_trauma(datum/brain_trauma/trauma, resilience)
/obj/item/organ/brain/proc/can_gain_trauma(datum/brain_trauma/trauma, resilience, natural_gain = FALSE)
if(!ispath(trauma))
trauma = trauma.type
if(!initial(trauma.can_gain))
@@ -348,7 +341,7 @@
if(TRAUMA_RESILIENCE_ABSOLUTE)
max_traumas = TRAUMA_LIMIT_ABSOLUTE
if(resilience_tier_count >= max_traumas)
if(natural_gain && resilience_tier_count >= max_traumas)
return FALSE
return TRUE
@@ -388,11 +381,11 @@
return actual_trauma
//Add a random trauma of a certain subtype
/obj/item/organ/brain/proc/gain_trauma_type(brain_trauma_type = /datum/brain_trauma, resilience)
/obj/item/organ/brain/proc/gain_trauma_type(brain_trauma_type = /datum/brain_trauma, resilience, natural_gain = FALSE)
var/list/datum/brain_trauma/possible_traumas = list()
for(var/T in subtypesof(brain_trauma_type))
var/datum/brain_trauma/BT = T
if(can_gain_trauma(BT, resilience) && initial(BT.random_gain))
if(can_gain_trauma(BT, resilience, natural_gain) && initial(BT.random_gain))
possible_traumas += BT
if(!LAZYLEN(possible_traumas))
-7
View File
@@ -25,10 +25,3 @@
/mob/living/brain/treat_message(message)
message = capitalize(message)
return message
/mob/living/brain/could_speak_in_language(datum/language/dt)
if(istype(container, /obj/item/mmi/posibrain/soul_vessel))
// soul vessels can only speak ratvarian.
. = ispath(dt, /datum/language/ratvar)
else
. = ..()
@@ -140,7 +140,8 @@ Des: Removes all infected images from the alien.
/mob/living/carbon/alien/proc/alien_evolve(mob/living/carbon/alien/new_xeno)
to_chat(src, "<span class='noticealien'>You begin to evolve!</span>")
visible_message("<span class='alertalien'>[src] begins to twist and contort!</span>")
visible_message("<span class='alertalien'>[src] begins to twist and contort!</span>",
"<span class='alertalien'>You begin to twist and contort!</span>")
new_xeno.setDir(dir)
if(!alien_name_regex.Find(name))
new_xeno.name = name
@@ -27,13 +27,16 @@ In all, this is a lot like the monkey code. /N
AdjustUnconscious(-60, FALSE)
AdjustSleeping(-100, FALSE)
update_mobility()
visible_message("<span class='notice'>[M.name] nuzzles [src] trying to wake [p_them()] up!</span>")
visible_message("<span class='notice'>[M.name] nuzzles [src] trying to wake [p_them()] up!</span>",
"<span class='notice'>[M.name] nuzzles you trying to wake you up!</span>", target = M,
target_message = "<span class='notice'>You nuzzle [src] trying to wake [p_them()] up!</span>")
if(INTENT_DISARM, INTENT_HARM)
if(health > 0)
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M.name] bites [src]!</span>", \
"<span class='userdanger'>[M.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='userdanger'>[M.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE, null, M,
"<span class='danger'>You bite [src]!</span>")
adjustBruteLoss(1)
log_combat(M, src, "attacked")
updatehealth()
@@ -21,10 +21,10 @@ Doesn't work on other aliens/AI.*/
. = ..()
action = new(src)
/obj/effect/proc_holder/alien/Trigger(mob/living/carbon/user, skip_cost_check)
/obj/effect/proc_holder/alien/Trigger(mob/living/carbon/user, skip_cost_check = FALSE)
if(!istype(user))
return TRUE
if(!skip_cost_check || cost_check(check_turf,user))
if(skip_cost_check || cost_check(check_turf,user))
if(fire(user) && user) // Second check to prevent runtimes when evolving
user.adjustPlasma(-plasma_cost)
return TRUE
@@ -66,7 +66,7 @@
if(hit_atom)
if(isliving(hit_atom))
var/mob/living/L = hit_atom
if(L.run_block(src, 0, "the [name]", ATTACK_TYPE_TACKLE, 0, src) & BLOCK_SUCCESS)
if(L.mob_run_block(src, 0, "the [name]", ATTACK_TYPE_TACKLE, 0, src, null, null) & BLOCK_SUCCESS)
DefaultCombatKnockdown(40, 1, 1)
else
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
@@ -25,6 +25,7 @@
/mob/living/carbon/alien/humanoid/Initialize()
AddAbility(new/obj/effect/proc_holder/alien/regurgitate(null))
. = ..()
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_CLAW, 0.5, -3)
/mob/living/carbon/alien/humanoid/restrained(ignore_grab)
return handcuffed
+6 -7
View File
@@ -22,9 +22,6 @@
QDEL_NULL(dna)
GLOB.carbon_list -= src
/mob/living/carbon/initialize_footstep()
AddComponent(/datum/component/footstep, 0.6, 2)
/mob/living/carbon/relaymove(mob/user, direction)
if(user in src.stomach_contents)
if(prob(40))
@@ -199,7 +196,7 @@
to_chat(src, "<span class='notice'>You set [I] down gently on the ground.</span>")
return
adjustStaminaLossBuffered(I.getweight()*2)//CIT CHANGE - throwing items shall be more tiring than swinging em. Doubly so.
adjustStaminaLossBuffered(I.getweight(src, STAM_COST_THROW_MULT, SKILL_THROW_STAM_COST))
if(thrown_thing)
visible_message("<span class='danger'>[src] has thrown [thrown_thing].</span>")
@@ -256,7 +253,8 @@
var/obj/item/ITEM = get_item_by_slot(slot)
if(ITEM && istype(ITEM, /obj/item/tank) && wear_mask && (wear_mask.clothing_flags & ALLOWINTERNALS))
visible_message("<span class='danger'>[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name].</span>", \
"<span class='userdanger'>[usr] tries to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name].</span>")
"<span class='userdanger'>[usr] tries to [internal ? "close" : "open"] the valve on your [ITEM.name].</span>", \
target = usr, target_message = "<span class='danger'>You try to [internal ? "close" : "open"] the valve on [src]'s [ITEM.name].</span>")
if(do_mob(usr, src, POCKET_STRIP_DELAY))
if(internal)
internal = null
@@ -267,7 +265,8 @@
update_internals_hud_icon(1)
visible_message("<span class='danger'>[usr] [internal ? "opens" : "closes"] the valve on [src]'s [ITEM.name].</span>", \
"<span class='userdanger'>[usr] [internal ? "opens" : "closes"] the valve on [src]'s [ITEM.name].</span>")
"<span class='userdanger'>[usr] [internal ? "opens" : "closes"] the valve on your [ITEM.name].</span>", \
target = usr, target_message = "<span class='danger'>You [internal ? "opens" : "closes"] the valve on [src]'s [ITEM.name].</span>")
/mob/living/carbon/fall(forced)
@@ -519,7 +518,7 @@
playsound(get_turf(src), 'sound/effects/splat.ogg', 50, 1)
var/turf/T = get_turf(src)
if(!blood)
nutrition -= lost_nutrition
adjust_nutrition(-lost_nutrition)
adjustToxLoss(-3)
for(var/i=0 to distance)
if(blood)
@@ -9,7 +9,7 @@
if(istype(src.glasses, /obj/item/clothing/glasses)) //glasses
var/obj/item/clothing/glasses/GFP = src.glasses
number += GFP.flash_protect
if(istype(src.wear_mask, /obj/item/clothing/mask)) //mask
var/obj/item/clothing/mask/MFP = src.wear_mask
number += MFP.flash_protect
@@ -77,18 +77,10 @@
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "embedded", /datum/mood_event/embedded)
/mob/living/carbon/attacked_by(obj/item/I, mob/living/user)
//CIT CHANGES START HERE - combatmode and resting checks
var/totitemdamage = I.force
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
totitemdamage *= 0.5
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
totitemdamage *= 0.5
if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
totitemdamage *= 1.5
//CIT CHANGES END HERE
var/totitemdamage = pre_attacked_by(I, user)
var/impacting_zone = (user == src)? check_zone(user.zone_selected) : ran_zone(user.zone_selected)
var/list/block_return = list()
if((user != src) && (run_block(I, totitemdamage, "the [I]", ATTACK_TYPE_MELEE, I.armour_penetration, user, impacting_zone, return_list = block_return) & BLOCK_SUCCESS))
if((user != src) && (mob_run_block(I, totitemdamage, "the [I]", ATTACK_TYPE_MELEE, I.armour_penetration, user, impacting_zone, block_return) & BLOCK_SUCCESS))
return FALSE
totitemdamage = block_calculate_resultant_damage(totitemdamage, block_return)
var/obj/item/bodypart/affecting = get_bodypart(impacting_zone)
@@ -96,7 +88,7 @@
affecting = bodyparts[1]
SEND_SIGNAL(I, COMSIG_ITEM_ATTACK_ZONE, src, user, affecting)
send_item_attack_message(I, user, affecting.name)
I.do_stagger_action(src, user)
I.do_stagger_action(src, user, totitemdamage)
if(I.force)
apply_damage(totitemdamage, I.damtype, affecting) //CIT CHANGE - replaces I.force with totitemdamage
if(I.damtype == BRUTE && affecting.status == BODYPART_ORGANIC)
@@ -189,7 +181,8 @@
M.powerlevel = 0
visible_message("<span class='danger'>The [M.name] has shocked [src]!</span>", \
"<span class='userdanger'>The [M.name] has shocked [src]!</span>")
"<span class='userdanger'>The [M.name] has shocked you!</span>", target = M,
target_message = "<span class='danger'>You have shocked [src]!</span>")
do_sparks(5, TRUE, src)
var/power = M.powerlevel + rand(0,3)
@@ -238,38 +231,44 @@
var/obj/item/organ/O = X
O.emp_act(severity)
///Adds to the parent by also adding functionality to propagate shocks through pulling and doing some fluff effects.
/mob/living/carbon/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
if((flags & SHOCK_TESLA) && (flags_1 & TESLA_IGNORE_1))
return FALSE
if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE))
return FALSE
shock_damage *= siemens_coeff
if(dna && dna.species)
shock_damage *= dna.species.siemens_coeff
if(shock_damage < 1)
return 0
if(reagents.has_reagent(/datum/reagent/teslium))
shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
if((flags & SHOCK_ILLUSION))
adjustStaminaLoss(shock_damage)
else
take_overall_damage(0,shock_damage)
visible_message(
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
"<span class='italics'>You hear a heavy electrical crack.</span>" \
)
jitteriness += 1000 //High numbers for violent convulsions
. = ..()
if(!.)
return
//Propagation through pulling, fireman carry
if(!(flags & SHOCK_ILLUSION))
var/list/shocking_queue = list()
if(iscarbon(pulling) && source != pulling)
shocking_queue += pulling
if(iscarbon(pulledby) && source != pulledby)
shocking_queue += pulledby
if(iscarbon(buckled) && source != buckled)
shocking_queue += buckled
for(var/mob/living/carbon/carried in buckled_mobs)
if(source != carried)
shocking_queue += carried
//Found our victims, now lets shock them all
for(var/victim in shocking_queue)
var/mob/living/carbon/C = victim
C.electrocute_act(shock_damage*0.75, src, 1, flags)
//Stun
var/should_stun = (!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN)
if(should_stun)
Stun(40)
//Jitter and other fluff.
jitteriness += 1000
do_jitter_animation(jitteriness)
stuttering += 2
if((!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN))
Stun(40)
spawn(20)
jitteriness = max(jitteriness - 990, 10) //Still jittery, but vastly less
if((!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN))
DefaultCombatKnockdown(60)
addtimer(CALLBACK(src, .proc/secondary_shock, should_stun), 20)
return shock_damage
///Called slightly after electrocute act to reduce jittering and apply a secondary stun.
/mob/living/carbon/proc/secondary_shock(should_stun)
jitteriness = max(jitteriness - 990, 10)
if(should_stun)
DefaultCombatKnockdown(60)
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/M)
if(on_fire)
to_chat(M, "<span class='warning'>You can't put [p_them()] out with just your bare hands!</span>")
@@ -277,19 +276,21 @@
if(health >= 0 && !(HAS_TRAIT(src, TRAIT_FAKEDEATH)))
var/friendly_check = FALSE
if(run_block(M, 0, M.name, ATTACK_TYPE_UNARMED))
if(mob_run_block(M, 0, M.name, ATTACK_TYPE_UNARMED, 0, null, null, null))
return
if(lying)
if(buckled)
to_chat(M, "<span class='warning'>You need to unbuckle [src] first to do that!")
return
M.visible_message("<span class='notice'>[M] shakes [src] trying to get [p_them()] up!</span>", \
"<span class='notice'>You shake [src] trying to get [p_them()] up!</span>")
"<span class='notice'>You shake [src] trying to get [p_them()] up!</span>", target = src,
target_message = "<span class='notice'>[M] shakes you trying to get you up!</span>")
else if(M.zone_selected == BODY_ZONE_PRECISE_MOUTH) // I ADDED BOOP-EH-DEH-NOSEH - Jon
M.visible_message( \
"<span class='notice'>[M] boops [src]'s nose.</span>", \
"<span class='notice'>You boop [src] on the nose.</span>", )
"<span class='notice'>You boop [src] on the nose.</span>", target = src,
target_message = "<span class='notice'>[M] boops your nose.</span>")
playsound(src, 'sound/items/Nose_boop.ogg', 50, 0)
else if(check_zone(M.zone_selected) == BODY_ZONE_HEAD)
@@ -298,7 +299,8 @@
S = dna.species
M.visible_message("<span class='notice'>[M] gives [src] a pat on the head to make [p_them()] feel better!</span>", \
"<span class='notice'>You give [src] a pat on the head to make [p_them()] feel better!</span>")
"<span class='notice'>You give [src] a pat on the head to make [p_them()] feel better!</span>", target = src,
target_message = "<span class='notice'>[M] gives you a pat on the head to make you feel better!</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "headpat", /datum/mood_event/headpat)
friendly_check = TRUE
if(S?.can_wag_tail(src) && !dna.species.is_wagging_tail())
@@ -311,11 +313,13 @@
else if(check_zone(M.zone_selected) == BODY_ZONE_R_ARM || check_zone(M.zone_selected) == BODY_ZONE_L_ARM)
M.visible_message( \
"<span class='notice'>[M] shakes [src]'s hand.</span>", \
"<span class='notice'>You shake [src]'s hand.</span>", )
"<span class='notice'>You shake [src]'s hand.</span>", target = src,
target_message = "<span class='notice'>[M] shakes your hand.</span>")
else
M.visible_message("<span class='notice'>[M] hugs [src] to make [p_them()] feel better!</span>", \
"<span class='notice'>You hug [src] to make [p_them()] feel better!</span>")
"<span class='notice'>You hug [src] to make [p_them()] feel better!</span>", target = src,\
target_message = "<span class='notice'>[M] hugs you to make you feel better!</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "hug", /datum/mood_event/hug)
friendly_check = TRUE
@@ -437,3 +441,17 @@
var/obj/item/organ/ears/ears = getorganslot(ORGAN_SLOT_EARS)
if(istype(ears) && !ears.deaf)
. = TRUE
/mob/living/carbon/getBruteLoss_nonProsthetic()
var/amount = 0
for(var/obj/item/bodypart/BP in bodyparts)
if (BP.status < 2)
amount += BP.brute_dam
return amount
/mob/living/carbon/getFireLoss_nonProsthetic()
var/amount = 0
for(var/obj/item/bodypart/BP in bodyparts)
if (BP.status < 2)
amount += BP.burn_dam
return amount
@@ -24,11 +24,12 @@
. = ..()
if(. && (movement_type & FLOATING)) //floating is easy
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
nutrition = NUTRITION_LEVEL_FED - 1 //just less than feeling vigorous
set_nutrition(NUTRITION_LEVEL_FED - 1) //just less than feeling vigorous
else if(nutrition && stat != DEAD)
nutrition -= HUNGER_FACTOR/10
var/loss = HUNGER_FACTOR/10
if(m_intent == MOVE_INTENT_RUN)
nutrition -= HUNGER_FACTOR/10
loss *= 2
adjust_nutrition(loss)
/mob/living/carbon/can_move_under_living(mob/living/other)
. = ..()
@@ -63,7 +63,7 @@
/mob/living/carbon/adjustBruteLoss(amount, updating_health = TRUE, forced = FALSE)
if (!forced && amount < 0 && HAS_TRAIT(src,TRAIT_NONATURALHEAL))
if(!forced && amount < 0 && HAS_TRAIT(src,TRAIT_NONATURALHEAL))
return FALSE
if(!forced && (status_flags & GODMODE))
return FALSE
@@ -74,7 +74,7 @@
return amount
/mob/living/carbon/adjustFireLoss(amount, updating_health = TRUE, forced = FALSE)
if (!forced && amount < 0 && HAS_TRAIT(src,TRAIT_NONATURALHEAL)) //Vamps don't heal naturally.
if(!forced && amount < 0 && HAS_TRAIT(src,TRAIT_NONATURALHEAL)) //Vamps don't heal naturally.
return FALSE
if(!forced && (status_flags & GODMODE))
return FALSE
+2 -1
View File
@@ -25,7 +25,8 @@
if(M in stomach_contents)
stomach_contents.Remove(M)
M.forceMove(Tsec)
visible_message("<span class='danger'>[M] bursts out of [src]!</span>")
M.visible_message("<span class='danger'>[M] bursts out of [src]!</span>",
"<span class='danger'>You burst out of [src]!</span>")
..()
/mob/living/carbon/spill_organs(no_brain, no_organs, no_bodyparts)
-58
View File
@@ -1,58 +0,0 @@
/mob/living/verb/give()
set category = "IC"
set name = "Give"
set src in oview(1) //Cannot handle giving shit to mobs on your own tile, but it's a small, small loss
give_item(usr)
/mob/living/proc/give_item(mob/living/carbon/user)
/mob/living/carbon/give_item(mob/living/carbon/user)
if(!istype(user))
return
if(src.stat == 2 || user.stat == 2 || src.client == null)
return
if(src.handcuffed)
user << "<span class='warning'>Those hands are cuffed right now.</span>"
return //Can't receive items while cuffed
var/obj/item/I
if(user.get_active_held_item() == null)
user << "You don't have anything in your [get_held_index_name(get_held_index_of_item(I))] to give to [src]."
return
I = user.get_active_held_item()
if(!I)
return
if(src == user) //Shouldn't happen
user << "<span class='warning'>You tried to give yourself \the [I], but you didn't want it.</span>"
return
if(get_empty_held_index_for_side())
switch(alert(src, "[user] wants to give you \a [I]?", , "Yes", "No"))
if("Yes")
if(!I)
return
if(!Adjacent(user))
user <<"<span class='warning'>You need to stay still while giving an object.</span>"
src << "<span class='warning'>[user] moved away.</span>"//What an asshole
return
if(user.get_active_held_item() != I)
user << "<span class='warning'>You need to keep the item in your hand.</span>"
src << "<span class='warning'>[user] has put \the [I] away!</span>"
return
if(!get_empty_held_index_for_side())
user << "<span class='warning'>Your hands are full.</span>"
user << "<span class='warning'>Their hands are full.</span>"
return
if(!user.dropItemToGround(I))
src << "<span class='warning'>[user] can't let go of \the [I]!</span>"
user << "<span class='warning'>You can't seem to let go of \the [I].</span>"
return
src.put_in_hands(I)
update_inv_hands()
src.visible_message("<span class='notice'>[user] handed \the [I] to [src].</span>")
if("No")
src.visible_message("<span class='warning'>[user] tried to hand \the [I] to [src] but \he didn't want it.</span>")
else
user << "<span class='warning'>[src]'s hands are full.</span>"
@@ -43,5 +43,6 @@ GLOBAL_LIST_EMPTY(dummy_mob_list)
return
var/mob/living/carbon/human/dummy/D = GLOB.human_dummy_list[slotnumber]
if(istype(D))
D.set_species(/datum/species/human,icon_update = TRUE, pref_load = TRUE) //for some fucking reason, if you don't change the species every time, some species will dafault certain things when it's their own species on the mannequin two times in a row, like lizards losing spines and tails setting to smooth. If you can find a fix for this that isn't this, good on you
D.wipe_state()
D.in_use = FALSE
@@ -26,6 +26,7 @@
physiology = new()
AddComponent(/datum/component/personal_crafting)
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_HUMAN, 1, 2)
. = ..()
if(CONFIG_GET(flag/disable_stambuffer))
@@ -38,8 +39,9 @@
. = ..()
if(!CONFIG_GET(flag/disable_human_mood))
AddComponent(/datum/component/mood)
AddElement(/datum/element/flavor_text/carbon)
AddElement(/datum/element/flavor_text/carbon, _name = "Flavor Text", _save_key = "flavor_text")
AddElement(/datum/element/flavor_text, "", "Temporary Flavor Text", "This should be used only for things pertaining to the current round!")
AddElement(/datum/element/flavor_text, _name = "OOC Notes", _addendum = "Put information on ERP/vore/lewd-related preferences here. THIS SHOULD NOT CONTAIN REGULAR FLAVORTEXT!!", _always_show = TRUE, _save_key = "ooc_notes", _examine_no_preview = TRUE)
/mob/living/carbon/human/Destroy()
QDEL_NULL(physiology)
@@ -1059,6 +1061,9 @@
if(health_deficiency >= 40)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown, TRUE, (health_deficiency-39) / 75)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying, TRUE, (health_deficiency-39) / 25)
else
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
else
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)
@@ -102,11 +102,15 @@
. = ..(user, TRUE)
if(.)
return
var/hulk_verb = pick("smash","pummel")
var/hulk_verb_continous = "smashes"
var/hulk_verb_simple = "smash"
if(prob(50))
hulk_verb_continous = "pummels"
hulk_verb_simple = "pummel"
playsound(loc, user.dna.species.attack_sound, 25, 1, -1)
var/message = "[user] has [hulk_verb]ed [src]!"
visible_message("<span class='danger'>[message]</span>", \
"<span class='userdanger'>[message]</span>")
visible_message("<span class='danger'>[user] [hulk_verb_continous] [src]!</span>", \
"<span class='userdanger'>[user] [hulk_verb_continous] you!</span>", null, COMBAT_MESSAGE_RANGE, null, user,
"<span class='danger'>You [hulk_verb_simple] [src]!</span>")
adjustBruteLoss(15)
return 1
@@ -130,14 +134,16 @@
var/obj/item/I = get_active_held_item()
if(I && dropItemToGround(I))
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] disarmed [src]!</span>", \
"<span class='userdanger'>[M] disarmed [src]!</span>")
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
"<span class='userdanger'>[M] has disarmed you!</span>", null, COMBAT_MESSAGE_RANGE, null, M,
"<span class='danger'>You have disarmed [src]!</span>")
else if(!M.client || prob(5)) // only natural monkeys get to stun reliably, (they only do it occasionaly)
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
DefaultCombatKnockdown(100)
log_combat(M, src, "tackled")
visible_message("<span class='danger'>[M] has tackled down [src]!</span>", \
"<span class='userdanger'>[M] has tackled down [src]!</span>")
"<span class='userdanger'>[M] has tackled you down!</span>", null, COMBAT_MESSAGE_RANGE, null, M,
"<span class='danger'>You have tackled [src] down!</span>")
if(M.limb_destroyer)
dismembering_strike(M, affecting.body_zone)
@@ -159,7 +165,8 @@
if(!damage)
playsound(loc, 'sound/weapons/slashmiss.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M] has lunged at [src]!</span>", \
"<span class='userdanger'>[M] has lunged at [src]!</span>")
"<span class='userdanger'>[M] has lunged at you!</span>", target = M, \
target_message = "<span class='danger'>You have lunged at [src]!</span>")
return 0
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
if(!affecting)
@@ -168,7 +175,8 @@
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
"<span class='userdanger'>[M] has slashed at [src]!</span>")
"<span class='userdanger'>[M] has slashed at you!</span>", target = M, \
target_message = "<span class='danger'>You have slashed at [src]!</span>")
log_combat(M, src, "attacked")
if(!dismembering_strike(M, M.zone_selected)) //Dismemberment successful
return 1
@@ -178,14 +186,16 @@
var/obj/item/I = get_active_held_item()
if(I && dropItemToGround(I))
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] disarmed [src]!</span>", \
"<span class='userdanger'>[M] disarmed [src]!</span>")
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
"<span class='userdanger'>[M] has disarmed you!</span>", target = M, \
target_message = "<span class='danger'>You have disarmed [src]!</span>")
else
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
DefaultCombatKnockdown(M.meleeKnockdownPower)
log_combat(M, src, "tackled")
visible_message("<span class='danger'>[M] has tackled down [src]!</span>", \
"<span class='userdanger'>[M] has tackled down [src]!</span>")
"<span class='userdanger'>[M] has tackled you down!</span>", target = M, \
target_message = "<span class='danger'>You have tackled down [src]!</span>")
/mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L)
. = ..()
@@ -268,7 +278,8 @@
updatehealth()
visible_message("<span class='danger'>[M.name] has hit [src]!</span>", \
"<span class='userdanger'>[M.name] has hit [src]!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='userdanger'>[M.name] has hit you!</span>", null, COMBAT_MESSAGE_RANGE, target = M,
target_message = "<span class='danger'>You have hit [src]!</span>")
log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
else
@@ -348,40 +359,34 @@
apply_damage(5, BRUTE, affecting, run_armor_check(affecting, "melee"))
//Added a safety check in case you want to shock a human mob directly through electrocute_act.
///Calculates the siemens coeff based on clothing and species, can also restart hearts.
/mob/living/carbon/human/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
if(flags & SHOCK_TESLA)
var/total_coeff = 1
if(gloves)
var/obj/item/clothing/gloves/G = gloves
if(G.siemens_coefficient <= 0)
total_coeff -= 0.5
//Calculates the siemens coeff based on clothing. Completely ignores the arguments
if(flags & SHOCK_TESLA) //I hate this entire block. This gets the siemens_coeff for tesla shocks
if(gloves && gloves.siemens_coefficient <= 0)
siemens_coeff -= 0.5
if(wear_suit)
var/obj/item/clothing/suit/S = wear_suit
if(S.siemens_coefficient <= 0)
total_coeff -= 0.95
else if(S.siemens_coefficient == (-1))
total_coeff -= 1
siemens_coeff = total_coeff
if(flags_1 & TESLA_IGNORE_1)
siemens_coeff = 0
else if(!(flags & SHOCK_NOGLOVES))
var/gloves_siemens_coeff = 1
if(wear_suit.siemens_coefficient == -1)
siemens_coeff -= 1
else if(wear_suit.siemens_coefficient <= 0)
siemens_coeff -= 0.95
siemens_coeff = max(siemens_coeff, 0)
else if(!(flags & SHOCK_NOGLOVES)) //This gets the siemens_coeff for all non tesla shocks
if(gloves)
var/obj/item/clothing/gloves/G = gloves
gloves_siemens_coeff = G.siemens_coefficient
siemens_coeff = gloves_siemens_coeff
if(undergoing_cardiac_arrest() && !(flags & SHOCK_ILLUSION))
if(shock_damage * siemens_coeff >= 1 && prob(25))
var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART)
heart.beating = TRUE
if(stat == CONSCIOUS)
to_chat(src, "<span class='notice'>You feel your heart beating again!</span>")
siemens_coeff *= gloves.siemens_coefficient
siemens_coeff *= physiology.siemens_coeff
. = ..()
if(.)
electrocution_animation(40)
//Don't go further if the shock was blocked/too weak.
if(!.)
return
//Note we both check that the user is in cardiac arrest and can actually heartattack
//If they can't, they're missing their heart and this would runtime
if(undergoing_cardiac_arrest() && can_heartattack() && !(flags & SHOCK_ILLUSION))
if(shock_damage * siemens_coeff >= 1 && prob(25))
var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART)
if(heart.Restart() && stat == CONSCIOUS)
to_chat(src, "<span class='notice'>You feel your heart beating again!</span>")
electrocution_animation(40)
/mob/living/carbon/human/emp_act(severity)
. = ..()
@@ -9,6 +9,7 @@
/// Enable stamina combat
combat_flags = COMBAT_FLAGS_DEFAULT
status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH|CANSTAGGER
has_field_of_vision = FALSE //Handled by species.
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
@@ -70,4 +71,5 @@
var/creamed = FALSE //to use with creampie overlays
var/static/list/can_ride_typecache = typecacheof(list(/mob/living/carbon/human, /mob/living/simple_animal/slime, /mob/living/simple_animal/parrot))
var/lastpuke = 0
var/account_id
var/last_fire_update
@@ -127,6 +127,17 @@
to_chat(src, "<span class='warning'>Your fingers don't fit in the trigger guard!</span>")
return FALSE
/mob/living/carbon/human/proc/get_bank_account()
RETURN_TYPE(/datum/bank_account)
var/datum/bank_account/account
var/obj/item/card/id/I = get_idcard()
if(I && I.registered_account)
account = I.registered_account
return account
return FALSE
/mob/living/carbon/human/can_see_reagents()
. = ..()
if(.) //No need to run through all of this if it's already true.
@@ -277,3 +277,65 @@
qdel(slot)
for(var/obj/item/I in held_items)
qdel(I)
/mob/living/carbon/human/proc/smart_equipbag() // take most recent item out of bag or place held item in bag
if(incapacitated())
return
var/obj/item/thing = get_active_held_item()
var/obj/item/equipped_back = get_item_by_slot(SLOT_BACK)
if(!equipped_back) // We also let you equip a backpack like this
if(!thing)
to_chat(src, "<span class='warning'>You have no backpack to take something out of!</span>")
return
if(equip_to_slot_if_possible(thing, ITEM_SLOT_BACK))
update_inv_hands()
return
if(!SEND_SIGNAL(equipped_back, COMSIG_CONTAINS_STORAGE)) // not a storage item
if(!thing)
equipped_back.attack_hand(src)
else
to_chat(src, "<span class='warning'>You can't fit anything in!</span>")
return
if(thing) // put thing in backpack
if(!SEND_SIGNAL(equipped_back, COMSIG_TRY_STORAGE_INSERT, thing, src))
to_chat(src, "<span class='warning'>You can't fit anything in!</span>")
return
if(!equipped_back.contents.len) // nothing to take out
to_chat(src, "<span class='warning'>There's nothing in your backpack to take out!</span>")
return
var/obj/item/stored = equipped_back.contents[equipped_back.contents.len]
if(!stored || stored.on_found(src))
return
stored.attack_hand(src) // take out thing from backpack
return
/mob/living/carbon/human/proc/smart_equipbelt() // put held thing in belt or take most recent item out of belt
if(incapacitated())
return
var/obj/item/thing = get_active_held_item()
var/obj/item/equipped_belt = get_item_by_slot(SLOT_BELT)
if(!equipped_belt) // We also let you equip a belt like this
if(!thing)
to_chat(src, "<span class='warning'>You have no belt to take something out of!</span>")
return
if(equip_to_slot_if_possible(thing, ITEM_SLOT_BELT))
update_inv_hands()
return
if(!SEND_SIGNAL(equipped_belt, COMSIG_CONTAINS_STORAGE)) // not a storage item
if(!thing)
equipped_belt.attack_hand(src)
else
to_chat(src, "<span class='warning'>You can't fit anything in!</span>")
return
if(thing) // put thing in belt
if(!SEND_SIGNAL(equipped_belt, COMSIG_TRY_STORAGE_INSERT, thing, src))
to_chat(src, "<span class='warning'>You can't fit anything in!</span>")
return
if(!equipped_belt.contents.len) // nothing to take out
to_chat(src, "<span class='warning'>There's nothing in your belt to take out!</span>")
return
var/obj/item/stored = equipped_belt.contents[equipped_belt.contents.len]
if(!stored || stored.on_found(src))
return
stored.attack_hand(src) // take out thing from belt
return
@@ -0,0 +1,4 @@
/mob/living/carbon/human/Login()
..()
if(dna?.species?.has_field_of_vision && CONFIG_GET(flag/use_field_of_vision))
LoadComponent(/datum/component/field_of_vision, field_of_vision_type)
@@ -25,5 +25,8 @@
var/do_after_speed = 1 //Speed mod for do_after. Lower is better. If temporarily adjusting, please only modify using *= and /=, so you don't interrupt other calculations.
/// footstep type override for both shoeless and not footstep sounds.
var/footstep_type
/datum/physiology/New()
armor = new
+83 -59
View File
@@ -10,6 +10,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/default_color = "#FFF" // if alien colors are disabled, this is the color that will be used by that race
var/sexes = 1 // whether or not the race has sexual characteristics. at the moment this is only 0 for skeletons and shadows
var/has_field_of_vision = TRUE
//Species Icon Drawing Offsets - Pixel X, Pixel Y, Aka X = Horizontal and Y = Vertical, from bottom left corner
var/list/offset_features = list(
@@ -49,6 +50,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/blacklisted = 0 //Flag to exclude from green slime core species.
var/dangerous_existence //A flag for transformation spells that tells them "hey if you turn a person into one of these without preperation, they'll probably die!"
var/say_mod = "says" // affects the speech message
var/species_language_holder = /datum/language_holder
var/list/mutant_bodyparts = list() // Visible CURRENT bodyparts that are unique to a species. Changes to this list for non-species specific bodyparts (ie cat ears and tails) should be assigned at organ level if possible. Layer hiding is handled by handle_mutant_bodyparts() below.
var/list/mutant_organs = list() //Internal organs that are unique to this race.
var/speedmod = 0 // this affects the race's speed. positive numbers make it move slower, negative numbers make it move faster
@@ -103,6 +105,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/whitelist = list() //List the ckeys that can use this species, if it's whitelisted.: list("John Doe", "poopface666", "SeeALiggerPullTheTrigger") Spaces & capitalization can be included or ignored entirely for each key as it checks for both.
var/icon_limbs //Overrides the icon used for the limbs of this species. Mainly for downstream, and also because hardcoded icons disgust me. Implemented and maintained as a favor in return for a downstream's implementation of synths.
/// Our default override for typing indicator state
var/typing_indicator_state
///////////
// PROCS //
///////////
@@ -327,6 +332,24 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(mutant_bodyparts["meat_type"]) //I can't believe it's come to the meat
H.type_of_meat = GLOB.meat_types[H.dna.features["meat_type"]]
if(H.physiology)
if(mutant_bodyparts["taur"])
var/datum/sprite_accessory/taur/T = GLOB.taur_list[H.dna.features["taur"]]
switch(T?.taur_mode)
if(STYLE_HOOF_TAURIC)
H.physiology.footstep_type = FOOTSTEP_MOB_SHOE
if(STYLE_PAW_TAURIC)
H.physiology.footstep_type = FOOTSTEP_MOB_CLAW
if(STYLE_SNEK_TAURIC)
H.physiology.footstep_type = FOOTSTEP_MOB_CRAWL
else
H.physiology.footstep_type = null
else
H.physiology.footstep_type = null
if(H.client && has_field_of_vision && CONFIG_GET(flag/use_field_of_vision))
H.LoadComponent(/datum/component/field_of_vision, H.field_of_vision_type)
C.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/species, TRUE, multiplicative_slowdown = speedmod)
SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species)
@@ -360,6 +383,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
C.dna.mutation_index[location] = new_species.inert_mutation
C.dna.mutation_index[new_species.inert_mutation] = create_sequence(new_species.inert_mutation)
if(!new_species.has_field_of_vision && has_field_of_vision && ishuman(C) && CONFIG_GET(flag/use_field_of_vision))
var/datum/component/field_of_vision/F = C.GetComponent(/datum/component/field_of_vision)
if(F)
qdel(F)
SEND_SIGNAL(C, COMSIG_SPECIES_LOSS, src)
/datum/species/proc/handle_hair(mob/living/carbon/human/H, forced_colour)
@@ -1287,7 +1315,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
H.Jitter(5)
hunger_rate = 3 * HUNGER_FACTOR
hunger_rate *= H.physiology.hunger_mod
H.nutrition = max(0, H.nutrition - hunger_rate)
H.adjust_nutrition(-hunger_rate)
if (H.nutrition > NUTRITION_LEVEL_FULL)
@@ -1394,7 +1422,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
/datum/species/proc/grab(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
if(target.check_martial_melee_block())
target.visible_message("<span class='warning'>[target] blocks [user]'s grab attempt!</span>")
target.visible_message("<span class='warning'>[target] blocks [user]'s grab attempt!</span>", target = user, \
target_message = "<span class='warning'>[target] blocks your grab attempt!</span>")
return 0
if(attacker_style && attacker_style.grab_act(user,target))
return 1
@@ -1410,7 +1439,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
to_chat(user, "<span class='warning'>You're too exhausted.</span>") //CITADEL CHANGE - ditto
return FALSE //CITADEL CHANGE - ditto
if(target.check_martial_melee_block())
target.visible_message("<span class='warning'>[target] blocks [user]'s attack!</span>")
target.visible_message("<span class='warning'>[target] blocks [user]'s attack!</span>", target = user, \
target_message = "<span class='warning'>[target] blocks your attack!</span>")
return FALSE
if(HAS_TRAIT(user, TRAIT_PUGILIST))//CITADEL CHANGE - makes punching cause staminaloss but funny martial artist types get a discount
@@ -1465,8 +1495,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(!damage || !affecting || prob(miss_chance))//future-proofing for species that have 0 damage/weird cases where no zone is targeted
playsound(target.loc, user.dna.species.miss_sound, 25, TRUE, -1)
target.visible_message("<span class='danger'>[user]'s [atk_verb] misses [target]!</span>", \
"<span class='danger'>You avoid [user]'s [atk_verb]!</span>", "<span class='hear'>You hear a swoosh!</span>", COMBAT_MESSAGE_RANGE, user)
to_chat(user, "<span class='warning'>Your [atk_verb] misses [target]!</span>")
"<span class='danger'>You avoid [user]'s [atk_verb]!</span>", "<span class='hear'>You hear a swoosh!</span>", null, COMBAT_MESSAGE_RANGE, null, \
user, "<span class='warning'>Your [atk_verb] misses [target]!</span>")
log_combat(user, target, "attempted to punch")
return FALSE
@@ -1475,8 +1505,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
playsound(target.loc, user.dna.species.attack_sound, 25, 1, -1)
target.visible_message("<span class='danger'>[user] has [atk_verb]ed [target]!</span>", \
"<span class='userdanger'>[user] has [atk_verb]ed [target]!</span>", null, COMBAT_MESSAGE_RANGE)
target.visible_message("<span class='danger'>[user] [atk_verb]s [target]!</span>", \
"<span class='userdanger'>[user] [atk_verb]s you!</span>", null, COMBAT_MESSAGE_RANGE, null, \
user, "<span class='danger'>You [atk_verb] [target]!</span>")
target.lastattacker = user.real_name
target.lastattackerckey = user.ckey
@@ -1498,8 +1529,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if((punchedstam > 50) && prob(punchedstam*0.5)) //If our punch victim has been hit above the threshold, and they have more than 50 stamina damage, roll for stun, probability of 1% per 2 stamina damage
target.visible_message("<span class='danger'>[user] knocks [target] down!</span>", \
"<span class='userdanger'>You're knocked down by [user]!</span>", "<span class='hear'>You hear aggressive shuffling followed by a loud thud!</span>", COMBAT_MESSAGE_RANGE, user)
to_chat(user, "<span class='danger'>You knock [target] down!</span>")
"<span class='userdanger'>You're knocked down by [user]!</span>",
"<span class='hear'>You hear aggressive shuffling followed by a loud thud!</span>", COMBAT_MESSAGE_RANGE, null,
user, "<span class='danger'>You knock [target] down!</span>")
var/knockdown_duration = 40 + (punchedstam + (punchedbrute*0.5))*0.8 - armor_block
target.DefaultCombatKnockdown(knockdown_duration)
@@ -1531,23 +1563,20 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/target_aiming_for_groin = target.zone_selected == "groin"
if(target.check_martial_melee_block()) //END EDIT
target.visible_message("<span class='warning'>[target] blocks [user]'s disarm attempt!</span>")
target.visible_message("<span class='warning'>[target] blocks [user]'s disarm attempt!</span>", target = user, \
target_message = "<span class='warning'>[target] blocks your disarm attempt!</span>")
return FALSE
if(IS_STAMCRIT(user))
to_chat(user, "<span class='warning'>You're too exhausted!</span>")
return FALSE
else if(target.check_block())
target.visible_message("<span class='warning'>[target] blocks [user]'s disarm attempt!</span>")
return FALSE
else if(aim_for_mouth && ( target_on_help || target_restrained || target_aiming_for_mouth))
playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1)
user.visible_message(\
"<span class='danger'>\The [user] slaps \the [target] in the face!</span>",\
"<span class='notice'>You slap [user == target ? "yourself" : "\the [target]"] in the face! </span>",\
"You hear a slap."
)
target.visible_message(\
"<span class='danger'>\The [user] slaps [user == target ? "[user.p_them()]self" : "\the [target]"] in the face!</span>",\
"<span class='notice'>[user] slaps you in the face! </span>",\
"You hear a slap.", target = user, target_message = "<span class='notice'>You slap [user == target ? "yourself" : "\the [target]"] in the face! </span>")
user.do_attack_animation(target, ATTACK_EFFECT_FACE_SLAP)
user.adjustStaminaLossBuffered(3)
if (!HAS_TRAIT(target, TRAIT_PERMABONER))
@@ -1565,11 +1594,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if (!HAS_TRAIT(target, TRAIT_PERMABONER))
stop_wagging_tail(target)
playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1)
user.visible_message(\
"<span class='danger'>\The [user] slaps \the [target]'s ass!</span>",\
"<span class='notice'>You slap [user == target ? "your" : "\the [target]'s"] ass!</span>",\
"You hear a slap."
)
target.visible_message(\
"<span class='danger'>\The [user] slaps [user == target ? "[user.p_their()] own" : "\the [target]'s"] ass!</span>",\
"<span class='notice'>[user] slaps your ass! </span>",\
"You hear a slap.", target = user, target_message = "<span class='notice'>You slap [user == target ? "your own" : "\the [target]'s"] ass! </span>")
return FALSE
else
@@ -1588,21 +1617,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
//var/randomized_zone = ran_zone(user.zone_selected) CIT CHANGE - comments out to prevent compiling errors
SEND_SIGNAL(target, COMSIG_HUMAN_DISARM_HIT, user, user.zone_selected)
if(target.pulling == user)
target.visible_message("<span class='warning'>[user] wrestles out of [target]'s grip!</span>")
target.visible_message("<span class='warning'>[user] wrestles out of [target]'s grip!</span>", \
"<span class='warning'>[user] wrestles out of your grip!</span>", target = user, \
target_message = "<span class='warning'>You wrestle out of [target]'s grip!</span>")
target.stop_pulling()
playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
log_combat(user, target, "disarmed out of grab from")
return
//var/obj/item/bodypart/affecting = target.get_bodypart(randomized_zone) CIT CHANGE - comments this out to prevent compile errors due to the below commented out bit
var/randn = rand(1, 100)
/*if(randn <= 25) CITADEL CHANGE - moves disarm push attempts to right click
playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
target.visible_message("<span class='danger'>[user] has pushed [target]!</span>",
"<span class='userdanger'>[user] has pushed [target]!</span>", null, COMBAT_MESSAGE_RANGE)
target.apply_effect(40, EFFECT_KNOCKDOWN, target.run_armor_check(affecting, "melee", "Your armor prevents your fall!", "Your armor softens your fall!"))
target.forcesay(GLOB.hit_appends)
log_combat(user, target, "pushed over")
return*/
if(!(target.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) // CITADEL CHANGE
randn += -10 //CITADEL CHANGE - being out of combat mode makes it easier for you to get disarmed
if(!CHECK_MOBILITY(user, MOBILITY_STAND)) //CITADEL CHANGE
@@ -1619,13 +1641,16 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(randn <= 35)//CIT CHANGE - changes this back to a 35% chance to accomodate for the above being commented out in favor of right-click pushing
var/obj/item/I = null
if(target.pulling)
target.visible_message("<span class='warning'>[user] has broken [target]'s grip on [target.pulling]!</span>")
target.visible_message("<span class='warning'>[user] has broken [target]'s grip on [target.pulling]!</span>", \
"<span class='warning'>[user] has broken your grip on [target.pulling]!</span>", target = user, \
target_message = "<span class='warning'>You have broken [target]'s grip on [target.pulling]!</span>")
target.stop_pulling()
else
I = target.get_active_held_item()
if(target.dropItemToGround(I))
target.visible_message("<span class='danger'>[user] has disarmed [target]!</span>", \
"<span class='userdanger'>[user] has disarmed [target]!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='userdanger'>[user] has disarmed you!</span>", null, COMBAT_MESSAGE_RANGE, null, \
user, "<span class='danger'>You have disarmed [target]!</span>")
else
I = null
playsound(target, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
@@ -1635,7 +1660,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
playsound(target, 'sound/weapons/punchmiss.ogg', 25, 1, -1)
target.visible_message("<span class='danger'>[user] attempted to disarm [target]!</span>", \
"<span class='userdanger'>[user] attemped to disarm [target]!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='userdanger'>[user] attemped to disarm [target]!</span>", null, COMBAT_MESSAGE_RANGE, null, \
user, "<span class='danger'>You attempted to disarm [target]!</span>")
log_combat(user, target, "attempted to disarm")
@@ -1668,20 +1694,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
disarm(M, H, attacker_style)
/datum/species/proc/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
//CIT CHANGES START HERE - combatmode and resting checks
var/totitemdamage = I.force
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
totitemdamage *= 0.5
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
totitemdamage *= 0.5
if(istype(H))
if(!(H.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
totitemdamage *= 1.5
//CIT CHANGES END HERE
var/totitemdamage = H.pre_attacked_by(I, user)
// Allows you to put in item-specific reactions based on species
if(user != H)
var/list/block_return = list()
if(H.run_block(I, I.force, "the [I.name]", ATTACK_TYPE_MELEE, I.armour_penetration, user, affecting.body_zone, return_list = block_return) & BLOCK_SUCCESS)
if(H.mob_run_block(I, totitemdamage, "the [I.name]", ATTACK_TYPE_MELEE, I.armour_penetration, user, affecting.body_zone, block_return) & BLOCK_SUCCESS)
return 0
totitemdamage = block_calculate_resultant_damage(totitemdamage, block_return)
if(H.check_martial_melee_block())
@@ -1704,9 +1721,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
H.send_item_attack_message(I, user, hit_area)
I.do_stagger_action(H, user)
I.do_stagger_action(H, user, totitemdamage)
if(!I.force)
if(!totitemdamage)
return 0 //item force is zero
//dismemberment
@@ -1735,7 +1752,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 20)
if(H.stat == CONSCIOUS)
H.visible_message("<span class='danger'>[H] has been knocked senseless!</span>", \
"<span class='userdanger'>[H] has been knocked senseless!</span>")
"<span class='userdanger'>You have been knocked senseless!</span>")
H.confused = max(H.confused, 20)
H.adjust_blurriness(10)
if(prob(10))
@@ -1791,9 +1808,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
return TRUE
if(M.mind)
attacker_style = M.mind.martial_art
if((M != H) && M.a_intent != INTENT_HELP && (H.run_block(M, 0, "[M]", ATTACK_TYPE_UNARMED, 0, M, M.zone_selected) & BLOCK_SUCCESS))
if((M != H) && M.a_intent != INTENT_HELP && (H.mob_run_block(M, 0, "[M]", ATTACK_TYPE_UNARMED, 0, M, M.zone_selected, null) & BLOCK_SUCCESS))
log_combat(M, H, "attempted to touch")
H.visible_message("<span class='warning'>[M] attempted to touch [H]!</span>")
H.visible_message("<span class='warning'>[M] attempted to touch [H]!</span>", \
"<span class='warning'>[M] attempted to touch you!</span>", target = M, \
target_message = "<span class='warning'>You attempted to touch [H]!</span>")
return TRUE
switch(M.a_intent)
if(INTENT_HELP)
@@ -1830,7 +1849,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
to_chat(user, "<span class='warning'>You're too exhausted.</span>")
return FALSE
if(target.check_martial_melee_block())
target.visible_message("<span class='warning'>[target] blocks [user]'s shoving attempt!</span>")
target.visible_message("<span class='warning'>[target] blocks [user]'s shoving attempt!</span>", \
"<span class='warning'>You block [user]'s shoving attempt!</span>", target = user, \
target_message = "<span class='warning'>[target] blocks your shoving attempt!</span>")
return FALSE
if(attacker_style && attacker_style.disarm_act(user,target))
return TRUE
@@ -1875,19 +1896,22 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
var/targetatrest = !CHECK_MOBILITY(target, MOBILITY_STAND)
if((directional_blocked || !(target_collateral_human || target_shove_turf.shove_act(target, user))) && !targetatrest)
target.DefaultCombatKnockdown(SHOVE_KNOCKDOWN_SOLID)
user.visible_message("<span class='danger'>[user.name] shoves [target.name], knocking them down!</span>",
"<span class='danger'>You shove [target.name], knocking them down!</span>", null, COMBAT_MESSAGE_RANGE)
target.visible_message("<span class='danger'>[user.name] shoves [target.name], knocking them down!</span>",
"<span class='danger'>[user.name] shoves you, knocking you down!</span>", null, COMBAT_MESSAGE_RANGE, null,
user, "<span class='danger'>You shove [target.name], knocking them down!</span>")
log_combat(user, target, "shoved", "knocking them down")
else if(target_collateral_human && !targetatrest)
target.DefaultCombatKnockdown(SHOVE_KNOCKDOWN_HUMAN)
target_collateral_human.DefaultCombatKnockdown(SHOVE_KNOCKDOWN_COLLATERAL)
user.visible_message("<span class='danger'>[user.name] shoves [target.name] into [target_collateral_human.name]!</span>",
"<span class='danger'>You shove [target.name] into [target_collateral_human.name]!</span>", null, COMBAT_MESSAGE_RANGE)
target.visible_message("<span class='danger'>[user.name] shoves [target.name] into [target_collateral_human.name]!</span>",
"<span class='danger'>[user.name] shoves you into [target_collateral_human.name]!</span>", null, COMBAT_MESSAGE_RANGE, null,
user, "<span class='danger'>You shove [target.name] into [target_collateral_human.name]!</span>")
append_message += ", into [target_collateral_human.name]"
else
user.visible_message("<span class='danger'>[user.name] shoves [target.name]!</span>",
"<span class='danger'>You shove [target.name]!</span>", null, COMBAT_MESSAGE_RANGE)
target.visible_message("<span class='danger'>[user.name] shoves [target.name]!</span>",
"<span class='danger'>[user.name] shoves you!</span>", null, COMBAT_MESSAGE_RANGE, null,
user, "<span class='danger'>You shove [target.name]!</span>")
var/obj/item/target_held_item = target.get_active_held_item()
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
target_held_item = null
@@ -9,6 +9,7 @@
gib_types = /obj/effect/gibspawner/robot
damage_overlay_type = "synth"
mutanttongue = /obj/item/organ/tongue/robot
species_language_holder = /datum/language_holder/synthetic
limbs_id = "synth"
/datum/species/android/on_species_gain(mob/living/carbon/C)
@@ -13,6 +13,7 @@
blacklisted = TRUE
limbs_id = "human"
skinned_type = /obj/item/stack/sheet/animalhide/human
has_field_of_vision = FALSE //Too much of a trouble, their vision is already bound to their severed head.
var/pumpkin = FALSE
var/obj/item/dullahan_relay/myhead
@@ -132,13 +133,13 @@
return INITIALIZE_HINT_QDEL
owner = new_owner
START_PROCESSING(SSobj, src)
RegisterSignal(owner, COMSIG_CLICK_SHIFT, .proc/examinate_check)
RegisterSignal(owner, COMSIG_MOB_CLICKED_SHIFT_ON, .proc/examinate_check)
RegisterSignal(src, COMSIG_ATOM_HEARER_IN_VIEW, .proc/include_owner)
RegisterSignal(owner, COMSIG_LIVING_REGENERATE_LIMBS, .proc/unlist_head)
RegisterSignal(owner, COMSIG_LIVING_REVIVE, .proc/retrieve_head)
/obj/item/dullahan_relay/proc/examinate_check(atom/source, mob/user)
if(user.client.eye == src)
/obj/item/dullahan_relay/proc/examinate_check(mob/source, atom/target)
if(source.client.eye == src)
return COMPONENT_ALLOW_EXAMINATE
/obj/item/dullahan_relay/proc/include_owner(datum/source, list/processing_list, list/hearers)
@@ -17,6 +17,7 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
disliked_food = JUNKFOOD | FRIED //Dwarves hate foods that have no nutrition other than alcohol.
mutant_organs = list(/obj/item/organ/dwarfgland) //Dwarven alcohol gland, literal gland warrior
mutantliver = /obj/item/organ/liver/dwarf //Dwarven super liver (Otherwise they r doomed)
species_language_holder = /datum/language_holder/dwarf
/mob/living/carbon/human/species/dwarf //species admin spawn path
race = /datum/species/dwarf //and the race the path is set to.
@@ -30,17 +31,14 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
. = ..()
var/dwarf_hair = pick("Beard (Dwarf)", "Beard (Very Long)", "Beard (Long)") //beard roullette
var/mob/living/carbon/human/H = C
H.grant_language(/datum/language/dwarf)
H.facial_hair_style = dwarf_hair
H.update_hair()
H.transform = H.transform.Scale(1, 0.8) //We use scale, and yeah. Dwarves can become gnomes with DWARFISM.
H.AddElement(/datum/element/dwarfism, COMSIG_SPECIES_LOSS, src)
RegisterSignal(C, COMSIG_MOB_SAY, .proc/handle_speech) //We register handle_speech is being used.
/datum/species/dwarf/on_species_loss(mob/living/carbon/H, datum/species/new_species)
. = ..()
H.transform = H.transform.Scale(1, 1.25) //And we undo it.
UnregisterSignal(H, COMSIG_MOB_SAY) //We register handle_speech is not being used.
H.remove_language(/datum/language/dwarf)
//Dwarf Name stuff
/proc/dwarf_name() //hello caller: my name is urist mcuristurister
@@ -122,7 +120,7 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
return
//Filth Reactions - Since miasma now exists
var/filth_counter = 0 //Holder for the filth check cycle, basically contains how much filth dwarf sees numerically.
for(var/fuck in view(owner,7)) //hello byond for view loop.
for(var/fuck in owner.fov_view(7)) //hello byond for view loop.
if(istype(fuck, /mob/living/carbon/human))
var/mob/living/carbon/human/H = fuck
if(H.stat == DEAD || (HAS_TRAIT(H, TRAIT_FAKEDEATH)))
@@ -293,9 +293,7 @@
if(isturf(H.loc)) //else, there's considered to be no light
var/turf/T = H.loc
light_amount = min(1,T.get_lumcount()) - 0.5
H.nutrition += light_amount * 10
if(H.nutrition > NUTRITION_LEVEL_FULL)
H.nutrition = NUTRITION_LEVEL_FULL
H.adjust_nutrition(light_amount * 4, NUTRITION_LEVEL_FULL)
if(light_amount > 0.2) //if there's enough light, heal
H.heal_overall_damage(1,1)
H.adjustToxLoss(-1)
@@ -21,20 +21,19 @@
coldmod = 6 // = 3x cold damage
heatmod = 0.5 // = 1/4x heat damage
burnmod = 0.5 // = 1/2x generic burn damage
species_language_holder = /datum/language_holder/jelly
/datum/species/jelly/on_species_loss(mob/living/carbon/C)
if(regenerate_limbs)
regenerate_limbs.Remove(C)
if(slime_change) //CIT CHANGE
slime_change.Remove(C) //CIT CHANGE
C.remove_language(/datum/language/slime)
C.faction -= "slime"
..()
C.faction -= "slime"
/datum/species/jelly/on_species_gain(mob/living/carbon/C, datum/species/old_species)
..()
C.grant_language(/datum/language/slime)
if(ishuman(C))
regenerate_limbs = new
regenerate_limbs.Grant(C)
@@ -24,9 +24,7 @@
disliked_food = GRAIN | DAIRY
liked_food = GROSS | MEAT
inert_mutation = FIREBREATH
/datum/species/lizard/after_equip_job(datum/job/J, mob/living/carbon/human/H)
H.grant_language(/datum/language/draconic)
species_language_holder = /datum/language_holder/lizard
/datum/species/lizard/random_name(gender,unique,lastname)
if(unique)
@@ -86,6 +84,7 @@
mutantlungs = /obj/item/organ/lungs/ashwalker
burnmod = 0.9
brutemod = 0.9
species_language_holder = /datum/language_holder/lizard/ash
/datum/species/lizard/ashwalker/on_species_gain(mob/living/carbon/human/C, datum/species/old_species)
if((C.dna.features["spines"] != "None" ) && (C.dna.features["tail_lizard"] == "None")) //tbh, it's kinda ugly for them not to have a tail yet have floating spines
@@ -23,9 +23,7 @@
mutanteyes = /obj/item/organ/eyes/night_vision/mushroom
var/datum/martial_art/mushpunch/mush
/datum/species/mush/after_equip_job(datum/job/J, mob/living/carbon/human/H)
H.grant_language(/datum/language/mushroom) //pomf pomf
species_language_holder = /datum/language_holder/mushroom
/datum/species/mush/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
@@ -12,7 +12,8 @@
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/plant
disliked_food = MEAT | DAIRY
liked_food = VEGETABLES | FRUIT | GRAIN
var/light_nutrition_gain_factor = 10
species_language_holder = /datum/language_holder/sylvan
var/light_nutrition_gain_factor = 4
var/light_toxheal = 1
var/light_oxyheal = 1
var/light_burnheal = 1
@@ -35,9 +36,7 @@
if(isturf(H.loc)) //else, there's considered to be no light
var/turf/T = H.loc
light_amount = min(1,T.get_lumcount()) - 0.5
H.nutrition += light_amount * light_nutrition_gain_factor
if(H.nutrition >= NUTRITION_LEVEL_FULL)
H.nutrition = NUTRITION_LEVEL_FULL - 1
H.adjust_nutrition(light_amount * light_nutrition_gain_factor, NUTRITION_LEVEL_FULL)
if(light_amount > 0.2) //if there's enough light, heal
H.heal_overall_damage(light_bruteheal, light_burnheal)
H.adjustToxLoss(-light_toxheal)
@@ -69,8 +68,7 @@
H.adjustFireLoss(rand(5,15))
H.show_message("<span class='userdanger'>The radiation beam singes you!</span>")
if(/obj/item/projectile/energy/florayield)
H.nutrition = min(H.nutrition+30, NUTRITION_LEVEL_FULL)
H.adjust_nutrition(30, NUTRITION_LEVEL_FULL)
/datum/species/pod/pseudo_weak
name = "Anthromorphic Plant"
@@ -78,7 +76,7 @@
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS)
mutant_bodyparts = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "mam_body_markings" = "Husky", "taur" = "None", "legs" = "Normal Legs")
limbs_id = "pod"
light_nutrition_gain_factor = 7.5
light_nutrition_gain_factor = 3
light_bruteheal = 0.2
light_burnheal = 0.2
light_toxheal = 0.7
@@ -16,6 +16,7 @@
var/list/initial_inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOLIMBDISABLE,TRAIT_NOHUNGER,TRAIT_NOBREATH)
var/disguise_fail_health = 75 //When their health gets to this level their synthflesh partially falls off
var/datum/species/fake_species = null //a species to do most of our work for us, unless we're damaged
species_language_holder = /datum/language_holder/synthetic
/datum/species/synth/military
name = "Military Synth"
@@ -34,12 +34,11 @@
/mob/living/carbon/human/set_drugginess(amount)
..()
if(!amount)
remove_language(/datum/language/beachbum)
remove_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH)
/mob/living/carbon/human/adjust_drugginess(amount)
..()
if(!dna.check_mutation(STONER))
if(druggy)
grant_language(/datum/language/beachbum)
else
remove_language(/datum/language/beachbum)
if(druggy)
grant_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH)
else
remove_language(/datum/language/beachbum, TRUE, TRUE, LANGUAGE_HIGH)
@@ -0,0 +1,2 @@
/mob/living/carbon/human/get_typing_indicator_icon_state()
return dna?.species?.typing_indicator_state || ..()
+17 -5
View File
@@ -476,7 +476,7 @@
if(SSmobs.times_fired%3==1)
if(!(M.status_flags & GODMODE))
M.adjustBruteLoss(5)
nutrition += 10
adjust_nutrition(10)
/*
@@ -502,11 +502,23 @@ GLOBAL_LIST_INIT(ballmer_good_msg, list("Hey guys, what if we rolled out a blues
"Hear me out here. What if, and this is just a theory, we made R&D controllable from our PDAs?",
"I'm thinking we should roll out a git repository for our research under the AGPLv3 license so that we can share it among the other stations freely.",
"I dunno about you guys, but IDs and PDAs being separate is clunky as fuck. Maybe we should merge them into a chip in our arms? That way they can't be stolen easily.",
"Why the fuck aren't we just making every pair of shoes into galoshes? We have the technology."))
"Why the fuck aren't we just making every pair of shoes into galoshes? We have the technology.",
"We can link the Ore Silo to our protolathes, so why don't we also link it to autolathes?",
"If we can make better bombs with heated plasma, oxygen, and tritium, then why do station nukes still use plutonium?",
"We should port all our NT programs to modular consoles and do away with computers. They're way more customizable, support cross-platform usage, and would allow crazy amounts of multitasking.",
"Wait, if we use more manipulators in something, then it prints for cheaper, right? So what if we just made a new type of printer that has like 12 manipulators inside of it to print stuff for really cheap?"
))
GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put a webserver that's automatically turned on with default admin passwords into every PDA?",
"So like, you know how we separate our codebase from the master copy that runs on our consumer boxes? What if we merged the two and undid the separation between codebase and server?",
"Dude, radical idea: H.O.N.K mechs but with no bananium required.",
"Best idea ever: Disposal pipes instead of hallways."))
"So like, you know how we separate our codebase from the master copy that runs on our consumer boxes? What if we merged the two and undid the separation between codebase and server?",
"Dude, radical idea: H.O.N.K mechs but with no bananium required.",
"Best idea ever: Disposal pipes instead of hallways.",
"What if we use a language that was written on a napkin and created over 1 weekend for all of our servers?",
"What if we took a locker, some random trash, and made an exosuit out of it? Wouldn't that be like, super cool and stuff?",
"Okay, hear me out, what if we make illegal things not illegal, so that sec stops arresting us for having it?",
"I have a crazy idea, guys. Rather than having monkeys to test on, what if we only used apes?",
"Woh man ok, what if we took slime cores and smashed them into other slimes, be kinda cool to see what happens.",
"We're NANOtrasen but we need to unlock nano parts, what's the deal with that?"
))
//this updates all special effects: stun, sleeping, knockdown, druggy, stuttering, etc..
/mob/living/carbon/handle_status_effects()
@@ -45,6 +45,7 @@
/mob/living/carbon/monkey/ComponentInitialize()
. = ..()
AddElement(/datum/element/mob_holder, worn_state = "monkey", inv_slots = ITEM_SLOT_HEAD)
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_BAREFOOT, 1, 2)
/mob/living/carbon/monkey/Destroy()
+3 -3
View File
@@ -12,9 +12,9 @@
return 0
return ..()
/mob/living/carbon/could_speak_in_language(datum/language/dt)
/mob/living/carbon/could_speak_language(datum/language/language)
var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE)
if(T)
. = T.could_speak_in_language(dt)
return T.could_speak_language(language)
else
. = initial(dt.flags) & TONGUELESS_SPEECH
return initial(language.flags) & TONGUELESS_SPEECH
+26 -16
View File
@@ -9,10 +9,6 @@
diag_hud.add_to_hud(src)
faction += "[REF(src)]"
GLOB.mob_living_list += src
initialize_footstep()
/mob/living/proc/initialize_footstep()
AddComponent(/datum/component/footstep)
/mob/living/prepare_huds()
..()
@@ -46,7 +42,8 @@
return ..()
/mob/living/proc/ZImpactDamage(turf/T, levels)
visible_message("<span class='danger'>[src] crashes into [T] with a sickening noise!</span>")
visible_message("<span class='danger'>[src] crashes into [T] with a sickening noise!</span>", \
"<span class='userdanger'>You crash into [T] with a sickening noise!</span>")
adjustBruteLoss((levels * 5) ** 1.5)
DefaultCombatKnockdown(levels * 50)
@@ -124,7 +121,9 @@
to_chat(src, "<span class='warning'>You're too exhausted to crawl under [L].</span>")
return TRUE
ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_ATTEMPTING_CRAWL)
visible_message("<span class='notice'>[src] is attempting to crawl under [L].</span>", "<span class='notice'>You are now attempting to crawl under [L].</span>")
visible_message("<span class='notice'>[src] is attempting to crawl under [L].</span>",
"<span class='notice'>You are now attempting to crawl under [L].</span>",
target = L, target_message = "<span class='notice'>[src] is attempting to crawl under you.</span>")
if(!do_after(src, CRAWLUNDER_DELAY, target = src) || CHECK_MOBILITY(src, MOBILITY_STAND))
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_ATTEMPTING_CRAWL)
return TRUE
@@ -276,7 +275,9 @@
if(AM.pulledby)
if(!supress_message)
visible_message("<span class='danger'>[src] has pulled [AM] from [AM.pulledby]'s grip.</span>")
AM.pulledby.visible_message("<span class='danger'>[src] has pulled [AM] from [AM.pulledby]'s grip.</span>",
"<span class='danger'>[src] has pulled [AM] from your grip.</span>", target = src,
target_message = "<span class='danger'>You have pulled [AM] from [AM.pulledby]'s grip.</span>")
log_combat(AM, AM.pulledby, "pulled from", src)
AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
@@ -291,7 +292,9 @@
log_combat(src, M, "grabbed", addition="passive grab")
if(!supress_message && !(iscarbon(AM) && HAS_TRAIT(src, TRAIT_STRONG_GRABBER)))
visible_message("<span class='warning'>[src] has grabbed [M][(zone_selected == "l_arm" || zone_selected == "r_arm")? " by their hands":" passively"]!</span>") //Cit change - And they thought ERP was bad.
visible_message("<span class='warning'>[src] has grabbed [M][(zone_selected == "l_arm" || zone_selected == "r_arm")? " by [M.p_their()] hands":" passively"]!</span>",
"<span class='warning'>You have grabbed [M][(zone_selected == "l_arm" || zone_selected == "r_arm")? " by [M.p_their()] hands":" passively"]!</span>", target = M,
target_message = "<span class='warning'>[src] has grabbed you[(zone_selected == "l_arm" || zone_selected == "r_arm")? " by your hands":" passively"]!</span>")
if(!iscarbon(src))
M.LAssailant = null
else
@@ -379,7 +382,7 @@
stop_pulling()
//same as above
/mob/living/pointed(atom/A as mob|obj|turf in view())
/mob/living/pointed(atom/A as mob|obj|turf in fov_view())
if(incapacitated())
return FALSE
if(HAS_TRAIT(src, TRAIT_DEATHCOMA))
@@ -563,7 +566,7 @@
SetAllImmobility(0, FALSE)
SetSleeping(0, FALSE)
radiation = 0
nutrition = NUTRITION_LEVEL_FED + 50
set_nutrition(NUTRITION_LEVEL_FED + 50)
bodytemperature = BODYTEMP_NORMAL
set_blindness(0)
set_blurriness(0)
@@ -756,12 +759,16 @@
. = ..()
if(pulledby.grab_state > GRAB_PASSIVE)
if(CHECK_MOBILITY(src, MOBILITY_RESIST) && prob(30/pulledby.grab_state))
visible_message("<span class='danger'>[src] has broken free of [pulledby]'s grip!</span>")
pulledby.visible_message("<span class='danger'>[src] has broken free of [pulledby]'s grip!</span>",
"<span class='danger'>[src] has broken free of your grip!</span>", target = src,
target_message = "<span class='danger'>You have broken free of [pulledby]'s grip!</span>")
pulledby.stop_pulling()
return TRUE
else if(moving_resist && client) //we resisted by trying to move // this is a horrible system and whoever thought using client instead of mob is okay is not an okay person
client.move_delay = world.time + 20
visible_message("<span class='danger'>[src] resists against [pulledby]'s grip!</span>")
pulledby.visible_message("<span class='danger'>[src] resists against [pulledby]'s grip!</span>",
"<span class='danger'>[src] resists against your grip!</span>", target = src,
target_message = "<span class='danger'>You resist against [pulledby]'s grip!</span>")
else
pulledby.stop_pulling()
return TRUE
@@ -826,7 +833,8 @@
strip_silence = g.strip_silence
if (!strip_silence)
who.visible_message("<span class='danger'>[src] tries to remove [who]'s [what.name].</span>", \
"<span class='userdanger'>[src] tries to remove [who]'s [what.name].</span>")
"<span class='userdanger'>[src] tries to remove your [what.name].</span>", target = src,
target_message = "<span class='danger'>You try to remove [who]'s [what.name].</span>")
what.add_fingerprint(src)
else
to_chat(src,"<span class='notice'>You try to remove [who]'s [what.name].</span>")
@@ -874,7 +882,9 @@
to_chat(src, "<span class='warning'>\The [what.name] doesn't fit in that place!</span>")
return
visible_message("<span class='notice'>[src] tries to put [what] on [who].</span>")
who.visible_message("<span class='notice'>[src] tries to put [what] on [who].</span>",
"<span class='notice'>[src] tries to put [what] on you.</span>", target = src,
target_message = "<span class='notice'>You try to put [what] on [who].</span>")
if(do_mob(src, who, what.equip_delay_other))
if(what && Adjacent(who) && what.mob_can_equip(who, src, final_where, TRUE, TRUE))
if(temporarilyRemoveItemFromInventory(what))
@@ -899,7 +909,7 @@
var/final_pixel_y = get_standard_pixel_y_offset(lying)
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = 6)
animate(pixel_x = final_pixel_x , pixel_y = final_pixel_y , time = 2)
setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure to restart it in next life().
floating_need_update = TRUE
/mob/living/proc/get_temperature(datum/gas_mixture/environment)
var/loc_temp = environment ? environment.temperature : T0C
@@ -1058,7 +1068,7 @@
/mob/living/proc/IgniteMob()
if(fire_stacks > 0 && !on_fire)
on_fire = 1
src.visible_message("<span class='warning'>[src] catches fire!</span>", \
visible_message("<span class='warning'>[src] catches fire!</span>", \
"<span class='userdanger'>You're set on fire!</span>")
new/obj/effect/dummy/lighting_obj/moblight/fire(src)
throw_alert("fire", /obj/screen/alert/fire)
+4 -10
View File
@@ -1,12 +1,5 @@
// This file has a weird name, but it's for anything related to the checks for shields, blocking, dodging, and similar "stop this attack before it actually impacts the target" as opposed to "defend once it has hit".
///Check whether or not we can block, without "triggering" a block. Basically run checks without effects like depleting shields. Wrapper for do_run_block(). The arguments on that means the same as for this.
/mob/living/proc/check_block(atom/object, damage, attack_text = "the attack", attack_type, armour_penetration, mob/attacker, def_zone, list/return_list, attack_direction)
return do_run_block(FALSE, object, damage, attack_text, attack_type, armour_penetration, attacker, check_zone(def_zone), return_list, attack_direction)
/// Runs a block "sequence", effectively checking and then doing effects if necessary. Wrapper for do_run_block(). The arguments on that means the same as for this.
/mob/living/proc/run_block(atom/object, damage, attack_text = "the attack", attack_type, armour_penetration, mob/attacker, def_zone, list/return_list, attack_direction)
return do_run_block(TRUE, object, damage, attack_text, attack_type, armour_penetration, attacker, check_zone(def_zone), return_list, attack_direction)
// This file has a weird name, but it's for anything related to the checks for shields, blocking, dodging,
// and similar "stop this attack before it actually impacts the target" as opposed to "defend once it has hit".
/** The actual proc for block checks. DO NOT USE THIS DIRECTLY UNLESS YOU HAVE VERY GOOD REASON TO. To reduce copypaste for differences between handling for real attacks and virtual checks.
* Automatically checks all held items for /obj/item/proc/run_block() with the same parameters.
@@ -84,7 +77,8 @@
if(. & BLOCK_SUCCESS)
return
if(prob(final_block_chance))
owner.visible_message("<span class='danger'>[owner] blocks [attack_text] with [src]!</span>")
owner.visible_message("<span class='danger'>[owner] blocks [attack_text] with [src]!</span>",
"<span class='danger'>You block [attack_text] with [src]!</span>")
return . | BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
return . | BLOCK_NONE
+6 -1
View File
@@ -17,7 +17,7 @@
update_combat_mode_icon()
/mob/living/proc/disable_combat_mode(silent = TRUE, was_forced = FALSE, visible = FALSE, update_icon = TRUE)
if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) || (combat_flags & COMBAT_FLAG_COMBAT_FORCED))
return
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_ACTIVE)
SEND_SIGNAL(src, COMSIG_LIVING_COMBAT_DISABLED, was_forced)
@@ -61,6 +61,8 @@
/mob/living/proc/disable_intentional_combat_mode(silent = TRUE, visible = FALSE)
if(!(combat_flags & COMBAT_FLAG_COMBAT_TOGGLED) && !(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
return
if(combat_flags & COMBAT_FLAG_COMBAT_FORCED)
return
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_TOGGLED)
if(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)
disable_combat_mode(silent, FALSE, visible, FALSE)
@@ -72,6 +74,9 @@
/mob/living/proc/user_toggle_intentional_combat_mode(visible = TRUE)
var/old = (combat_flags & COMBAT_FLAG_COMBAT_TOGGLED)
if(old)
if(combat_flags & COMBAT_FLAG_COMBAT_FORCED)
to_chat(src, "<span class='warning'>You are unable to relax your muscles.</span>")
return
disable_intentional_combat_mode()
playsound_local(src, 'sound/misc/ui_toggleoff.ogg', 50, FALSE, pressure_affected = FALSE) //Slightly modified version of the above!
else if(CAN_TOGGLE_COMBAT_MODE(src))
+79 -44
View File
@@ -43,21 +43,21 @@
P.setAngle(SIMPLIFY_DEGREES(P.Angle + rand(120, 240)))
if(!silent)
visible_message("<span class='danger'>[P] gets deflected by [src]!</span>", \
"<span class='userdanger'>[P] gets deflected by [src]!</span>")
"<span class='userdanger'>You deflect [P]!</span>")
if(REDIRECT_METHOD_REFLECT)
P.setAngle(SIMPLIFY_DEGREES(P.Angle + 180))
if(!silent)
visible_message("<span class='danger'>[P] gets reflected by [src]!</span>", \
"<span class='userdanger'>[P] gets reflected by [src]!</span>")
"<span class='userdanger'>You reflect [P]!</span>")
if(REDIRECT_METHOD_PASSTHROUGH)
if(!silent)
visible_message("<span class='danger'>[P] passes through [src]!</span>", \
"<span class='userdanger'>[P] passes through [src]!</span>")
"<span class='userdanger'>[P] passes through you!</span>")
return
if(REDIRECT_METHOD_RETURN_TO_SENDER)
if(!silent)
visible_message("<span class='danger'>[src] deflects [P] back at their attacker!</span>", \
"<span class='userdanger'>[src] deflects [P] back at their attacker!</span>")
"<span class='userdanger'>You deflect [P] back at your attacker!</span>")
if(P.firer)
P.setAngle(Get_Angle(src, P.firer))
else
@@ -69,7 +69,7 @@
var/totaldamage = P.damage
if(P.original != src || P.firer != src) //try to block or reflect the bullet, can't do so when shooting oneself
var/list/returnlist = list()
var/returned = run_block(P, P.damage, "the [P.name]", ATTACK_TYPE_PROJECTILE, P.armour_penetration, P.firer, def_zone, returnlist)
var/returned = mob_run_block(P, P.damage, "the [P.name]", ATTACK_TYPE_PROJECTILE, P.armour_penetration, P.firer, def_zone, returnlist)
if(returned & BLOCK_SHOULD_REDIRECT)
handle_projectile_attack_redirection(P, returnlist[BLOCK_RETURN_REDIRECT_METHOD])
if(returned & BLOCK_REDIRECTED)
@@ -115,7 +115,7 @@
var/impacting_zone = ran_zone(BODY_ZONE_CHEST, 65)//Hits a random part of the body, geared towards the chest
var/list/block_return = list()
var/total_damage = I.throwforce
if(run_block(AM, throwpower, "\the [AM.name]", ATTACK_TYPE_THROWN, 0, throwingdatum?.thrower, impacting_zone, return_list = block_return) & BLOCK_SUCCESS)
if(mob_run_block(AM, throwpower, "\the [AM.name]", ATTACK_TYPE_THROWN, 0, throwingdatum?.thrower, impacting_zone, block_return) & BLOCK_SUCCESS)
hitpush = FALSE
skipcatch = TRUE
blocked = TRUE
@@ -146,7 +146,7 @@
playsound(loc, 'sound/weapons/throwtap.ogg', 1, volume, -1)//...play throwtap.ogg.
if(!blocked)
visible_message("<span class='danger'>[src] has been hit by [I].</span>", \
"<span class='userdanger'>[src] has been hit by [I].</span>")
"<span class='userdanger'>You have been hit by [I].</span>")
var/armor = run_armor_check(impacting_zone, "melee", "Your armor has protected your [parse_zone(impacting_zone)].", "Your armor has softened hit to your [parse_zone(impacting_zone)].",I.armour_penetration)
apply_damage(total_damage, dtype, impacting_zone, armor)
if(I.thrownby)
@@ -180,12 +180,15 @@
return
updatehealth()
visible_message("<span class='danger'>[M.name] has hit [src]!</span>", \
"<span class='userdanger'>[M.name] has hit [src]!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='userdanger'>[M.name] has hit you!</span>", null, COMBAT_MESSAGE_RANGE, null,
M.occupant, "<span class='danger'>You hit [src] with your [M.name]!</span>")
log_combat(M.occupant, src, "attacked", M, "(INTENT: [uppertext(M.occupant.a_intent)]) (DAMTYPE: [uppertext(M.damtype)])")
else
step_away(src,M)
log_combat(M.occupant, src, "pushed", M)
visible_message("<span class='warning'>[M] pushes [src] out of the way.</span>", null, null, 5)
visible_message("<span class='warning'>[M] pushes [src] out of the way.</span>", \
"<span class='warning'>[M] pushes you out of the way.</span>", null, COMBAT_MESSAGE_RANGE, null,
M.occupant, "<span class='warning'>You push [src] out of the way with your [M.name].</span>")
/mob/living/fire_act()
adjust_fire_stacks(3)
@@ -229,7 +232,8 @@
var/old_grab_state = user.grab_state
var/grab_upgrade_time = instant ? 0 : 30
visible_message("<span class='danger'>[user] starts to tighten [user.p_their()] grip on [src]!</span>", \
"<span class='userdanger'>[user] starts to tighten [user.p_their()] grip on you!</span>")
"<span class='userdanger'>[user] starts to tighten [user.p_their()] grip on you!</span>", target = user,
target_message = "<span class='danger'>You start to tighten your grip on [src]!</span>")
switch(user.grab_state)
if(GRAB_AGGRESSIVE)
log_combat(user, src, "attempted to neck grab", addition="neck grab")
@@ -247,25 +251,29 @@
var/add_log = ""
if(HAS_TRAIT(user, TRAIT_PACIFISM))
visible_message("<span class='danger'>[user] has firmly gripped [src]!</span>",
"<span class='danger'>[user] has firmly gripped you!</span>")
"<span class='danger'>[user] has firmly gripped you!</span>", target = user,
target_message = "<span class='danger'>You have firmly gripped [src]!</span>")
add_log = " (pacifist)"
else
visible_message("<span class='danger'>[user] has grabbed [src] aggressively!</span>", \
"<span class='userdanger'>[user] has grabbed you aggressively!</span>")
"<span class='userdanger'>[user] has grabbed you aggressively!</span>", target = user, \
target_message = "<span class='danger'>You have grabbed [src] aggressively!</span>")
update_mobility()
stop_pulling()
log_combat(user, src, "grabbed", addition="aggressive grab[add_log]")
if(GRAB_NECK)
log_combat(user, src, "grabbed", addition="neck grab")
visible_message("<span class='danger'>[user] has grabbed [src] by the neck!</span>",\
"<span class='userdanger'>[user] has grabbed you by the neck!</span>")
"<span class='userdanger'>[user] has grabbed you by the neck!</span>", target = user, \
target_message = "<span class='danger'>You have grabbed [src] by the neck!</span>")
update_mobility() //we fall down
if(!buckled && !density)
Move(user.loc)
if(GRAB_KILL)
log_combat(user, src, "strangled", addition="kill grab")
visible_message("<span class='danger'>[user] is strangling [src]!</span>", \
"<span class='userdanger'>[user] is strangling you!</span>")
"<span class='userdanger'>[user] is strangling you!</span>", target = user, \
target_message = "<span class='danger'>You are strangling [src]!</span>")
update_mobility() //we fall down
if(!buckled && !density)
Move(user.loc)
@@ -275,9 +283,11 @@
/mob/living/attack_hand(mob/user)
..() //Ignoring parent return value here.
SEND_SIGNAL(src, COMSIG_MOB_ATTACK_HAND, user)
if((user != src) && user.a_intent != INTENT_HELP && (run_block(user, 0, user.name, ATTACK_TYPE_UNARMED | ATTACK_TYPE_MELEE, null, user, check_zone(user.zone_selected)) & BLOCK_SUCCESS))
if((user != src) && user.a_intent != INTENT_HELP && (mob_run_block(user, 0, user.name, ATTACK_TYPE_UNARMED | ATTACK_TYPE_MELEE, null, user, check_zone(user.zone_selected), null) & BLOCK_SUCCESS))
log_combat(user, src, "attempted to touch")
visible_message("<span class='warning'>[user] attempted to touch [src]!</span>")
visible_message("<span class='warning'>[user] attempted to touch [src]!</span>",
"<span class='warning'>[user] attempted to touch you!</span>", target = user,
target_message = "<span class='warning'>You attempted to touch [src]!</span>")
return TRUE
/mob/living/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
@@ -286,7 +296,7 @@
to_chat(user, "<span class='notice'>You don't want to hurt [src]!</span>")
return TRUE
var/hulk_verb = pick("smash","pummel")
if(user != src && (run_block(user, 15, "the [hulk_verb]ing", ATTACK_TYPE_MELEE, null, user, check_zone(user.zone_selected)) & BLOCK_SUCCESS))
if(user != src && (mob_run_block(user, 15, "the [hulk_verb]ing", ATTACK_TYPE_MELEE, null, user, check_zone(user.zone_selected), null) & BLOCK_SUCCESS))
return TRUE
..()
return FALSE
@@ -309,7 +319,7 @@
if(M.is_adult)
damage = rand(20, 40)
var/list/block_return = list()
if(run_block(M, damage, "the [M.name]", ATTACK_TYPE_MELEE, null, M, check_zone(M.zone_selected), return_list = block_return) & BLOCK_SUCCESS)
if(mob_run_block(M, damage, "the [M.name]", ATTACK_TYPE_MELEE, null, M, check_zone(M.zone_selected), block_return) & BLOCK_SUCCESS)
return FALSE
damage = block_calculate_resultant_damage(damage, block_return)
@@ -317,25 +327,29 @@
log_combat(M, src, "attacked")
M.do_attack_animation(src)
visible_message("<span class='danger'>The [M.name] glomps [src]!</span>", \
"<span class='userdanger'>The [M.name] glomps [src]!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='userdanger'>The [M.name] glomps [src]!</span>", null, COMBAT_MESSAGE_RANGE, null,
M, "<span class='danger'>You glomp [src]!</span>")
return TRUE
/mob/living/attack_animal(mob/living/simple_animal/M)
M.face_atom(src)
if(M.melee_damage_upper == 0)
M.visible_message("<span class='notice'>\The [M] [M.friendly] [src]!</span>")
M.visible_message("<span class='notice'>\The [M] [M.friendly_verb_continuous] [src]!</span>",
"<span class='notice'>You [M.friendly_verb_simple] [src]!</span>", target = src,
target_message = "<span class='notice'>\The [M] [M.friendly_verb_continuous] you!</span>")
return FALSE
else
if(HAS_TRAIT(M, TRAIT_PACIFISM))
to_chat(M, "<span class='notice'>You don't want to hurt anyone!</span>")
return FALSE
if(run_block(M, rand(M.melee_damage_lower, M.melee_damage_upper), "the [M.name]", ATTACK_TYPE_MELEE, M.armour_penetration, M, check_zone(M.zone_selected)) & BLOCK_SUCCESS)
if(mob_run_block(M, rand(M.melee_damage_lower, M.melee_damage_upper), "the [M.name]", ATTACK_TYPE_MELEE, M.armour_penetration, M, check_zone(M.zone_selected), null) & BLOCK_SUCCESS)
return FALSE
if(M.attack_sound)
playsound(loc, M.attack_sound, 50, 1, 1)
M.do_attack_animation(src)
visible_message("<span class='danger'>\The [M] [M.attacktext] [src]!</span>", \
"<span class='userdanger'>\The [M] [M.attacktext] [src]!</span>", null, COMBAT_MESSAGE_RANGE)
visible_message("<span class='danger'>\The [M] [M.attack_verb_continuous] [src]!</span>", \
"<span class='userdanger'>\The [M] [M.attack_verb_continuous] you!</span>", null, COMBAT_MESSAGE_RANGE, null,
M, "<span class='danger'>You [M.attack_verb_simple] [src]!</span>")
log_combat(M, src, "attacked")
return TRUE
@@ -347,51 +361,60 @@
if(M.is_muzzled() || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
to_chat(M, "<span class='warning'>You can't bite with your mouth covered!</span>")
return FALSE
if(run_block(M, 0, "the [M.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, M, check_zone(M.zone_selected)) & BLOCK_SUCCESS)
if(mob_run_block(M, 0, "the [M.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, 0, M, check_zone(M.zone_selected), null) & BLOCK_SUCCESS)
return FALSE
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
if (prob(75))
log_combat(M, src, "attacked")
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
visible_message("<span class='danger'>[M.name] bites [src]!</span>", \
"<span class='userdanger'>[M.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='userdanger'>[M.name] bites you!</span>", null, COMBAT_MESSAGE_RANGE, null,
M, "<span class='danger'>You bite [src]!</span>")
return TRUE
else
visible_message("<span class='danger'>[M.name] has attempted to bite [src]!</span>", \
"<span class='userdanger'>[M.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='userdanger'>[M.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE, null,
M, "<span class='danger'>You have attempted to bite [src]!</span>")
return FALSE
/mob/living/attack_larva(mob/living/carbon/alien/larva/L)
switch(L.a_intent)
if(INTENT_HELP)
visible_message("<span class='notice'>[L.name] rubs its head against [src].</span>")
visible_message("<span class='notice'>[L.name] rubs its head against [src].</span>",
"<span class='notice'>[L.name] rubs its head against you.</span>", target = L, \
target_message = "<span class='notice'>You rub your head against [src].</span>")
return FALSE
else
if(HAS_TRAIT(L, TRAIT_PACIFISM))
to_chat(L, "<span class='notice'>You don't want to hurt anyone!</span>")
return FALSE
if(L != src && (run_block(L, rand(1, 3), "the [L.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, L, check_zone(L.zone_selected)) & BLOCK_SUCCESS))
if(L != src && (mob_run_block(L, rand(1, 3), "the [L.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, 0, L, check_zone(L.zone_selected), null) & BLOCK_SUCCESS))
return FALSE
L.do_attack_animation(src)
if(prob(90))
log_combat(L, src, "attacked")
visible_message("<span class='danger'>[L.name] bites [src]!</span>", \
"<span class='userdanger'>[L.name] bites [src]!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='userdanger'>[L.name] bites you!</span>", null, COMBAT_MESSAGE_RANGE, null, L, \
"<span class='danger'>You bite [src]!</span>")
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
return TRUE
else
visible_message("<span class='danger'>[L.name] has attempted to bite [src]!</span>", \
"<span class='userdanger'>[L.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='userdanger'>[L.name] has attempted to bite you!</span>", null, COMBAT_MESSAGE_RANGE, null, L, \
"<span class='danger'>You have attempted to bite [src]!</span>")
/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
if((M != src) && M.a_intent != INTENT_HELP && (run_block(M, 0, "the [M.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, M, check_zone(M.zone_selected)) & BLOCK_SUCCESS))
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>")
if((M != src) && M.a_intent != INTENT_HELP && (mob_run_block(M, 0, "the [M.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, 0, M, check_zone(M.zone_selected), null) & BLOCK_SUCCESS))
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>",
"<span class='danger'>[M] attempted to touch you!</span>")
return FALSE
switch(M.a_intent)
if (INTENT_HELP)
if(!isalien(src)) //I know it's ugly, but the alien vs alien attack_alien behaviour is a bit different.
visible_message("<span class='notice'>[M] caresses [src] with its scythe like arm.</span>")
visible_message("<span class='notice'>[M] caresses [src] with its scythe like arm.</span>",
"<span class='notice'>[M] caresses you with its scythe like arm.</span>", target = M,
target_message = "<span class='notice'>You caress [src] with your scythe like arm.</span>")
return FALSE
if (INTENT_GRAB)
grabbedby(M)
@@ -419,21 +442,26 @@
take_bodypart_damage(acidpwr * min(1, acid_volume * 0.1))
return 1
///As the name suggests, this should be called to apply electric shocks.
/mob/living/proc/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage, source, siemens_coeff, flags)
if((flags & SHOCK_TESLA) && (flags_1 & TESLA_IGNORE_1))
shock_damage *= siemens_coeff
if((flags & SHOCK_TESLA) && HAS_TRAIT(src, TRAIT_TESLA_SHOCKIMMUNE))
return FALSE
if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE))
return FALSE
if(shock_damage > 0)
if(!(flags & SHOCK_ILLUSION))
adjustFireLoss(shock_damage)
visible_message(
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
"<span class='italics'>You hear a heavy electrical crack.</span>" \
)
return shock_damage
if(shock_damage < 1)
return FALSE
if(!(flags & SHOCK_ILLUSION))
adjustFireLoss(shock_damage)
else
adjustStaminaLoss(shock_damage)
visible_message(
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
"<span class='userdanger'>You feel a powerful shock coursing through your body!</span>", \
"<span class='hear'>You hear a heavy electrical crack.</span>" \
)
return shock_damage
/mob/living/emp_act(severity)
. = ..()
@@ -512,4 +540,11 @@
if(!used_item)
used_item = get_active_held_item()
..()
setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
floating_need_update = TRUE
/mob/living/proc/getBruteLoss_nonProsthetic()
return getBruteLoss()
/mob/living/proc/getFireLoss_nonProsthetic()
return getFireLoss()
+3 -2
View File
@@ -4,6 +4,9 @@
see_in_dark = 2
hud_possible = list(HEALTH_HUD,STATUS_HUD,ANTAG_HUD,NANITE_HUD,DIAG_NANITE_FULL_HUD,RAD_HUD)
pressure_resistance = 10
has_field_of_vision = TRUE
typing_indicator_enabled = TRUE
var/resize = 1 //Badminnery resize
var/lastattacker = null
@@ -98,8 +101,6 @@
var/datum/riding/riding_datum
var/datum/language/selected_default_language
var/last_words //used for database logging
var/list/obj/effect/proc_holder/abilities = list()
@@ -1,6 +1,8 @@
/mob/living/Moved()
. = ..()
update_turf_movespeed(loc)
//Hide typing indicator if we move.
clear_typing_indicator()
if(is_shifted)
is_shifted = FALSE
pixel_x = get_standard_pixel_x_offset(lying)
+6 -1
View File
@@ -33,7 +33,7 @@
update_sprint_icon()
/mob/living/proc/disable_sprint_mode(update_icon = TRUE)
if(!(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
if(!(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) || (combat_flags & COMBAT_FLAG_SPRINT_FORCED))
return
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_ACTIVE)
if(update_icon)
@@ -51,6 +51,8 @@
/mob/living/proc/disable_intentional_sprint_mode()
if(!(combat_flags & COMBAT_FLAG_SPRINT_TOGGLED) && !(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
return
if(combat_flags & COMBAT_FLAG_SPRINT_FORCED)
return
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_TOGGLED)
if(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE)
disable_sprint_mode(FALSE)
@@ -59,6 +61,9 @@
/mob/living/proc/user_toggle_intentional_sprint_mode()
var/old = (combat_flags & COMBAT_FLAG_SPRINT_TOGGLED)
if(old)
if(combat_flags & COMBAT_FLAG_SPRINT_FORCED)
to_chat(src, "<span class='warning'>You are unable to stop sprinting!</span>")
return
disable_intentional_sprint_mode()
if((m_intent == MOVE_INTENT_RUN) && CHECK_ALL_MOBILITY(src, MOBILITY_STAND|MOBILITY_MOVE))
playsound_local(src, 'sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE)
+5 -9
View File
@@ -133,7 +133,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
var/datum/language/message_language = get_message_language(message)
if(message_language)
// No, you cannot speak in xenocommon just because you know the key
if(can_speak_in_language(message_language))
if(can_speak_language(message_language))
language = message_language
message = copytext_char(message, 3)
@@ -141,7 +141,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
message = trim_left(message)
if(!language)
language = get_default_language()
language = get_selected_language()
// Detection of language needs to be before inherent channels, because
// AIs use inherent channels for the holopad. Most inherent channels
@@ -415,11 +415,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
/mob/living/whisper(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
say("#[message]", bubble_type, spans, sanitize, language, ignore_spam, forced)
/mob/living/get_language_holder(shadow=TRUE)
if(mind && shadow)
// Mind language holders shadow mob holders.
. = mind.get_language_holder()
if(.)
return .
/mob/living/get_language_holder(get_minds = TRUE)
if(get_minds && mind)
return mind.get_language_holder()
. = ..()
+25 -21
View File
@@ -28,6 +28,7 @@
sec_hud = DATA_HUD_SECURITY_BASIC
d_hud = DATA_HUD_DIAGNOSTIC_ADVANCED
mob_size = MOB_SIZE_LARGE
has_field_of_vision = FALSE //Vision through cameras.
var/list/network = list("ss13")
var/obj/machinery/camera/current
var/list/connected_robots = list()
@@ -868,30 +869,33 @@
light_cameras()
if(istype(A, /obj/machinery/camera))
current = A
if(client)
if(ismovable(A))
if(A != GLOB.ai_camera_room_landmark)
end_multicam()
client.perspective = EYE_PERSPECTIVE
client.eye = A
else
if(!client)
return
if(ismovable(A))
if(A != GLOB.ai_camera_room_landmark)
end_multicam()
if(isturf(loc))
if(eyeobj)
client.eye = eyeobj
client.perspective = EYE_PERSPECTIVE
else
client.eye = client.mob
client.perspective = MOB_PERSPECTIVE
else
client.perspective = EYE_PERSPECTIVE
client.eye = A
else
end_multicam()
if(isturf(loc))
if(eyeobj)
client.eye = eyeobj
client.perspective = EYE_PERSPECTIVE
client.eye = loc
update_sight()
if(client.eye != src)
var/atom/AT = client.eye
AT.get_remote_view_fullscreens(src)
else
client.eye = client.mob
client.perspective = MOB_PERSPECTIVE
else
clear_fullscreen("remote_view", 0)
client.perspective = EYE_PERSPECTIVE
client.eye = loc
update_sight()
if(client.eye != src)
var/atom/AT = client.eye
AT.get_remote_view_fullscreens(src)
else
clear_fullscreen("remote_view", 0)
SEND_SIGNAL(src, COMSIG_MOB_RESET_PERSPECTIVE, A)
return TRUE
/mob/living/silicon/ai/revive(full_heal = 0, admin_revive = 0)
. = ..()
@@ -171,10 +171,3 @@
#undef VOX_DELAY
#endif
/mob/living/silicon/ai/could_speak_in_language(datum/language/dt)
if(is_servant_of_ratvar(src))
// Ratvarian AIs can only speak Ratvarian
. = ispath(dt, /datum/language/ratvar)
else
. = ..()
@@ -32,22 +32,28 @@
/mob/living/silicon/pai/attack_hand(mob/living/carbon/human/user)
switch(user.a_intent)
if(INTENT_HELP)
visible_message("<span class='notice'>[user] gently pats [src] on the head, eliciting an off-putting buzzing from its holographic field.</span>")
visible_message("<span class='notice'>[user] gently pats [src] on the head, eliciting an off-putting buzzing from its holographic field.</span>",
"<span class='notice'>[user] gently pats you on the head, eliciting an off-putting buzzing from your holographic field.</span>", target = user,
target_message = "<span class='notice'>You gently pat [src] on the head, eliciting an off-putting buzzing from its holographic field.</span>")
if(INTENT_DISARM)
visible_message("<span class='notice'>[user] boops [src] on the head!</span>")
visible_message("<span class='notice'>[user] boops [src] on the head!</span>",
"<span class='notice'>[user] boops you on the head!</span>", target = user,
target_message = "<span class='notice'>You boop [src] on the head!</span>")
if(INTENT_HARM)
user.do_attack_animation(src)
if (user.name == master)
visible_message("<span class='notice'>Responding to its master's touch, [src] disengages its holochassis emitter, rapidly losing coherence.</span>")
spawn(10)
fold_in()
if(user.put_in_hands(card))
user.visible_message("<span class='notice'>[user] promptly scoops up [user.p_their()] pAI's card.</span>")
fold_in()
if(user.put_in_hands(card))
user.visible_message("<span class='notice'>[user] promptly scoops up [user.p_their()] pAI's card.</span>",
"<span class='notice'>You promptly scoops up your pAI's card.</span>")
else
if(HAS_TRAIT(user, TRAIT_PACIFISM))
to_chat(user, "<span class='notice'>You don't want to hurt [src]!</span>")
return
visible_message("<span class='danger'>[user] stomps on [src]!.</span>")
visible_message("<span class='danger'>[user] stomps on [src]!.</span>",
"<span class='userdanger'>[user] stomps on you!.</span>", target = user,
target_message = "<span class='danger'>You stomp on [src]!.</span>")
take_holo_damage(2)
else
grabbedby(user)
@@ -267,9 +267,8 @@
if(href_list["toggle"])
encryptmod = TRUE
if("translator")
if(href_list["toggle"])
grant_all_languages(TRUE)
// this is PERMAMENT.
if(href_list["toggle"]) //This is permanent.
grant_all_languages(TRUE, TRUE, TRUE, LANGUAGE_SOFTWARE)
if("doorjack")
if(href_list["jack"])
if(cable && cable.machine)
+7 -123
View File
@@ -3,122 +3,7 @@
real_name = "Cyborg"
icon = 'icons/mob/robots.dmi'
icon_state = "robot"
maxHealth = 100
health = 100
bubble_icon = "robot"
designation = "Default" //used for displaying the prefix & getting the current module of cyborg
has_limbs = 1
hud_type = /datum/hud/robot
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
var/custom_name = ""
var/braintype = "Cyborg"
var/obj/item/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of..
var/obj/item/mmi/mmi = null
var/shell = FALSE
var/deployed = FALSE
var/mob/living/silicon/ai/mainframe = null
var/datum/action/innate/undeployment/undeployment_action = new
//Hud stuff
var/obj/screen/inv1 = null
var/obj/screen/inv2 = null
var/obj/screen/inv3 = null
var/obj/screen/lamp_button = null
var/obj/screen/thruster_button = null
var/obj/screen/hands = null
var/shown_robot_modules = 0 //Used to determine whether they have the module menu shown or not
var/obj/screen/robot_modules_background
//3 Modules can be activated at any one time.
var/obj/item/robot_module/module = null
var/obj/item/module_active = null
held_items = list(null, null, null) //we use held_items for the module holding, because that makes sense to do!
var/mutable_appearance/eye_lights
var/mob/living/silicon/ai/connected_ai = null
var/obj/item/stock_parts/cell/cell = null
var/opened = 0
var/emagged = FALSE
var/emag_cooldown = 0
var/wiresexposed = 0
var/ident = 0
var/locked = TRUE
var/list/req_access = list(ACCESS_ROBOTICS)
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list(), "Burglar"=list())
var/speed = 0 // VTEC speed boost.
var/magpulse = FALSE // Magboot-like effect.
var/ionpulse = FALSE // Jetpack-like effect.
var/ionpulse_on = FALSE // Jetpack-like effect.
var/datum/effect_system/trail_follow/ion/ion_trail // Ionpulse effect.
var/low_power_mode = 0 //whether the robot has no charge left.
var/datum/effect_system/spark_spread/spark_system // So they can initialize sparks whenever/N
var/lawupdate = 1 //Cyborgs will sync their laws with their AI by default
var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them.
var/locked_down //Boolean of whether the borg is locked down or not
var/toner = 0
var/tonermax = 40
var/lamp_max = 10 //Maximum brightness of a borg lamp. Set as a var for easy adjusting.
var/lamp_intensity = 0 //Luminosity of the headlamp. 0 is off. Higher settings than the minimum require power.
light_color = "#FFCC66"
light_power = 0.8
var/lamp_cooldown = 0 //Flag for if the lamp is on cooldown after being forcibly disabled.
var/sight_mode = 0
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD)
var/list/upgrades = list()
var/hasExpanded = FALSE
var/obj/item/hat
var/hat_offset = -3
var/list/equippable_hats = list(/obj/item/clothing/head/caphat,
/obj/item/clothing/head/hardhat,
/obj/item/clothing/head/centhat,
/obj/item/clothing/head/HoS,
/obj/item/clothing/head/beret,
/obj/item/clothing/head/kitty,
/obj/item/clothing/head/hopcap,
/obj/item/clothing/head/wizard,
/obj/item/clothing/head/nursehat,
/obj/item/clothing/head/sombrero,
/obj/item/clothing/head/helmet/chaplain/witchunter_hat,
/obj/item/clothing/head/soft/, //All baseball caps
/obj/item/clothing/head/that, //top hat
/obj/item/clothing/head/collectable/tophat, //Not sure where this one is found, but it looks the same so might as well include
/obj/item/clothing/mask/bandana/, //All bandanas (which only work in hat mode)
/obj/item/clothing/head/fedora,
/obj/item/clothing/head/beanie/, //All beanies
/obj/item/clothing/ears/headphones,
/obj/item/clothing/head/helmet/skull,
/obj/item/clothing/head/crown/fancy)
can_buckle = TRUE
buckle_lying = FALSE
var/static/list/can_ride_typecache = typecacheof(/mob/living/carbon/human)
var/sitting = 0
var/bellyup = 0
var/dogborg = FALSE
var/cansprint = 1
var/orebox = null
/mob/living/silicon/robot
/mob/living/silicon/robot/get_cell()
return cell
@@ -129,7 +14,7 @@
spark_system.attach(src)
wires = new /datum/wires/robot(src)
AddComponent(/datum/component/empprotection, EMP_PROTECT_WIRES)
AddElement(/datum/element/empprotection, EMP_PROTECT_WIRES)
robot_modules_background = new()
robot_modules_background.icon_state = "block"
@@ -427,24 +312,23 @@
else if(istype(W, /obj/item/stack/cable_coil) && wiresexposed)
user.changeNext_move(CLICK_CD_MELEE)
var/obj/item/stack/cable_coil/coil = W
if (getFireLoss() > 0 || getToxLoss() > 0)
if(src == user && coil.use(1))
if(src == user)
to_chat(user, "<span class='notice'>You start fixing yourself...</span>")
if(!do_after(user, 50, target = src))
if(!W.use_tool(src, user, 50, 1, max_level = JOB_SKILL_TRAINED))
to_chat(user, "<span class='warning'>You need more cable to repair [src]!</span>")
return
adjustFireLoss(-10)
adjustToxLoss(-10)
if (coil.use(1))
else
to_chat(user, "<span class='notice'>You start fixing [src]...</span>")
if(!do_after(user, 30, target = src))
if(!W.use_tool(src, user, 30, 1))
to_chat(user, "<span class='warning'>You need more cable to repair [src]!</span>")
return
adjustFireLoss(-30)
adjustToxLoss(-30)
updatehealth()
user.visible_message("[user] has fixed some of the burnt wires on [src].", "<span class='notice'>You fix some of the burnt wires on [src].</span>")
else
to_chat(user, "<span class='warning'>You need more cable to repair [src]!</span>")
else
to_chat(user, "The wires seem fine, there's no need to fix them.")
@@ -32,15 +32,17 @@
var/obj/item/I = get_active_held_item()
if(I)
uneq_active()
visible_message("<span class='danger'>[M] disarmed [src]!</span>", \
"<span class='userdanger'>[M] has disabled [src]'s active module!</span>", null, COMBAT_MESSAGE_RANGE)
visible_message("<span class='danger'>[M] has disarmed [src]!</span>", \
"<span class='userdanger'>[M] has disabled your active module!</span>", null, COMBAT_MESSAGE_RANGE, null, M,
"<span class='danger'>You have disarmed [src]!</span>")
log_combat(M, src, "disarmed", "[I ? " removing \the [I]" : ""]")
else
Paralyze(40)
step(src,get_dir(M,src))
log_combat(M, src, "pushed")
visible_message("<span class='danger'>[M] has forced back [src]!</span>", \
"<span class='userdanger'>[M] has forced back [src]!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='userdanger'>[M] has forced you back!</span>", null, COMBAT_MESSAGE_RANGE, null, M,
"<span class='danger'>You have forced back [src]!</span>")
playsound(loc, 'sound/weapons/pierce.ogg', 50, 1, -1)
/mob/living/silicon/robot/attack_slime(mob/living/simple_animal/slime/M)
@@ -0,0 +1,123 @@
/mob/living/silicon/robot
designation = "Default" //used for displaying the prefix & getting the current module of cyborg
has_limbs = TRUE
hud_type = /datum/hud/robot
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
maxHealth = 100
health = 100
var/custom_name = ""
var/braintype = "Cyborg"
var/obj/item/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of..
var/obj/item/mmi/mmi = null
var/shell = FALSE
var/deployed = FALSE
var/mob/living/silicon/ai/mainframe = null
var/datum/action/innate/undeployment/undeployment_action = new
//Hud stuff
var/obj/screen/inv1 = null
var/obj/screen/inv2 = null
var/obj/screen/inv3 = null
var/obj/screen/lamp_button = null
var/obj/screen/thruster_button = null
var/obj/screen/hands = null
var/shown_robot_modules = 0 //Used to determine whether they have the module menu shown or not
var/obj/screen/robot_modules_background
//3 Modules can be activated at any one time.
var/obj/item/robot_module/module = null
var/obj/item/module_active = null
held_items = list(null, null, null) //we use held_items for the module holding, because that makes sense to do!
var/mutable_appearance/eye_lights
var/mob/living/silicon/ai/connected_ai = null
var/obj/item/stock_parts/cell/cell = null
var/opened = 0
var/emagged = FALSE
var/emag_cooldown = 0
var/wiresexposed = 0
var/ident = 0
var/locked = TRUE
var/list/req_access = list(ACCESS_ROBOTICS)
var/alarms = list("Motion"=list(), "Fire"=list(), "Atmosphere"=list(), "Power"=list(), "Camera"=list(), "Burglar"=list())
var/speed = 0 // VTEC speed boost.
var/magpulse = FALSE // Magboot-like effect.
var/ionpulse = FALSE // Jetpack-like effect.
var/ionpulse_on = FALSE // Jetpack-like effect.
var/datum/effect_system/trail_follow/ion/ion_trail // Ionpulse effect.
var/low_power_mode = 0 //whether the robot has no charge left.
var/datum/effect_system/spark_spread/spark_system // So they can initialize sparks whenever/N
var/lawupdate = 1 //Cyborgs will sync their laws with their AI by default
var/scrambledcodes = 0 // Used to determine if a borg shows up on the robotics console. Setting to one hides them.
var/locked_down //Boolean of whether the borg is locked down or not
var/toner = 0
var/tonermax = 40
var/lamp_max = 10 //Maximum brightness of a borg lamp. Set as a var for easy adjusting.
var/lamp_intensity = 0 //Luminosity of the headlamp. 0 is off. Higher settings than the minimum require power.
light_color = "#FFCC66"
light_power = 0.8
var/lamp_cooldown = 0 //Flag for if the lamp is on cooldown after being forcibly disabled.
var/sight_mode = 0
hud_possible = list(ANTAG_HUD, DIAG_STAT_HUD, DIAG_HUD, DIAG_BATT_HUD, DIAG_TRACK_HUD)
var/list/upgrades = list()
var/hasExpanded = FALSE
var/obj/item/hat
var/hat_offset = -3
var/list/equippable_hats = list(/obj/item/clothing/head/caphat,
/obj/item/clothing/head/hardhat,
/obj/item/clothing/head/centhat,
/obj/item/clothing/head/HoS,
/obj/item/clothing/head/beret,
/obj/item/clothing/head/kitty,
/obj/item/clothing/head/hopcap,
/obj/item/clothing/head/wizard,
/obj/item/clothing/head/nursehat,
/obj/item/clothing/head/sombrero,
/obj/item/clothing/head/helmet/chaplain/witchunter_hat,
/obj/item/clothing/head/soft/, //All baseball caps
/obj/item/clothing/head/that, //top hat
/obj/item/clothing/head/collectable/tophat, //Not sure where this one is found, but it looks the same so might as well include
/obj/item/clothing/mask/bandana/, //All bandanas (which only work in hat mode)
/obj/item/clothing/head/fedora,
/obj/item/clothing/head/beanie/, //All beanies
/obj/item/clothing/ears/headphones,
/obj/item/clothing/head/helmet/skull,
/obj/item/clothing/head/crown/fancy)
can_buckle = TRUE
buckle_lying = FALSE
var/static/list/can_ride_typecache = typecacheof(/mob/living/carbon/human)
var/sitting = 0
var/bellyup = 0
var/dogborg = FALSE
var/cansprint = 1
var/orebox = null
//doggie borg stuff.
var/disabler
var/laser
var/sleeper_g
var/sleeper_r
var/sleeper_nv
@@ -276,6 +276,19 @@
R.hud_used.update_robot_modules_display()
SSblackbox.record_feedback("tally", "cyborg_modules", 1, R.module)
/**
* check_menu: Checks if we are allowed to interact with a radial menu
*
* Arguments:
* * user The mob interacting with a menu
*/
/obj/item/robot_module/proc/check_menu(mob/user)
if(!istype(user))
return FALSE
if(user.incapacitated() || !user.Adjacent(src))
return FALSE
return TRUE
/obj/item/robot_module/standard
name = "Standard"
basic_modules = list(
@@ -337,13 +350,28 @@
/obj/item/robot_module/medical/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/medmodels = list("Default", "Heavy", "Sleek", "Marina", "Droid", "Eyebot", "Medihound", "Medihound Dark", "Vale")
if(R.client && (R.client.ckey in list("nezuli")))
medmodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in medmodels
if(!borg_icon)
return FALSE
switch(borg_icon)
var/static/list/med_icons
if(!med_icons)
med_icons = list(
"Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "medical"),
"Droid" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "medical"),
"Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekmed"),
"Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinamed"),
"Eyebot" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "eyebotmed"),
"Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavymed")
)
var/list/L = list("Medihound" = "medihound", "Medihound Dark" = "medihounddark", "Vale" = "valemed")
for(var/a in L)
var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a])
wide.pixel_x = -16
med_icons[a] = wide
if(R.client && R.client.ckey == "nezuli")
var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-med")
bad_snowflake.pixel_x = -16
med_icons["Alina"] = bad_snowflake
med_icons = sortList(med_icons)
var/med_borg_icon = show_radial_menu(R, R , med_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
switch(med_borg_icon)
if("Default")
cyborg_base_icon = "medical"
if("Droid")
@@ -391,6 +419,8 @@
moduleselect_icon = "medihound"
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
dogborg = TRUE
else
return FALSE
return ..()
/obj/item/robot_module/engineering
@@ -434,13 +464,31 @@
/obj/item/robot_module/engineering/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/list/engymodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Marina", "Can", "Spider", "Loader","Handy", "Pup Dozer", "Vale")
if(R.client && (R.client.ckey in list("nezuli")))
engymodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in engymodels
if(!borg_icon)
return FALSE
switch(borg_icon)
var/static/list/engi_icons
if(!engi_icons)
engi_icons = list(
"Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "engineer"),
"Default - Treads" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "engi-tread"),
"Loader" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "loaderborg"),
"Handy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "handyeng"),
"Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekeng"),
"Can" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "caneng"),
"Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinaeng"),
"Spider" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "spidereng"),
"Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavyeng")
)
var/list/L = list("Pup Dozer" = "pupdozer", "Vale" = "valeeng")
for(var/a in L)
var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a])
wide.pixel_x = -16
engi_icons[a] = wide
if(R.client && R.client.ckey == "nezuli")
var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-eng")
bad_snowflake.pixel_x = -16
engi_icons["Alina"] = bad_snowflake
engi_icons = sortList(engi_icons)
var/engi_borg_icon = show_radial_menu(R, R , engi_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
switch(engi_borg_icon)
if("Default")
cyborg_base_icon = "engineer"
if("Default - Treads")
@@ -485,6 +533,8 @@
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
sleeper_overlay = "alinasleeper"
dogborg = TRUE
else
return FALSE
return ..()
/obj/item/robot_module/security
@@ -512,13 +562,29 @@
/obj/item/robot_module/security/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/list/secmodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Can", "Marina", "Spider", "K9", "K9 Dark", "Vale")
if(R.client && (R.client.ckey in list("nezuli")))
secmodels += "Alina"
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in secmodels
if(!borg_icon)
return FALSE
switch(borg_icon)
var/static/list/sec_icons
if(!sec_icons)
sec_icons = list(
"Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "sec"),
"Default - Treads" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sec-tread"),
"Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleeksec"),
"Can" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "cansec"),
"Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinasec"),
"Spider" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "spidersec"),
"Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavysec")
)
var/list/L = list("K9" = "k9", "Vale" = "valesec", "K9 Dark" = "k9dark")
for(var/a in L)
var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a])
wide.pixel_x = -16
sec_icons[a] = wide
if(R.client && R.client.ckey == "nezuli")
var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-sec")
bad_snowflake.pixel_x = -16
sec_icons["Alina"] = bad_snowflake
sec_icons = sortList(sec_icons)
var/sec_borg_icon = show_radial_menu(R, R , sec_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
switch(sec_borg_icon)
if("Default")
cyborg_base_icon = "sec"
if("Default - Treads")
@@ -561,6 +627,8 @@
sleeper_overlay = "valesecsleeper"
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
dogborg = TRUE
else
return FALSE
return ..()
/obj/item/robot_module/security/Initialize()
@@ -599,10 +667,13 @@
/obj/item/robot_module/peacekeeper/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Spider", "Borgi")
if(!borg_icon)
return FALSE
switch(borg_icon)
var/static/list/peace_icons = sortList(list(
"Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "peace"),
"Borgi" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "borgi"),
"Spider" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "whitespider")
))
var/peace_borg_icon = show_radial_menu(R, R , peace_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
switch(peace_borg_icon)
if("Default")
cyborg_base_icon = "peace"
if("Spider")
@@ -615,6 +686,8 @@
hat_offset = INFINITY
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
has_snowflake_deadsprite = TRUE
else
return FALSE
return ..()
//Janitor module combined with Service module
@@ -696,9 +769,9 @@
/obj/item/toy/crayon/spraycan/borg,
/obj/item/hand_labeler/borg,
/obj/item/razor,
/obj/item/rsf,
/obj/item/instrument/violin,
/obj/item/instrument/guitar,
/obj/item/rsf/cyborg,
/obj/item/reagent_containers/dropper,
/obj/item/lighter,
/obj/item/storage/bag/tray,
@@ -738,10 +811,35 @@
/obj/item/robot_module/butler/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("(Service) Waitress", "(Service) Heavy", "(Service) Sleek", "(Service) Butler", "(Service) Tophat", "(Service) Can", "(Service) Bro", "(Service) DarkK9", "(Service) Vale", "(Service) ValeDark", "(Janitor) Default", "(Janitor) Sleek", "(Janitor) Marina", "(Janitor) Can", "(Janitor) Heavy", "(Janitor) Scrubpuppy")
if(!borg_icon)
return FALSE
switch(borg_icon)
var/static/list/service_icons
if(!service_icons)
service_icons = list(
"(Service) Waitress" = image(icon = 'icons/mob/robots.dmi', icon_state = "service_f"),
"(Service) Butler" = image(icon = 'icons/mob/robots.dmi', icon_state = "service_m"),
"(Service) Bro" = image(icon = 'icons/mob/robots.dmi', icon_state = "brobot"),
"(Service) Can" = image(icon = 'icons/mob/robots.dmi', icon_state = "kent"),
"(Service) Tophat" = image(icon = 'icons/mob/robots.dmi', icon_state = "tophat"),
"(Service) Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekserv"),
"(Service) Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavyserv"),
"(Janitor) Default" = image(icon = 'icons/mob/robots.dmi', icon_state = "janitor"),
"(Janitor) Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinajan"),
"(Janitor) Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekjan"),
"(Janitor) Can" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "canjan"),
"(Janitor) Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavyjan"),
)
var/list/L = list("(Service) DarkK9" = "k50", "(Service) Vale" = "valeserv", "(Service) ValeDark" = "valeservdark",
"(Janitor) Scrubpuppy" = "scrubpup")
for(var/a in L)
var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a])
wide.pixel_x = -16
service_icons[a] = wide
if(R.client && R.client.ckey == "nezuli")
var/image/bad_snowflake = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = "alina-sec")
bad_snowflake.pixel_x = -16
service_icons["Alina"] = bad_snowflake
service_icons = sortList(service_icons)
var/service_robot_icon = show_radial_menu(R, R , service_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
switch(service_robot_icon)
if("(Service) Waitress")
cyborg_base_icon = "service_f"
special_light_key = "service"
@@ -799,6 +897,8 @@
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
sleeper_overlay = "jsleeper"
dogborg = TRUE
else
return FALSE
return ..()
/obj/item/robot_module/miner
@@ -833,10 +933,25 @@
/obj/item/robot_module/miner/be_transformed_to(obj/item/robot_module/old_module)
var/mob/living/silicon/robot/R = loc
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Lavaland", "Heavy", "Sleek", "Marina", "Can", "Spider", "Asteroid", "Droid", "Blade", "Vale")
if(!borg_icon)
return FALSE
switch(borg_icon)
var/static/list/mining_icons
if(!mining_icons)
mining_icons = list(
"Lavaland" = image(icon = 'icons/mob/robots.dmi', icon_state = "miner"),
"Asteroid" = image(icon = 'icons/mob/robots.dmi', icon_state = "minerOLD"),
"Droid" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "miner"),
"Sleek" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "sleekmin"),
"Marina" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "marinamin"),
"Can" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "canmin"),
"Heavy" = image(icon = 'modular_citadel/icons/mob/robots.dmi', icon_state = "heavymin"),
)
var/list/L = list("Blade" = "blade", "Vale" = "valemine")
for(var/a in L)
var/image/wide = image(icon = 'modular_citadel/icons/mob/widerobot.dmi', icon_state = L[a])
wide.pixel_x = -16
mining_icons[a] = wide
mining_icons = sortList(mining_icons)
var/mining_borg_icon = show_radial_menu(R, R , mining_icons, custom_check = CALLBACK(src, .proc/check_menu, R), radius = 42, require_near = TRUE)
switch(mining_borg_icon)
if("Lavaland")
cyborg_base_icon = "miner"
if("Asteroid")
@@ -871,6 +986,8 @@
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
sleeper_overlay = "valeminesleeper"
dogborg = TRUE
else
return FALSE
return ..()
/obj/item/robot_module/syndicate
@@ -57,3 +57,5 @@
cut_overlays()
else
icon_state = "[module.cyborg_base_icon]"
SEND_SIGNAL(src, COMSIG_ROBOT_UPDATE_ICONS)
@@ -17,7 +17,8 @@
log_combat(M, src, "attacked")
playsound(loc, 'sound/weapons/slash.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
"<span class='userdanger'>[M] has slashed at [src]!</span>")
"<span class='userdanger'>[M] has slashed at you!</span>", target = M, \
target_message = "<span class='danger'>You have slashed at [src]!</span>")
if(prob(8))
flash_act(affect_silicon = 1)
log_combat(M, src, "attacked")
@@ -25,8 +26,9 @@
updatehealth()
else
playsound(loc, 'sound/weapons/slashmiss.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] took a swipe at [src]!</span>", \
"<span class='userdanger'>[M] took a swipe at [src]!</span>")
visible_message("<span class='danger'>[M] take a swipe at [src]!</span>", \
"<span class='userdanger'>[M] take a swipe at you!</span>", target = M, \
target_message = "<span class='danger'>You take a swipe at [src]!</span>")
/mob/living/silicon/attack_animal(mob/living/simple_animal/M)
. = ..()
@@ -36,7 +38,8 @@
for(var/mob/living/N in buckled_mobs)
N.DefaultCombatKnockdown(20)
unbuckle_mob(N)
N.visible_message("<span class='boldwarning'>[N] is knocked off of [src] by [M]!</span>")
N.visible_message("<span class='boldwarning'>[N] is knocked off of [src] by [M]!</span>",
"<span class='boldwarning'>You are knocked off of [src] by [M]!</span>")
switch(M.melee_damage_type)
if(BRUTE)
adjustBruteLoss(damage)
@@ -62,7 +65,8 @@
adjustBruteLoss(rand(10, 15))
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[user] has punched [src]!</span>", \
"<span class='userdanger'>[user] has punched [src]!</span>")
"<span class='userdanger'>[user] has punched you!</span>", target = user, \
target_message = "<span class='danger'>You have punched [src]!</span>")
return TRUE
return FALSE
@@ -73,14 +77,16 @@
switch(M.a_intent)
if (INTENT_HELP)
M.visible_message("[M] pets [src].", \
"<span class='notice'>You pet [src].</span>")
"<span class='notice'>You pet [src].</span>", target = src,
target_message = "[M] pets you.")
if(INTENT_GRAB)
grabbedby(M)
else
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
playsound(src.loc, 'sound/effects/bang.ogg', 10, 1)
visible_message("<span class='danger'>[M] punches [src], but doesn't leave a dent.</span>", \
"<span class='warning'>[M] punches [src], but doesn't leave a dent.</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='warning'>[M] punches you, but doesn't leave a dent.</span>", null, COMBAT_MESSAGE_RANGE, null, M,
"<span class='danger'>You punch [src], but don't leave a dent.</span>")
/mob/living/silicon/attack_drone(mob/living/simple_animal/drone/M)
if(M.a_intent == INTENT_HARM)
@@ -109,14 +115,15 @@
if(prob(severity*50))
unbuckle_mob(M)
M.DefaultCombatKnockdown(40)
M.visible_message("<span class='boldwarning'>[M] is thrown off of [src]!</span>")
M.visible_message("<span class='boldwarning'>[M] is thrown off of [src]!</span>",
"<span class='boldwarning'>You are thrown off of [src]!</span>")
flash_act(affect_silicon = 1)
/mob/living/silicon/bullet_act(obj/item/projectile/P, def_zone)
var/totaldamage = P.damage
if(P.original != src || P.firer != src) //try to block or reflect the bullet, can't do so when shooting oneself
var/list/returnlist = list()
var/returned = run_block(P, P.damage, "the [P.name]", ATTACK_TYPE_PROJECTILE, P.armour_penetration, P.firer, def_zone, returnlist)
var/returned = mob_run_block(P, P.damage, "the [P.name]", ATTACK_TYPE_PROJECTILE, P.armour_penetration, P.firer, def_zone, returnlist)
if(returned & BLOCK_SHOULD_REDIRECT)
handle_projectile_attack_redirection(P, returnlist[BLOCK_RETURN_REDIRECT_METHOD])
if(returned & BLOCK_REDIRECTED)
@@ -129,7 +136,8 @@
adjustBruteLoss(totaldamage)
if((P.damage >= 10) || P.stun || P.knockdown || (P.stamina >= 20))
for(var/mob/living/M in buckled_mobs)
M.visible_message("<span class='boldwarning'>[M] is knocked off of [src]!</span>")
M.visible_message("<span class='boldwarning'>[M] is knocked off of [src] by the [P]!</span>",
"<span class='boldwarning'>You are knocked off of [src] by the [P]!</span>")
unbuckle_mob(M)
M.DefaultCombatKnockdown(40)
P.on_hit(src)
@@ -7,7 +7,9 @@
switch(M.a_intent)
if(INTENT_HELP)
if (health > 0)
visible_message("<span class='notice'>[M] [response_help] [src].</span>")
visible_message("<span class='notice'>[M] [response_help_continuous] [src].</span>", \
"<span class='notice'>[M] [response_help_continuous] you.</span>", null, null, null,
M, "<span class='notice'>You [response_help_simple] [src].</span>")
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
if(INTENT_GRAB)
@@ -16,13 +18,22 @@
else
grabbedby(M)
if(INTENT_HARM, INTENT_DISARM)
if(INTENT_DISARM)
M.do_attack_animation(src, ATTACK_EFFECT_DISARM)
visible_message("<span class='danger'>[M] [response_disarm_continuous] [src]!</span>",\
"<span class='danger'>[M] [response_disarm_continuous] you!</span>", null, COMBAT_MESSAGE_RANGE, null, \
M, "<span class='danger'>You [response_disarm_simple] [src]!</span>")
playsound(src, 'sound/weapons/thudswoosh.ogg', 25, 1)
log_combat(M, src, "disarmed")
if(INTENT_HARM)
if(HAS_TRAIT(M, TRAIT_PACIFISM))
to_chat(M, "<span class='notice'>You don't want to hurt [src]!</span>")
return
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
visible_message("<span class='danger'>[M] [response_harm] [src]!</span>",\
"<span class='userdanger'>[M] [response_harm] [src]!</span>", null, COMBAT_MESSAGE_RANGE)
visible_message("<span class='danger'>[M] [response_harm_continuous] [src]!</span>",\
"<span class='userdanger'>[M] [response_harm_continuous] you!</span>", null, COMBAT_MESSAGE_RANGE, null, \
M, "<span class='danger'>You [response_harm_simple] [src]!</span>")
playsound(loc, attacked_sound, 25, 1, -1)
attack_threshold_check(harm_intent_damage)
log_combat(M, src, "attacked")
@@ -35,8 +46,9 @@
if(.)
return
playsound(loc, "punch", 25, 1, -1)
visible_message("<span class='danger'>[user] has punched [src]!</span>", \
"<span class='userdanger'>[user] has punched [src]!</span>", null, COMBAT_MESSAGE_RANGE)
visible_message("<span class='danger'>[user] punches [src]!</span>", \
"<span class='userdanger'>[user] punches you!</span>", null, COMBAT_MESSAGE_RANGE, null, \
user, "<span class='danger'>You punch [src]!</span>")
adjustBruteLoss(15)
return TRUE
@@ -48,7 +60,9 @@
return 1
if (M.a_intent == INTENT_HELP)
if (health > 0)
visible_message("<span class='notice'>[M.name] [response_help] [src].</span>")
visible_message("<span class='notice'>[M.name] [response_help_continuous] [src].</span>", \
"<span class='notice'>[M.name] [response_help_continuous] you.</span>", \
target = M, target_message = "<span class='notice'>You [response_help_simple] [src].</span>")
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
/mob/living/simple_animal/attack_alien(mob/living/carbon/alien/humanoid/M)
@@ -57,12 +71,14 @@
return
if(M.a_intent == INTENT_DISARM)
playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] [response_disarm] [name]!</span>", \
"<span class='userdanger'>[M] [response_disarm] [name]!</span>", null, COMBAT_MESSAGE_RANGE)
visible_message("<span class='danger'>[M] [response_disarm_continuous] [name]!</span>", \
"<span class='userdanger'>[M] [response_disarm_continuous] [name]!</span>", null, COMBAT_MESSAGE_RANGE, null, \
M, "<span class='danger'>You [response_disarm_simple] [name]!</span>")
log_combat(M, src, "disarmed")
else
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
"<span class='userdanger'>[M] has slashed at [src]!</span>", null, COMBAT_MESSAGE_RANGE)
"<span class='userdanger'>[M] has slashed at [src]!</span>", null, COMBAT_MESSAGE_RANGE, null, \
M, "<span class='danger'>[M] has slashed at [src]!</span>")
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
attack_threshold_check(M.meleeSlashSAPower)
log_combat(M, src, "attacked")
@@ -102,7 +118,7 @@
temp_damage *= damage_coeff[damagetype]
if(temp_damage >= 0 && temp_damage <= force_threshold)
visible_message("<span class='warning'>[src] looks unharmed.</span>")
visible_message("<span class='warning'>[src] looks unharmed!</span>")
return FALSE
else
apply_damage(damage, damagetype, null, getarmor(null, armorcheck))
@@ -5,10 +5,15 @@
icon_state = "ghost"
icon_living = "ghost"
mob_biotypes = MOB_SPIRIT
attacktext = "raises the hairs on the neck of"
response_harm = "disrupts the concentration of"
response_disarm = "wafts"
friendly = "communes with"
has_field_of_vision = FALSE //we are a spoopy ghost
attack_verb_continuous = "raises the hair on the neck of"
attack_verb_simple = "raise the hair on the neck of"
response_harm_continuous = "disrupts the concentration of"
response_harm_simple = "disrupt the concentration of"
response_disarm_continuous = "wafts"
response_disarm_simple = "waft"
friendly_verb_continuous = "communes with"
friendly_verb_simple = "commute with"
loot = null
maxHealth = 10
health = 10
@@ -18,7 +23,6 @@
deathmessage = "disappears as if it was never really there to begin with"
incorporeal_move = 1
alpha = 50
attacktext = "touches the mind of"
speak_emote = list("echos")
movement_type = FLYING
var/pseudo_death = FALSE
@@ -32,7 +36,6 @@
/mob/living/simple_animal/astral/death()
icon_state = "shade_dead"
Stun(1000)
friendly = "deads at"
pseudo_death = TRUE
incorporeal_move = 0
to_chat(src, "<span class='notice'>Your astral projection is interrupted and your mind is sent back to your body with a shock!</span>")
@@ -49,14 +52,14 @@
to_chat(src, "<span class='warning'><b><i>The intensity of the astrogen in your body is too much allow you to return to yourself yet!</b></i></span>")
return
to_chat(src, "<b><i>You astrally possess [H]!</b></i>")
log_game("FERMICHEM: [src] has astrally possessed [A]!")
log_reagent("FERMICHEM: [src] has astrally possessed [A]!")
src.mind.transfer_to(H)
qdel(src)
var/message = html_decode(stripped_input(src, "Enter a message to send to [A]", MAX_MESSAGE_LEN))
if(!message)
return
to_chat(A, "[src] projects into your mind, <b><i> \"[message]\"</b></i>")
log_game("FERMICHEM: [src] has astrally transmitted [message] into [A]")
log_reagent("FERMICHEM: [src] has astrally transmitted [message] into [A]")
//Delete the mob if there's no mind! Pay that mob no mind.
/mob/living/simple_animal/astral/Life()
@@ -911,7 +911,6 @@ Pass a positive integer as an argument to override a bot's default speed.
bot_name = name
name = paicard.pai.name
faction = user.faction.Copy()
language_holder = paicard.pai.language_holder.copy(src)
log_combat(user, paicard.pai, "uploaded to [bot_name],")
return TRUE
else
@@ -20,9 +20,7 @@
weather_immunities = list("lava","ash")
var/clean_time = 50 //How long do we take to clean?
var/broom = FALSE //Do we have an speed buff from a broom?
var/adv_mop = FALSE //Do we have a cleaning buff from a better mop?
var/upgrades = 0
var/blood = 1
var/trash = 0
@@ -79,26 +77,38 @@
if(open)
to_chat(user, "<span class='warning'>Please close the access panel before locking it.</span>")
else
to_chat(user, "<span class='notice'>\The [src] doesn't seem to respect your authority.</span>")
to_chat(user, "<span class='notice'>The [src] doesn't seem to respect your authority.</span>")
if(istype(W, /obj/item/mop/advanced))
if(bot_core.allowed(user) && open && adv_mop == TRUE)
else if(istype(W, /obj/item/mop/advanced))
if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_CLEANER_ADVANCED_MOP))
to_chat(user, "<span class='notice'>You replace \the [src] old mop with a new better one!</span>")
adv_mop = TRUE
upgrades |= UPGRADE_CLEANER_ADVANCED_MOP
clean_time = 20 //2.5 the speed!
window_name = "Automatic Station Cleaner v2.1 BETA" //New!
qdel(W)
if(!open)
to_chat(user, "<span class='notice'>The [src] access pannle is not open!</span>")
return
if(!bot_core.allowed(user))
to_chat(user, "<span class='notice'>The [src] access pannel locked off to you!</span>")
return
else
to_chat(user, "<span class='notice'>\the [src] already has this mop!</span>")
to_chat(user, "<span class='notice'>The [src] already has this mop!</span>")
if(istype(W, /obj/item/twohanded/broom))
if(bot_core.allowed(user) && open && broom == TRUE)
else if(istype(W, /obj/item/twohanded/broom))
if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_CLEANER_BROOM))
to_chat(user, "<span class='notice'>You add to \the [src] a broom speeding it up!</span>")
broom = TRUE
upgrades |= UPGRADE_CLEANER_BROOM
base_speed = 1 //2x faster!
qdel(W)
if(!open)
to_chat(user, "<span class='notice'>The [src] access pannel is not open!</span>")
return
if(!bot_core.allowed(user))
to_chat(user, "<span class='notice'>The [src] access pannel locked off to you!</span>")
return
else
to_chat(user, "<span class='notice'>\the [src] already has a broom!</span>")
to_chat(user, "<span class='notice'>The [src] already has a broom!</span>")
else
return ..()
@@ -147,9 +147,8 @@
to_chat(user, "<span class='warning'>You need one length of cable to wire the ED-209!</span>")
return
to_chat(user, "<span class='notice'>You start to wire [src]...</span>")
if(do_after(user, 40, target = src))
if(coil.get_amount() >= 1 && build_step == 6)
coil.use(1)
if(coil.use_tool(src, user, 40, 1))
if(build_step == 6)
to_chat(user, "<span class='notice'>You wire [src].</span>")
name = "wired ED-209 assembly"
build_step++
@@ -44,8 +44,6 @@
var/cell_type = /obj/item/stock_parts/cell
var/vest_type = /obj/item/clothing/suit/armor/vest
do_footstep = TRUE
/mob/living/simple_animal/bot/ed209/Initialize(mapload,created_name,created_lasercolor)
. = ..()
@@ -33,6 +33,8 @@
var/oldloc = null
var/toolbox = /obj/item/storage/toolbox/mechanical
var/upgrades = 0
#define HULL_BREACH 1
#define LINE_SPACE_MODE 2
#define FIX_TILE 3
@@ -120,6 +122,36 @@
to_chat(user, "<span class='notice'>You load [loaded] tiles into the floorbot. It now contains [specialtiles] tiles.</span>")
else
to_chat(user, "<span class='warning'>You need at least one floor tile to put into [src]!</span>")
else if(istype(W, /obj/item/storage/toolbox/artistic))
if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_FLOOR_ARTBOX))
to_chat(user, "<span class='notice'>You upgrade \the [src] case to hold more!</span>")
upgrades |= UPGRADE_FLOOR_ARTBOX
maxtiles += 100 //Double the storage!
qdel(W)
if(!open)
to_chat(user, "<span class='notice'>The [src] access pannle is not open!</span>")
return
if(!bot_core.allowed(user))
to_chat(user, "<span class='notice'>The [src] access pannel locked off to you!</span>")
return
else
to_chat(user, "<span class='notice'>The [src] already has a upgraded case!</span>")
else if(istype(W, /obj/item/storage/toolbox/syndicate))
if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_FLOOR_SYNDIBOX))
to_chat(user, "<span class='notice'>You upgrade \the [src] case to hold more!</span>")
upgrades |= UPGRADE_FLOOR_SYNDIBOX
maxtiles += 200 //Double bse storage
base_speed = 1 //2x faster!
qdel(W)
if(!bot_core.allowed(user))
to_chat(user, "<span class='notice'>The [src] access pannel locked off to you!</span>")
return
else
to_chat(user, "<span class='notice'>The [src] already has a upgraded case!</span>")
else
..()
@@ -42,6 +42,7 @@
var/declare_crit = 1 //If active, the bot will transmit a critical patient alert to MedHUD users.
var/declare_cooldown = 0 //Prevents spam of critical patient alerts.
var/stationary_mode = 0 //If enabled, the Medibot will not move automatically.
var/injection_time = 30 //How long we take to inject someone
//Setting which reagents to use to treat what by default. By id.
var/treatment_brute_avoid = /datum/reagent/medicine/tricordrazine
var/treatment_brute = /datum/reagent/medicine/bicaridine
@@ -51,19 +52,25 @@
var/treatment_fire = /datum/reagent/medicine/kelotane
var/treatment_tox_avoid = /datum/reagent/medicine/tricordrazine
var/treatment_tox = /datum/reagent/medicine/charcoal
var/treatment_tox_toxlover = /datum/reagent/toxin
var/treatment_tox_toxlover = /datum/reagent/toxin //Injects toxins into people that heal via toxins
var/treatment_virus_avoid = null
var/treatment_virus = /datum/reagent/medicine/spaceacillin
var/treat_virus = 1 //If on, the bot will attempt to treat viral infections, curing them if possible.
var/shut_up = 0 //self explanatory :)
var/upgrades = 0
var/upgraded_dispenser_1 //Do we have the nicer chemicals? - replaces dex with salbutamol
var/upgraded_dispenser_2 //Do we have the nicer chemicals? - replaces kep with oxandrolone
var/upgraded_dispenser_3 //Do we have the nicer chemicals? - replaces bic with sal acid
var/upgraded_dispenser_4 //Do we have the nicer chemicals? - replaces charcoal/toxin with pentetic acid / pentetic jelly
/mob/living/simple_animal/bot/medbot/mysterious
name = "\improper Mysterious Medibot"
desc = "International Medibot of mystery."
skin = "bezerk"
treatment_brute = /datum/reagent/medicine/tricordrazine
treatment_fire = /datum/reagent/medicine/tricordrazine
treatment_tox = /datum/reagent/medicine/tricordrazine
treatment_brute = /datum/reagent/medicine/regen_jelly
treatment_fire = /datum/reagent/medicine/regen_jelly
treatment_tox = /datum/reagent/medicine/regen_jelly
/mob/living/simple_animal/bot/medbot/derelict
name = "\improper Old Medibot"
@@ -220,7 +227,6 @@
/mob/living/simple_animal/bot/medbot/attackby(obj/item/W as obj, mob/user as mob, params)
if(istype(W, /obj/item/reagent_containers/glass))
. = 1 //no afterattack
if(locked)
to_chat(user, "<span class='warning'>You cannot insert a beaker because the panel is locked!</span>")
return
@@ -234,6 +240,97 @@
to_chat(user, "<span class='notice'>You insert [W].</span>")
show_controls(user)
else if(istype(W, /obj/item/reagent_containers/syringe/piercing))
if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_PIERERCING))
to_chat(user, "<span class='notice'>You replace \the [src] syringe with a diamond-tipped one!</span>")
upgrades |= UPGRADE_MEDICAL_PIERERCING
qdel(W)
if(!open)
to_chat(user, "<span class='notice'>The [src] access pannel is not open!</span>")
return
if(!bot_core.allowed(user))
to_chat(user, "<span class='notice'>The [src] access pannel locked off to you!</span>")
return
else
to_chat(user, "<span class='notice'>The [src] already has a diamond-tipped syringe!</span>")
else if(istype(W, /obj/item/hypospray/mkii))
if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_HYPOSPRAY))
to_chat(user, "<span class='notice'>You replace \the [src] syringe base with a DeForest Medical MK.II Hypospray!</span>")
upgrades |= UPGRADE_MEDICAL_HYPOSPRAY
injection_time = 15 //Half the time half the death!
window_name = "Automatic Medical Unit v2.4 ALPHA"
qdel(W)
if(!open)
to_chat(user, "<span class='notice'>The [src] access pannel is not open!</span>")
return
if(!bot_core.allowed(user))
to_chat(user, "<span class='notice'>The [src] access pannel locked off to you!</span>")
return
else
to_chat(user, "<span class='notice'>The [src] already has a DeForest Medical Hypospray base!</span>")
else if(istype(W, /obj/item/circuitboard/machine/chem_dispenser))
if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_CHEM_BOARD))
to_chat(user, "<span class='notice'>You add in the board upgrading \the [src] reagent banks!</span>")
upgrades |= UPGRADE_MEDICAL_CHEM_BOARD
treatment_oxy = /datum/reagent/medicine/salbutamol //Replaces Dex with salbutamol "better" healing of o2
qdel(W)
if(!open)
to_chat(user, "<span class='notice'>The [src] access pannel is not open!</span>")
return
if(!bot_core.allowed(user))
to_chat(user, "<span class='notice'>The [src] access pannel locked off to you!</span>")
return
else
to_chat(user, "<span class='notice'>The [src] already has this upgrade!</span>")
else if(istype(W, /obj/item/circuitboard/machine/cryo_tube))
if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_CRYO_BOARD))
to_chat(user, "<span class='notice'>You add in the board upgrading \the [src] reagent banks!</span>")
upgrades |= UPGRADE_MEDICAL_CRYO_BOARD
treatment_fire = /datum/reagent/medicine/oxandrolone //Replaces Kep with oxandrolone "better" healing of burns
qdel(W)
if(!open)
to_chat(user, "<span class='notice'>The [src] access pannel is not open!</span>")
return
if(!bot_core.allowed(user))
to_chat(user, "<span class='notice'>The [src] access pannel locked off to you!</span>")
return
else
to_chat(user, "<span class='notice'>The [src] already has this upgrade!</span>")
else if(istype(W, /obj/item/circuitboard/machine/chem_master))
if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_CHEM_MASTER))
to_chat(user, "<span class='notice'>You add in the board upgrading \the [src] reagent banks!</span>")
upgrades |= UPGRADE_MEDICAL_CHEM_MASTER
treatment_brute = /datum/reagent/medicine/sal_acid //Replaces Bic with Sal Acid "better" healing of brute
qdel(W)
if(!open)
to_chat(user, "<span class='notice'>the [src] access pannel is not open!</span>")
return
if(!bot_core.allowed(user))
to_chat(user, "<span class='notice'>the [src] access pannel locked off to you!</span>")
return
else
to_chat(user, "<span class='notice'>the [src] already has this upgrade!</span>")
else if(istype(W, /obj/item/circuitboard/machine/sleeper))
if(bot_core.allowed(user) && open && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_SLEEP_BOARD))
to_chat(user, "<span class='notice'>You add in the board upgrading \the [src] reagent banks!</span>")
upgrades |= UPGRADE_MEDICAL_SLEEP_BOARD
treatment_tox = /datum/reagent/medicine/pen_acid //replaces charcoal with pen acid a "better" healing of toxins
treatment_tox_toxlover = /datum/reagent/medicine/pen_acid/pen_jelly //Injects pen jelly into people that heal via toxins
qdel(W)
if(!open)
to_chat(user, "<span class='notice'>The [src] access pannle is not open!</span>")
return
if(!bot_core.allowed(user))
to_chat(user, "<span class='notice'>The [src] access pannel locked off to you!</span>")
return
else
to_chat(user, "<span class='notice'>The [src] already has this upgrade!</span>")
else
var/current_health = health
..()
@@ -249,6 +346,8 @@
audible_message("<span class='danger'>[src] buzzes oddly!</span>")
flick("medibot_spark", src)
playsound(src, "sparks", 75, 1)
if(!CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_PIERERCING))
upgrades |= UPGRADE_MEDICAL_PIERERCING //Jabs even harder through the clothing!
if(user)
oldpatient = user
@@ -361,7 +460,7 @@
if(ishuman(C))
var/mob/living/carbon/human/H = C
if (H.wear_suit && H.head && istype(H.wear_suit, /obj/item/clothing) && istype(H.head, /obj/item/clothing))
if (H.wear_suit && H.head && istype(H.wear_suit, /obj/item/clothing) && istype(H.head, /obj/item/clothing) && !CHECK_BITFIELD(upgrades,UPGRADE_MEDICAL_PIERERCING))
var/obj/item/clothing/CS = H.wear_suit
var/obj/item/clothing/CH = H.head
if (CS.clothing_flags & CH.clothing_flags & THICKMATERIAL)
@@ -418,7 +517,7 @@
else
..()
/mob/living/simple_animal/bot/medbot/examinate(atom/A as mob|obj|turf in view())
/mob/living/simple_animal/bot/medbot/examinate(atom/A as mob|obj|turf in fov_view())
..()
if(!is_blind(src))
chemscan(src, A)
@@ -504,7 +603,7 @@
"<span class='userdanger'>[src] is trying to inject you!</span>")
var/failed = FALSE
if(do_mob(src, patient, 30)) //Is C == patient? This is so confusing
if(do_mob(src, patient, injection_time)) //Is C == patient? This is so confusing
if((get_dist(src, patient) <= 1) && (on) && assess_patient(patient))
if(reagent_id == "internal_beaker")
if(use_beaker && reagent_glass && reagent_glass.reagents.total_volume)
@@ -5,9 +5,12 @@
gender = NEUTER
mob_biotypes = NONE
speak_emote = list("hisses")
response_help = "thinks better of touching"
response_disarm = "flails at"
response_harm = "punches"
response_help_continuous = "thinks better of touching"
response_help_simple = "think better of touching"
response_disarm_continuous = "flails at"
response_disarm_simple = "flail at"
response_harm_continuous = "punches"
response_harm_simple = "punch"
threat = 1
speak_chance = 1
icon = 'icons/mob/mob.dmi'
@@ -122,12 +125,14 @@
threat = 3
maxHealth = 150
health = 150
response_harm = "harmlessly punches"
response_harm_continuous = "harmlessly punches"
response_harm_simple = "harmlessly punch"
harm_intent_damage = 0
obj_damage = 90
melee_damage_lower = 25
melee_damage_upper = 25
attacktext = "smashes their armored gauntlet into"
attack_verb_continuous = "smashes their armored gauntlet into"
attack_verb_simple = "smash your armored gauntlet into"
speed = 2.5
environment_smash = ENVIRONMENT_SMASH_WALLS
attack_sound = 'sound/weapons/punch3.ogg'
@@ -188,7 +193,8 @@
melee_damage_lower = 20
melee_damage_upper = 20
retreat_distance = 2 //AI wraiths will move in and out of combat
attacktext = "slashes"
attack_verb_continuous = "slashes"
attack_verb_simple = "slash"
attack_sound = 'sound/weapons/bladeslice.ogg'
construct_spells = list(/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift)
runetype = /datum/action/innate/cult/create_rune/tele
@@ -232,14 +238,16 @@
icon_living = "artificer"
maxHealth = 50
health = 50
response_harm = "viciously beats"
response_harm_continuous = "viciously beats"
response_harm_simple = "viciously beat"
harm_intent_damage = 5
obj_damage = 60
melee_damage_lower = 5
melee_damage_upper = 5
retreat_distance = 10
minimum_distance = 10 //AI artificers will flee like fuck
attacktext = "rams"
attack_verb_continuous = "rams"
attack_verb_simple = "ram"
environment_smash = ENVIRONMENT_SMASH_WALLS
attack_sound = 'sound/weapons/punch2.ogg'
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/conjure/wall,
@@ -319,7 +327,8 @@
sight = SEE_MOBS
melee_damage_lower = 15
melee_damage_upper = 20
attacktext = "butchers"
attack_verb_continuous = "butchers"
attack_verb_simple = "butcher"
attack_sound = 'sound/weapons/bladeslice.ogg'
construct_spells = list(/obj/effect/proc_holder/spell/aoe_turf/area_conversion,
/obj/effect/proc_holder/spell/targeted/forcewall/cult)
@@ -5,14 +5,18 @@
icon_living = "bumbles"
icon_dead = "bumbles_dead"
turns_per_move = 1
response_help = "pets"
response_disarm = "brushes aside"
response_harm = "squashes"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "brushes aside"
response_help_simple = "brush aside"
response_harm_continuous = "squashes"
response_harm_simple = "squash"
speak_emote = list("buzzes")
maxHealth = 100
health = 100
harm_intent_damage = 1
friendly = "bzzs"
friendly_verb_continuous = "bzzs"
friendly_verb_simple = "bzz"
density = FALSE
movement_type = FLYING
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
@@ -5,14 +5,18 @@
icon_living = "butterfly"
icon_dead = "butterfly_dead"
turns_per_move = 1
response_help = "shoos"
response_disarm = "brushes aside"
response_harm = "squashes"
response_help_continuous = "shoos"
response_help_simple = "shoo"
response_disarm_continuous = "brushes aside"
response_disarm_simple = "brush aside"
response_harm_continuous = "squashes"
response_harm_simple = "squash"
speak_emote = list("flutters")
maxHealth = 2
health = 2
harm_intent_damage = 1
friendly = "nudges"
friendly_verb_continuous = "nudges"
friendly_verb_simple = "nudge"
density = FALSE
movement_type = FLYING
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
@@ -24,15 +24,18 @@
animal_species = /mob/living/simple_animal/pet/cat
childtype = list(/mob/living/simple_animal/pet/cat/kitten)
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2, /obj/item/organ/ears/cat = 1, /obj/item/organ/tail/cat = 1)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
var/turns_since_scan = 0
var/mob/living/simple_animal/mouse/movement_target
gold_core_spawnable = FRIENDLY_SPAWN
collar_type = "cat"
var/held_icon = "cat2"
do_footstep = TRUE
footstep_type = FOOTSTEP_MOB_CLAW
/mob/living/simple_animal/pet/cat/Initialize()
. = ..()
@@ -87,7 +90,6 @@
pass_flags = PASSMOB
mob_size = MOB_SIZE_SMALL
collar_type = "kitten"
held_icon = "cat"
//RUNTIME IS ALIVE! SQUEEEEEEEE~
/mob/living/simple_animal/pet/cat/Runtime
@@ -99,6 +101,7 @@
gender = FEMALE
gold_core_spawnable = NO_SPAWN
unique_pet = TRUE
held_icon = "cat"
var/list/family = list()//var restored from savefile, has count of each child type
var/list/children = list()//Actual mob instances of children
var/cats_deployed = 0
@@ -245,7 +248,8 @@
harm_intent_damage = 10
butcher_results = list(/obj/item/organ/brain = 1, /obj/item/organ/heart = 1, /obj/item/reagent_containers/food/snacks/cakeslice/birthday = 3, \
/obj/item/reagent_containers/food/snacks/meat/slab = 2)
response_harm = "takes a bite out of"
response_harm_continuous = "takes a bite out of"
response_harm_simple = "take a bite out of"
attacked_sound = 'sound/items/eatfood.ogg'
deathmessage = "loses its false life and collapses!"
death_sound = "bodyfall"
@@ -306,7 +310,6 @@
if (pseudo_death == TRUE) //secret cat chem
icon_state = "custom_cat_dead"
Stun(1000)
friendly = "deads at"
return
else
..()
@@ -14,9 +14,12 @@
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_TINY
mob_biotypes = MOB_ORGANIC|MOB_BUG
response_help = "pokes"
response_disarm = "shoos"
response_harm = "splats"
response_help_continuous = "pokes"
response_help_simple = "poke"
response_disarm_continuous = "shoos"
response_disarm_simple = "shoo"
response_harm_continuous = "splats"
response_harm_simple = "splat"
speak_emote = list("chitters")
density = FALSE
ventcrawler = VENTCRAWLER_ALWAYS
@@ -12,11 +12,15 @@
speak_chance = 1
turns_per_move = 5
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/rawcrab = 4)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "stomps"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "stomps"
response_harm_continuous = "stomp"
stop_automated_movement = 1
friendly = "pinches"
friendly_verb_continuous = "pinches"
friendly_verb_simple = "pinch"
ventcrawler = VENTCRAWLER_ALWAYS
var/obj/item/inventory_head
var/obj/item/inventory_mask
@@ -41,9 +45,6 @@
real_name = "Coffee"
desc = "It's Coffee, the other pet!"
gender = FEMALE
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "stomps"
gold_core_spawnable = NO_SPAWN
/mob/living/simple_animal/crab/evil
@@ -53,9 +54,10 @@
icon_state = "evilcrab"
icon_living = "evilcrab"
icon_dead = "evilcrab_dead"
response_help = "pokes"
response_disarm = "shoves"
response_harm = "stomps"
response_help_continuous = "pokes"
response_help_simple = "poke"
response_disarm_continuous = "shoves"
response_disarm_simple = "shove"
gold_core_spawnable = HOSTILE_SPAWN
/mob/living/simple_animal/crab/kreb
@@ -65,9 +67,6 @@
icon_state = "kreb"
icon_living = "kreb"
icon_dead = "kreb_dead"
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "stomps"
gold_core_spawnable = NO_SPAWN
/mob/living/simple_animal/crab/evil/kreb
@@ -2,9 +2,12 @@
/mob/living/simple_animal/pet/dog
mob_biotypes = MOB_ORGANIC|MOB_BEAST
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "bops"
response_disarm_simple = "bop"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
speak = list("YAP", "Woof!", "Bark!", "AUUUUUU")
speak_emote = list("barks", "woofs")
emote_hear = list("barks!", "woofs!", "yaps.","pants.")
@@ -15,7 +18,7 @@
turns_per_move = 10
var/held_icon = "corgi"
do_footstep = TRUE
footstep_type = FOOTSTEP_MOB_CLAW
/mob/living/simple_animal/pet/dog/ComponentInitialize()
. = ..()
@@ -332,9 +335,6 @@
desc = "It's the HoP's beloved corgi."
var/turns_since_scan = 0
var/obj/movement_target
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
gold_core_spawnable = NO_SPAWN
unique_pet = TRUE
var/age = 0
@@ -604,9 +604,6 @@
icon_state = "lisa"
icon_living = "lisa"
icon_dead = "lisa_dead"
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
var/turns_since_scan = 0
var/puppies = 0
held_icon = "lisa"
@@ -13,13 +13,17 @@
turns_per_move = 5
see_in_dark = 6
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 4)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
faction = list("neutral")
mob_biotypes = MOB_ORGANIC|MOB_BEAST
attack_same = 1
attacktext = "kicks"
attack_verb_continuous = "kicks"
attack_verb_simple = "kick"
attack_sound = 'sound/weapons/punch1.ogg'
health = 40
maxHealth = 40
@@ -30,7 +34,7 @@
blood_volume = BLOOD_VOLUME_NORMAL
var/obj/item/udder/udder = null
do_footstep = TRUE
footstep_type = FOOTSTEP_MOB_SHOE
/mob/living/simple_animal/hostile/retaliate/goat/Initialize()
udder = new()
@@ -121,10 +125,14 @@
turns_per_move = 5
see_in_dark = 6
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 6)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicks"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
attack_verb_continuous = "kicks"
attack_verb_simple = "kick"
attack_sound = 'sound/weapons/punch1.ogg'
health = 50
maxHealth = 50
@@ -132,7 +140,7 @@
gold_core_spawnable = FRIENDLY_SPAWN
blood_volume = BLOOD_VOLUME_NORMAL
do_footstep = TRUE
footstep_type = FOOTSTEP_MOB_SHOE
/mob/living/simple_animal/cow/Initialize()
udder = new()
@@ -198,10 +206,14 @@
speak_chance = 2
turns_per_move = 2
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/chicken = 1)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicks"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
attack_verb_continuous = "kicks"
attack_verb_simple = "kick"
health = 3
maxHealth = 3
ventcrawler = VENTCRAWLER_ALWAYS
@@ -210,7 +222,7 @@
mob_size = MOB_SIZE_TINY
gold_core_spawnable = FRIENDLY_SPAWN
do_footstep = TRUE
footstep_type = FOOTSTEP_MOB_CLAW
/mob/living/simple_animal/chick/Initialize()
. = ..()
@@ -249,10 +261,14 @@
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/chicken = 2)
var/egg_type = /obj/item/reagent_containers/food/snacks/egg
var/food_type = /obj/item/reagent_containers/food/snacks/grown/wheat
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicks"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
attack_verb_continuous = "kicks"
attack_verb_simple = "kick"
health = 15
maxHealth = 15
ventcrawler = VENTCRAWLER_ALWAYS
@@ -268,7 +284,7 @@
gold_core_spawnable = FRIENDLY_SPAWN
var/static/chicken_count = 0
do_footstep = TRUE
footstep_type = FOOTSTEP_MOB_CLAW
/mob/living/simple_animal/chicken/Initialize()
. = ..()
@@ -342,10 +358,14 @@
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3)
var/egg_type = /obj/item/reagent_containers/food/snacks/egg/kiwiEgg
var/food_type = /obj/item/reagent_containers/food/snacks/grown/wheat
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicks"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
attack_verb_continuous = "kicks"
attack_verb_simple = "kick"
health = 25
maxHealth = 25
ventcrawler = VENTCRAWLER_ALWAYS
@@ -358,6 +378,8 @@
gold_core_spawnable = FRIENDLY_SPAWN
var/static/kiwi_count = 0
footstep_type = FOOTSTEP_MOB_CLAW
/mob/living/simple_animal/kiwi/Destroy()
--kiwi_count
return ..()
@@ -418,10 +440,14 @@
speak_chance = 2
turns_per_move = 2
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
attacktext = "kicks"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
attack_verb_continuous = "kicks"
attack_verb_simple = "kick"
health = 10
maxHealth = 10
ventcrawler = VENTCRAWLER_ALWAYS
@@ -430,6 +456,8 @@
mob_size = MOB_SIZE_TINY
gold_core_spawnable = FRIENDLY_SPAWN
footstep_type = FOOTSTEP_MOB_CLAW
/mob/living/simple_animal/babyKiwi/Initialize()
. = ..()
pixel_x = rand(-6, 6)
@@ -472,3 +500,33 @@
user.visible_message("[user] milks [src] using \the [O].", "<span class='notice'>You milk [src] using \the [O].</span>")
else
to_chat(user, "<span class='danger'>The udder is dry. Wait a bit longer...</span>")
/mob/living/simple_animal/deer
name = "doe"
desc = "A gentle, peaceful forest animal. How did this get into space?"
icon_state = "deer-doe"
icon_living = "deer-doe"
icon_dead = "deer-doe-dead"
gender = FEMALE
mob_biotypes = MOB_ORGANIC|MOB_BEAST
speak = list("Weeeeeeee?","Weeee","WEOOOOOOOOOO")
speak_emote = list("grunts","grunts lowly")
emote_hear = list("brays.")
emote_see = list("shakes its head.")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3)
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently nudges"
response_disarm_simple = "gently nudge"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
attack_verb_continuous = "bucks"
attack_verb_simple = "buck"
attack_sound = 'sound/weapons/punch1.ogg'
health = 75
maxHealth = 75
blood_volume = BLOOD_VOLUME_NORMAL
footstep_type = FOOTSTEP_MOB_SHOE
@@ -14,11 +14,14 @@
turns_per_move = 5
see_in_dark = 6
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
gold_core_spawnable = FRIENDLY_SPAWN
do_footstep = TRUE
footstep_type = FOOTSTEP_MOB_CLAW
/mob/living/simple_animal/pet/fox/ComponentInitialize()
. = ..()
@@ -9,9 +9,12 @@
name = "gondola"
real_name = "gondola"
desc = "Gondola is the silent walker. Having no hands he embodies the Taoist principle of wu-wei (non-action) while his smiling facial expression shows his utter and complete acceptance of the world as it is. Its hide is extremely valuable."
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "bops"
response_disarm_simple = "bop"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
faction = list("gondola")
turns_per_move = 10
icon = 'icons/mob/gondolas.dmi'
@@ -8,12 +8,16 @@
health = 5
maxHealth = 5
faction = list("Lizard")
attacktext = "bites"
attack_verb_continuous = "bites"
attack_verb_simple = "bite"
melee_damage_lower = 1
melee_damage_upper = 2
response_help = "pets"
response_disarm = "shoos"
response_harm = "stomps on"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "shoos"
response_disarm_simple = "shoo"
response_harm_continuous = "stomps on"
response_harm_simple = "stomp on"
ventcrawler = VENTCRAWLER_ALWAYS
density = FALSE
pass_flags = PASSTABLE | PASSMOB
@@ -15,9 +15,12 @@
maxHealth = 5
health = 5
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 1)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "splats"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "splats"
response_harm_simple = "splat"
density = FALSE
ventcrawler = VENTCRAWLER_ALWAYS
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
@@ -103,9 +106,6 @@ GLOBAL_VAR(tom_existed)
/mob/living/simple_animal/mouse/brown/Tom
name = "Tom"
desc = "Jerry the cat is not amused."
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "splats"
gold_core_spawnable = NO_SPAWN
/mob/living/simple_animal/mouse/brown/Tom/Initialize()
@@ -13,8 +13,11 @@
turns_per_move = 5
see_in_dark = 6
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
gold_core_spawnable = FRIENDLY_SPAWN
do_footstep = TRUE
footstep_type = FOOTSTEP_MOB_CLAW
@@ -1,9 +1,12 @@
//Penguins
/mob/living/simple_animal/pet/penguin
response_help = "pets"
response_disarm = "bops"
response_harm = "kicks"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "bops"
response_disarm_simple = "bop"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
speak = list("Gah Gah!", "NOOT NOOT!", "NOOT!", "Noot", "noot", "Prah!", "Grah!")
speak_emote = list("squawks", "gakkers")
emote_hear = list("squawk!", "gakkers!", "noots.","NOOTS!")
@@ -15,7 +18,7 @@
turns_per_move = 10
icon = 'icons/mob/penguins.dmi'
do_footstep = TRUE
footstep_type = FOOTSTEP_MOB_BAREFOOT
/mob/living/simple_animal/pet/penguin/emperor
name = "Emperor penguin"
@@ -11,9 +11,12 @@
speak_chance = 1
turns_per_move = 5
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
mob_biotypes = MOB_ORGANIC|MOB_BEAST
gold_core_spawnable = FRIENDLY_SPAWN
melee_damage_lower = 18
@@ -22,7 +25,7 @@
maxHealth = 50
speed = 10
glide_size = 2
do_footstep = TRUE
footstep_type = FOOTSTEP_MOB_CLAW
/mob/living/simple_animal/pet/fox/ComponentInitialize()
. = ..()
@@ -19,12 +19,16 @@
speak_emote = list("hisses")
health = 20
maxHealth = 20
attacktext = "bites"
attack_verb_continuous = "bites"
attack_verb_simple = "bite"
melee_damage_lower = 5
melee_damage_upper = 6
response_help = "pets"
response_disarm = "shoos"
response_harm = "steps on"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "shoos"
response_disarm_simple = "shoo"
response_harm_continuous = "steps on"
response_harm_simple = "step on"
faction = list("hostile")
ventcrawler = VENTCRAWLER_ALWAYS
density = FALSE
@@ -13,9 +13,12 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
gender = NEUTER
mob_biotypes = NONE
bubble_icon = "guardian"
response_help = "passes through"
response_disarm = "flails at"
response_harm = "punches"
response_help_continuous = "passes through"
response_help_simple = "pass through"
response_disarm_continuous = "flails at"
response_disarm_simple = "flail at"
response_harm_continuous = "punches"
response_harm_simple = "punch"
icon = 'icons/mob/guardian.dmi'
icon_state = "magicbase"
icon_living = "magicbase"
@@ -29,7 +32,8 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
maxbodytemp = INFINITY
attacktext = "punches"
attack_verb_continuous = "punches"
attack_verb_simple = "punch"
maxHealth = INFINITY //The spirit itself is invincible
health = INFINITY
healable = FALSE //don't brusepack the guardian
@@ -109,7 +113,8 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
icon_dead = "holocarp"
speak_emote = list("gnashes")
desc = "A mysterious fish that stands by its charge, ever vigilant."
attacktext = "bites"
attack_verb_continuous = "bites"
attack_verb_simple = "bite"
attack_sound = 'sound/weapons/bite.ogg'
recolorentiresprite = TRUE
if(!recolorentiresprite) //we want this to proc before stand logs in, so the overlay isnt gone for some reason
@@ -1,6 +1,7 @@
//Assassin
/mob/living/simple_animal/hostile/guardian/assassin
attacktext = "slashes"
attack_verb_continuous = "slashes"
attack_verb_simple = "slash"
attack_sound = 'sound/weapons/bladeslice.ogg'
damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 1, CLONE = 1, STAMINA = 0, OXY = 1)
playstyle_string = "<span class='holoparasite'>As an <b>assassin</b> type you do medium damage and have no damage resistance, but can enter stealth, massively increasing the damage of your next attack and causing it to ignore armor. Stealth is broken when you attack or take damage.</span>"
@@ -54,7 +54,7 @@
var/blocked = FALSE
if(hasmatchingsummoner(hit_atom)) //if the summoner matches don't hurt them
blocked = TRUE
if(L.run_block(src, 90, "[name]", ATTACK_TYPE_TACKLE, 0, src) & BLOCK_SUCCESS)
if(L.mob_run_block(src, 90, "[name]", ATTACK_TYPE_TACKLE, 0, src, null, null) & BLOCK_SUCCESS)
blocked = TRUE
if(!blocked)
L.drop_all_held_items()
@@ -4,7 +4,8 @@
melee_damage_lower = 10
melee_damage_upper = 10
attack_sound = 'sound/items/welder.ogg'
attacktext = "ignites"
attack_verb_continuous = "ignites"
attack_verb_simple = "ignite"
melee_damage_type = BURN
damage_coeff = list(BRUTE = 0.7, BURN = 0.1, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7)
playstyle_string = "<span class='holoparasite'>As a <b>chaos</b> type, you take 30% damage reduction to all but burn, which you are almost immune to. You will ignite any enemy you bump into. in addition, your melee attacks will cause human targets to see everyone as you.</span>"
@@ -6,7 +6,8 @@
/mob/living/simple_animal/hostile/guardian/beam
melee_damage_lower = 10
melee_damage_upper = 10
attacktext = "shocks"
attack_verb_continuous = "shocks"
attack_verb_simple = "shock"
melee_damage_type = BURN
attack_sound = 'sound/machines/defib_zap.ogg'
damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7)
@@ -8,7 +8,8 @@
/mob/living/simple_animal/hostile/guardian/ranged
a_intent = INTENT_HELP
friendly = "quietly assesses"
friendly_verb_continuous = "quietly assesses"
friendly_verb_simple = "quietly assess"
melee_damage_lower = 10
melee_damage_upper = 10
damage_coeff = list(BRUTE = 0.9, BURN = 0.9, TOX = 0.9, CLONE = 0.9, STAMINA = 0, OXY = 0.9)
@@ -1,7 +1,8 @@
//Healer
/mob/living/simple_animal/hostile/guardian/healer
a_intent = INTENT_HARM
friendly = "heals"
friendly_verb_continuous = "heals"
friendly_verb_simple = "heal"
damage_coeff = list(BRUTE = 0.7, BURN = 0.7, TOX = 0.7, CLONE = 0.7, STAMINA = 0, OXY = 0.7)
playstyle_string = "<span class='holoparasite'>As a <b>support</b> type, you have 30% damage reduction and may toggle your basic attacks to a healing mode. In addition, Alt-Clicking on an adjacent object or mob will warp them to your bluespace beacon after a short delay.</span>"
magic_fluff_string = "<span class='holoparasite'>..And draw the CMO, a potent force of life... and death.</span>"
@@ -8,9 +8,12 @@
icon_gib = "syndicate_gib"
gender = FEMALE
threat = 1
response_help = "pokes"
response_disarm = "shoves"
response_harm = "hits"
response_help_continuous = "pokes"
response_help_simple = "poke"
response_disarm_continuous = "shoves"
response_disarm_simple = "shove"
response_harm_continuous = "hits"
response_harm_simple = "hit"
speed = 0
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/xeno = 4,
/obj/item/stack/sheet/animalhide/xeno = 1)
@@ -20,7 +23,8 @@
obj_damage = 60
melee_damage_lower = 25
melee_damage_upper = 25
attacktext = "slashes"
attack_verb_continuous = "slashes"
attack_verb_simple = "slash"
speak_emote = list("hisses")
bubble_icon = "alien"
a_intent = INTENT_HARM
@@ -37,7 +41,9 @@
death_sound = 'sound/voice/hiss6.ogg'
deathmessage = "lets out a waning guttural screech, green blood bubbling from its maw..."
do_footstep = TRUE
/mob/living/simple_animal/hostile/alien/Initialize()
. = ..()
AddComponent(/datum/component/footstep, FOOTSTEP_MOB_CLAW)
/mob/living/simple_animal/hostile/alien/drone
name = "alien drone"
@@ -80,6 +86,7 @@
icon_state = "alienq"
icon_living = "alienq"
icon_dead = "alienq_dead"
pixel_x = -16
threat = 8
health = 250
maxHealth = 250
@@ -162,7 +169,8 @@
melee_damage_upper = 0
threat = -1
a_intent = INTENT_HELP
friendly = "caresses"
friendly_verb_continuous = "caresses"
friendly_verb_simple = "caress"
obj_damage = 0
environment_smash = ENVIRONMENT_SMASH_NONE
gold_core_spawnable = HOSTILE_SPAWN
@@ -13,14 +13,16 @@
maxbodytemp = INFINITY
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
mob_size = MOB_SIZE_TINY
response_help = "pokes"
response_disarm = "shoos"
response_harm = "splats"
response_help_continuous = "pokes"
response_help_simple = "poke"
response_disarm_continuous = "shoos"
response_disarm_simple = "shoo"
response_harm_continuous = "splats"
response_harm_simple = "plat"
speak_emote = list("chitters")
mouse_opacity = 2
density = TRUE
ventcrawler = VENTCRAWLER_ALWAYS
gold_core_spawnable = FRIENDLY_SPAWN
verb_say = "chitters"
verb_ask = "chitters inquisitively"
verb_exclaim = "chitters loudly"
@@ -17,9 +17,12 @@
turns_per_move = 5
see_in_dark = 6
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/bear = 5, /obj/item/clothing/head/bearpelt = 1)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "hits"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
response_harm_continuous = "kicks"
response_harm_simple = "kick"
maxHealth = 60
health = 60
spacewalk = TRUE
@@ -28,9 +31,11 @@
obj_damage = 60
melee_damage_lower = 20
melee_damage_upper = 30
attacktext = "claws"
attack_verb_continuous = "claws"
attack_verb_simple = "claw"
attack_sound = 'sound/weapons/bladeslice.ogg'
friendly = "bear hugs"
friendly_verb_continuous = "bear hugs"
friendly_verb_simple = "bear hug"
//Space bears aren't affected by cold.
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
@@ -40,7 +45,7 @@
faction = list("russian")
gold_core_spawnable = HOSTILE_SPAWN
do_footstep = TRUE
footstep_type = FOOTSTEP_MOB_CLAW
//SPACE BEARS! SQUEEEEEEEE~ OW! FUCK! IT BIT MY HAND OFF!!
/mob/living/simple_animal/hostile/bear/Hudson
@@ -111,12 +116,14 @@ mob/living/simple_animal/hostile/bear/butter //The mighty companion to Cak. Seve
melee_damage_lower = 1
melee_damage_upper = 1
armour_penetration = 0
response_harm = "takes a bite out of"
response_harm_continuous = "takes a bite out of"
response_harm_simple = "take a bite out of"
attacked_sound = 'sound/items/eatfood.ogg'
deathmessage = "loses its false life and collapses!"
butcher_results = list(/obj/item/reagent_containers/food/snacks/butter = 6, /obj/item/reagent_containers/food/snacks/meat/slab = 3, /obj/item/organ/brain = 1, /obj/item/organ/heart = 1)
attack_sound = 'sound/weapons/slap.ogg'
attacktext = "slaps"
attack_verb_continuous = "slaps"
attack_verb_simple = "slap"
/mob/living/simple_animal/hostile/bear/butter/Life() //Heals butter bear really fast when he takes damage.
if(stat)
@@ -23,10 +23,14 @@
turns_per_move = 0
melee_damage_lower = 1
melee_damage_upper = 1
attacktext = "stings"
response_help = "shoos"
response_disarm = "swats away"
response_harm = "squashes"
attack_verb_continuous = "stings"
attack_verb_simple = "sting"
response_help_continuous = "shoos"
response_help_simple = "shoo"
response_disarm_continuous = "swats away"
response_disarm_simple = "swat away"
response_harm_continuous = "squashes"
response_harm_simple = "squash"
maxHealth = 10
health = 10
spacewalk = TRUE
@@ -7,6 +7,7 @@
status_flags = 0
a_intent = INTENT_HARM
gender = NEUTER
has_field_of_vision = FALSE //You are a frikkin boss
var/list/boss_abilities = list() //list of /datum/action/boss
var/datum/boss_active_timed_battle/atb
var/point_regen_delay = 1
@@ -23,7 +23,7 @@
attack_sound = 'sound/hallucinations/growl1.ogg'
var/list/copies = list()
do_footstep = TRUE
footstep_type = FOOTSTEP_MOB_SHOE
//Summon Ability
@@ -12,9 +12,10 @@
speak_chance = 0
turns_per_move = 5
butcher_results = list(/obj/item/reagent_containers/food/snacks/carpmeat = 2)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "hits"
response_help_continuous = "pets"
response_help_simple = "pet"
response_disarm_continuous = "gently pushes aside"
response_disarm_simple = "gently push aside"
emote_taunt = list("gnashes")
taunt_chance = 30
speed = 0
@@ -25,7 +26,8 @@
obj_damage = 50
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = "bites"
attack_verb_continuous = "bites"
attack_verb_simple = "bite"
attack_sound = 'sound/weapons/bite.ogg'
speak_emote = list("gnashes")
//Space carp aren't affected by cold.
@@ -8,9 +8,6 @@
icon_gib = "syndicate_gib"
speak_chance = 0
turns_per_move = 5
response_help = "pokes"
response_disarm = "shoves"
response_harm = "hits"
speed = 0
stat_attack = UNCONSCIOUS
robust_searching = 1
@@ -19,7 +16,8 @@
harm_intent_damage = 5
melee_damage_lower = 15
melee_damage_upper = 15
attacktext = "slashes at"
attack_verb_continuous = "slashes at"
attack_verb_simple = "slash at"
attack_sound = 'sound/weapons/circsawhit.ogg'
a_intent = INTENT_HARM
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID

Some files were not shown because too many files have changed in this diff Show More