diff --git a/code/__DEFINES/is_helpers.dm b/code/__DEFINES/is_helpers.dm index e73af05c7d6..cab2662a7ec 100644 --- a/code/__DEFINES/is_helpers.dm +++ b/code/__DEFINES/is_helpers.dm @@ -27,6 +27,8 @@ #define isaliensentinel(A) (istype(A, /mob/living/carbon/alien/humanoid/sentinel)) +#define isalienqueen(A) (istype(A, /mob/living/carbon/alien/humanoid/queen)) + // Simple animals #define issimple_animal(A) (istype(A, /mob/living/simple_animal)) diff --git a/code/_onclick/hud/alien_hud.dm b/code/_onclick/hud/alien_hud.dm index 1dd86fe5ce5..a541fca8b57 100644 --- a/code/_onclick/hud/alien_hud.dm +++ b/code/_onclick/hud/alien_hud.dm @@ -16,8 +16,21 @@ /obj/screen/alien/nightvision/Click() var/mob/living/carbon/alien/humanoid/A = usr - A.nightvisiontoggle() + A.night_vision_toggle() +/mob/living/carbon/alien/proc/night_vision_toggle() + if(!nightvision) + see_in_dark = 8 + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE + nightvision = TRUE + hud_used.nightvisionicon.icon_state = "nightvision1" + else + see_in_dark = initial(see_in_dark) + lighting_alpha = initial(lighting_alpha) + nightvision = FALSE + hud_used.nightvisionicon.icon_state = "nightvision0" + + update_sight() /obj/screen/alien/plasma_display icon = 'icons/mob/screen_gen.dmi' diff --git a/code/datums/beam.dm b/code/datums/beam.dm index d4005122083..f67b5f2ed4c 100644 --- a/code/datums/beam.dm +++ b/code/datums/beam.dm @@ -14,8 +14,9 @@ var/origin_oldloc = null var/static_beam = FALSE var/beam_type = /obj/effect/ebeam //must be subtype + var/beamcolor -/datum/beam/New(beam_origin,beam_target,beam_icon='icons/effects/beam.dmi',beam_icon_state="b_beam",time=50,maxdistance=10,btype = /obj/effect/ebeam,beam_sleep_time=3) +/datum/beam/New(beam_origin, beam_target,beam_icon = 'icons/effects/beam.dmi', beam_icon_state = "b_beam", time = 50, maxdistance = 10, btype = /obj/effect/ebeam, beam_sleep_time = 3, beam_color) endtime = world.time+time origin = beam_origin origin_oldloc = get_turf(origin) @@ -29,6 +30,7 @@ icon = beam_icon icon_state = beam_icon_state beam_type = btype + beamcolor = beam_color /datum/beam/proc/Start() Draw() @@ -77,10 +79,12 @@ //cropped by a transparent box of length-N pixel size if(N+32>length) var/icon/II = new(icon, icon_state) - II.DrawBox(null,1,(length-N),32,32) + II.DrawBox(null, 1, (length-N), 32, 32) X.icon = II else X.icon = base_icon + if(beamcolor) + X.color = beamcolor X.transform = rot_matrix //Calculate pixel offsets (If necessary) @@ -163,7 +167,7 @@ var/armor = L.run_armor_check(limb_to_hit, LASER) L.apply_damage(damage, BURN, limb_to_hit, armor) -/atom/proc/Beam(atom/BeamTarget,icon_state="b_beam",icon='icons/effects/beam.dmi',time=50, maxdistance=10,beam_type=/obj/effect/ebeam,beam_sleep_time=3) - var/datum/beam/newbeam = new(src,BeamTarget,icon,icon_state,time,maxdistance,beam_type,beam_sleep_time) +/atom/proc/Beam(atom/BeamTarget, icon_state="b_beam", icon='icons/effects/beam.dmi', time = 5 SECONDS, maxdistance = 10, beam_type = /obj/effect/ebeam, beam_sleep_time = 3, beam_color) + var/datum/beam/newbeam = new(src, BeamTarget, icon, icon_state, time, maxdistance, beam_type, beam_sleep_time, beam_color) INVOKE_ASYNC(newbeam, TYPE_PROC_REF(/datum/beam, Start)) return newbeam diff --git a/code/datums/spells/alien_spells/basetype_alien_spell.dm b/code/datums/spells/alien_spells/basetype_alien_spell.dm index 3cacc2e8e02..c4413e45d90 100644 --- a/code/datums/spells/alien_spells/basetype_alien_spell.dm +++ b/code/datums/spells/alien_spells/basetype_alien_spell.dm @@ -20,8 +20,7 @@ Updates the spell's actions on use as well, so they know when they can or can't /obj/effect/proc_holder/spell/alien_spell action_background_icon_state = "bg_alien" clothes_req = FALSE - /// Extremely fast cooldown, only present so the cooldown system doesn't explode - base_cooldown = 1 + base_cooldown = 0 create_attack_logs = FALSE /// Every alien spell creates only logs, no attack messages on someone placing weeds, but you DO get attack messages on neurotoxin and corrosive acid create_custom_logs = TRUE diff --git a/code/datums/spells/alien_spells/build_resin_structure.dm b/code/datums/spells/alien_spells/build_resin_structure.dm index aadbcabcdea..9da55a22ebf 100644 --- a/code/datums/spells/alien_spells/build_resin_structure.dm +++ b/code/datums/spells/alien_spells/build_resin_structure.dm @@ -8,14 +8,18 @@ return new /datum/spell_targeting/self /obj/effect/proc_holder/spell/alien_spell/build_resin/cast(list/targets, mob/living/carbon/user) - var/static/list/resin_buildings = list("Resin Wall (55)" = image(icon = 'icons/obj/smooth_structures/alien/resin_wall.dmi', icon_state = "resin_wall-0"), - "Resin Nest (55)" = image(icon = 'icons/mob/alien.dmi', icon_state = "nest"), - "Resin door (80)" = image(icon = 'icons/obj/smooth_structures/alien/resin_door.dmi', icon_state = "resin")) + var/static/list/resin_buildings = list("Resin Wall" = image(icon = 'icons/obj/smooth_structures/alien/resin_wall.dmi', icon_state = "resin_wall-0"), + "Resin Nest" = image(icon = 'icons/mob/alien.dmi', icon_state = "nest"), + "Resin Door" = image(icon = 'icons/obj/smooth_structures/alien/resin_door.dmi', icon_state = "resin"), + "Revival Nest" = image(icon = 'icons/mob/alien.dmi', icon_state = "placeholder_rejuv_nest")) var/choice = show_radial_menu(user, user, resin_buildings, src, radius = 40) var/turf/turf_to_spawn_at = user.loc if(!choice) revert_cast(user) return + if(!do_mob(user, user, 3 SECONDS)) + revert_cast() + return if(isspaceturf(turf_to_spawn_at)) to_chat(user, "You cannot build the [choice] while in space!") revert_cast(user) @@ -27,15 +31,52 @@ return visible_message("[user] vomits up a thick purple substance and shapes it!") switch(choice) - if("Resin Wall (55)") + if("Resin Wall") new /obj/structure/alien/resin/wall(turf_to_spawn_at) - if("Resin Nest (55)") + if("Resin Nest") new /obj/structure/bed/nest(turf_to_spawn_at) - if("Resin door (80)") - var/plasma_current = user.get_plasma() - if(plasma_current >= 25) - new /obj/structure/alien/resin/door(turf_to_spawn_at) - user.add_plasma(-25) - return - to_chat(user, "You don't have enough plasma to place a door down.") - revert_cast(user) + if("Resin Door") + new /obj/structure/alien/resin/door(turf_to_spawn_at) + if("Revival Nest") + new /obj/structure/bed/revival_nest(turf_to_spawn_at) + +/obj/effect/proc_holder/spell/touch/alien_spell/consume_resin + name = "Consume resin structures" + desc = "Allows you to rip and tear straight through resin structures." + action_icon_state = "alien_resin" + hand_path = "/obj/item/melee/touch_attack/alien/consume_resin" + plasma_cost = 10 + base_cooldown = 5 SECONDS + +/obj/item/melee/touch_attack/alien/consume_resin + name = "Resin consumption" + desc = "The hunger..." + icon_state = "alien_acid" + +/obj/item/melee/touch_attack/alien/consume_resin/afterattack(atom/target, mob/living/carbon/user, proximity) + if(target == user) + to_chat(user, "You stop trying to consume resin.") + ..() + return + if(!proximity || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) + return + if(istype(target, /obj/structure/alien/weeds)) + qdel(target) + if(istype(target, /obj/structure/alien/weeds/node)) + user.add_plasma(50) + user.visible_message("[user] rips and tears into [target] with their teeth!", "You viciously rip apart and consume [target]!") + return + if(!plasma_check(10, user)) + to_chat(user, "You don't have enough plasma to perform this action!") + return + var/static/list/resin_objects = list(/obj/structure/alien/resin, /obj/structure/alien/egg, /obj/structure/bed/nest, /obj/structure/bed/revival_nest) + for(var/resin_type in resin_objects) + if(!istype(target, resin_type)) + continue + user.visible_message("[user] rips and tears into [target] with their teeth!") + if(!do_after(user, 3 SECONDS, target = target)) + return + to_chat(user, "You viciously rip apart and consume [target]!") + user.add_plasma(-10) + qdel(target) + ..() diff --git a/code/datums/spells/alien_spells/corrosive_acid_spit.dm b/code/datums/spells/alien_spells/corrosive_acid_spit.dm index 18a58b9494b..17e7756f7c7 100644 --- a/code/datums/spells/alien_spells/corrosive_acid_spit.dm +++ b/code/datums/spells/alien_spells/corrosive_acid_spit.dm @@ -4,6 +4,7 @@ hand_path = "/obj/item/melee/touch_attack/alien/corrosive_acid" action_icon_state = "alien_acid" plasma_cost = 200 + base_cooldown = 15 SECONDS /obj/item/melee/touch_attack/alien/corrosive_acid name = "Corrosive acid" @@ -30,3 +31,45 @@ else to_chat(user, "You cannot dissolve this object.") ..() + +/obj/effect/proc_holder/spell/touch/alien_spell/burning_touch + name = "Blazing touch" + desc = "Boil acid within your hand to burn through anything you touch with it, deals a lot of damage to aliens and destroys resin structures instantly." + hand_path = "/obj/item/melee/touch_attack/alien/burning_touch" + action_icon_state = "alien_acid" + plasma_cost = 100 + base_cooldown = 10 SECONDS + +/obj/item/melee/touch_attack/alien/burning_touch + name = "Blazing touch" + desc = "The air warps around your hand, somehow the heat doesn't hurt." + icon_state = "alien_acid" + +/obj/item/melee/touch_attack/alien/burning_touch/afterattack(atom/target, mob/living/carbon/user, proximity) + if(target == user) + to_chat(user, "You cool down your boiled aid.") + ..() + return + if(!proximity || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) + return + if(!plasma_check(100, user)) + to_chat(user, "You don't have enough plasma to perform this action!") + return + if(isliving(target)) + var/mob/living/guy_to_burn = target + add_attack_logs(user, target, "Applied blazing touch") // Want this logged + guy_to_burn.adjustFireLoss(60) + guy_to_burn.adjust_fire_stacks(3) + guy_to_burn.IgniteMob() + user.visible_message("[user] touches [target] and a fireball erupts on contact!") + user.add_plasma(-100) + ..() + else + var/static/list/resin_objects = list(/obj/structure/alien/resin, /obj/structure/alien/egg, /obj/structure/bed/nest, /obj/structure/bed/revival_nest) + for(var/resin_type in resin_objects) + if(!istype(target, resin_type)) + continue + user.visible_message("[user] touches [target] and burns right through it!") + user.add_plasma(-100) + qdel(target) + ..() diff --git a/code/datums/spells/alien_spells/lay_alien_eggs.dm b/code/datums/spells/alien_spells/lay_alien_eggs.dm index 7789420e1c3..f2bfc89011f 100644 --- a/code/datums/spells/alien_spells/lay_alien_eggs.dm +++ b/code/datums/spells/alien_spells/lay_alien_eggs.dm @@ -5,3 +5,35 @@ weed_type = /obj/structure/alien/egg weed_name = "alien egg" action_icon_state = "alien_egg" + requires_do_after = FALSE + +/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers + name = "Combust facehuggers and eggs" + desc = "Take over the programming of facehuggers and eggs, sending out a shockwave which causes them to combust." + plasma_cost = 25 + action_icon_state = "alien_egg" + base_cooldown = 3 SECONDS + +/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers/create_new_targeting() + return new /datum/spell_targeting/clicked_atom + +/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers/cast(list/targets, mob/living/carbon/user) + var/obj/target = targets[1] + var/turf/T = user.loc + if(!istype(T) || !istype(target)) + revert_cast() + return FALSE + + if(!istype(target, /obj/item/clothing/mask/facehugger) && !istype(target, /obj/structure/alien/egg)) + revert_cast() + return FALSE + + target.color = "#c72623" + addtimer(CALLBACK(src, PROC_REF(blow_it_up), target, user), 3 SECONDS) + to_chat(user, "[target] will explode in 3 seconds!") + return TRUE + +/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers/proc/blow_it_up(obj/target, mob/user) + add_attack_logs(user, target, "Caused it to explode") + explosion(get_turf(target), 0, 2, 3, 3, cause = user) + to_chat(user, "[target] has detonated!") diff --git a/code/datums/spells/alien_spells/neurotoxin_spit.dm b/code/datums/spells/alien_spells/neurotoxin_spit.dm index ca688886d13..ad4048f53a1 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 = 5 SECONDS + base_cooldown = 3 SECONDS plasma_cost = 50 selection_activated_message = "Your prepare some neurotoxin!" selection_deactivated_message = "You swallow your prepared neurotoxin." @@ -34,3 +34,9 @@ user.newtonian_move(get_dir(U, T)) return TRUE + +/obj/effect/proc_holder/spell/alien_spell/neurotoxin/death_to_xenos + name = "Neurotoxin spit" + desc = "This ability allows you to fire some neurotoxin. Knocks aliens down." + neurotoxin_type = /obj/item/projectile/bullet/anti_alien_toxin + base_cooldown = 2 SECONDS diff --git a/code/datums/spells/alien_spells/plasma_weeds.dm b/code/datums/spells/alien_spells/plasma_weeds.dm index c816475f7ea..b254403bc6e 100644 --- a/code/datums/spells/alien_spells/plasma_weeds.dm +++ b/code/datums/spells/alien_spells/plasma_weeds.dm @@ -2,9 +2,10 @@ name = "Plant weeds" desc = "Allows you to plant some alien weeds on the floor below you. Does not work while in space." plasma_cost = 50 - var/weed_type = /obj/structure/alien/weeds/node + var/atom/weed_type = /obj/structure/alien/weeds/node var/weed_name = "alien weed node" action_icon_state = "alien_plant" + var/requires_do_after = TRUE /obj/effect/proc_holder/spell/alien_spell/plant_weeds/create_new_targeting() return new /datum/spell_targeting/self @@ -26,5 +27,10 @@ revert_cast() return + user.visible_message("Vines burst from the back of [user], quickly scurring to the ground and swarm onto [user.loc].", "You begin infesting [user.loc] with [initial(weed_type.name)].") + if(requires_do_after && !do_mob(user, user, 2 SECONDS)) + revert_cast() + return + user.visible_message("[user] has planted \a [weed_name]!") new weed_type(T) diff --git a/code/datums/spells/alien_spells/queen_evolve.dm b/code/datums/spells/alien_spells/queen_evolve.dm index e8112f0506c..75502cfcd69 100644 --- a/code/datums/spells/alien_spells/queen_evolve.dm +++ b/code/datums/spells/alien_spells/queen_evolve.dm @@ -1,7 +1,7 @@ /obj/effect/proc_holder/spell/alien_spell/evolve_queen name = "Evolve into an alien queen" desc = "Evolve into an alien queen." - plasma_cost = 500 + plasma_cost = 300 action_icon_state = "alien_evolve_drone" /obj/effect/proc_holder/spell/alien_spell/evolve_queen/create_new_targeting() @@ -17,8 +17,7 @@ // 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!") - var/turf/userloc = user.loc - var/mob/living/carbon/alien/humanoid/queen/new_xeno = new(userloc) + var/mob/living/carbon/alien/humanoid/queen/new_xeno = new(get_turf(user)) user.mind.transfer_to(new_xeno) new_xeno.mind.name = new_xeno.name SSblackbox.record_feedback("tally", "alien_growth", 1, "queen") diff --git a/code/datums/spells/alien_spells/regurgitate.dm b/code/datums/spells/alien_spells/regurgitate.dm index effd0a9629b..02960c88afb 100644 --- a/code/datums/spells/alien_spells/regurgitate.dm +++ b/code/datums/spells/alien_spells/regurgitate.dm @@ -9,6 +9,9 @@ /obj/effect/proc_holder/spell/alien_spell/regurgitate/cast(list/targets, mob/living/carbon/user) for(var/mob/M in user.stomach_contents) var/turf/output_loc = user.loc + if(!istype(output_loc)) + return + user.stomach_contents -= M M.forceMove(output_loc) visible_message("[user] hurls out the contents of [p_their()] stomach!") return diff --git a/code/datums/spells/alien_spells/tail_lash.dm b/code/datums/spells/alien_spells/tail_lash.dm new file mode 100644 index 00000000000..0daa1e8a6a0 --- /dev/null +++ b/code/datums/spells/alien_spells/tail_lash.dm @@ -0,0 +1,23 @@ +/obj/effect/proc_holder/spell/alien_spell/tail_lash + name = "Tail lash" + desc = "Knocks down anyone around you." + action_icon_state = "tailsweep" + base_cooldown = 10 SECONDS + +/obj/effect/proc_holder/spell/alien_spell/tail_lash/create_new_targeting() + return new /datum/spell_targeting/self + +/obj/effect/proc_holder/spell/alien_spell/tail_lash/cast(list/targets, mob/user) + var/turf/T = user.loc + var/cast_resolved = FALSE + if(!istype(T)) + revert_cast() + return + for(var/mob/living/to_knock_down in orange(1, user)) + if(to_knock_down.KnockDown(10 SECONDS)) + cast_resolved = TRUE + to_knock_down.visible_message("[user] sweeps [to_knock_down] off their feet!") + if(!cast_resolved) + revert_cast() + + return cast_resolved diff --git a/code/datums/spells/alien_spells/transfer_plasma.dm b/code/datums/spells/alien_spells/transfer_plasma.dm index 1edf34dfa67..3ab94da1daf 100644 --- a/code/datums/spells/alien_spells/transfer_plasma.dm +++ b/code/datums/spells/alien_spells/transfer_plasma.dm @@ -1,28 +1,55 @@ -/obj/effect/proc_holder/spell/touch/alien_spell/transfer_plasma +/obj/effect/proc_holder/spell/alien_spell/transfer_plasma name = "Transfer Plasma" desc = "Transfers 50 plasma to a nearby alien" - hand_path = "/obj/item/melee/touch_attack/alien/transfer_plasma" action_icon_state = "alien_transfer" plasma_cost = 50 -/obj/item/melee/touch_attack/alien/transfer_plasma - name = "plasma transfer" - desc = "Transfers 50 plasma to another alien." - icon_state = "alien_transfer" +/obj/effect/proc_holder/spell/alien_spell/transfer_plasma/create_new_targeting() + return new /datum/spell_targeting/clicked_atom -/obj/item/melee/touch_attack/alien/transfer_plasma/afterattack(atom/target, mob/living/carbon/user, proximity) - if(target == user) - to_chat(user, "You withdraw your readied plasma.") - ..() +/obj/effect/proc_holder/spell/alien_spell/transfer_plasma/cast(list/targets, mob/living/carbon/user) + var/mob/living/carbon/alien/target = targets[1] + var/turf/T = user.loc + if(!istype(T) || !istype(target)) + revert_cast() + return FALSE + + user.Beam(target, icon_state = "sendbeam", time = 2 SECONDS, beam_color = "#f180bd") + target.add_plasma(50) + to_chat(user, "You have transfered 50 plasma to [target].") + to_chat(target, "[user] has transfered 50 plasma to you!") + return TRUE + +/obj/effect/proc_holder/spell/alien_spell/syphon_plasma + name = "Syphon plasma" + desc = "Syphons 150 plasma from a nearby alien." + action_icon_state = "alien_transfer" + plasma_cost = 0 + base_cooldown = 10 SECONDS + +/obj/effect/proc_holder/spell/alien_spell/syphon_plasma/create_new_targeting() + return new /datum/spell_targeting/clicked_atom + +/obj/effect/proc_holder/spell/alien_spell/syphon_plasma/cast(list/targets, mob/living/carbon/user) + var/mob/living/carbon/alien/target = targets[1] + var/turf/T = user.loc + if(!istype(T) || !istype(target)) + revert_cast() + return FALSE + + user.Beam(target, icon_state = "drainbeam", time = 2 SECONDS, beam_color = "#f180bd") + var/obj/item/organ/internal/alien/plasmavessel/vessel = target.get_int_organ(/obj/item/organ/internal/alien/plasmavessel) + if(!vessel) return - if(!proximity || !isalien(target) || !iscarbon(user) || HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) - return - if(!plasma_check(50, user)) - to_chat(user, "You don't have enough plasma to perform this action!") - return - user.add_plasma(-50) - var/mob/living/carbon/transfering_to = target - transfering_to.add_plasma(50) - to_chat(user, "You have transfered 50 plasma to [transfering_to].") - to_chat(transfering_to, "[user] has transfered 50 plasma to you!") - ..() + var/plasma_syphoned + if(vessel.stored_plasma < 150) + user.add_plasma(vessel.stored_plasma) + plasma_syphoned = vessel.stored_plasma + vessel.stored_plasma = 0 + else + user.add_plasma(150) + plasma_syphoned = 50 + vessel.stored_plasma = vessel.stored_plasma - 150 + to_chat(user, "You have syphoned [plasma_syphoned] plasma from [target].") + to_chat(target, "[user] has syphoned [plasma_syphoned] from you!") + return TRUE diff --git a/code/game/mecha/combat/combat.dm b/code/game/mecha/combat/combat.dm index a15406306dc..17ea778639f 100644 --- a/code/game/mecha/combat/combat.dm +++ b/code/game/mecha/combat/combat.dm @@ -3,7 +3,7 @@ var/maxsize = 2 internal_damage_threshold = 50 maint_access = 0 - armor = list(melee = 30, bullet = 30, laser = 15, energy = 20, bomb = 20, rad = 0, fire = 100, acid = 100) + armor = list(melee = 30, bullet = 30, laser = 15, energy = 20, bomb = 20, rad = 0, fire = 100) destruction_sleep_duration = 4 SECONDS var/am = "d3c2fbcadca903a41161ccc9df9cf948" diff --git a/code/game/mecha/combat/durand.dm b/code/game/mecha/combat/durand.dm index 3694b525650..1ba971d347f 100644 --- a/code/game/mecha/combat/durand.dm +++ b/code/game/mecha/combat/durand.dm @@ -7,7 +7,7 @@ dir_in = 1 //Facing North. max_integrity = 400 deflect_chance = 20 - armor = list(melee = 40, bullet = 35, laser = 15, energy = 10, bomb = 20, rad = 50, fire = 100, acid = 100) + armor = list(melee = 40, bullet = 35, laser = 15, energy = 10, bomb = 20, rad = 50, fire = 100, acid = 75) max_temperature = 30000 infra_luminosity = 8 force = 40 diff --git a/code/game/mecha/combat/gygax.dm b/code/game/mecha/combat/gygax.dm index e32ec8e3236..f8f4c97d9d9 100644 --- a/code/game/mecha/combat/gygax.dm +++ b/code/game/mecha/combat/gygax.dm @@ -7,7 +7,7 @@ dir_in = 1 //Facing North. max_integrity = 250 deflect_chance = 5 - armor = list(melee = 25, bullet = 20, laser = 30, energy = 15, bomb = 0, rad = 0, fire = 100, acid = 100) + armor = list(melee = 25, bullet = 20, laser = 30, energy = 15, bomb = 0, rad = 0, fire = 100, acid = 75) max_temperature = 25000 infra_luminosity = 6 leg_overload_coeff = 2 diff --git a/code/game/mecha/combat/marauder.dm b/code/game/mecha/combat/marauder.dm index 6559f69ad4d..f57aa643db7 100644 --- a/code/game/mecha/combat/marauder.dm +++ b/code/game/mecha/combat/marauder.dm @@ -52,7 +52,8 @@ initial_icon = "ares" operation_req_access = list(ACCESS_SECURITY) max_integrity = 450 - armor = list(melee = 50, bullet = 40, laser = 20, energy = 20, bomb = 20, rad = 60, fire = 100, acid = 100) + resistance_flags = LAVA_PROOF | FIRE_PROOF + armor = list(melee = 50, bullet = 40, laser = 20, energy = 20, bomb = 20, rad = 60, fire = 100, acid = 75) max_temperature = 40000 wreckage = /obj/structure/mecha_wreckage/ares max_equip = 5 diff --git a/code/game/mecha/combat/phazon.dm b/code/game/mecha/combat/phazon.dm index 1d7b748d344..4711eedb5fd 100644 --- a/code/game/mecha/combat/phazon.dm +++ b/code/game/mecha/combat/phazon.dm @@ -9,7 +9,7 @@ normal_step_energy_drain = 3 max_integrity = 200 deflect_chance = 30 - armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 30, RAD = 50, FIRE = 100, ACID = 100) + armor = list(MELEE = 30, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 30, RAD = 50, FIRE = 100, ACID = 75) max_temperature = 25000 infra_luminosity = 3 wreckage = /obj/structure/mecha_wreckage/phazon diff --git a/code/game/mecha/combat/reticence.dm b/code/game/mecha/combat/reticence.dm index 1e9beb7016e..e6970740a80 100644 --- a/code/game/mecha/combat/reticence.dm +++ b/code/game/mecha/combat/reticence.dm @@ -7,7 +7,7 @@ dir_in = 1 //Facing North. max_integrity = 150 deflect_chance = 30 - armor = list(MELEE = 25, BULLET = 20, LASER = 30, ENERGY = 15, BOMB = 0, RAD = 0, FIRE = 100, ACID = 100) + armor = list(MELEE = 25, BULLET = 20, LASER = 30, ENERGY = 15, BOMB = 0, RAD = 0, FIRE = 100, ACID = 75) max_temperature = 15000 wreckage = /obj/structure/mecha_wreckage/reticence operation_req_access = list(ACCESS_MIME) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 8d41450c50b..3af23927e21 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -7,12 +7,12 @@ density = TRUE //Dense. To raise the heat. opacity = TRUE ///opaque. Menacing. anchored = TRUE //no pulling around. - resistance_flags = FIRE_PROOF | ACID_PROOF + resistance_flags = FIRE_PROOF layer = MOB_LAYER //icon draw layer infra_luminosity = 15 //byond implementation is bugged. force = 5 max_integrity = 300 //max_integrity is base health - armor = list(melee = 20, bullet = 10, laser = 0, energy = 0, bomb = 0, rad = 0, fire = 100, acid = 100) + armor = list(melee = 20, bullet = 10, laser = 0, energy = 0, bomb = 0, rad = 0, fire = 100, acid = 75) bubble_icon = "machine" var/list/facing_modifiers = list(MECHA_FRONT_ARMOUR = 1.5, MECHA_SIDE_ARMOUR = 1, MECHA_BACK_ARMOUR = 0.5) var/ruin_mecha = FALSE //if the mecha starts on a ruin, don't automatically give it a tracking beacon to prevent metagaming. diff --git a/code/game/mecha/working/ripley.dm b/code/game/mecha/working/ripley.dm index 7c2b0ff3f7c..66ad6d2f864 100644 --- a/code/game/mecha/working/ripley.dm +++ b/code/game/mecha/working/ripley.dm @@ -78,9 +78,9 @@ initial_icon = "firefighter" max_temperature = 65000 max_integrity = 250 - resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF + resistance_flags = LAVA_PROOF | FIRE_PROOF lights_power = 7 - armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 60, RAD = 70, FIRE = 100, ACID = 100) + armor = list(MELEE = 40, BULLET = 30, LASER = 30, ENERGY = 30, BOMB = 60, RAD = 70, FIRE = 100) max_equip = 5 // More armor, less tools wreckage = /obj/structure/mecha_wreckage/ripley/firefighter diff --git a/code/game/objects/cleaning.dm b/code/game/objects/cleaning.dm index f1ba88a0441..b65980d1daa 100644 --- a/code/game/objects/cleaning.dm +++ b/code/game/objects/cleaning.dm @@ -46,6 +46,7 @@ var/obj/effect/decal/cleanable/C = locate() in src qdel(C) clean_blood() + SEND_SIGNAL(src, COMSIG_COMPONENT_CLEAN_ACT) return TRUE /atom/proc/can_clean() //For determining if a cleaning object can actually remove decals diff --git a/code/game/objects/effects/alien_acid.dm b/code/game/objects/effects/alien_acid.dm index 8d1eb45036e..86c1c0c2c73 100644 --- a/code/game/objects/effects/alien_acid.dm +++ b/code/game/objects/effects/alien_acid.dm @@ -24,7 +24,6 @@ START_PROCESSING(SSobj, src) - /obj/effect/acid/Destroy() STOP_PROCESSING(SSobj, src) target = null @@ -67,6 +66,14 @@ /obj/effect/acid/alien var/target_strength = 30 +/obj/effect/acid/alien/Initialize(mapload, acid_pwr, acid_amt) + . = ..() + var/turf/cleanable_turf = get_turf(src) + RegisterSignal(cleanable_turf, COMSIG_COMPONENT_CLEAN_ACT, PROC_REF(remove_acid)) + +/obj/effect/acid/alien/proc/remove_acid(datum/source) + SIGNAL_HANDLER + qdel(src) /obj/effect/acid/alien/process() . = ..() diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index fd263b11f9d..a21489172e8 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -192,6 +192,11 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e SSacid.processing -= src deconstruct(FALSE) +/obj/cleaning_act(mob/user, atom/cleaner, cleanspeed, text_verb, text_description, text_targetname) + . = ..() + if(acid_level) + acid_level = 0 + //// FIRE /obj/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume, global_overlay = TRUE) diff --git a/code/game/objects/structures/aliens.dm b/code/game/objects/structures/aliens.dm index c11b47c82cd..9beb67b5e35 100644 --- a/code/game/objects/structures/aliens.dm +++ b/code/game/objects/structures/aliens.dm @@ -111,7 +111,7 @@ icon = 'icons/obj/smooth_structures/alien/resin_door.dmi' icon_state = "resin" base_icon_state = "resin" - max_integrity = 100 + max_integrity = 60 armor = list(MELEE = 0, BULLET = 0, LASER = 0, ENERGY = 0, BOMB = 0, RAD = 0, FIRE = 50, ACID = 50) damage_deflection = 0 flags_2 = RAD_PROTECT_CONTENTS_2 | RAD_NO_CONTAMINATE_2 @@ -156,7 +156,7 @@ /obj/structure/alien/resin/door/CanAtmosPass(turf/T) return !density -/obj/structure/alien/resin/door/proc/try_to_operate(mob/user) +/obj/structure/alien/resin/door/proc/try_to_operate(mob/user, bumped_open = FALSE) if(is_operating) return if(!iscarbon(user)) @@ -164,7 +164,7 @@ var/mob/living/carbon/C = user if(C.get_int_organ(/obj/item/organ/internal/alien/hivenode)) if(!C.handcuffed) - operate() + operate(bumped_open) return to_chat(user, "Your lack of connection to the hive prevents the resin door from opening") /* @@ -178,7 +178,7 @@ return operate() -/obj/structure/alien/resin/door/proc/operate() +/obj/structure/alien/resin/door/proc/operate(bumped_open = FALSE) is_operating = TRUE if(!state_open) playsound(loc, open_sound, 50, TRUE) @@ -194,14 +194,14 @@ density = !density opacity = !opacity state_open = !state_open - addtimer(CALLBACK(src, PROC_REF(operate_update)), 1 SECONDS) + addtimer(CALLBACK(src, PROC_REF(operate_update), bumped_open), 1 SECONDS) -/obj/structure/alien/resin/door/proc/operate_update() +/obj/structure/alien/resin/door/proc/operate_update(bumped_open) air_update_turf(1) update_icon(UPDATE_ICON_STATE) is_operating = FALSE - if(state_open) + if(state_open && bumped_open) addtimer(CALLBACK(src, PROC_REF(mobless_try_to_operate)), close_delay) /obj/structure/alien/resin/door/update_icon_state() @@ -219,7 +219,7 @@ /obj/structure/alien/resin/door/Bumped(atom/user) ..() if(!state_open) - return try_to_operate(user) + return try_to_operate(user, TRUE) /* * Weeds diff --git a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm index 25b08b00413..3313812d833 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/alien_nests.dm @@ -110,3 +110,118 @@ /obj/structure/bed/nest/prevents_buckled_mobs_attacking() return TRUE + +/obj/structure/bed/revival_nest + name = "alien rejuvenation nest" + desc = "It's a gruesome pile of thick, sticky resin shaped like a flytrap. Heals damaged aliens and slowly revives the dead, breaks down non xenos and uses their genetic soup to make an alien egg." + icon = 'icons/mob/alien.dmi' + icon_state = "placeholder_rejuv_nest" + max_integrity = 30 + var/image/nest_overlay + comfort = 0 + flags = NODECONSTRUCT + var/processing_ticks = 0 + var/revive_or_decay_timer + +/obj/structure/bed/revival_nest/user_unbuckle_mob(mob/living/buckled_mob, mob/user) + for(var/mob/living/M in buckled_mobs) //breaking a nest releases all the buckled mobs, because the nest isn't holding them down anymore + if(HAS_TRAIT(user, TRAIT_XENO_IMMUNE)) + unbuckle_mob(M) + add_fingerprint(user) + return + + if(M != user) + M.visible_message("[user] tears [M] out of the rejuvination pod!",\ + "[user] pulls you free from the rejuvination pod!",\ + "You hear squelching...") + else + M.visible_message("[M] struggles to break free from the rejuvination pod!",\ + "You struggle to break free from the rejuvination pod... (Stay still for 15 seconds.)",\ + "You hear squelching...") + if(!do_after(M, 15 SECONDS, target = src)) + if(M && M.buckled) + to_chat(M, "You fail to escape \the [src]!") + return + if(!M.buckled) + return + M.visible_message("[M] breaks free from the rejuvination pod!",\ + "You break free from the rejuvination pod!",\ + "You hear squelching...") + unbuckle_mob(M) + add_fingerprint(user) + +/obj/structure/bed/revival_nest/post_unbuckle_mob(mob/living/M) + STOP_PROCESSING(SSobj, src) + deltimer(revive_or_decay_timer) + +/obj/structure/bed/revival_nest/process() + for(var/mob/living/buckled_mob in buckled_mobs) + processing_ticks++ + if(isalien(buckled_mob)) + buckled_mob.adjustBruteLoss(-5) + buckled_mob.adjustFireLoss(-5) + buckled_mob.adjustToxLoss(-5) + buckled_mob.adjustOxyLoss(-5) + buckled_mob.adjustCloneLoss(-5) + for(var/datum/disease/virus in buckled_mob.viruses) + if(virus.stage < 1 && processing_ticks >= 4) + virus.cure() + processing_ticks = 0 + if(virus.stage > 1 && processing_ticks >= 4) + virus.stage-- + processing_ticks = 0 + if(buckled_mob.stat == DEAD && !revive_or_decay_timer) + revive_or_decay_timer = addtimer(CALLBACK(src, PROC_REF(revive_dead_alien), buckled_mob), 40 SECONDS, TIMER_UNIQUE|TIMER_STOPPABLE) + else + buckled_mob.adjustBruteLoss(3) + buckled_mob.adjustFireLoss(3) + +/obj/structure/bed/revival_nest/proc/revive_dead_alien(mob/living/carbon/alien/dead_alien) + dead_alien.revive() + dead_alien.visible_message("Vines seep into the back of [dead_alien], and it awakes with a burning rage!") + if(dead_alien.ghost_can_reenter()) + var/mob/dead/observer/dead_bro = dead_alien.grab_ghost() + SEND_SOUND(dead_alien, sound('sound/voice/hiss5.ogg')) + if(isalienqueen(dead_alien)) + 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)) + to_chat(dead_bro, "We already have an alive queen. We've been reverted to our drone form!") + qdel(dead_alien) + var/mob/living/carbon/alien/humanoid/drone/new_drone = new(get_turf(src)) + new_drone.key = dead_bro.key + else + var/list/candidates = SSghost_spawns.poll_candidates("Do you want to play as [dead_alien]?", ROLE_ALIEN, FALSE, source = dead_alien) + if(!length(candidates)) + return + var/mob/C = pick(candidates) + dead_alien.key = C.key + dust_if_respawnable(C) + dead_alien.mind.name = dead_alien.name + dead_alien.mind.assigned_role = SPECIAL_ROLE_XENOMORPH + dead_alien.mind.special_role = SPECIAL_ROLE_XENOMORPH + SEND_SOUND(dead_alien, sound('sound/voice/hiss5.ogg')) + +/obj/structure/bed/revival_nest/user_buckle_mob(mob/living/M, mob/living/user) + if(!istype(M) || (get_dist(src, user) > 1) || (M.loc != loc) || user.incapacitated() || M.buckled) + return + + if(!user.get_int_organ(/obj/item/organ/internal/alien/hivenode)) + to_chat(user, "Your lack of linkage to the hive prevents you from buckling [M] into [src].") + return + + if(has_buckled_mobs()) + unbuckle_all_mobs() + + if(buckle_mob(M)) + M.visible_message("[user] secretes a thick vile goo, securing [M] into [src]!",\ + "[user] drenches you in a foul-smelling resin, trapping you in [src]!",\ + "You hear squelching...") + START_PROCESSING(SSobj, src) + +/obj/structure/bed/revival_nest/attack_alien(mob/living/carbon/alien/user) + if(user.a_intent != INTENT_HARM) + return attack_hand(user) + if(!do_after(user, 4 SECONDS, target = src) || QDELETED(src)) + return + playsound(get_turf(user), pick('sound/effects/alien_resin_break2.ogg', 'sound/effects/alien_resin_break1.ogg'), 50, FALSE) + qdel(src) diff --git a/code/modules/mob/living/carbon/alien/alien_base.dm b/code/modules/mob/living/carbon/alien/alien_base.dm index 07722061279..8d2a727019e 100644 --- a/code/modules/mob/living/carbon/alien/alien_base.dm +++ b/code/modules/mob/living/carbon/alien/alien_base.dm @@ -5,18 +5,16 @@ bubble_icon = "alien" icon = 'icons/mob/alien.dmi' gender = NEUTER - dna = null var/nightvision = TRUE see_in_dark = 4 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 status_flags = CANPARALYSE|CANPUSH var/heal_rate = 5 - var/large = FALSE var/loudspeaker = FALSE var/heat_protection = 0.5 var/leaping = FALSE @@ -27,8 +25,6 @@ /mob/living/carbon/alien/Initialize(mapload) . = ..() create_reagents(1000) - verbs += /mob/living/verb/mob_sleep - verbs += /mob/living/verb/rest for(var/organ_path in get_caste_organs()) var/obj/item/organ/internal/organ = new organ_path() @@ -50,17 +46,17 @@ return GLOB.all_languages["Xenomorph"] /mob/living/carbon/alien/say_quote(message, datum/language/speaking = null) - var/verb = "hisses" + var/speech_verb = "hisses" var/ending = copytext(message, length(message)) if(speaking && (speaking.name != "Galactic Common")) //this is so adminbooze xenos speaking common have their custom verbs, - verb = speaking.get_spoken_verb(ending) //and use normal verbs for their own languages and non-common languages + speech_verb = speaking.get_spoken_verb(ending) //and use normal verbs for their own languages and non-common languages else - if(ending=="!") - verb = "roars" - else if(ending=="?") - verb = "hisses curiously" - return verb + if(ending == "!") + speech_verb = "roars" + else if(ending== "?") + speech_verb = "hisses curiously" + return speech_verb /mob/living/carbon/alien/adjustToxLoss(amount) @@ -68,7 +64,7 @@ /mob/living/carbon/alien/adjustFireLoss(amount) // Weak to Fire if(amount > 0) - return ..(amount * 2) + return ..(amount * 1.5) else return ..(amount) @@ -77,17 +73,11 @@ return 2 /mob/living/carbon/alien/handle_environment(datum/gas_mixture/environment) - if(!environment) return var/loc_temp = get_temperature(environment) -// to_chat(world, "Loc temp: [loc_temp] - Body temp: [bodytemperature] - Fireloss: [getFireLoss()] - Fire protection: [heat_protection] - Location: [loc] - src: [src]") - - // Aliens are now weak to fire. - - //After then, it reacts to the surrounding atmosphere based on your thermal protection if(!on_fire) // If you're on fire, ignore local air temperature if(loc_temp > bodytemperature) //Place is hotter than we are @@ -121,8 +111,8 @@ /mob/living/carbon/alien/Stat() ..() if(statpanel("Status")) - stat(null, "Intent: [a_intent]") - stat(null, "Move Mode: [m_intent]") + stat("Intent: [a_intent]") + stat("Move Mode: [m_intent]") show_stat_emergency_shuttle_eta() /mob/living/carbon/alien/SetStunned(amount, updating = TRUE, force = 0) @@ -141,24 +131,6 @@ /mob/living/carbon/alien/setDNA() return -/mob/living/carbon/alien/verb/nightvisiontoggle() - set name = "Toggle Night Vision" - set category = "Alien" - - if(!nightvision) - see_in_dark = 8 - lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE - nightvision = TRUE - usr.hud_used.nightvisionicon.icon_state = "nightvision1" - else if(nightvision) - see_in_dark = initial(see_in_dark) - lighting_alpha = initial(lighting_alpha) - nightvision = FALSE - usr.hud_used.nightvisionicon.icon_state = "nightvision0" - - update_sight() - - /mob/living/carbon/alien/assess_threat(mob/living/simple_animal/bot/secbot/judgebot, lasercolor) if(judgebot.emagged) return 10 //Everyone is a criminal! @@ -209,34 +181,31 @@ /mob/living/carbon/alien/proc/deathrattle_message() return "The hivemind echoes: [name] has been slain!" -/mob/living/carbon/alien/CanContractDisease(datum/disease/D) - return FALSE - /*---------------------------------------- Proc: AddInfectionImages() Des: Gives the client of the alien an image on each infected mob. ----------------------------------------*/ /mob/living/carbon/alien/proc/AddInfectionImages() - if(client) - for(var/mob/living/C in GLOB.mob_list) - if(HAS_TRAIT(C, TRAIT_XENO_HOST)) - var/obj/item/organ/internal/body_egg/alien_embryo/A = C.get_int_organ(/obj/item/organ/internal/body_egg/alien_embryo) - if(A) - var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]") - client.images += I - return - + if(!client) + return + for(var/mob/living/C in GLOB.mob_list) + if(HAS_TRAIT(C, TRAIT_XENO_HOST)) + var/obj/item/organ/internal/body_egg/alien_embryo/A = C.get_int_organ(/obj/item/organ/internal/body_egg/alien_embryo) + if(!A) + continue + var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]") + client.images += I /*---------------------------------------- Proc: RemoveInfectionImages() Des: Removes all infected images from the alien. ----------------------------------------*/ /mob/living/carbon/alien/proc/RemoveInfectionImages() - if(client) - for(var/image/I in client.images) - if(dd_hasprefix_case(I.icon_state, "infected")) - qdel(I) - return + if(!client) + return + for(var/image/I in client.images) + if(dd_hasprefix_case(I.icon_state, "infected")) + qdel(I) /mob/living/carbon/alien/canBeHandcuffed() return TRUE @@ -309,3 +278,8 @@ and carry the owner just to make sure*/ medicine.reagents.reaction(src, reagent_application, fraction) medicine.reagents.trans_to(src, how_many_reagents) return TRUE + +/mob/living/carbon/alien/update_stat(reason) + if(health <= HEALTH_THRESHOLD_CRIT && stat == CONSCIOUS) + KnockOut() + return ..() diff --git a/code/modules/mob/living/carbon/alien/alien_death.dm b/code/modules/mob/living/carbon/alien/alien_death.dm index 12757bd3a8b..fa5e5a1f12c 100644 --- a/code/modules/mob/living/carbon/alien/alien_death.dm +++ b/code/modules/mob/living/carbon/alien/alien_death.dm @@ -12,7 +12,7 @@ animation.icon = 'icons/mob/mob.dmi' animation.master = src - playsound(src.loc, 'sound/goonstation/effects/gib.ogg', 50, 1) + playsound(loc, 'sound/goonstation/effects/gib.ogg', 50, TRUE) for(var/mob/M in stomach_contents) //Release eaten mobs when Beno is gibbed LAZYREMOVE(stomach_contents, M) @@ -21,6 +21,13 @@ var/mob/living/carbon/human/H = M H.KnockDown(5 SECONDS) + for(var/obj/item/organ/internal/I in internal_organs) + if(isturf(loc)) + var/atom/movable/thing = I.remove(src) + if(thing) + thing.forceMove(get_turf(src)) + thing.throw_at(get_edge_target_turf(src, pick(GLOB.alldirs)), rand(1, 3), 5) + flick("gibbed-a", animation) xgibs(loc) GLOB.dead_mob_list -= src diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm index de23bdcd5bb..491d5612f72 100644 --- a/code/modules/mob/living/carbon/alien/alien_defense.dm +++ b/code/modules/mob/living/carbon/alien/alien_defense.dm @@ -10,9 +10,6 @@ In all, this is a lot like the monkey code. This code could certainly use with a touch of TLC, but it functions alright. Bit odd aliens attacking other aliens are like, full logged though */ /mob/living/carbon/alien/attack_alien(mob/living/carbon/alien/M) - if(isturf(loc) && 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) @@ -82,9 +79,9 @@ This code could certainly use with a touch of TLC, but it functions alright. Bit /mob/living/carbon/alien/attack_slime(mob/living/simple_animal/slime/M) // This is very RNG based, maybe come back to this later - GDN if(..()) //successful slime attack - var/damage = rand(5, 35) + var/damage = 10 if(M.is_adult) - damage = rand(10, 40) + damage = 15 adjustBruteLoss(damage) add_attack_logs(M, src, "Slime'd for [damage] damage") updatehealth("slime attack") diff --git a/code/modules/mob/living/carbon/alien/alien_login.dm b/code/modules/mob/living/carbon/alien/alien_login.dm index 589a9741627..fa043b3e8c8 100644 --- a/code/modules/mob/living/carbon/alien/alien_login.dm +++ b/code/modules/mob/living/carbon/alien/alien_login.dm @@ -2,4 +2,3 @@ ..() AddInfectionImages() update_plasma_display(src) - return diff --git a/code/modules/mob/living/carbon/alien/humanoid/caste/alien_drone.dm b/code/modules/mob/living/carbon/alien/humanoid/caste/alien_drone.dm index 1195a46e735..35c75e4931a 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/alien_drone.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/alien_drone.dm @@ -1,15 +1,14 @@ /mob/living/carbon/alien/humanoid/drone name = "alien drone" caste = "d" - maxHealth = 100 - health = 100 + maxHealth = 150 + health = 150 icon_state = "aliend_s" /mob/living/carbon/alien/humanoid/drone/Initialize(mapload) . = ..() - if(src.name == "alien drone") - src.name = "alien drone ([rand(1, 1000)])" - src.real_name = src.name + name = "alien drone ([rand(1, 1000)])" + real_name = name AddSpell(new /obj/effect/proc_holder/spell/alien_spell/evolve_queen) /mob/living/carbon/alien/humanoid/drone/get_caste_organs() @@ -19,8 +18,3 @@ /obj/item/organ/internal/alien/acidgland, /obj/item/organ/internal/alien/resinspinner, ) - - -//Drones use the same base as generic humanoids. -//Drone verbs - 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 a3084c4af42..0b8c0ab5441 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/hunter.dm @@ -1,38 +1,35 @@ /mob/living/carbon/alien/humanoid/hunter name = "alien hunter" caste = "h" - maxHealth = 125 - health = 125 + maxHealth = 150 + health = 150 icon_state = "alienh_s" - alien_movement_delay = -1 //hunters are faster than normal xenomorphs, and people + alien_movement_delay = -0.5 //hunters are faster than normal xenomorphs, and people + var/leap_on_click = FALSE + /// Are we on leap cooldown? + var/on_leap_cooldown = FALSE /mob/living/carbon/alien/humanoid/hunter/Initialize(mapload) . = ..() - if(name == "alien hunter") - name = "alien hunter ([rand(1, 1000)])" + name = "alien hunter ([rand(1, 1000)])" real_name = name /mob/living/carbon/alien/humanoid/hunter/get_caste_organs() . = ..() . += /obj/item/organ/internal/alien/plasmavessel/hunter - /mob/living/carbon/alien/humanoid/hunter/handle_environment() if(m_intent == MOVE_INTENT_RUN || IS_HORIZONTAL(src)) ..() else add_plasma(-heal_rate) - -//Hunter verbs - -/mob/living/carbon/alien/humanoid/hunter/proc/toggle_leap(message = 1) +/mob/living/carbon/alien/humanoid/hunter/proc/toggle_leap(message = TRUE) leap_on_click = !leap_on_click leap_icon.icon_state = "leap_[leap_on_click ? "on":"off"]" + update_icons() if(message) - to_chat(src, "You will now [leap_on_click ? "leap at":"slash at"] enemies!") - else - return + to_chat(src, "You will now [leap_on_click ? "leap at" : "slash at"] enemies!") /mob/living/carbon/alien/humanoid/hunter/ClickOn(atom/A, params) face_atom(A) @@ -44,64 +41,71 @@ #define MAX_ALIEN_LEAP_DIST 7 /mob/living/carbon/alien/humanoid/hunter/proc/leap_at(atom/A) - if(pounce_cooldown > world.time) - to_chat(src, "You are too fatigued to pounce right now!") + if(leaping || on_leap_cooldown) 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(IS_HORIZONTAL(src)) return - else //Maybe uses plasma in the future, although that wouldn't make any sense... - leaping = 1 - update_icons() - throw_at(A, MAX_ALIEN_LEAP_DIST, 1, spin = 0, diagonals_first = 1, callback = CALLBACK(src, PROC_REF(leap_end))) + leaping = TRUE + on_leap_cooldown = TRUE + update_icons() + Immobilize(15 SECONDS, TRUE) + addtimer(VARSET_CALLBACK(src, on_leap_cooldown, FALSE), 3 SECONDS) + throw_at(A, MAX_ALIEN_LEAP_DIST, 1.5, 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 + SetImmobilized(0, TRUE) update_icons() /mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/A) if(!leaping) return ..() - if(A) - if(isliving(A)) - var/mob/living/L = A - var/blocked = 0 - if(ishuman(A)) - var/mob/living/carbon/human/H = A - 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!") - if(ishuman(L)) - var/mob/living/carbon/human/H = L - H.apply_effect(10 SECONDS, KNOCKDOWN, H.run_armor_check(null, MELEE)) - H.apply_damage(40, STAMINA) - else - L.Weaken(10 SECONDS) - sleep(2)//Runtime prevention (infinite bump() calls on hulks) - step_towards(src,L) + if(isliving(A)) + var/mob/living/L = A + var/blocked = FALSE + if(ishuman(A)) + var/mob/living/carbon/human/H = A + if(H.check_shields(src, 0, "the [name]", attack_type = LEAP_ATTACK)) + blocked = TRUE + if(!blocked) + L.visible_message("[src] pounces on [L]!", "[src] pounces on you!") + if(ishuman(L)) + var/mob/living/carbon/human/H = L + H.apply_effect(10 SECONDS, KNOCKDOWN, H.run_armor_check(null, MELEE)) + H.apply_damage(40, STAMINA) else - Weaken(4 SECONDS, TRUE) + L.Weaken(5 SECONDS) + sleep(2)//Runtime prevention (infinite bump() calls on hulks) + step_towards(src, L) + else + Weaken(2 SECONDS, TRUE) + ..() - toggle_leap(0) - pounce_cooldown = world.time + pounce_cooldown_time - else if(A.density && !A.CanPass(src)) - visible_message("[src] smashes into [A]!", "[src] smashes into [A]!") - Weaken(4 SECONDS, TRUE) - - if(leaping) - leaping = 0 - update_icons() + toggle_leap(FALSE) + else if(A.density && !A.CanPass(src)) + visible_message("[src] smashes into [A]!", "[src] smashes into [A]!") + Weaken(2 SECONDS, TRUE) + playsound(get_turf(src), 'sound/effects/bang.ogg', 50, 0, 0) // owwie + ..() + if(leaping) + leaping = FALSE + update_icons() +/mob/living/carbon/alien/humanoid/hunter/update_icons() + ..() + if(leap_on_click && !leaping) + icon_state = "alien[caste]_pounce" + if(leaping) + if(alt_icon == initial(alt_icon)) + var/old_icon = icon + icon = alt_icon + alt_icon = old_icon + icon_state = "alien[caste]_leap" + pixel_x = -32 + pixel_y = -32 /mob/living/carbon/alien/humanoid/float(on) if(leaping) 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 bd3075eadf6..9b9ae103770 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/caste/sentinel.dm @@ -1,8 +1,8 @@ /mob/living/carbon/alien/humanoid/sentinel name = "alien sentinel" caste = "s" - maxHealth = 150 - health = 150 + maxHealth = 175 + health = 175 icon_state = "aliens_s" /mob/living/carbon/alien/humanoid/sentinel/large @@ -12,13 +12,6 @@ pixel_x = -16 maxHealth = 200 health = 200 - large = 1 - -/mob/living/carbon/alien/humanoid/sentinel/praetorian - name = "alien praetorian" - maxHealth = 200 - health = 200 - large = 1 /mob/living/carbon/alien/humanoid/sentinel/large/update_icons() overlays.Cut() @@ -34,8 +27,7 @@ /mob/living/carbon/alien/humanoid/sentinel/Initialize(mapload) . = ..() - if(name == "alien sentinel") - name = "alien sentinel ([rand(1, 1000)])" + name = "alien sentinel ([rand(1, 1000)])" real_name = name /mob/living/carbon/alien/humanoid/sentinel/get_caste_organs() diff --git a/code/modules/mob/living/carbon/alien/humanoid/empress.dm b/code/modules/mob/living/carbon/alien/humanoid/empress.dm index 2ab7d866323..9ea090b459e 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/empress.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/empress.dm @@ -8,7 +8,6 @@ loudspeaker = TRUE mob_size = MOB_SIZE_LARGE bubble_icon = "alienroyal" - large = 1 ventcrawler = VENTCRAWLER_NONE move_resist = MOVE_FORCE_STRONG //Yes, big benos is huge and heavy alien_disarm_damage = 60 //Empress do higher disarm stamina damage than normal aliens @@ -37,16 +36,7 @@ /mob/living/carbon/alien/humanoid/empress/Initialize(mapload) . = ..() //there should only be one queen - for(var/mob/living/carbon/alien/humanoid/empress/E in GLOB.alive_mob_list) - if(E == src) - continue - if(E.stat == DEAD) - continue - if(E.client) - name = "alien grand princess ([rand(1, 999)])" //if this is too cutesy feel free to change it/remove it. - break - - real_name = name + ADD_TRAIT(src, TRAIT_FORCE_DOORS, UNIQUE_TRAIT_SOURCE(src)) /mob/living/carbon/alien/humanoid/empress/get_caste_organs() . = ..() diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index 004546a18f1..5b139d6652d 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -7,10 +7,6 @@ var/obj/item/l_store = null var/caste = "" var/alt_icon = 'icons/mob/alienleap.dmi' //used to switch between the two alien icon files. - var/next_attack = 0 - var/pounce_cooldown = 0 - var/pounce_cooldown_time = 30 - var/leap_on_click = 0 var/custom_pixel_x_offset = 0 //for admin fuckery. var/custom_pixel_y_offset = 0 var/alien_disarm_damage = 30 //Aliens deal a good amount of stamina damage on disarm intent @@ -32,13 +28,14 @@ /mob/living/carbon/alien/humanoid/Process_Spacemove(check_drift = 0) if(..()) - return 1 - - return 0 + return TRUE + return FALSE /mob/living/carbon/alien/humanoid/emp_act(severity) - if(r_store) r_store.emp_act(severity) - if(l_store) l_store.emp_act(severity) + if(r_store) + r_store.emp_act(severity) + if(l_store) + l_store.emp_act(severity) ..() /mob/living/carbon/alien/humanoid/ex_act(severity) @@ -70,9 +67,8 @@ /mob/living/carbon/alien/humanoid/restrained() if(handcuffed) - return 1 - return 0 - + return TRUE + return FALSE /mob/living/carbon/alien/humanoid/movement_delay() //Aliens have a varied movespeed . = ..() @@ -101,9 +97,6 @@ popup.set_content(dat) popup.open() -/mob/living/carbon/alien/humanoid/canBeHandcuffed() - return 1 - /mob/living/carbon/alien/humanoid/cuff_resist(obj/item/I) playsound(src, 'sound/voice/hiss5.ogg', 40, 1, 1) //Alien roars when starting to break free ..(I, cuff_break = 1) diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm index 5d0f1aff481..43c9bd95936 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid_defense.dm @@ -4,14 +4,11 @@ to_chat(user, "You don't want to hurt [src]!") return FALSE ..(user, TRUE) - adjustBruteLoss(15) + adjustBruteLoss(10) var/hitverb = "punched" if(mob_size < MOB_SIZE_LARGE) - Paralyse(2 SECONDS) - spawn(0) - step_away(src, user, 15) - sleep(1) - step_away(src, user, 15) + Stun(2 SECONDS) + throw_at(get_edge_target_turf(user, get_dir(user, src)), 3, 7) hitverb = "slammed" playsound(loc, "punch", 25, 1, -1) visible_message("[user] has [hitverb] [src]!", "[user] has [hitverb] [src]!") diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid_update_icons.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid_update_icons.dm index 9c168e564c4..70f37d83d21 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid_update_icons.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid_update_icons.dm @@ -28,8 +28,6 @@ else if(stat == UNCONSCIOUS || IsWeakened()) icon_state = "alien[caste]_unconscious" pixel_y = 0 - else if(leap_on_click) - icon_state = "alien[caste]_pounce" else if(IS_HORIZONTAL(src)) icon_state = "alien[caste]_sleep" @@ -38,21 +36,12 @@ else icon_state = "alien[caste]_s" - if(leaping) - if(alt_icon == initial(alt_icon)) - var/old_icon = icon - icon = alt_icon - alt_icon = old_icon - icon_state = "alien[caste]_leap" - pixel_x = -32 - pixel_y = -32 - else - if(alt_icon != initial(alt_icon)) - var/old_icon = icon - icon = alt_icon - alt_icon = old_icon - pixel_x = get_standard_pixel_x_offset() - pixel_y = get_standard_pixel_y_offset() + if(alt_icon != initial(alt_icon)) + var/old_icon = icon + icon = alt_icon + alt_icon = old_icon + pixel_x = get_standard_pixel_x_offset() + pixel_y = get_standard_pixel_y_offset() /mob/living/carbon/alien/humanoid/regenerate_icons() ..() diff --git a/code/modules/mob/living/carbon/alien/humanoid/queen.dm b/code/modules/mob/living/carbon/alien/humanoid/queen.dm index 2564f8ec7b8..1d0e6e931de 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/queen.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/queen.dm @@ -1,13 +1,11 @@ /mob/living/carbon/alien/humanoid/queen name = "alien queen" caste = "q" - maxHealth = 250 - health = 250 + maxHealth = 300 + health = 300 icon_state = "alienq_s" status_flags = CANPARALYSE loudspeaker = TRUE - heal_rate = 5 - large = 1 ventcrawler = VENTCRAWLER_NONE pressure_resistance = 200 //Because big, stompy xenos should not be blown around like paper. move_resist = MOVE_FORCE_STRONG //Yes, queenos is huge and heavy @@ -17,19 +15,8 @@ /mob/living/carbon/alien/humanoid/queen/Initialize(mapload) . = ..() - //there should only be one queen - for(var/mob/living/carbon/alien/humanoid/queen/Q in GLOB.alive_mob_list) - if(Q == src) - ADD_TRAIT(Q, TRAIT_FORCE_DOORS, VAMPIRE_TRAIT) - continue - if(Q.stat == DEAD) - ADD_TRAIT(Q, TRAIT_FORCE_DOORS, VAMPIRE_TRAIT) - continue - if(Q.client) - name = "alien princess ([rand(1, 999)])" //if this is too cutesy feel free to change it/remove it. - break - - real_name = src.name + ADD_TRAIT(src, TRAIT_FORCE_DOORS, UNIQUE_TRAIT_SOURCE(src)) + AddSpell(new /obj/effect/proc_holder/spell/alien_spell/tail_lash) /mob/living/carbon/alien/humanoid/queen/get_caste_organs() . = ..() @@ -38,8 +25,7 @@ /obj/item/organ/internal/alien/acidgland, /obj/item/organ/internal/alien/eggsac, /obj/item/organ/internal/alien/resinspinner, - /obj/item/organ/internal/alien/neurotoxin, - ) + /obj/item/organ/internal/alien/neurotoxin) /mob/living/carbon/alien/humanoid/queen/deathrattle_message() return "A shock reverberates through the hive; [name] has been slain!" @@ -51,7 +37,6 @@ icon = 'icons/mob/alienlarge.dmi' icon_state = "queen_s" pixel_x = -16 - large = 1 /mob/living/carbon/alien/humanoid/queen/large/update_icons() overlays.Cut() diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 20d6c23c669..c1e3b1d69cf 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -12,15 +12,14 @@ var/temperature_resistance = T0C+75 var/amount_grown = 0 var/max_grown = 200 - var/time_of_birth death_message = "lets out a waning high-pitched cry." death_sound = null //This is fine right now, if we're adding organ specific damage this needs to be updated /mob/living/carbon/alien/larva/Initialize(mapload) . = ..() - if(name == "alien larva") - name = "alien larva ([rand(1, 1000)])" + + name = "alien larva ([rand(1, 1000)])" real_name = name regenerate_icons() add_language("Xenomorph") @@ -42,7 +41,7 @@ /mob/living/carbon/alien/larva/Stat() ..() - stat(null, "Progress: [amount_grown]/[max_grown]") + stat("Progress: [amount_grown]/[max_grown]") /mob/living/carbon/alien/larva/add_plasma(amount) if(stat != DEAD && amount > 0) @@ -82,7 +81,6 @@ // new damage icon system // now constructs damage icon for each organ from mask * damage field - /mob/living/carbon/alien/larva/show_inv(mob/user as mob) return diff --git a/code/modules/mob/living/carbon/alien/larva/larva_inventory.dm b/code/modules/mob/living/carbon/alien/larva/larva_inventory.dm index fc5acb63fd0..0c5df6d99e9 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva_inventory.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva_inventory.dm @@ -1,3 +1,3 @@ -//can't unequip since it can't equip anything +//can't unequip since it can't equip anything // why the fuck is this it's own file /mob/living/carbon/alien/larva/unEquip(obj/item/I, force, silent = FALSE) return diff --git a/code/modules/mob/living/carbon/alien/larva/larva_life.dm b/code/modules/mob/living/carbon/alien/larva/larva_life.dm index ea964329fd4..141f5e8d950 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva_life.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva_life.dm @@ -1,7 +1,5 @@ /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) @@ -19,10 +17,8 @@ if(IsParalyzed() || IsSleeping() || getOxyLoss() > 50 || (health <= HEALTH_THRESHOLD_CRIT && check_death_method())) if(stat == CONSCIOUS) KnockOut() - create_debug_log("fell unconscious, trigger reason: [reason]") else if(stat == UNCONSCIOUS) WakeUp() - create_debug_log("woke up, trigger reason: [reason]") update_damage_hud() update_health_hud() diff --git a/code/modules/mob/living/carbon/alien/larva/larva_update_icons.dm b/code/modules/mob/living/carbon/alien/larva/larva_update_icons.dm index 60db90600d1..90e14393f5f 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva_update_icons.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva_update_icons.dm @@ -1,4 +1,3 @@ - /mob/living/carbon/alien/larva/regenerate_icons() overlays = list() update_icons() diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index ff85b6ec8e5..0bd858d98c5 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -1080,7 +1080,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, list(/obj/machinery/atmospherics/unary/ven if(statpanel("Status")) var/obj/item/organ/internal/alien/plasmavessel/vessel = get_int_organ(/obj/item/organ/internal/alien/plasmavessel) if(vessel) - stat(null, "Plasma Stored: [vessel.stored_plasma]/[vessel.max_plasma]") + stat("Plasma Stored: [vessel.stored_plasma]/[vessel.max_plasma]") /mob/living/carbon/get_all_slots() return list(l_hand, diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 9af4de76228..f463a173a82 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -666,12 +666,10 @@ emp_act visible_message("[src] is not affected by [M]'s disarm attempt!") playsound(loc, 'sound/weapons/punchmiss.ogg', 25, 1, -1) return FALSE - var/obj/item/I = get_active_hand() - if(I) - unEquip(I) var/obj/item/organ/external/affecting = get_organ(ran_zone(M.zone_selected)) playsound(loc, 'sound/weapons/pierce.ogg', 25, 1, -1) apply_effect(10 SECONDS, KNOCKDOWN, run_armor_check(affecting, MELEE)) + M.changeNext_move(1.6 SECONDS) apply_damage(M.alien_disarm_damage, STAMINA) add_attack_logs(M, src, "Alien tackled") visible_message("[M] has tackled down [src]!", "You hear aggressive shuffling!") diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 117d256420e..6de1b1b4d79 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -144,7 +144,8 @@ if(locate(/obj/item/grab, mob)) - delay += 7 + if(!isalienhunter(mob)) // i hate grab code + delay += 7 if(istype(living_mob)) var/newdir = NONE diff --git a/code/modules/projectiles/projectile/bullets.dm b/code/modules/projectiles/projectile/bullets.dm index 01c719abfff..56935aae546 100644 --- a/code/modules/projectiles/projectile/bullets.dm +++ b/code/modules/projectiles/projectile/bullets.dm @@ -275,8 +275,21 @@ if(isalien(target)) knockdown = 0 nodamage = TRUE + if(isrobot(target)) + stun = 10 SECONDS . = ..() // Execute the rest of the code. +/obj/item/projectile/bullet/anti_alien_toxin + name = "neurotoxin spit" + icon_state = "neurotoxin" + damage = 15 // FRENDLY FIRE FRENDLY FIRE + damage_type = BURN + +/obj/item/projectile/bullet/anti_alien_toxin/on_hit(atom/target, blocked = 0) + if(isalien(target)) + stun = 10 SECONDS + . = ..() + /obj/item/projectile/bullet/cap name = "cap" damage = 0 diff --git a/code/modules/shuttle/supply.dm b/code/modules/shuttle/supply.dm index 6e081554cae..a211c2e69f0 100644 --- a/code/modules/shuttle/supply.dm +++ b/code/modules/shuttle/supply.dm @@ -206,6 +206,10 @@ msg += "[S.rarity]: New species discovered: \"[capitalize(S.species)]\". Excellent work.
" service_credits += S.rarity / 2 // That's right, no bonus for potency. Send a crappy sample first to "show improvement" later credits_to_deposit += S.rarity / 2 + + if(istype(thing, /obj/item/organ/internal/alien)) + var/obj/item/organ/internal/alien/organ = thing + credits_to_deposit += organ.cargo_profit qdel(MA) SSeconomy.sold_atoms += "." diff --git a/code/modules/surgery/organs/brain.dm b/code/modules/surgery/organs/brain.dm index f756a29f392..762fc793df6 100644 --- a/code/modules/surgery/organs/brain.dm +++ b/code/modules/surgery/organs/brain.dm @@ -38,16 +38,20 @@ if(isnull(dna)) // someone didn't set this right... stack_trace("[src] at [loc] did not contain a dna datum at time of removal.") dna = H.dna.Clone() - name = "\the [dna.real_name]'s [initial(src.name)]" + if(dna.real_name) + name = "\the [dna.real_name]'s [initial(name)]" + brainmob.name = dna.real_name + brainmob.real_name = dna.real_name + else + name = "\the [H.real_name]'s [initial(name)]" + brainmob.name = H.real_name + brainmob.real_name = H.real_name brainmob.dna = dna.Clone() // Silly baycode, what you do -// brainmob.dna = H.dna.Clone() Putting in and taking out a brain doesn't make it a carbon copy of the original brain of the body you put it in - brainmob.name = dna.real_name - brainmob.real_name = dna.real_name brainmob.timeofhostdeath = H.timeofdeath if(H.mind) H.mind.transfer_to(brainmob) - to_chat(brainmob, "You feel slightly disoriented. That's normal when you're just a [initial(src.name)].") + to_chat(brainmob, "You feel slightly disoriented. That's normal when you're just a [initial(name)].") /obj/item/organ/internal/brain/examine(mob/user) // -- TLE . = ..() diff --git a/code/modules/surgery/organs/subtypes/xenos.dm b/code/modules/surgery/organs/subtypes/xenos.dm index d69ef938b7e..98960fdd4b5 100644 --- a/code/modules/surgery/organs/subtypes/xenos.dm +++ b/code/modules/surgery/organs/subtypes/xenos.dm @@ -2,20 +2,51 @@ origin_tech = "biotech=5" icon_state = "xgibmid2" var/list/alien_powers = list() + var/list/human_powers = list() tough = TRUE sterile = TRUE + /// Amount of credits that will be received by selling this in the cargo shuttle + var/cargo_profit = 250 + /// Has this organ been hijacked? Can hijack via a hemostat + var/hijacked = FALSE /// This adds and removes alien spells upon addition, if a noncarbon tries to do this well... I blame adminbus /obj/item/organ/internal/alien/insert(mob/living/carbon/M, special = 0) ..() - for(var/powers_to_add in alien_powers) - M.AddSpell(new powers_to_add) + if(!hijacked) + for(var/powers_to_add in alien_powers) + M.AddSpell(new powers_to_add) + else + for(var/powers_to_add in human_powers) + M.AddSpell(new powers_to_add) /obj/item/organ/internal/alien/remove(mob/living/carbon/M, special = 0) - for(var/powers_to_remove in alien_powers) - M.RemoveSpell(new powers_to_remove) + if(!hijacked) + for(var/powers_to_remove in alien_powers) + M.RemoveSpell(new powers_to_remove) + else + for(var/powers_to_add in human_powers) + M.AddSpell(new powers_to_add) . = ..() +/obj/item/organ/internal/alien/examine(mob/user) + . = ..() + . += "Can be sold on the cargo shuttle for [cargo_profit] credits." + if(hijacked) + . += "This organ is hijacked, use a Hemostat on it to revert it to it's original function." + else + . += "You can hijack the latent functions of this organ by using a Hemostat on it." + +/obj/item/organ/internal/alien/attackby(obj/item/hemostat/item, mob/user, params) + if(istype(item)) + if(!hijacked) + to_chat(user, "You slice off the control node of this organ. This organ will now be effective against aliens.") + else + to_chat(user, "You reattach the control node of this organ. This organ will now be effective against those who attack the hive.") + hijacked = !hijacked + return + return ..() + /obj/item/organ/internal/alien/prepare_eat() var/obj/S = ..() S.reagents.add_reagent("sacid", 10) @@ -28,18 +59,18 @@ icon_state = "plasma" w_class = WEIGHT_CLASS_NORMAL origin_tech = "biotech=5;plasmatech=4" - parent_organ = "chest" slot = "plasmavessel" - alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/plant_weeds, /obj/effect/proc_holder/spell/touch/alien_spell/transfer_plasma) + alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/plant_weeds, /obj/effect/proc_holder/spell/alien_spell/transfer_plasma) + human_powers = list(/obj/effect/proc_holder/spell/alien_spell/syphon_plasma) - var/stored_plasma = 0 - var/max_plasma = 500 + var/stored_plasma = 100 + var/max_plasma = 300 var/heal_rate = 5 var/plasma_rate = 10 /obj/item/organ/internal/alien/plasmavessel/prepare_eat() var/obj/S = ..() - S.reagents.add_reagent("plasma", stored_plasma/10) + S.reagents.add_reagent("plasma", stored_plasma / 10) return S /obj/item/organ/internal/alien/plasmavessel/queen @@ -47,14 +78,12 @@ icon_state = "plasma_large" origin_tech = "biotech=6;plasmatech=4" stored_plasma = 200 - max_plasma = 500 plasma_rate = 25 /obj/item/organ/internal/alien/plasmavessel/drone name = "large xeno plasma vessel" icon_state = "plasma_large" stored_plasma = 200 - max_plasma = 500 /obj/item/organ/internal/alien/plasmavessel/sentinel stored_plasma = 100 @@ -63,16 +92,15 @@ /obj/item/organ/internal/alien/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 = 50 + max_plasma = 100 /obj/item/organ/internal/alien/plasmavessel/larva name = "tiny xeno plasma vessel" icon_state = "plasma_tiny" - max_plasma = 100 - alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/plant_weeds) - + stored_plasma = 25 + max_plasma = 50 + cargo_profit = 150 /obj/item/organ/internal/alien/plasmavessel/on_life() //If there are alien weeds on the ground then heal if needed or give some plasma @@ -83,7 +111,7 @@ var/heal_amt = heal_rate if(!isalien(owner)) heal_amt *= 0.2 - owner.add_plasma((plasma_rate*0.5)) + owner.add_plasma((plasma_rate / 2)) owner.adjustBruteLoss(-heal_amt) owner.adjustFireLoss(-heal_amt) owner.adjustOxyLoss(-heal_amt) @@ -97,20 +125,17 @@ . =..() M.update_plasma_display(M) - /obj/item/organ/internal/alien/acidgland name = "xeno acid gland" icon_state = "acid" - parent_organ = "head" slot = "acid" origin_tech = "biotech=5;materials=2;combat=2" alien_powers = list(/obj/effect/proc_holder/spell/touch/alien_spell/corrosive_acid) - + human_powers = list(/obj/effect/proc_holder/spell/touch/alien_spell/burning_touch) /obj/item/organ/internal/alien/hivenode name = "xeno hive node" icon_state = "hivenode" - parent_organ = "head" slot = "hivenode" origin_tech = "biotech=5;magnets=4;bluespace=3" w_class = WEIGHT_CLASS_TINY @@ -133,24 +158,25 @@ /obj/item/organ/internal/alien/neurotoxin name = "xeno neurotoxin gland" icon_state = "neurotox" - parent_organ = "head" slot = "neurotox" origin_tech = "biotech=5;combat=5" alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/neurotoxin) + human_powers = list(/obj/effect/proc_holder/spell/alien_spell/neurotoxin/death_to_xenos) /obj/item/organ/internal/alien/resinspinner - name = "xeno resin organ"//...there tiger.... - parent_organ = "mouth" + name = "xeno resin organ" icon_state = "liver-x" slot = "spinner" origin_tech = "biotech=5;materials=4" alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/build_resin) + human_powers = list(/obj/effect/proc_holder/spell/touch/alien_spell/consume_resin) /obj/item/organ/internal/alien/eggsac name = "xeno egg sac" icon_state = "eggsac" - parent_organ = "groin" slot = "eggsac" w_class = WEIGHT_CLASS_BULKY origin_tech = "biotech=6" alien_powers = list(/obj/effect/proc_holder/spell/alien_spell/plant_weeds/eggs) + human_powers = list(/obj/effect/proc_holder/spell/alien_spell/combust_facehuggers) + cargo_profit = 1000 diff --git a/icons/mob/alien.dmi b/icons/mob/alien.dmi index 15631f719db..aa921ea1343 100644 Binary files a/icons/mob/alien.dmi and b/icons/mob/alien.dmi differ diff --git a/paradise.dme b/paradise.dme index ef10a3ef4d1..742bfa526f9 100644 --- a/paradise.dme +++ b/paradise.dme @@ -568,6 +568,7 @@ #include "code\datums\spells\alien_spells\plasma_weeds.dm" #include "code\datums\spells\alien_spells\queen_evolve.dm" #include "code\datums\spells\alien_spells\regurgitate.dm" +#include "code\datums\spells\alien_spells\tail_lash.dm" #include "code\datums\spells\alien_spells\transfer_plasma.dm" #include "code\datums\spells\alien_spells\whisper.dm" #include "code\datums\station_traits\_station_trait.dm"