diff --git a/code/datums/spells/alien_spells/evolve.dm b/code/datums/spells/alien_spells/evolve.dm
index fcae6b1e541..e1bb39e386c 100644
--- a/code/datums/spells/alien_spells/evolve.dm
+++ b/code/datums/spells/alien_spells/evolve.dm
@@ -1,9 +1,10 @@
+#define LIVING_PLAYERS_COUNT_FOR_1_PRAETORIAN 25
+
/obj/effect/proc_holder/spell/alien_spell/evolve
desc = "Evolve into reporting this issue."
action_icon_state = "larva2"
action_icon = 'icons/mob/alien.dmi'
action_icon_state = "AlienMMI"
- plasma_cost = 500
var/queen_check = FALSE
var/evolution_path = /mob/living/carbon/alien/larva
@@ -27,22 +28,28 @@
return new /datum/spell_targeting/self
-/obj/effect/proc_holder/spell/alien_spell/evolve/cast(list/targets, mob/living/carbon/user)
+/obj/effect/proc_holder/spell/alien_spell/evolve/cast(list/targets, mob/living/carbon/alien/user)
+ if(!user.can_evolve)
+ to_chat(user, span_warning("We have nowhere to evolve further!"))
+ return
- if(queen_check)
- for(var/mob/living/carbon/alien/humanoid/queen/living_queen in GLOB.alive_mob_list)
- if(living_queen.key && living_queen.get_int_organ(/obj/item/organ/internal/brain)) // We do a once over to check the queen didn't end up going away into the magic land of semi-dead
- to_chat(user, "We already have an alive queen.")
- return
+ if(user.evolution_points < user.max_evolution_points)
+ to_chat(user, span_warning("We are not ready to evolve yet!"))
+ return
if(user.has_brain_worms())
- to_chat(user, "We cannot perform this ability at the present time!")
- revert_cast(user)
+ to_chat(user, span_warning("We cannot perform this ability at the present time!"))
return
- // If there is no queen, that means we can evolve
- to_chat(user, "You begin to evolve!")
- user.visible_message("[user] begins to twist and contort!")
+ if(queen_check)
+ if(user.queen_count >= user.queen_maximum)
+ to_chat(user, span_warning("We already have a queen."))
+ return
+ else
+ user.queen_count++
+
+ to_chat(user, span_noticealien("You begin to evolve!"))
+ user.visible_message(span_alertalien("[user] begins to twist and contort!"))
var/mob/living/carbon/alien/new_xeno = new evolution_path(user.loc)
user.mind.transfer_to(new_xeno)
new_xeno.mind.name = new_xeno.name
@@ -50,3 +57,19 @@
SSblackbox.record_feedback("tally", "alien_growth", 1, "[new_xeno]")
qdel(user)
+/obj/effect/proc_holder/spell/alien_spell/evolve/praetorian/cast(list/targets, mob/living/carbon/user)
+ var/mob/living/carbon/alien/spell_owner = user
+ if(!istype(spell_owner))
+ return
+
+ var/living_players_count = 0
+ for(var/mob/living/player in GLOB.player_list)
+ if(player.client && player.stat != DEAD)
+ living_players_count++
+
+ if(spell_owner.praetorian_count < (living_players_count/LIVING_PLAYERS_COUNT_FOR_1_PRAETORIAN))
+ ..()
+ else
+ to_chat(user, span_warning("We have too many praetorians."))
+
+#undef LIVING_PLAYERS_COUNT_FOR_1_PRAETORIAN
diff --git a/code/datums/spells/alien_spells/larva_evolve.dm b/code/datums/spells/alien_spells/larva_evolve.dm
index 3931d4f94c6..52e0b34d605 100644
--- a/code/datums/spells/alien_spells/larva_evolve.dm
+++ b/code/datums/spells/alien_spells/larva_evolve.dm
@@ -17,7 +17,7 @@
to_chat(user, "You cannot evolve when you are cuffed.")
return
- if(user.amount_grown < user.max_grown)
+ if(user.evolution_points < user.max_evolution_points)
to_chat(user, "You are not fully grown.")
return
//green is impossible to read, so i made these blue and changed the formatting slightly
diff --git a/code/datums/spells/alien_spells/neurotoxin_spit.dm b/code/datums/spells/alien_spells/neurotoxin_spit.dm
index 2281de22e64..66913cc2e65 100644
--- a/code/datums/spells/alien_spells/neurotoxin_spit.dm
+++ b/code/datums/spells/alien_spells/neurotoxin_spit.dm
@@ -1,7 +1,7 @@
/obj/effect/proc_holder/spell/alien_spell/neurotoxin
name = "Neurotoxin spit"
desc = "This ability allows you to fire some neurotoxin. Knocks down anyone you hit, applies a small amount of stamina damage as well."
- base_cooldown = 0.5 SECONDS
+ base_cooldown = 1 SECONDS
plasma_cost = 50
selection_activated_message = span_noticealien("Your prepare some neurotoxin!")
selection_deactivated_message = span_noticealien("You swallow your prepared neurotoxin.")
@@ -9,6 +9,8 @@
action_icon_state = "alien_neurotoxin_0"
sound = 'sound/creatures/terrorspiders/spit2.ogg'
+/obj/effect/proc_holder/spell/alien_spell/neurotoxin/sentinel
+ base_cooldown = 0.5 SECONDS
/obj/effect/proc_holder/spell/alien_spell/neurotoxin/create_new_targeting()
return new /datum/spell_targeting/clicked_atom
@@ -38,6 +40,10 @@
return TRUE
+/obj/effect/proc_holder/spell/alien_spell/neurotoxin/after_cast(list/targets, mob/user)
+ . = ..()
+ if(should_remove_click_intercept(user))
+ remove_ranged_ability(user)
/obj/effect/proc_holder/spell/alien_spell/neurotoxin/should_remove_click_intercept(mob/living/carbon/user)
if(user.get_plasma() < plasma_cost)
diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm
index d9fdfa98b17..abfdbf5dbf6 100644
--- a/code/game/machinery/doors/airlock.dm
+++ b/code/game/machinery/doors/airlock.dm
@@ -1350,24 +1350,36 @@ About the new airlock wires panel:
if(isElectrified())
shock(user, 100) //Mmm, fried xeno!
return
- if(!density) //Already open
+
+ if(operating)
return
- if(locked || welded) //Extremely generic, as aliens only understand the basics of how airlocks work.
- to_chat(user, span_warning("[src] refuses to budge!"))
+
+ if(locked || welded)
+ return ..()
+
+ var/is_opening = density
+ if(allowed(user))
+ if(is_opening)
+ open(TRUE)
+ else
+ close(TRUE)
return
- user.visible_message(span_warning("[user] begins prying open [src]."),\
- span_noticealien("You begin digging your claws into [src] with all your might!"),\
- span_warning("You hear groaning metal..."))
- var/time_to_open = 0.2 SECONDS
+
+ var/time_to_action = 0.2 SECONDS
if(arePowerSystemsOn())
- time_to_open = user.time_to_open_doors
- if(time_to_open > 3 SECONDS)
+ time_to_action = user.time_to_open_doors
+ if(time_to_action > 3 SECONDS)
playsound(src, 'sound/machines/airlock_alien_prying.ogg', 100, TRUE)
+ user.visible_message(span_warning("[user] begins prying [is_opening ? "open":"close"] [src]."),\
+ span_noticealien("You begin digging your claws into [src] with all your might!"),\
+ span_warning("You hear groaning metal..."))
+
+ if(do_after(user, time_to_action, TRUE, src))
+ var/returns = is_opening ? open(TRUE) : close(TRUE)
+ if(!returns) //The airlock is still closed, but something prevented it opening. (Another player noticed and bolted/welded the airlock in time!)
+ to_chat(user, span_warning("Despite your efforts, [src] managed to resist your attempts!"))
- if(do_after(user, time_to_open, TRUE, src))
- if(density && !open(2)) //The airlock is still closed, but something prevented it opening. (Another player noticed and bolted/welded the airlock in time!)
- to_chat(user, span_warning("Despite your efforts, [src] managed to resist your attempts to open it!"))
/obj/machinery/door/airlock/power_change() //putting this is obj/machinery/door itself makes non-airlock doors turn invisible for some reason
..()
diff --git a/code/game/machinery/doors/firedoor.dm b/code/game/machinery/doors/firedoor.dm
index 2254e844037..bc9eb38a6ad 100644
--- a/code/game/machinery/doors/firedoor.dm
+++ b/code/game/machinery/doors/firedoor.dm
@@ -186,8 +186,7 @@
/obj/machinery/door/firedoor/attack_alien(mob/user)
add_fingerprint(user)
if(welded)
- to_chat(user, span_warning("[src] refuses to budge!"))
- return
+ return ..()
open()
/obj/machinery/door/firedoor/attack_animal(mob/user)
diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm
index aff77d4ded6..b42bdeef94e 100644
--- a/code/game/mecha/mecha.dm
+++ b/code/game/mecha/mecha.dm
@@ -679,7 +679,7 @@
log_message("Attack by alien. Attacker - [user].", TRUE)
add_attack_logs(user, OCCUPANT_LOGGING, "Alien attacked mech [src]")
playsound(src.loc, 'sound/weapons/slash.ogg', 100, TRUE)
- attack_generic(user, user.attack_damage, BRUTE, "melee", 0, user.armour_penetration)
+ attack_generic(user, user.obj_damage, BRUTE, MELEE, 0, user.armour_penetration)
/obj/mecha/attack_animal(mob/living/simple_animal/user)
log_message("Attack by simple animal. Attacker - [user].")
diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm
index 7976fac4099..f7060c17f70 100644
--- a/code/game/objects/structures/aliens.dm
+++ b/code/game/objects/structures/aliens.dm
@@ -107,16 +107,17 @@
return !density
/obj/structure/alien/resin/attack_alien(mob/living/carbon/alien/humanoid/A)
- var/damage = 0
- switch(A.caste)
- if("d") //drone breaks wall in 2 hits
- damage = max_integrity/2/ALIEN_RESIN_BRUTE_MOD
- if("q") //queen breaks wall in 1 hit
- damage = max_integrity/ALIEN_RESIN_BRUTE_MOD
- else
- return ..()
- if(attack_generic(A, damage, BRUTE, "melee", 0, 100))
- playsound(loc, 'sound/effects/attackblob.ogg', 50, TRUE)
+ if(A.a_intent == INTENT_HARM)
+ var/damage = 0
+ switch(A.caste)
+ if("d") //drone breaks wall in 2 hits
+ damage = max_integrity/2/ALIEN_RESIN_BRUTE_MOD
+ if("q") //queen breaks wall in 1 hit
+ damage = max_integrity/ALIEN_RESIN_BRUTE_MOD
+ else
+ return ..()
+ if(attack_generic(A, damage, BRUTE, "melee", 0, 100))
+ playsound(loc, 'sound/effects/attackblob.ogg', 50, TRUE)
#define RESIN_DOOR_CLOSED 0
@@ -421,6 +422,10 @@
/obj/structure/alien/weeds/node/New()
..(loc, src)
+/obj/structure/alien/weeds/attack_alien(mob/living/carbon/alien/humanoid/A)
+ if(A.a_intent == INTENT_HARM)
+ return ..()
+
#undef NODERANGE
@@ -433,8 +438,8 @@
#define BURSTING 1
#define GROWING 2
#define GROWN 3
-#define MIN_GROWTH_TIME 1800 //time it takes to grow a hugger
-#define MAX_GROWTH_TIME 3000
+#define MIN_GROWTH_TIME 1200 //time it takes to grow a hugger
+#define MAX_GROWTH_TIME 1800
/obj/structure/alien/egg
name = "egg"
diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm
index affa5f4e139..2a7cbe1ffc7 100644
--- a/code/game/objects/structures/grille.dm
+++ b/code/game/objects/structures/grille.dm
@@ -43,7 +43,7 @@
//height=42
icon='icons/obj/fence-ns.dmi'
-/obj/structure/grille/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
+/obj/structure/grille/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir, armour_penetration)
. = ..()
update_icon()
@@ -130,7 +130,7 @@
user.changeNext_move(CLICK_CD_MELEE)
user.visible_message("[user] mangles [src].")
if(!shock(user, 70))
- take_damage(user.obj_damage, BRUTE, "melee", 1)
+ take_damage(user.obj_damage, BRUTE, MELEE, 1, armour_penetration = user.armour_penetration)
/obj/structure/grille/CanPass(atom/movable/mover, turf/target, height=0)
diff --git a/code/modules/events/alien_infestation.dm b/code/modules/events/alien_infestation.dm
index 91f345ea9e3..1a54d755227 100644
--- a/code/modules/events/alien_infestation.dm
+++ b/code/modules/events/alien_infestation.dm
@@ -30,14 +30,20 @@
if(playercount >= ALIEN_HIGHPOP_TRIGGER) //spawn with 4 if highpop
spawncount = 4
var/list/candidates = SSghost_spawns.poll_candidates("Вы хотите сыграть за Чужого?", ROLE_ALIEN, TRUE, source = /mob/living/carbon/alien/larva)
+ var/first_spawn = TRUE
while(spawncount && length(vents) && length(candidates))
var/obj/vent = pick_n_take(vents)
var/mob/C = pick_n_take(candidates)
if(C)
GLOB.respawnable_list -= C.client
var/mob/living/carbon/alien/larva/new_xeno = new(vent.loc)
- new_xeno.amount_grown += (0.75 * new_xeno.max_grown) //event spawned larva start off almost ready to evolve.
+ new_xeno.evolution_points += (0.75 * new_xeno.max_evolution_points) //event spawned larva start off almost ready to evolve.
new_xeno.key = C.key
+
+ if(first_spawn)
+ new_xeno.queen_maximum++
+ first_spawn = FALSE
+
if(SSticker && SSticker.mode)
SSticker.mode.xenos += new_xeno.mind
@@ -49,6 +55,7 @@
/datum/event/alien_infestation/proc/spawn_vectors(list/vents, playercount)
spawncount = 1
var/list/candidates = SSghost_spawns.poll_candidates("Вы хотите сыграть за Чужого Вектора?", ROLE_ALIEN, TRUE, source = /mob/living/carbon/alien/humanoid/hunter/vector)
+ var/first_spawn = TRUE
while(spawncount && length(vents) && length(candidates))
var/obj/vent = pick_n_take(vents)
var/mob/C = pick_n_take(candidates)
@@ -56,6 +63,11 @@
GLOB.respawnable_list -= C.client
var/mob/living/carbon/alien/humanoid/hunter/vector/new_xeno = new(vent.loc)
new_xeno.key = C.key
+
+ if(first_spawn)
+ new_xeno.queen_maximum++
+ first_spawn = FALSE
+
if(SSticker && SSticker.mode)
SSticker.mode.xenos += new_xeno.mind
diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm
index 5fbb90133af..102026c0f0b 100644
--- a/code/modules/mob/living/carbon/alien/alien.dm
+++ b/code/modules/mob/living/carbon/alien/alien.dm
@@ -17,10 +17,10 @@
var/obj/item/card/id/wear_id = null // Fix for station bounced radios -- Skie
var/has_fine_manipulation = FALSE
- var/move_delay_add = FALSE // movement delay to add
+ var/move_delay_add = 0 // movement delay to add
+ var/caste_movement_delay = 0
status_flags = CANPARALYSE|CANPUSH
- var/heal_rate = 5
var/attack_damage = 20
var/armour_penetration = 20
@@ -35,11 +35,19 @@
var/leaping = FALSE
dirslash_enabled = TRUE
ventcrawler = 1
+
+ var/can_evolve = FALSE
+ var/evolution_points = 0
+ var/max_evolution_points = 200
+
/// See [/proc/genderize_decode] for more info.
var/death_message = "изда%(ет,ют)% тихий гортанный звук, зелёная кровь пузырится из %(его,её,его,их)% пасти..."
var/death_sound = 'sound/voice/hiss6.ogg'
var/datum/action/innate/alien_nightvision_toggle/night_vision_action
+ var/static/praetorian_count = 0
+ var/static/queen_count = 0
+ var/static/queen_maximum = 0
/mob/living/carbon/alien/New()
@@ -72,6 +80,11 @@
/obj/item/organ/internal/ears
)
+/mob/living/carbon/alien/Stat()
+ ..()
+ if(can_evolve)
+ stat(null, "Evolution progress: [evolution_points]/[max_evolution_points]")
+
/mob/living/carbon/alien/get_default_language()
if(default_language)
@@ -169,15 +182,21 @@
stat(null, "Move Mode: [m_intent]")
show_stat_emergency_shuttle_eta()
+/mob/living/carbon/alien/Weaken(amount, ignore_canweaken)
+ ..()
+ if(!(status_flags & CANWEAKEN) && amount && !large)
+ // add some movement delay
+ move_delay_add = min(move_delay_add + round(amount / 5), 10)
+
/mob/living/carbon/alien/SetWeakened(amount, ignore_canweaken)
..()
- if(!(status_flags & CANWEAKEN) && amount)
+ if(!(status_flags & CANWEAKEN) && amount && !large)
// add some movement delay
- move_delay_add = min(move_delay_add + round(amount / 2), 10) // a maximum delay of 10
+ move_delay_add = min(move_delay_add + round(amount / 5), 10)
/mob/living/carbon/alien/movement_delay()
. = ..()
- . += move_delay_add + CONFIG_GET(number/alien_delay) //move_delay_add is used to slow aliens with stuns
+ . += move_delay_add + caste_movement_delay + CONFIG_GET(number/alien_delay) //move_delay_add is used to slow aliens with stuns
/mob/living/carbon/alien/getDNA()
return null
diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm
index bff525c39ce..8ba2705d9cb 100644
--- a/code/modules/mob/living/carbon/alien/alien_defense.dm
+++ b/code/modules/mob/living/carbon/alien/alien_defense.dm
@@ -6,15 +6,8 @@
..(AM, skip_catch, FALSE, blocked, throwingdatum)
-/*Code for aliens attacking aliens. Because aliens act on a hivemind, I don't see them as very aggressive with each other.
-As such, they can either help or harm other aliens. Help works like the human help command while harm is a simple nibble.
-In all, this is a lot like the monkey code. /N
-*/
+/// Alien attack another alien
/mob/living/carbon/alien/attack_alien(mob/living/carbon/alien/M)
- if(istype(loc, /turf) && istype(loc.loc, /area/start))
- to_chat(M, "No attacking people at spawn, you jackass.")
- return
-
switch(M.a_intent)
if(INTENT_HELP)
AdjustSleeping(-10 SECONDS)
@@ -22,24 +15,33 @@ In all, this is a lot like the monkey code. /N
AdjustParalysis(-6 SECONDS)
AdjustStunned(-6 SECONDS)
AdjustWeakened(-6 SECONDS)
- visible_message("[M.name] nuzzles [src] trying to wake it up!")
+ if(on_fire)
+ M.visible_message(span_warning("[M] trying to extinguish [src.name]!"), span_warning("You trying to extinguish [src.name]!"))
+ playsound(get_turf(src), 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
+ adjust_fire_stacks(-0.5)
+ else
+ M.visible_message(span_notice("[M.name] nuzzles [src] trying to wake it up!"))
if(INTENT_GRAB)
grabbedby(M)
- else
- if(health > 0)
- M.do_attack_animation(src, ATTACK_EFFECT_BITE)
- playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
- visible_message("[M.name] bites [src]!", \
- "[M.name] bites [src]!")
- adjustBruteLoss(1)
- add_attack_logs(M, src, "Alien attack", ATKLOG_ALL)
- else
- to_chat(M, "[name] is too injured for that.")
+ if(INTENT_DISARM)
+ ..()
+ if(drop_from_active_hand())
+ M.visible_message(span_danger("[M.name] disarms [src.name]!"))
+ playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
+
+ if(INTENT_HARM)
+ ..()
+ visible_message(span_danger("[M] has slashed at [src]!"), span_userdanger("[M] has slashed at [src]!"))
+ playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
+ adjustBruteLoss(M.attack_damage)
+ add_attack_logs(M, src, "Alien attack", ATKLOG_ALL)
+
/mob/living/carbon/alien/attack_larva(mob/living/carbon/alien/larva/L)
- return attack_alien(L)
+ if(..() && L.a_intent == INTENT_HARM)
+ adjustBruteLoss(L.attack_damage)
/mob/living/carbon/alien/attack_hand(mob/living/carbon/human/M)
if(..()) //to allow surgery to return properly.
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm
index 59a627d5168..397297b0bac 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/drone.dm
@@ -6,6 +6,7 @@
obj_damage = 60
icon_state = "aliend_s"
time_to_open_doors = 0.2 SECONDS
+ can_evolve = TRUE
var/sterile = FALSE
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
index 18f473975cc..03e196e0993 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm
@@ -5,6 +5,10 @@
health = 205
devour_time = 2 SECONDS
icon_state = "alienh_s"
+ caste_movement_delay = -1
+ var/invisibility_cost = 5
+ var/leap_speed = 1.5
+ var/leap_without_gravity_speed = 4
/mob/living/carbon/alien/humanoid/hunter/New()
@@ -19,16 +23,11 @@
. += /obj/item/organ/internal/xenos/plasmavessel/hunter
-/mob/living/carbon/alien/humanoid/hunter/movement_delay()
- . = -1 //hunters are sanic
- . += ..() //but they still need to slow down on stun
-
-
/mob/living/carbon/alien/humanoid/hunter/handle_environment()
if(m_intent == MOVE_INTENT_RUN || resting)
..()
else
- adjust_alien_plasma(-heal_rate)
+ adjust_alien_plasma(-invisibility_cost)
//Hunter verbs
@@ -53,26 +52,23 @@
/mob/living/carbon/alien/humanoid/hunter/proc/leap_at(var/atom/A)
if(pounce_cooldown > world.time)
- to_chat(src, "You are too fatigued to pounce right now!")
+ to_chat(src, span_alertalien("You are too fatigued to pounce right now!"))
return
if(leaping) //Leap while you leap, so you can leap while you leap
return
- if(!has_gravity(src) || !has_gravity(A))
- to_chat(src, "It is unsafe to leap without gravity!")
- //It's also extremely buggy visually, so it's balance+bugfix
- return
if(lying)
return
else //Maybe uses plasma in the future, although that wouldn't make any sense...
- leaping = 1
+ leaping = TRUE
update_icons()
- throw_at(A, MAX_ALIEN_LEAP_DIST, 1, spin = 0, diagonals_first = 1, callback = CALLBACK(src, PROC_REF(leap_end)))
+ var/speed = (!has_gravity(src) || !has_gravity(A)) ? leap_without_gravity_speed : leap_speed
+ throw_at(A, MAX_ALIEN_LEAP_DIST, speed, spin = 0, diagonals_first = 1, callback = CALLBACK(src, PROC_REF(leap_end)))
/mob/living/carbon/alien/humanoid/hunter/proc/leap_end()
- leaping = 0
+ leaping = FALSE
update_icons()
/mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/A, datum/thrownthing/throwingdatum)
@@ -89,7 +85,7 @@
if(H.check_shields(src, 0, "the [name]", attack_type = LEAP_ATTACK))
blocked = 1
if(!blocked)
- L.visible_message("[src] pounces on [L]!", "[src] pounces on you!")
+ L.visible_message(span_danger("[src] pounces on [L]!"), span_userdanger("[src] pounces on you!"))
if(ishuman(L))
var/mob/living/carbon/human/H = L
H.apply_effect(10 SECONDS, WEAKEN, H.run_armor_check(null, "melee"))
@@ -102,11 +98,11 @@
toggle_leap(0)
else if(A.density && !A.CanPass(src))
- visible_message("[src] smashes into [A]!", "[src] smashes into [A]!")
- Weaken(4 SECONDS, TRUE)
+ visible_message(span_danger("[src] smashes into [A]!"), span_alertalien("[src] smashes into [A]!"))
+ Weaken(0.5 SECONDS, TRUE)
if(leaping)
- leaping = 0
+ leaping = FALSE
update_icons()
update_canmove()
diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
index 5b73ca7753e..db564c8c094 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm
@@ -6,6 +6,7 @@
attack_damage = 25
time_to_open_doors = 0.2 SECONDS
icon_state = "aliens_s"
+ can_evolve = TRUE
/mob/living/carbon/alien/humanoid/sentinel/New()
@@ -22,7 +23,7 @@
. += list(
/obj/item/organ/internal/xenos/plasmavessel/sentinel,
/obj/item/organ/internal/xenos/acidgland/sentinel,
- /obj/item/organ/internal/xenos/neurotoxin
+ /obj/item/organ/internal/xenos/neurotoxin/sentinel
)
@@ -31,11 +32,15 @@
icon = 'icons/mob/alienlarge.dmi'
icon_state = "prat_s"
pixel_x = -16
- maxHealth = 300
- health = 300
- large = 1
+ maxHealth = 420
+ health = 420
+ status_flags = CANPARALYSE
+ large = TRUE
+ move_resist = MOVE_FORCE_STRONG
+ caste_movement_delay = 1
ventcrawler = 0
attack_damage = 30
+ disarm_stamina_damage = 34
armour_penetration = 30
obj_damage = 80
time_to_open_doors = 0.2 SECONDS
@@ -51,6 +56,7 @@
action_sprite.Grant(src)
..()
AddSpell(new /obj/effect/proc_holder/spell/alien_spell/break_vents)
+ praetorian_count++
/mob/living/carbon/alien/humanoid/praetorian/Destroy()
@@ -59,11 +65,19 @@
action_sprite = null
return ..()
+/mob/living/carbon/alien/humanoid/praetorian/death(gibbed)
+ // Only execute the below if we successfully died
+ . = ..(gibbed)
+ if(.)
+ praetorian_count--
+
+/mob/living/carbon/alien/humanoid/praetorian/is_strong()
+ return TRUE
/mob/living/carbon/alien/humanoid/praetorian/get_caste_organs()
. = ..()
. += list(
- /obj/item/organ/internal/xenos/plasmavessel/sentinel,
+ /obj/item/organ/internal/xenos/plasmavessel/praetorian,
/obj/item/organ/internal/xenos/acidgland/praetorian,
/obj/item/organ/internal/xenos/neurotoxin
)
diff --git a/code/modules/mob/living/carbon/alien/humanoid/empress.dm b/code/modules/mob/living/carbon/alien/humanoid/empress.dm
index ac5db670aff..de6250a4c9a 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/empress.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/empress.dm
@@ -7,7 +7,8 @@
status_flags = CANPARALYSE
mob_size = MOB_SIZE_LARGE
bubble_icon = "alienroyal"
- large = 1
+ large = TRUE
+ move_resist = MOVE_FORCE_STRONG
ventcrawler = 0
/mob/living/carbon/alien/humanoid/empress/large
diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
index 6d717415554..5c9beb8da82 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm
@@ -5,12 +5,13 @@
health = 640
icon_state = "alienq_s"
status_flags = CANPARALYSE
- heal_rate = 5
- large = 1
+ large = TRUE
+ move_resist = MOVE_FORCE_STRONG
+ caste_movement_delay = 3
ventcrawler = 0
- attack_damage = 30
- disarm_stamina_damage = 34
- armour_penetration = 30
+ attack_damage = 40
+ disarm_stamina_damage = 50
+ armour_penetration = 50
obj_damage = 80
time_to_open_doors = 0.2 SECONDS
environment_smash = ENVIRONMENT_SMASH_RWALLS
@@ -43,9 +44,6 @@
/obj/item/organ/internal/xenos/neurotoxin
)
-/mob/living/carbon/alien/humanoid/queen/movement_delay()
- . = ..()
- . += 3
/mob/living/carbon/alien/humanoid/queen/can_inject(mob/user, error_msg, target_zone, penetrate_thick, ignore_pierceimmune)
return FALSE
@@ -57,7 +55,6 @@
icon = 'icons/mob/alienlarge.dmi'
icon_state = "queen_s"
pixel_x = -16
- large = 1
var/datum/action/innate/small_sprite_alien/action_sprite
diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm
index 355a0218e4b..715d8f9efe3 100644
--- a/code/modules/mob/living/carbon/alien/larva/larva.dm
+++ b/code/modules/mob/living/carbon/alien/larva/larva.dm
@@ -4,16 +4,15 @@
icon_state = "larva0"
pass_flags = PASSTABLE | PASSMOB
mob_size = MOB_SIZE_SMALL
-
+ attack_damage = 3
+ obj_damage = 10
maxHealth = 25
health = 25
density = 0
tts_seed = "Templar"
- var/amount_grown = 0
- var/max_grown = 200
- var/time_of_birth
+ can_evolve = TRUE
death_message = "с тошнотворным шипением выдыха%(ет,ют)% воздух и пада%(ет,ют)% на пол..."
death_sound = null
@@ -48,16 +47,6 @@
. += /obj/item/organ/internal/xenos/plasmavessel/larva
-//This needs to be fixed
-/mob/living/carbon/alien/larva/Stat()
- ..()
- stat(null, "Progress: [amount_grown]/[max_grown]")
-
-/mob/living/carbon/alien/larva/adjust_alien_plasma(amount)
- if(stat != DEAD && amount > 0)
- amount_grown = min(amount_grown + 1, max_grown)
- ..(amount)
-
/mob/living/carbon/alien/larva/ex_act(severity)
..()
diff --git a/code/modules/mob/living/carbon/alien/larva/life.dm b/code/modules/mob/living/carbon/alien/larva/life.dm
index 70a5f0a336a..394b547718a 100644
--- a/code/modules/mob/living/carbon/alien/larva/life.dm
+++ b/code/modules/mob/living/carbon/alien/larva/life.dm
@@ -1,12 +1,6 @@
/mob/living/carbon/alien/larva/Life(seconds, times_fired)
set invisibility = 0
- if(notransform)
- return
- if(..()) //not dead and not in stasis
- // GROW!
- if(amount_grown < max_grown)
- amount_grown++
- update_icons()
+ . = ..()
/mob/living/carbon/alien/larva/update_stat(reason = "none given", should_log = FALSE)
if(status_flags & GODMODE)
diff --git a/code/modules/mob/living/carbon/alien/larva/update_icons.dm b/code/modules/mob/living/carbon/alien/larva/update_icons.dm
index 0681b698f09..0859832fc32 100644
--- a/code/modules/mob/living/carbon/alien/larva/update_icons.dm
+++ b/code/modules/mob/living/carbon/alien/larva/update_icons.dm
@@ -5,9 +5,9 @@
/mob/living/carbon/alien/larva/update_icons()
var/state = 0
- if(amount_grown > 150)
+ if(evolution_points > 150)
state = 2
- else if(amount_grown > 50)
+ else if(evolution_points > 50)
state = 1
if(stat == DEAD)
diff --git a/code/modules/mob/living/carbon/alien/life.dm b/code/modules/mob/living/carbon/alien/life.dm
index a29bdf04e67..940f30d4384 100644
--- a/code/modules/mob/living/carbon/alien/life.dm
+++ b/code/modules/mob/living/carbon/alien/life.dm
@@ -1,3 +1,13 @@
+/mob/living/carbon/alien/Life(seconds, times_fired)
+ if(..() && can_evolve && evolution_points < max_evolution_points)
+ var/points_to_add = 1
+ if(locate(/obj/structure/alien/weeds) in loc)
+ points_to_add *= 2
+ if(lying)
+ points_to_add *= 2
+ evolution_points = min(evolution_points + points_to_add, max_evolution_points)
+ update_icons()
+
/mob/living/carbon/alien/check_breath(datum/gas_mixture/breath)
if(status_flags & GODMODE)
return
@@ -48,6 +58,6 @@
LAZYREMOVE(stomach_contents, M)
continue
if(stat != DEAD)
- M.Weaken(3 SECONDS)
- M.EyeBlind(3 SECONDS)
+ M.SetWeakened(4 SECONDS)
+ M.SetEyeBlind(4 SECONDS)
M.adjustBruteLoss(1.5)
diff --git a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
index 6bc10769e5a..4610be8e4b9 100644
--- a/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
+++ b/code/modules/mob/living/carbon/alien/special/alien_embryo.dm
@@ -15,7 +15,7 @@
else
to_chat(finder, "It's grown quite large, and writhes slightly as you look at it.")
if(prob(10))
- AttemptGrow(0)
+ AttemptGrow(FALSE)
/obj/item/organ/internal/body_egg/alien_embryo/prepare_eat()
var/obj/S = ..()
@@ -40,18 +40,16 @@
owner.emote("cough")
if(prob(4))
to_chat(owner, "Your muscles ache.")
- if(prob(20))
- owner.take_organ_damage(1)
+ owner.take_organ_damage(1)
if(prob(4))
to_chat(owner, "Your stomach hurts.")
- if(prob(20))
- owner.adjustToxLoss(1)
+ owner.adjustToxLoss(1)
if(5)
to_chat(owner, "You feel something tearing its way out of your stomach...")
owner.adjustToxLoss(10)
/obj/item/organ/internal/body_egg/alien_embryo/egg_process()
- if(stage < 5 && prob(3))
+ if(stage < 5 && prob(4))
stage++
spawn(0)
RefreshInfectionImage()
@@ -59,13 +57,13 @@
if(stage == 5 && prob(50))
for(var/datum/surgery/S in owner.surgeries)
if(S.location == BODY_ZONE_CHEST && istype(S.get_surgery_step(), /datum/surgery_step/internal/manipulate_organs))
- AttemptGrow(0)
+ AttemptGrow(FALSE)
return
AttemptGrow()
-/obj/item/organ/internal/body_egg/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1)
+/obj/item/organ/internal/body_egg/alien_embryo/proc/AttemptGrow(gib_on_success = TRUE)
if(!owner || polling)
return
polling = 1
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index ac07d9ab1a7..e03544cc45e 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -593,12 +593,11 @@ emp_act
/mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L)
if(..()) //successful larva bite.
- var/damage = rand(1, 3)
if(stat != DEAD)
- L.amount_grown = min(L.amount_grown + damage, L.max_grown)
+ L.evolution_points = min(L.evolution_points + L.attack_damage, L.max_evolution_points)
var/obj/item/organ/external/affecting = get_organ(ran_zone(L.zone_selected))
var/armor_block = run_armor_check(affecting, "melee")
- apply_damage(damage, BRUTE, affecting, armor_block)
+ apply_damage(L.attack_damage, BRUTE, affecting, armor_block)
updatehealth("larva attack")
/mob/living/carbon/human/attack_alien(mob/living/carbon/alien/humanoid/M)
@@ -622,7 +621,7 @@ emp_act
visible_message("[M] has slashed at [src]!", \
"[M] has slashed at [src]!")
- apply_damage(damage, BRUTE, affecting, armor_block)
+ apply_damage(damage, BRUTE, affecting, armor_block, TRUE)
add_attack_logs(M, src, "Alien attacked")
updatehealth("alien attack")
var/all_objectives = M?.mind?.get_all_objectives()
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index 7498fc85ab0..dfde272a32d 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -353,12 +353,12 @@
switch(L.a_intent)
if(INTENT_HELP)
visible_message("[L.declent_ru(NOMINATIVE)] [pluralize_ru(L.gender,"трётся","трутся")] головой о [src.declent_ru(ACCUSATIVE)].")
- return 0
+ return FALSE
else
if(HAS_TRAIT(L, TRAIT_PACIFISM) || GLOB.pacifism_after_gt)
to_chat(L, "[pluralize_ru(L.gender,"Ты не хочешь","Вы не хотите")] никому навредить!")
- return
+ return FALSE
L.do_attack_animation(src)
if(prob(90))
@@ -366,11 +366,11 @@
visible_message("[L.declent_ru(NOMINATIVE)] куса[pluralize_ru(L.gender,"ет","ют")] [src.declent_ru(ACCUSATIVE)]!", \
"[L.declent_ru(NOMINATIVE)] куса[pluralize_ru(L.gender,"ет","ют")] [src.declent_ru(ACCUSATIVE)]!")
playsound(loc, 'sound/weapons/bite.ogg', 50, 1, -1)
- return 1
+ return TRUE
else
visible_message("[L.declent_ru(NOMINATIVE)] пыта[pluralize_ru(L.gender,"ет","ют")]ся укусить [src.declent_ru(ACCUSATIVE)]!", \
"[L.declent_ru(NOMINATIVE)] пыта[pluralize_ru(L.gender,"ет","ют")]ся укусить [src.declent_ru(ACCUSATIVE)]!")
- return 0
+ return FALSE
/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
switch(M.a_intent)
diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm
index 9a10e074536..5bacaf20427 100644
--- a/code/modules/mob/living/simple_animal/animal_defense.dm
+++ b/code/modules/mob/living/simple_animal/animal_defense.dm
@@ -53,10 +53,9 @@
/mob/living/simple_animal/attack_larva(mob/living/carbon/alien/larva/L)
if(..()) //successful larva bite
if(stat != DEAD)
- var/damage = rand(5, 10)
- . = attack_threshold_check(damage)
+ . = attack_threshold_check(L.attack_damage)
if(.)
- L.amount_grown = min(L.amount_grown + damage, L.max_grown)
+ L.evolution_points = min(L.evolution_points + L.attack_damage, L.max_evolution_points)
/mob/living/simple_animal/attack_animal(mob/living/simple_animal/M)
. = ..()
diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm
index 083ba11b49b..00dddf35c7e 100644
--- a/code/modules/projectiles/projectile/bullets.dm
+++ b/code/modules/projectiles/projectile/bullets.dm
@@ -355,7 +355,7 @@
if(isalien(target))
weaken = 0
nodamage = 1
- if(ismecha(target) || issilicon(target))
+ if(isobj(target) || issilicon(target) || ismachineperson(target))
damage_type = BURN
. = ..() // Execute the rest of the code.
diff --git a/code/modules/spacepods/spacepod.dm b/code/modules/spacepods/spacepod.dm
index d5e80d80437..ff6737ba46c 100644
--- a/code/modules/spacepods/spacepod.dm
+++ b/code/modules/spacepods/spacepod.dm
@@ -208,9 +208,9 @@
light_color = icon_light_color[src.icon_state]
/obj/spacepod/bullet_act(var/obj/item/projectile/P)
+ . = P.on_hit(src)
if(P.damage_type == BRUTE || P.damage_type == BURN)
deal_damage(P.damage)
- P.on_hit(src)
/obj/spacepod/AllowDrop()
return TRUE
@@ -245,13 +245,15 @@
return TRUE
/obj/spacepod/attack_alien(mob/living/carbon/alien/user)
- user.changeNext_move(CLICK_CD_MELEE)
- deal_damage(user.attack_damage)
- playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1, -1)
- to_chat(user, "You slash at [src]!")
- visible_message("The [user] slashes at [src.name]'s armor!")
-
-/obj/spacepod/proc/deal_damage(var/damage)
+ if(user.a_intent == INTENT_HARM)
+ user.do_attack_animation(src)
+ user.changeNext_move(CLICK_CD_MELEE)
+ deal_damage(user.obj_damage)
+ playsound(src.loc, 'sound/weapons/slash.ogg', 50, 1, -1)
+ to_chat(user, "You slash at [src]!")
+ visible_message("The [user] slashes at [src.name]'s armor!")
+
+/obj/spacepod/proc/deal_damage(damage)
var/oldhealth = health
health = max(0, health - damage)
var/percentage = (health / initial(health)) * 100
diff --git a/code/modules/surgery/organs/subtypes/xenos.dm b/code/modules/surgery/organs/subtypes/xenos.dm
index f04372860b5..e1311ed00da 100644
--- a/code/modules/surgery/organs/subtypes/xenos.dm
+++ b/code/modules/surgery/organs/subtypes/xenos.dm
@@ -47,8 +47,10 @@
var/stored_plasma = 0
/// Maximum vessel capacity.
var/max_plasma = 500
- /// Gained heal amount per Life() cycle.
+ /// Gained heal amount per Life() cycle, while on weeds.
var/heal_rate = 7.5
+ /// Gained passive heal amount per Life() cycle.
+ var/passive_heal_rate = 1
/// Gained plasma amount per Life() cycle.
var/plasma_rate = 10
@@ -57,27 +59,41 @@
name = "bloated xeno plasma vessel"
icon_state = "plasma_large"
origin_tech = "biotech=6;plasmatech=4"
- stored_plasma = 200
- plasma_rate = 25
+ max_plasma = 750
+ stored_plasma = 300
+ plasma_rate = 30
alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/plant_weeds/queen, /obj/effect/proc_holder/spell/touch/alien_spell/transfer_plasma)
+/obj/item/organ/internal/xenos/plasmavessel/praetorian
+ name = "huge xeno plasma vessel"
+ icon_state = "plasma_large"
+ max_plasma = 750
+ stored_plasma = 100
+ plasma_rate = 15
+
+
/obj/item/organ/internal/xenos/plasmavessel/drone
name = "large xeno plasma vessel"
icon_state = "plasma_large"
+ max_plasma = 300
stored_plasma = 200
+ plasma_rate = 25
/obj/item/organ/internal/xenos/plasmavessel/sentinel
+ name = "medium xeno plasma vessel"
+ max_plasma = 200
stored_plasma = 100
+ plasma_rate = 25
/obj/item/organ/internal/xenos/plasmavessel/hunter
name = "small xeno plasma vessel"
icon_state = "plasma_tiny"
- stored_plasma = 100
max_plasma = 150
- alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/plant_weeds)
+ stored_plasma = 100
+ plasma_rate = 10
/obj/item/organ/internal/xenos/plasmavessel/larva
@@ -87,6 +103,7 @@
alien_powers = list()
+
/obj/item/organ/internal/xenos/plasmavessel/prepare_eat()
var/obj/S = ..()
S.reagents.add_reagent("plasma", stored_plasma/10)
@@ -96,22 +113,27 @@
/obj/item/organ/internal/xenos/plasmavessel/on_life()
if(!owner)
return
+ if(owner.on_fire)
+ return
update_hud()
- //If there are alien weeds on the ground then heal if needed or give some plasma
- if(!(locate(/obj/structure/alien/weeds) in owner.loc))
- return
-
- if(owner.health >= owner.maxHealth)
- owner.adjust_alien_plasma(plasma_rate)
- update_hud()
- return
+ var/heal_amt = passive_heal_rate
+ var/plasma_amt = 0
+ if(locate(/obj/structure/alien/weeds) in owner.loc)
+ if(owner.health >= owner.maxHealth)
+ plasma_amt = plasma_rate
+ else
+ heal_amt += heal_rate
+ plasma_amt = plasma_rate/2
+ else
+ if(stored_plasma < 50)
+ plasma_amt = plasma_rate/10
- var/heal_amt = heal_rate
if(!isalien(owner))
heal_amt *= 0.2
- owner.adjust_alien_plasma((plasma_rate * 0.5))
+
+ owner.adjust_alien_plasma(plasma_amt)
owner.adjustBruteLoss(-heal_amt)
owner.adjustFireLoss(-heal_amt)
owner.adjustOxyLoss(-heal_amt)
@@ -181,6 +203,8 @@
origin_tech = "biotech=5;combat=5"
alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/neurotoxin)
+/obj/item/organ/internal/xenos/neurotoxin/sentinel
+ alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/neurotoxin/sentinel)
/obj/item/organ/internal/xenos/resinspinner
name = "xeno resin organ"//...there tiger....