mirror of
https://github.com/VOREStation/VOREStation.git
synced 2026-08-22 11:38:12 +01:00
Cherrypicked xenophage-rewrite mechanics over.
This commit is contained in:
@@ -1119,16 +1119,6 @@
|
||||
log_admin("[key_name(usr)] AIized [key_name(H)]")
|
||||
H.AIize()
|
||||
|
||||
else if(href_list["makealien"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["makealien"])
|
||||
if(!istype(H))
|
||||
usr << "This can only be used on instances of type /mob/living/carbon/human"
|
||||
return
|
||||
|
||||
usr.client.cmd_admin_alienize(H)
|
||||
|
||||
else if(href_list["makeslime"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
// callproc moved to code/modules/admin/callproc
|
||||
|
||||
|
||||
/client/proc/Cell()
|
||||
set category = "Debug"
|
||||
set name = "Cell"
|
||||
@@ -100,23 +101,6 @@
|
||||
paiController.pai_candidates.Remove(candidate)
|
||||
feedback_add_details("admin_verb","MPAI") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/cmd_admin_alienize(var/mob/M in mob_list)
|
||||
set category = "Fun"
|
||||
set name = "Make Alien"
|
||||
|
||||
if(!ticker)
|
||||
alert("Wait until the game starts")
|
||||
return
|
||||
if(ishuman(M))
|
||||
log_admin("[key_name(src)] has alienized [M.key].")
|
||||
spawn(10)
|
||||
M:Alienize()
|
||||
feedback_add_details("admin_verb","MKAL") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
log_admin("[key_name(usr)] made [key_name(M)] into an alien.")
|
||||
message_admins("\blue [key_name_admin(usr)] made [key_name(M)] into an alien.", 1)
|
||||
else
|
||||
alert("Invalid mob")
|
||||
|
||||
/client/proc/cmd_admin_slimeize(var/mob/M in mob_list)
|
||||
set category = "Fun"
|
||||
set name = "Make slime"
|
||||
|
||||
@@ -278,20 +278,6 @@
|
||||
return
|
||||
holder.Topic(href, list("makerobot"=href_list["makerobot"]))
|
||||
|
||||
else if(href_list["makealien"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
var/mob/living/carbon/human/H = locate(href_list["makealien"])
|
||||
if(!istype(H))
|
||||
usr << "This can only be done to instances of type /mob/living/carbon/human"
|
||||
return
|
||||
|
||||
if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return
|
||||
if(!H)
|
||||
usr << "Mob doesn't exist anymore"
|
||||
return
|
||||
holder.Topic(href, list("makealien"=href_list["makealien"]))
|
||||
|
||||
else if(href_list["makeslime"])
|
||||
if(!check_rights(R_SPAWN)) return
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
var/trash_type // Garbage item produced when eaten.
|
||||
var/splat_type = /obj/effect/decal/cleanable/fruit_smudge // Graffiti decal.
|
||||
var/has_mob_product
|
||||
var/force_layer
|
||||
|
||||
/datum/seed/New()
|
||||
|
||||
|
||||
@@ -1106,3 +1106,22 @@
|
||||
set_trait(TRAIT_PRODUCTION,7)
|
||||
set_trait(TRAIT_YIELD,3)
|
||||
set_trait(TRAIT_POTENCY,3)
|
||||
|
||||
// Alien weeds.
|
||||
/datum/seed/xenomorph
|
||||
name = "xenomorph"
|
||||
seed_name = "alien weed"
|
||||
display_name = "alien weeds"
|
||||
force_layer = 3
|
||||
|
||||
/datum/seed/xenomorph/New()
|
||||
..()
|
||||
set_trait(TRAIT_PLANT_ICON,"vine2")
|
||||
set_trait(TRAIT_IMMUTABLE,1)
|
||||
set_trait(TRAIT_PRODUCT_COLOUR,"#080006")
|
||||
set_trait(TRAIT_FLESH_COLOUR,"#080006")
|
||||
set_trait(TRAIT_PLANT_COLOUR,"#080006")
|
||||
set_trait(TRAIT_PRODUCTION,1)
|
||||
set_trait(TRAIT_YIELD,-1)
|
||||
set_trait(TRAIT_SPREAD,2)
|
||||
set_trait(TRAIT_POTENCY,50)
|
||||
@@ -188,12 +188,12 @@
|
||||
icon_state = "[seed.get_trait(TRAIT_PLANT_ICON)]-[growth]"
|
||||
|
||||
if(growth>2 && growth == max_growth)
|
||||
layer = 5
|
||||
layer = (seed && seed.force_layer) ? seed.force_layer : 5
|
||||
opacity = 1
|
||||
if(!isnull(seed.chems["woodpulp"]))
|
||||
density = 1
|
||||
else
|
||||
layer = 3
|
||||
layer = (seed && seed.force_layer) ? seed.force_layer : 5
|
||||
density = 0
|
||||
|
||||
/obj/effect/plant/proc/calc_dir()
|
||||
|
||||
@@ -11,4 +11,5 @@
|
||||
/mob/living/carbon/alien/larva/New()
|
||||
..()
|
||||
add_language("Xenomorph") //Bonus language.
|
||||
internal_organs |= new /obj/item/organ/xenos/hivenode(src)
|
||||
internal_organs |= new /obj/item/organ/xenos/hivenode(src)
|
||||
create_reagents(100)
|
||||
@@ -1,12 +1,34 @@
|
||||
#define MIN_LARVA_BLOOD_DRINK 0.5
|
||||
|
||||
//Larvae regenerate health and nutrition from plasma and alien weeds.
|
||||
/mob/living/carbon/alien/larva/handle_environment(var/datum/gas_mixture/environment)
|
||||
|
||||
if(!environment) return
|
||||
|
||||
var/turf/T = get_turf(src)
|
||||
if(environment.gas["phoron"] > 0 || (T && locate(/obj/effect/alien/weeds) in T.contents))
|
||||
var/obj/effect/plant/plant = locate() in T
|
||||
if(environment.gas["phoron"] > 0 || (plant && plant.seed && plant.seed.name == "xenophage"))
|
||||
update_progression()
|
||||
adjustBruteLoss(-1)
|
||||
adjustFireLoss(-1)
|
||||
adjustToxLoss(-1)
|
||||
adjustOxyLoss(-1)
|
||||
adjustOxyLoss(-1)
|
||||
|
||||
// Maybe not the -best- place but it's semiappropriate and fitting.
|
||||
// Drink the blood of your host!
|
||||
/mob/living/carbon/alien/larva/handle_chemicals_in_body()
|
||||
if(!loc)
|
||||
return
|
||||
if(!istype(loc, /obj/item/weapon/holder))
|
||||
return
|
||||
var/mob/living/carbon/human/M = loc.loc //ergh, replace with a flag sometime
|
||||
if(!istype(M))
|
||||
return
|
||||
if(M.vessel.total_volume > 0)
|
||||
M.vessel.trans_to(src,min(M.vessel.total_volume,MIN_LARVA_BLOOD_DRINK))
|
||||
update_progression()
|
||||
else
|
||||
src << "<span class='danger'>This host is depleted of blood...</span>"
|
||||
leave_host()
|
||||
|
||||
#undef MIN_LARVA_BLOOD_DRINK
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/mob/living/carbon/alien/larva/proc/check_can_infest(var/mob/living/M)
|
||||
if(!src)
|
||||
return 0
|
||||
if(!istype(loc, /turf))
|
||||
src << "<span class='danger'>You cannot infest a target in your current position.</span>"
|
||||
return 0
|
||||
if(stat)
|
||||
src << "<span class='danger'>You cannot infest a target in your current state.</span>"
|
||||
return 0
|
||||
if(!M)
|
||||
return 1
|
||||
if(!M.lying)
|
||||
src << "<span class='danger'>\The [M] is not prone.</span>"
|
||||
return 0
|
||||
if(!(src.Adjacent(M)))
|
||||
src << "<span class='danger'>\The [M] is not in range.</span>"
|
||||
return 0
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/larva/verb/attach_host()
|
||||
|
||||
set name = "Attach to host"
|
||||
set desc = "Burrow into a prone victim and begin drinking their blood."
|
||||
set category = "Abilities"
|
||||
|
||||
if(!check_can_infest())
|
||||
return
|
||||
|
||||
var/list/choices = list()
|
||||
for(var/mob/living/carbon/human/H in view(1,src))
|
||||
if(istype(H.species, /datum/species/xenos)) //Kinda gross, but easier and cleaner than a string check.
|
||||
continue
|
||||
if(src.Adjacent(H) && H.lying)
|
||||
choices += H
|
||||
|
||||
if(!choices.len)
|
||||
src << "<span class='danger'>There are no viable hosts within range.</span>"
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = input(src,"Who do you wish to infest?") as null|anything in choices
|
||||
|
||||
if(!H || !src || !H.lying) return
|
||||
|
||||
visible_message("<span class='danger'>\The [src] begins questing blindly towards \the [H]'s warm flesh...</span>")
|
||||
|
||||
if(!do_after(src,30))
|
||||
return
|
||||
|
||||
if(!check_can_infest(H))
|
||||
return
|
||||
|
||||
var/obj/item/organ/external/E = pick(H.organs)
|
||||
src << "<span class='danger'>You burrow deeply into \the [H]'s [E.name]!</span>"
|
||||
var/obj/item/weapon/holder/holder = new (loc)
|
||||
src.loc = holder
|
||||
holder.name = src.name
|
||||
E.embed(holder,0,"\The [src] burrows deeply into \the [H]'s [E.name]!")
|
||||
|
||||
/mob/living/carbon/alien/larva/verb/release_host()
|
||||
set category = "Abilities"
|
||||
set name = "Release Host"
|
||||
set desc = "Release your host."
|
||||
|
||||
if(stat)
|
||||
src << "You cannot leave your host in your current state."
|
||||
return
|
||||
|
||||
if(!loc || !loc.loc)
|
||||
src << "You are not inside a host."
|
||||
return
|
||||
|
||||
var/mob/living/carbon/human/H = loc.loc
|
||||
|
||||
if(!istype(H))
|
||||
src << "You are not inside a host."
|
||||
return
|
||||
|
||||
src << "<span class='danger'>You begin writhing your way free of \the [H]'s flesh...</span>"
|
||||
|
||||
if(!do_after(src, 30))
|
||||
return
|
||||
|
||||
if(!H || !src)
|
||||
return
|
||||
|
||||
leave_host()
|
||||
|
||||
/mob/living/carbon/alien/larva/proc/leave_host()
|
||||
if(!loc || !loc.loc)
|
||||
src << "You are not inside a host."
|
||||
return
|
||||
var/mob/living/carbon/human/H = loc.loc
|
||||
if(!istype(H))
|
||||
src << "You are not inside a host."
|
||||
return
|
||||
var/obj/item/weapon/holder/holder = loc
|
||||
var/obj/item/organ/external/affected
|
||||
if(istype(holder))
|
||||
for(var/obj/item/organ/external/organ in H.organs) //Grab the organ holding the implant.
|
||||
for(var/obj/item/O in organ.implants)
|
||||
if(O == holder)
|
||||
affected = organ
|
||||
break
|
||||
affected.implants -= holder
|
||||
holder.loc = get_turf(holder)
|
||||
else
|
||||
src.loc = get_turf(src)
|
||||
if(affected)
|
||||
src << "<span class='danger'>You crawl out of \the [H]'s [affected.name] and plop to the ground.</span>"
|
||||
else
|
||||
src << "<span class='danger'>You plop to the ground.</span>"
|
||||
@@ -9,8 +9,7 @@
|
||||
|
||||
..()
|
||||
|
||||
if (stat != DEAD) //still breathing
|
||||
// GROW!
|
||||
if (stat != DEAD && can_progress())
|
||||
update_progression()
|
||||
|
||||
blinded = null
|
||||
@@ -18,6 +17,10 @@
|
||||
//Status updates, death etc.
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/proc/can_progress()
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/carbon/alien/handle_mutations_and_radiation()
|
||||
|
||||
// Currently both Dionaea and larvae like to eat radiation, so I'm defining the
|
||||
@@ -158,7 +161,7 @@
|
||||
adjustFireLoss((environment.temperature - (T0C+66))/5) // Might be too high, check in testing.
|
||||
if (fire) fire.icon_state = "fire2"
|
||||
if(prob(20))
|
||||
src << "\red You feel a searing heat!"
|
||||
src << "<span class='danger'>You feel a searing heat!</span>"
|
||||
else
|
||||
if (fire) fire.icon_state = "fire0"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/mob/living/carbon/alien/verb/evolve()
|
||||
|
||||
set name = "Evolve"
|
||||
set desc = "Evolve into your adult form."
|
||||
set name = "Moult"
|
||||
set desc = "Moult your skin and become an adult."
|
||||
set category = "Abilities"
|
||||
|
||||
if(stat != CONSCIOUS)
|
||||
@@ -12,11 +12,11 @@
|
||||
return
|
||||
|
||||
if(handcuffed || legcuffed)
|
||||
src << "\red You cannot evolve when you are cuffed."
|
||||
src << "<span class='warning'>You cannot evolve when you are cuffed.</span>"
|
||||
return
|
||||
|
||||
if(amount_grown < max_grown)
|
||||
src << "\red You are not fully grown."
|
||||
src << "<span class='warning'>You are not fully grown.</span>"
|
||||
return
|
||||
|
||||
// confirm_evolution() handles choices and other specific requirements.
|
||||
@@ -27,6 +27,7 @@
|
||||
var/mob/living/carbon/human/adult = new adult_form(get_turf(src))
|
||||
adult.set_species(new_species)
|
||||
show_evolution_blurb()
|
||||
// TODO: drop a moulted skin. Ew.
|
||||
|
||||
if(mind)
|
||||
mind.transfer_to(adult)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
var/prone_icon // If set, draws this from icobase when mob is prone.
|
||||
var/eyes = "eyes_s" // Icon for eyes.
|
||||
var/has_floating_eyes // Eyes will overlay over darkness (glow)
|
||||
var/blood_color = "#A10808" // Red.
|
||||
var/flesh_color = "#FFC896" // Pink.
|
||||
var/base_color // Used by changelings. Should also be used for icon previes..
|
||||
@@ -152,6 +153,9 @@
|
||||
|
||||
var/pass_flags = 0
|
||||
|
||||
/datum/species/proc/get_eyes(var/mob/living/carbon/human/H)
|
||||
return
|
||||
|
||||
/datum/species/New()
|
||||
if(hud_type)
|
||||
hud = new hud_type()
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
// This is to replace the previous datum/disease/alien_embryo for slightly improved handling and maintainability
|
||||
// It functions almost identically (see code/datums/diseases/alien_embryo.dm)
|
||||
|
||||
/obj/item/alien_embryo
|
||||
name = "alien embryo"
|
||||
desc = "All slimy and yuck."
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
icon_state = "larva0_dead"
|
||||
var/mob/living/affected_mob
|
||||
var/stage = 0
|
||||
|
||||
/obj/item/alien_embryo/New()
|
||||
if(istype(loc, /mob/living))
|
||||
affected_mob = loc
|
||||
processing_objects.Add(src)
|
||||
spawn(0)
|
||||
AddInfectionImages(affected_mob)
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/obj/item/alien_embryo/Destroy()
|
||||
if(affected_mob)
|
||||
affected_mob.status_flags &= ~(XENO_HOST)
|
||||
spawn(0)
|
||||
RemoveInfectionImages(affected_mob)
|
||||
..()
|
||||
|
||||
/obj/item/alien_embryo/process()
|
||||
if(!affected_mob) return
|
||||
if(loc != affected_mob)
|
||||
affected_mob.status_flags &= ~(XENO_HOST)
|
||||
processing_objects.Remove(src)
|
||||
spawn(0)
|
||||
RemoveInfectionImages(affected_mob)
|
||||
affected_mob = null
|
||||
return
|
||||
|
||||
if(stage < 5 && prob(3))
|
||||
stage++
|
||||
spawn(0)
|
||||
RefreshInfectionImage(affected_mob)
|
||||
|
||||
switch(stage)
|
||||
if(2, 3)
|
||||
if(prob(1))
|
||||
affected_mob.emote("sneeze")
|
||||
if(prob(1))
|
||||
affected_mob.emote("cough")
|
||||
if(prob(1))
|
||||
affected_mob << "\red Your throat feels sore."
|
||||
if(prob(1))
|
||||
affected_mob << "\red Mucous runs down the back of your throat."
|
||||
if(4)
|
||||
if(prob(1))
|
||||
affected_mob.emote("sneeze")
|
||||
if(prob(1))
|
||||
affected_mob.emote("cough")
|
||||
if(prob(2))
|
||||
affected_mob << "\red Your muscles ache."
|
||||
if(prob(20))
|
||||
affected_mob.take_organ_damage(1)
|
||||
if(prob(2))
|
||||
affected_mob << "\red Your stomach hurts."
|
||||
if(prob(20))
|
||||
affected_mob.adjustToxLoss(1)
|
||||
affected_mob.updatehealth()
|
||||
if(5)
|
||||
affected_mob << "\red You feel something tearing its way out of your stomach..."
|
||||
affected_mob.adjustToxLoss(10)
|
||||
affected_mob.updatehealth()
|
||||
if(prob(50))
|
||||
AttemptGrow()
|
||||
|
||||
/obj/item/alien_embryo/proc/AttemptGrow(var/gib_on_success = 1)
|
||||
var/list/candidates = get_alien_candidates()
|
||||
var/picked = null
|
||||
|
||||
// To stop clientless larva, we will check that our host has a client
|
||||
// if we find no ghosts to become the alien. If the host has a client
|
||||
// he will become the alien but if he doesn't then we will set the stage
|
||||
// to 2, so we don't do a process heavy check everytime.
|
||||
|
||||
if(candidates.len)
|
||||
picked = pick(candidates)
|
||||
else if(affected_mob.client)
|
||||
picked = affected_mob.key
|
||||
else
|
||||
stage = 4 // Let's try again later.
|
||||
return
|
||||
|
||||
if(affected_mob.lying)
|
||||
affected_mob.overlays += image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "burst_lie")
|
||||
else
|
||||
affected_mob.overlays += image('icons/mob/alien.dmi', loc = affected_mob, icon_state = "burst_stand")
|
||||
spawn(6)
|
||||
var/mob/living/carbon/alien/larva/new_xeno = new(affected_mob.loc)
|
||||
new_xeno.key = picked
|
||||
new_xeno << sound('sound/voice/hiss5.ogg',0,0,0,100) //To get the player's attention
|
||||
if(gib_on_success)
|
||||
affected_mob.gib()
|
||||
qdel(src)
|
||||
|
||||
/*----------------------------------------
|
||||
Proc: RefreshInfectionImage()
|
||||
Des: Removes all infection images from aliens and places an infection image on all infected mobs for aliens.
|
||||
----------------------------------------*/
|
||||
/obj/item/alien_embryo/proc/RefreshInfectionImage()
|
||||
|
||||
for(var/mob/living/carbon/alien in player_list)
|
||||
|
||||
if(!locate(/obj/item/organ/xenos/hivenode) in alien.internal_organs)
|
||||
continue
|
||||
|
||||
if(alien.client)
|
||||
for(var/image/I in alien.client.images)
|
||||
if(dd_hasprefix_case(I.icon_state, "infected"))
|
||||
qdel(I)
|
||||
for(var/mob/living/L in mob_list)
|
||||
if(iscorgi(L) || iscarbon(L))
|
||||
if(L.status_flags & XENO_HOST)
|
||||
var/I = image('icons/mob/alien.dmi', loc = L, icon_state = "infected[stage]")
|
||||
alien.client.images += I
|
||||
|
||||
/*----------------------------------------
|
||||
Proc: AddInfectionImages(C)
|
||||
Des: Checks if the passed mob (C) is infected with the alien egg, then gives each alien client an infected image at C.
|
||||
----------------------------------------*/
|
||||
/obj/item/alien_embryo/proc/AddInfectionImages(var/mob/living/C)
|
||||
if(C)
|
||||
|
||||
for(var/mob/living/carbon/alien in player_list)
|
||||
|
||||
if(!locate(/obj/item/organ/xenos/hivenode) in alien.internal_organs)
|
||||
continue
|
||||
|
||||
if(alien.client)
|
||||
if(C.status_flags & XENO_HOST)
|
||||
var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[stage]")
|
||||
alien.client.images += I
|
||||
|
||||
/*----------------------------------------
|
||||
Proc: RemoveInfectionImage(C)
|
||||
Des: Removes the alien infection image from all aliens in the world located in passed mob (C).
|
||||
----------------------------------------*/
|
||||
|
||||
/obj/item/alien_embryo/proc/RemoveInfectionImages(var/mob/living/C)
|
||||
|
||||
if(C)
|
||||
|
||||
for(var/mob/living/carbon/alien in player_list)
|
||||
|
||||
if(!locate(/obj/item/organ/xenos/hivenode) in alien.internal_organs)
|
||||
continue
|
||||
|
||||
if(alien.client)
|
||||
for(var/image/I in alien.client.images)
|
||||
if(I.loc == C)
|
||||
if(dd_hasprefix_case(I.icon_state, "infected"))
|
||||
qdel(I)
|
||||
@@ -1,231 +0,0 @@
|
||||
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||
|
||||
//TODO: Make these simple_animals
|
||||
|
||||
var/const/MIN_IMPREGNATION_TIME = 100 //time it takes to impregnate someone
|
||||
var/const/MAX_IMPREGNATION_TIME = 150
|
||||
|
||||
var/const/MIN_ACTIVE_TIME = 200 //time between being dropped and going idle
|
||||
var/const/MAX_ACTIVE_TIME = 400
|
||||
|
||||
/obj/item/clothing/mask/facehugger
|
||||
name = "alien"
|
||||
desc = "It has some sort of a tube at the end of its tail."
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
icon_state = "facehugger"
|
||||
item_state = "facehugger"
|
||||
w_class = 3 //note: can be picked up by aliens unlike most other items of w_class below 4
|
||||
flags = PROXMOVE
|
||||
body_parts_covered = FACE|EYES
|
||||
throw_range = 5
|
||||
|
||||
var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
|
||||
var/sterile = 0
|
||||
var/strength = 5
|
||||
var/attached = 0
|
||||
|
||||
/obj/item/clothing/mask/facehugger/attack_hand(user as mob)
|
||||
|
||||
if((stat == CONSCIOUS && !sterile))
|
||||
if(Attach(user))
|
||||
return
|
||||
|
||||
..()
|
||||
|
||||
/obj/item/clothing/mask/facehugger/attack(mob/living/M as mob, mob/user as mob)
|
||||
..()
|
||||
user.drop_from_inventory(src)
|
||||
Attach(M)
|
||||
|
||||
/obj/item/clothing/mask/facehugger/New()
|
||||
if(config.aliens_allowed)
|
||||
..()
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/obj/item/clothing/mask/facehugger/examine(mob/user)
|
||||
..(user)
|
||||
switch(stat)
|
||||
if(DEAD,UNCONSCIOUS)
|
||||
user << "\red \b [src] is not moving."
|
||||
if(CONSCIOUS)
|
||||
user << "\red \b [src] seems to be active."
|
||||
if (sterile)
|
||||
user << "\red \b It looks like the proboscis has been removed."
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/attackby(obj/item/I, mob/user)
|
||||
if(I.force)
|
||||
user.do_attack_animation(src)
|
||||
Die()
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/bullet_act()
|
||||
Die()
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature > T0C+80)
|
||||
Die()
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/equipped(mob/M)
|
||||
Attach(M)
|
||||
|
||||
/obj/item/clothing/mask/facehugger/Crossed(atom/target)
|
||||
HasProximity(target)
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/on_found(mob/finder as mob)
|
||||
if(stat == CONSCIOUS)
|
||||
HasProximity(finder)
|
||||
return 1
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/HasProximity(atom/movable/AM as mob|obj)
|
||||
if(CanHug(AM))
|
||||
Attach(AM)
|
||||
|
||||
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed)
|
||||
..()
|
||||
if(stat == CONSCIOUS)
|
||||
icon_state = "[initial(icon_state)]_thrown"
|
||||
spawn(15)
|
||||
if(icon_state == "[initial(icon_state)]_thrown")
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
/obj/item/clothing/mask/facehugger/throw_impact(atom/hit_atom)
|
||||
..()
|
||||
if(stat == CONSCIOUS)
|
||||
icon_state = "[initial(icon_state)]"
|
||||
throwing = 0
|
||||
GoIdle(30,100) //stunned for a few seconds - allows throwing them to be useful for positioning but not as an offensive action (unless you're setting up a trap)
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/Attach(M as mob)
|
||||
|
||||
if((!iscorgi(M) && !iscarbon(M)))
|
||||
return
|
||||
|
||||
if(attached)
|
||||
return
|
||||
|
||||
var/mob/living/carbon/C = M
|
||||
if(istype(C) && locate(/obj/item/organ/xenos/hivenode) in C.internal_organs)
|
||||
return
|
||||
|
||||
|
||||
attached++
|
||||
spawn(MAX_IMPREGNATION_TIME)
|
||||
attached = 0
|
||||
|
||||
var/mob/living/L = M //just so I don't need to use :
|
||||
|
||||
if(loc == L) return
|
||||
if(stat != CONSCIOUS) return
|
||||
if(!sterile) L.take_organ_damage(strength,0) //done here so that even borgs and humans in helmets take damage
|
||||
|
||||
L.visible_message("\red \b [src] leaps at [L]'s face!")
|
||||
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/target = L
|
||||
|
||||
if(target.wear_mask)
|
||||
if(prob(20)) return
|
||||
var/obj/item/clothing/W = target.wear_mask
|
||||
if(!W.canremove) return
|
||||
target.drop_from_inventory(W)
|
||||
|
||||
target.visible_message("\red \b [src] tears [W] off of [target]'s face!")
|
||||
|
||||
target.equip_to_slot(src, slot_wear_mask)
|
||||
target.contents += src // Monkey sanity check - Snapshot
|
||||
|
||||
if(!sterile) L.Paralyse(MAX_IMPREGNATION_TIME/6) //something like 25 ticks = 20 seconds with the default settings
|
||||
else if (iscorgi(M))
|
||||
var/mob/living/simple_animal/corgi/corgi = M
|
||||
src.loc = corgi
|
||||
corgi.facehugger = src
|
||||
corgi.wear_mask = src
|
||||
//C.regenerate_icons()
|
||||
|
||||
GoIdle() //so it doesn't jump the people that tear it off
|
||||
|
||||
spawn(rand(MIN_IMPREGNATION_TIME,MAX_IMPREGNATION_TIME))
|
||||
Impregnate(L)
|
||||
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/Impregnate(mob/living/target as mob)
|
||||
if(!target || target.wear_mask != src || target.stat == DEAD) //was taken off or something
|
||||
return
|
||||
|
||||
if(!sterile)
|
||||
//target.contract_disease(new /datum/disease/alien_embryo(0)) //so infection chance is same as virus infection chance
|
||||
new /obj/item/alien_embryo(target)
|
||||
target.status_flags |= XENO_HOST
|
||||
|
||||
target.visible_message("\red \b [src] falls limp after violating [target]'s face!")
|
||||
|
||||
Die()
|
||||
icon_state = "[initial(icon_state)]_impregnated"
|
||||
|
||||
if(iscorgi(target))
|
||||
var/mob/living/simple_animal/corgi/C = target
|
||||
src.loc = get_turf(C)
|
||||
C.facehugger = null
|
||||
else
|
||||
target.visible_message("\red \b [src] violates [target]'s face!")
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/GoActive()
|
||||
if(stat == DEAD || stat == CONSCIOUS)
|
||||
return
|
||||
|
||||
stat = CONSCIOUS
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/GoIdle(var/min_time=MIN_ACTIVE_TIME, var/max_time=MAX_ACTIVE_TIME)
|
||||
if(stat == DEAD || stat == UNCONSCIOUS)
|
||||
return
|
||||
|
||||
/* RemoveActiveIndicators() */
|
||||
|
||||
stat = UNCONSCIOUS
|
||||
icon_state = "[initial(icon_state)]_inactive"
|
||||
|
||||
spawn(rand(min_time,max_time))
|
||||
GoActive()
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/Die()
|
||||
if(stat == DEAD)
|
||||
return
|
||||
|
||||
/* RemoveActiveIndicators() */
|
||||
|
||||
icon_state = "[initial(icon_state)]_dead"
|
||||
stat = DEAD
|
||||
|
||||
src.visible_message("\red \b[src] curls up into a ball!")
|
||||
|
||||
return
|
||||
|
||||
/proc/CanHug(var/mob/M)
|
||||
|
||||
if(iscorgi(M))
|
||||
return 1
|
||||
|
||||
if(!iscarbon(M))
|
||||
return 0
|
||||
|
||||
var/mob/living/carbon/C = M
|
||||
if(istype(C) && locate(/obj/item/organ/xenos/hivenode) in C.internal_organs)
|
||||
return 0
|
||||
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(H.head && (H.head.body_parts_covered & FACE) && !(H.head.item_flags & FLEXIBLEMATERIAL))
|
||||
return 0
|
||||
return 1
|
||||
@@ -88,13 +88,13 @@
|
||||
verbs -= /mob/living/carbon/human/proc/lay_egg
|
||||
return
|
||||
|
||||
if(locate(/obj/effect/alien/egg) in get_turf(src))
|
||||
if(locate(/obj/structure/alien/egg) in get_turf(src))
|
||||
src << "There's already an egg here."
|
||||
return
|
||||
|
||||
if(check_alien_ability(75,1,"egg sac"))
|
||||
visible_message("<span class='alium'><B>[src] has laid an egg!</B></span>")
|
||||
new /obj/effect/alien/egg(loc)
|
||||
new /obj/structure/alien/egg(loc)
|
||||
|
||||
return
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
|
||||
if(check_alien_ability(50,1,"resin spinner"))
|
||||
visible_message("<span class='alium'><B>[src] has planted some alien weeds!</B></span>")
|
||||
new /obj/effect/alien/weeds/node(loc)
|
||||
new /obj/structure/alien/node(loc)
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/corrosive_acid(O as obj|turf in oview(1)) //If they right click to corrode, an error will flash if its an invalid target./N
|
||||
@@ -154,7 +154,7 @@
|
||||
return
|
||||
|
||||
if(check_alien_ability(200,0,"acid gland"))
|
||||
new /obj/effect/alien/acid(get_turf(O), O)
|
||||
new /obj/effect/acid(get_turf(O), O)
|
||||
visible_message("<span class='alium'><B>[src] vomits globs of vile stuff all over [O]. It begins to sizzle and melt under the bubbling mess of acid!</B></span>")
|
||||
|
||||
return
|
||||
@@ -199,7 +199,7 @@
|
||||
|
||||
/mob/living/carbon/human/proc/resin() // -- TLE
|
||||
set name = "Secrete Resin (75)"
|
||||
set desc = "Secrete tough malleable resin."
|
||||
set desc = "Secrete tough, malleable resin."
|
||||
set category = "Abilities"
|
||||
|
||||
var/choice = input("Choose what you wish to shape.","Resin building") as null|anything in list("resin door","resin wall","resin membrane","resin nest") //would do it through typesof but then the player choice would have the type path and we don't want the internal workings to be exposed ICly - Urist
|
||||
@@ -214,9 +214,9 @@
|
||||
if("resin door")
|
||||
new /obj/structure/simple_door/resin(loc)
|
||||
if("resin wall")
|
||||
new /obj/effect/alien/resin/wall(loc)
|
||||
new /obj/structure/alien/resin/wall(loc)
|
||||
if("resin membrane")
|
||||
new /obj/effect/alien/resin/membrane(loc)
|
||||
new /obj/structure/alien/resin/membrane(loc)
|
||||
if("resin nest")
|
||||
new /obj/structure/bed/nest(loc)
|
||||
return
|
||||
@@ -98,11 +98,11 @@
|
||||
var/datum/gas_mixture/environment = T.return_air()
|
||||
if(!environment) return
|
||||
|
||||
if(environment.gas["phoron"] > 0 || locate(/obj/effect/alien/weeds) in T)
|
||||
if(!regenerate(H))
|
||||
var/obj/item/organ/xenos/plasmavessel/P = H.internal_organs_by_name["plasma vessel"]
|
||||
P.stored_plasma += weeds_plasma_rate
|
||||
P.stored_plasma = min(max(P.stored_plasma,0),P.max_plasma)
|
||||
var/obj/effect/plant/plant = locate() in T
|
||||
if((environment.gas["phoron"] > 0 || (plant && plant.seed && plant.seed.name == "xenomorph")) && !regenerate(H))
|
||||
var/obj/item/organ/xenos/plasmavessel/P = H.internal_organs_by_name["plasma vessel"]
|
||||
P.stored_plasma += weeds_plasma_rate
|
||||
P.stored_plasma = min(max(P.stored_plasma,0),P.max_plasma)
|
||||
..()
|
||||
|
||||
/datum/species/xenos/proc/regenerate(var/mob/living/carbon/human/H)
|
||||
@@ -140,14 +140,6 @@
|
||||
|
||||
return 0
|
||||
|
||||
/datum/species/xenos/handle_login_special(var/mob/living/carbon/human/H)
|
||||
H.AddInfectionImages()
|
||||
..()
|
||||
|
||||
/datum/species/xenos/handle_logout_special(var/mob/living/carbon/human/H)
|
||||
H.RemoveInfectionImages()
|
||||
..()
|
||||
|
||||
/datum/species/xenos/drone
|
||||
name = "Xenomorph Drone"
|
||||
caste_name = "drone"
|
||||
|
||||
@@ -22,28 +22,3 @@ proc/create_new_xenomorph(var/alien_caste,var/target)
|
||||
/mob/living/carbon/human/xqueen/New(var/new_loc)
|
||||
h_style = "Bald"
|
||||
..(new_loc, "Xenomorph Queen")
|
||||
|
||||
// I feel like we should generalize/condense down all the various icon-rendering antag procs.
|
||||
/*----------------------------------------
|
||||
Proc: AddInfectionImages()
|
||||
Des: Gives the client of the alien an image on each infected mob.
|
||||
----------------------------------------*/
|
||||
/mob/living/carbon/human/proc/AddInfectionImages()
|
||||
if (client)
|
||||
for (var/mob/living/C in mob_list)
|
||||
if(C.status_flags & XENO_HOST)
|
||||
var/obj/item/alien_embryo/A = locate() in C
|
||||
var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]")
|
||||
client.images += I
|
||||
return
|
||||
|
||||
/*----------------------------------------
|
||||
Proc: RemoveInfectionImages()
|
||||
Des: Removes all infected images from the alien.
|
||||
----------------------------------------*/
|
||||
/mob/living/carbon/human/proc/RemoveInfectionImages()
|
||||
if (client)
|
||||
for(var/image/I in client.images)
|
||||
if(dd_hasprefix_case(I.icon_state, "infected"))
|
||||
qdel(I)
|
||||
return
|
||||
|
||||
@@ -162,6 +162,8 @@ Please contact me on #coderbus IRC. ~Carn x
|
||||
icon = stand_icon
|
||||
for(var/image/I in overlays_standing)
|
||||
overlays += I
|
||||
if(species.has_floating_eyes)
|
||||
overlays |= species.get_eyes(src)
|
||||
|
||||
if(lying && !species.prone_icon) //Only rotate them if we're not drawing a specific icon for being prone.
|
||||
var/matrix/M = matrix()
|
||||
|
||||
@@ -281,87 +281,3 @@
|
||||
/mob/living/carbon/slime/has_eyes()
|
||||
return 0
|
||||
|
||||
//////////////////////////////Old shit from metroids/RoRos, and the old cores, would not take much work to re-add them////////////////////////
|
||||
|
||||
/*
|
||||
// Basically this slime Core catalyzes reactions that normally wouldn't happen anywhere
|
||||
/obj/item/slime_core
|
||||
name = "slime extract"
|
||||
desc = "Goo extracted from a slime. Legends claim these to have \"magical powers\"."
|
||||
icon = 'icons/mob/slimes.dmi'
|
||||
icon_state = "slime extract"
|
||||
force = 1.0
|
||||
w_class = 1.0
|
||||
throwforce = 1.0
|
||||
throw_speed = 2
|
||||
throw_range = 6
|
||||
origin_tech = list(TECH_BIO = 4)
|
||||
var/POWERFLAG = 0 // sshhhhhhh
|
||||
var/Flush = 30
|
||||
var/Uses = 5 // uses before it goes inert
|
||||
|
||||
/obj/item/slime_core/New()
|
||||
..()
|
||||
create_reagents(100)
|
||||
POWERFLAG = rand(1,10)
|
||||
Uses = rand(7, 25)
|
||||
//flags |= NOREACT
|
||||
/*
|
||||
spawn()
|
||||
Life()
|
||||
|
||||
proc/Life()
|
||||
while(src)
|
||||
sleep(25)
|
||||
Flush--
|
||||
if(Flush <= 0)
|
||||
reagents.clear_reagents()
|
||||
Flush = 30
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/egg/slime
|
||||
name = "slime egg"
|
||||
desc = "A small, gelatinous egg."
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
icon_state = "slime egg-growing"
|
||||
bitesize = 12
|
||||
origin_tech = list(TECH_BIO = 4)
|
||||
var/grown = 0
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/egg/slime/New()
|
||||
..()
|
||||
reagents.add_reagent("nutriment", 4)
|
||||
reagents.add_reagent("slimejelly", 1)
|
||||
spawn(rand(1200,1500))//the egg takes a while to "ripen"
|
||||
Grow()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/egg/slime/proc/Grow()
|
||||
grown = 1
|
||||
icon_state = "slime egg-grown"
|
||||
processing_objects.Add(src)
|
||||
return
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/egg/slime/proc/Hatch()
|
||||
processing_objects.Remove(src)
|
||||
var/turf/T = get_turf(src)
|
||||
src.visible_message("<span class='warning'> The [name] pulsates and quivers!</span>")
|
||||
spawn(rand(50,100))
|
||||
src.visible_message("<span class='warning'> The [name] bursts open!</span>")
|
||||
new/mob/living/carbon/slime(T)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/egg/slime/process()
|
||||
var/turf/location = get_turf(src)
|
||||
var/datum/gas_mixture/environment = location.return_air()
|
||||
if (environment.phoron > MOLES_PHORON_VISIBLE)//phoron exposure causes the egg to hatch
|
||||
src.Hatch()
|
||||
|
||||
/obj/item/weapon/reagent_containers/food/snacks/egg/slime/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||
if(istype( W, /obj/item/weapon/pen/crayon ))
|
||||
return
|
||||
else
|
||||
..()
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
var/obj/item/inventory_head
|
||||
var/obj/item/inventory_back
|
||||
var/facehugger
|
||||
|
||||
//IAN! SQUEEEEEEEEE~
|
||||
/mob/living/simple_animal/corgi/Ian
|
||||
@@ -123,13 +122,6 @@
|
||||
var/icon/back_icon = image('icons/mob/corgi_back.dmi',back_icon_state)
|
||||
if(back_icon)
|
||||
overlays += back_icon
|
||||
|
||||
if(facehugger)
|
||||
if(istype(src, /mob/living/simple_animal/corgi/puppy))
|
||||
overlays += image('icons/mob/mask.dmi',"facehugger_corgipuppy")
|
||||
else
|
||||
overlays += image('icons/mob/mask.dmi',"facehugger_corgi")
|
||||
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -161,30 +161,6 @@
|
||||
qdel(src)
|
||||
return O
|
||||
|
||||
//human -> alien
|
||||
/mob/living/carbon/human/proc/Alienize()
|
||||
if (transforming)
|
||||
return
|
||||
for(var/obj/item/W in src)
|
||||
drop_from_inventory(W)
|
||||
regenerate_icons()
|
||||
transforming = 1
|
||||
canmove = 0
|
||||
icon = null
|
||||
invisibility = 101
|
||||
for(var/t in organs)
|
||||
qdel(t)
|
||||
|
||||
var/alien_caste = pick("Hunter","Sentinel","Drone")
|
||||
var/mob/living/carbon/human/new_xeno = create_new_xenomorph(alien_caste,loc)
|
||||
|
||||
new_xeno.a_intent = I_HURT
|
||||
new_xeno.key = key
|
||||
|
||||
new_xeno << "<B>You are now an alien.</B>"
|
||||
qdel(src)
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/slimeize(adult as num, reproduce as num)
|
||||
if (transforming)
|
||||
return
|
||||
|
||||
@@ -939,11 +939,14 @@ Note that amputating the affected organ does in fact remove the infection from t
|
||||
/obj/item/organ/external/proc/is_malfunctioning()
|
||||
return ((status & ORGAN_ROBOT) && (brute_dam + burn_dam) >= 10 && prob(brute_dam + burn_dam))
|
||||
|
||||
/obj/item/organ/external/proc/embed(var/obj/item/weapon/W, var/silent = 0)
|
||||
/obj/item/organ/external/proc/embed(var/obj/item/weapon/W, var/silent = 0, var/supplied_message)
|
||||
if(!owner || loc != owner)
|
||||
return
|
||||
if(!silent)
|
||||
owner.visible_message("<span class='danger'>\The [W] sticks in the wound!</span>")
|
||||
if(supplied_message)
|
||||
owner.visible_message("<span class='danger'>[supplied_message]</span>")
|
||||
else
|
||||
owner.visible_message("<span class='danger'>\The [W] sticks in the wound!</span>")
|
||||
implants += W
|
||||
owner.embedded_flag = 1
|
||||
owner.verbs += /mob/proc/yank_out_object
|
||||
|
||||
@@ -175,11 +175,7 @@
|
||||
W.visible_message("<span class='notice'>The fungi are completely dissolved by the solution!</span>")
|
||||
|
||||
/datum/reagent/toxin/plantbgone/touch_obj(var/obj/O, var/volume)
|
||||
if(istype(O, /obj/effect/alien/weeds/))
|
||||
var/obj/effect/alien/weeds/alien_weeds = O
|
||||
alien_weeds.health -= rand(15, 35)
|
||||
alien_weeds.healthcheck()
|
||||
else if(istype(O, /obj/effect/plant))
|
||||
if(istype(O, /obj/effect/plant))
|
||||
qdel(O)
|
||||
|
||||
/datum/reagent/toxin/plantbgone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||
|
||||
@@ -12,46 +12,6 @@
|
||||
var/obj/item/organ/external/affected = target.get_organ(target_zone)
|
||||
return affected && affected.open == (affected.encased ? 3 : 2)
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// ALIEN EMBRYO SURGERY //
|
||||
//////////////////////////////////////////////////////////////////
|
||||
/datum/surgery_step/internal/remove_embryo
|
||||
allowed_tools = list(
|
||||
/obj/item/weapon/hemostat = 100, \
|
||||
/obj/item/weapon/wirecutters = 75, \
|
||||
/obj/item/weapon/material/kitchen/utensil/fork = 20
|
||||
)
|
||||
blood_level = 2
|
||||
|
||||
min_duration = 80
|
||||
max_duration = 100
|
||||
|
||||
can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/embryo = 0
|
||||
for(var/obj/item/alien_embryo/A in target)
|
||||
embryo = 1
|
||||
break
|
||||
|
||||
if (!hasorgans(target))
|
||||
return
|
||||
var/obj/item/organ/external/affected = target.get_organ(target_zone)
|
||||
return ..() && affected && embryo && affected.open == 3 && target_zone == "chest"
|
||||
|
||||
begin_step(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
var/msg = "[user] starts to pull something out from [target]'s ribcage with \the [tool]."
|
||||
var/self_msg = "You start to pull something out from [target]'s ribcage with \the [tool]."
|
||||
user.visible_message(msg, self_msg)
|
||||
target.custom_pain("Something hurts horribly in your chest!",1)
|
||||
..()
|
||||
|
||||
end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool)
|
||||
user.visible_message("\red [user] rips the larva out of [target]'s ribcage!",
|
||||
"You rip the larva out of [target]'s ribcage!")
|
||||
|
||||
for(var/obj/item/alien_embryo/A in target)
|
||||
A.loc = A.loc.loc
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// CHEST INTERNAL ORGAN SURGERY //
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
Reference in New Issue
Block a user