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....