mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 10:12:45 +00:00
Brings back the aliens as they were when removed, minus huggers (until we can get a suitable replacement), for admins to use.
This commit is contained in:
@@ -63,6 +63,7 @@ var/list/be_special_flags = list(
|
|||||||
|
|
||||||
// Mode/antag template macros.
|
// Mode/antag template macros.
|
||||||
#define MODE_BORER "borer"
|
#define MODE_BORER "borer"
|
||||||
|
#define MODE_XENOMORPH "xeno"
|
||||||
#define MODE_LOYALIST "loyalist"
|
#define MODE_LOYALIST "loyalist"
|
||||||
#define MODE_MUTINEER "mutineer"
|
#define MODE_MUTINEER "mutineer"
|
||||||
#define MODE_COMMANDO "commando"
|
#define MODE_COMMANDO "commando"
|
||||||
|
|||||||
47
code/game/antagonist/alien/xenomorph.dm
Normal file
47
code/game/antagonist/alien/xenomorph.dm
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
var/datum/antagonist/xenos/xenomorphs
|
||||||
|
|
||||||
|
/datum/antagonist/xenos
|
||||||
|
id = MODE_XENOMORPH
|
||||||
|
role_type = BE_ALIEN
|
||||||
|
role_text = "Xenomorph"
|
||||||
|
role_text_plural = "Xenomorphs"
|
||||||
|
mob_path = /mob/living/carbon/alien/larva
|
||||||
|
bantype = "Xenomorph"
|
||||||
|
flags = ANTAG_OVERRIDE_MOB | ANTAG_RANDSPAWN | ANTAG_OVERRIDE_JOB | ANTAG_VOTABLE
|
||||||
|
welcome_text = "Hiss! You are a larval alien. Hide and bide your time until you are ready to evolve."
|
||||||
|
antaghud_indicator = "hudalien"
|
||||||
|
|
||||||
|
hard_cap = 5
|
||||||
|
hard_cap_round = 8
|
||||||
|
initial_spawn_req = 4
|
||||||
|
initial_spawn_target = 6
|
||||||
|
|
||||||
|
spawn_announcement = "Unidentified lifesigns detected coming aboard the station. Secure any exterior access, including ducting and ventilation."
|
||||||
|
spawn_announcement_title = "Lifesign Alert"
|
||||||
|
spawn_announcement_sound = 'sound/AI/aliens.ogg'
|
||||||
|
spawn_announcement_delay = 5000
|
||||||
|
|
||||||
|
/datum/antagonist/xenos/New(var/no_reference)
|
||||||
|
..()
|
||||||
|
if(!no_reference)
|
||||||
|
xenomorphs = src
|
||||||
|
|
||||||
|
/datum/antagonist/xenos/attempt_random_spawn()
|
||||||
|
if(config.aliens_allowed) ..()
|
||||||
|
|
||||||
|
/datum/antagonist/xenos/proc/get_vents()
|
||||||
|
var/list/vents = list()
|
||||||
|
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in machines)
|
||||||
|
if(!temp_vent.welded && temp_vent.network && temp_vent.loc.z in using_map.station_levels)
|
||||||
|
if(temp_vent.network.normal_members.len > 50)
|
||||||
|
vents += temp_vent
|
||||||
|
return vents
|
||||||
|
|
||||||
|
/datum/antagonist/xenos/create_objectives(var/datum/mind/player)
|
||||||
|
if(!..())
|
||||||
|
return
|
||||||
|
player.objectives += new /datum/objective/survive()
|
||||||
|
player.objectives += new /datum/objective/escape()
|
||||||
|
|
||||||
|
/datum/antagonist/xenos/place_mob(var/mob/living/player)
|
||||||
|
player.forceMove(get_turf(pick(get_vents())))
|
||||||
@@ -525,7 +525,7 @@ var/list/turret_icons
|
|||||||
if(isanimal(L) || issmall(L)) // Animals are not so dangerous
|
if(isanimal(L) || issmall(L)) // Animals are not so dangerous
|
||||||
return check_anomalies ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET
|
return check_anomalies ? TURRET_SECONDARY_TARGET : TURRET_NOT_TARGET
|
||||||
|
|
||||||
if(isalien(L)) // Xenos are dangerous
|
if(isxenomorph(L) || isalien(L)) // Xenos are dangerous
|
||||||
return check_anomalies ? TURRET_PRIORITY_TARGET : TURRET_NOT_TARGET
|
return check_anomalies ? TURRET_PRIORITY_TARGET : TURRET_NOT_TARGET
|
||||||
|
|
||||||
if(ishuman(L)) //if the target is a human, analyze threat level
|
if(ishuman(L)) //if the target is a human, analyze threat level
|
||||||
|
|||||||
443
code/game/objects/effects/alien/aliens.dm
Normal file
443
code/game/objects/effects/alien/aliens.dm
Normal file
@@ -0,0 +1,443 @@
|
|||||||
|
/* Alien Effects!
|
||||||
|
* Contains:
|
||||||
|
* effect/alien
|
||||||
|
* Resin
|
||||||
|
* Weeds
|
||||||
|
* Acid
|
||||||
|
* Egg
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* effect/alien
|
||||||
|
*/
|
||||||
|
/obj/effect/alien
|
||||||
|
name = "alien thing"
|
||||||
|
desc = "theres something alien about this"
|
||||||
|
icon = 'icons/mob/alien.dmi'
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Resin
|
||||||
|
*/
|
||||||
|
/obj/effect/alien/resin
|
||||||
|
name = "resin"
|
||||||
|
desc = "Looks like some kind of slimy growth."
|
||||||
|
icon_state = "resin"
|
||||||
|
|
||||||
|
density = 1
|
||||||
|
opacity = 1
|
||||||
|
anchored = 1
|
||||||
|
var/health = 200
|
||||||
|
//var/mob/living/affecting = null
|
||||||
|
|
||||||
|
/obj/effect/alien/resin/wall
|
||||||
|
name = "resin wall"
|
||||||
|
desc = "Purple slime solidified into a wall."
|
||||||
|
icon_state = "resinwall" //same as resin, but consistency ho!
|
||||||
|
|
||||||
|
/obj/effect/alien/resin/membrane
|
||||||
|
name = "resin membrane"
|
||||||
|
desc = "Purple slime just thin enough to let light pass through."
|
||||||
|
icon_state = "resinmembrane"
|
||||||
|
opacity = 0
|
||||||
|
health = 120
|
||||||
|
|
||||||
|
/obj/effect/alien/resin/New()
|
||||||
|
..()
|
||||||
|
var/turf/T = get_turf(src)
|
||||||
|
T.thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
|
||||||
|
|
||||||
|
/obj/effect/alien/resin/Destroy()
|
||||||
|
var/turf/T = get_turf(src)
|
||||||
|
T.thermal_conductivity = initial(T.thermal_conductivity)
|
||||||
|
..()
|
||||||
|
|
||||||
|
/obj/effect/alien/resin/proc/healthcheck()
|
||||||
|
if(health <=0)
|
||||||
|
density = 0
|
||||||
|
qdel(src)
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/effect/alien/resin/bullet_act(var/obj/item/projectile/Proj)
|
||||||
|
health -= Proj.damage
|
||||||
|
..()
|
||||||
|
healthcheck()
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/effect/alien/resin/ex_act(severity)
|
||||||
|
switch(severity)
|
||||||
|
if(1.0)
|
||||||
|
health-=50
|
||||||
|
if(2.0)
|
||||||
|
health-=50
|
||||||
|
if(3.0)
|
||||||
|
if (prob(50))
|
||||||
|
health-=50
|
||||||
|
else
|
||||||
|
health-=25
|
||||||
|
healthcheck()
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/effect/alien/resin/hitby(AM as mob|obj)
|
||||||
|
..()
|
||||||
|
for(var/mob/O in viewers(src, null))
|
||||||
|
O.show_message("<span class='danger'>[src] was hit by [AM].</span>", 1)
|
||||||
|
var/tforce = 0
|
||||||
|
if(ismob(AM))
|
||||||
|
tforce = 10
|
||||||
|
else
|
||||||
|
tforce = AM:throwforce
|
||||||
|
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
|
||||||
|
health = max(0, health - tforce)
|
||||||
|
healthcheck()
|
||||||
|
..()
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/effect/alien/resin/attack_hand()
|
||||||
|
usr.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||||
|
if (HULK in usr.mutations)
|
||||||
|
usr << "<span class='notice'>You easily destroy the [name].</span>"
|
||||||
|
for(var/mob/O in oviewers(src))
|
||||||
|
O.show_message("<span class='warning'>[usr] destroys the [name]!</span>", 1)
|
||||||
|
health = 0
|
||||||
|
else
|
||||||
|
|
||||||
|
// Aliens can get straight through these.
|
||||||
|
if(istype(usr,/mob/living/carbon))
|
||||||
|
var/mob/living/carbon/M = usr
|
||||||
|
if(locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs)
|
||||||
|
for(var/mob/O in oviewers(src))
|
||||||
|
O.show_message("<span class='warning'>[usr] strokes the [name] and it melts away!</span>", 1)
|
||||||
|
health = 0
|
||||||
|
healthcheck()
|
||||||
|
return
|
||||||
|
|
||||||
|
usr << "<span class='notice'>You claw at the [name].</span>"
|
||||||
|
for(var/mob/O in oviewers(src))
|
||||||
|
O.show_message("<span class='warning'>[usr] claws at the [name]!</span>", 1)
|
||||||
|
health -= rand(5,10)
|
||||||
|
healthcheck()
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/effect/alien/resin/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||||
|
|
||||||
|
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||||
|
var/aforce = W.force
|
||||||
|
health = max(0, health - aforce)
|
||||||
|
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
|
||||||
|
healthcheck()
|
||||||
|
..()
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/effect/alien/resin/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
|
||||||
|
if(air_group) return 0
|
||||||
|
if(istype(mover) && mover.checkpass(PASSGLASS))
|
||||||
|
return !opacity
|
||||||
|
return !density
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Weeds
|
||||||
|
*/
|
||||||
|
#define NODERANGE 3
|
||||||
|
|
||||||
|
/obj/effect/alien/weeds
|
||||||
|
name = "weeds"
|
||||||
|
desc = "Weird purple weeds."
|
||||||
|
icon_state = "weeds"
|
||||||
|
|
||||||
|
anchored = 1
|
||||||
|
density = 0
|
||||||
|
layer = 2
|
||||||
|
var/health = 15
|
||||||
|
var/obj/effect/alien/weeds/node/linked_node = null
|
||||||
|
|
||||||
|
/obj/effect/alien/weeds/node
|
||||||
|
icon_state = "weednode"
|
||||||
|
name = "purple sac"
|
||||||
|
desc = "Weird purple octopus-like thing."
|
||||||
|
layer = 3
|
||||||
|
light_range = NODERANGE
|
||||||
|
var/node_range = NODERANGE
|
||||||
|
|
||||||
|
/obj/effect/alien/weeds/node/New()
|
||||||
|
..(src.loc, src)
|
||||||
|
|
||||||
|
|
||||||
|
/obj/effect/alien/weeds/New(pos, node)
|
||||||
|
..()
|
||||||
|
if(istype(loc, /turf/space))
|
||||||
|
qdel(src)
|
||||||
|
return
|
||||||
|
linked_node = node
|
||||||
|
if(icon_state == "weeds")icon_state = pick("weeds", "weeds1", "weeds2")
|
||||||
|
spawn(rand(150, 200))
|
||||||
|
if(src)
|
||||||
|
Life()
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/effect/alien/weeds/proc/Life()
|
||||||
|
set background = 1
|
||||||
|
var/turf/U = get_turf(src)
|
||||||
|
/*
|
||||||
|
if (locate(/obj/movable, U))
|
||||||
|
U = locate(/obj/movable, U)
|
||||||
|
if(U.density == 1)
|
||||||
|
qdel(src)
|
||||||
|
return
|
||||||
|
Alien plants should do something if theres a lot of poison
|
||||||
|
if(U.poison> 200000)
|
||||||
|
health -= round(U.poison/200000)
|
||||||
|
update()
|
||||||
|
return
|
||||||
|
*/
|
||||||
|
if (istype(U, /turf/space))
|
||||||
|
qdel(src)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!linked_node || (get_dist(linked_node, src) > linked_node.node_range) )
|
||||||
|
return
|
||||||
|
|
||||||
|
direction_loop:
|
||||||
|
for(var/dirn in cardinal)
|
||||||
|
var/turf/T = get_step(src, dirn)
|
||||||
|
|
||||||
|
if (!istype(T) || T.density || locate(/obj/effect/alien/weeds) in T || istype(T.loc, /area/arrival) || istype(T, /turf/space))
|
||||||
|
continue
|
||||||
|
|
||||||
|
// if (locate(/obj/movable, T)) // don't propogate into movables
|
||||||
|
// continue
|
||||||
|
|
||||||
|
for(var/obj/O in T)
|
||||||
|
if(O.density)
|
||||||
|
continue direction_loop
|
||||||
|
|
||||||
|
new /obj/effect/alien/weeds(T, linked_node)
|
||||||
|
|
||||||
|
|
||||||
|
/obj/effect/alien/weeds/ex_act(severity)
|
||||||
|
switch(severity)
|
||||||
|
if(1.0)
|
||||||
|
qdel(src)
|
||||||
|
if(2.0)
|
||||||
|
if (prob(50))
|
||||||
|
qdel(src)
|
||||||
|
if(3.0)
|
||||||
|
if (prob(5))
|
||||||
|
qdel(src)
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/effect/alien/weeds/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||||
|
user.setClickCooldown(DEFAULT_ATTACK_COOLDOWN)
|
||||||
|
if(W.attack_verb.len)
|
||||||
|
visible_message("<span class='danger'>\The [src] have been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]</span>")
|
||||||
|
else
|
||||||
|
visible_message("<span class='danger'>\The [src] have been attacked with \the [W][(user ? " by [user]." : ".")]</span>")
|
||||||
|
|
||||||
|
var/damage = W.force / 4.0
|
||||||
|
|
||||||
|
if(istype(W, /obj/item/weapon/weldingtool))
|
||||||
|
var/obj/item/weapon/weldingtool/WT = W
|
||||||
|
|
||||||
|
if(WT.remove_fuel(0, user))
|
||||||
|
damage = 15
|
||||||
|
playsound(loc, 'sound/items/Welder.ogg', 100, 1)
|
||||||
|
|
||||||
|
health -= damage
|
||||||
|
healthcheck()
|
||||||
|
|
||||||
|
/obj/effect/alien/weeds/proc/healthcheck()
|
||||||
|
if(health <= 0)
|
||||||
|
qdel(src)
|
||||||
|
|
||||||
|
|
||||||
|
/obj/effect/alien/weeds/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||||
|
if(exposed_temperature > 300 + T0C)
|
||||||
|
health -= 5
|
||||||
|
healthcheck()
|
||||||
|
|
||||||
|
#undef NODERANGE
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Acid
|
||||||
|
*/
|
||||||
|
/obj/effect/alien/acid
|
||||||
|
name = "acid"
|
||||||
|
desc = "Burbling corrossive stuff. I wouldn't want to touch it."
|
||||||
|
icon_state = "acid"
|
||||||
|
|
||||||
|
density = 0
|
||||||
|
opacity = 0
|
||||||
|
anchored = 1
|
||||||
|
|
||||||
|
var/atom/target
|
||||||
|
var/ticks = 0
|
||||||
|
var/target_strength = 0
|
||||||
|
|
||||||
|
/obj/effect/alien/acid/New(loc, target)
|
||||||
|
..(loc)
|
||||||
|
src.target = target
|
||||||
|
|
||||||
|
if(isturf(target)) // Turf take twice as long to take down.
|
||||||
|
target_strength = 8
|
||||||
|
else
|
||||||
|
target_strength = 4
|
||||||
|
tick()
|
||||||
|
|
||||||
|
/obj/effect/alien/acid/proc/tick()
|
||||||
|
if(!target)
|
||||||
|
qdel(src)
|
||||||
|
|
||||||
|
ticks += 1
|
||||||
|
|
||||||
|
if(ticks >= target_strength)
|
||||||
|
|
||||||
|
for(var/mob/O in hearers(src, null))
|
||||||
|
O.show_message("<span class='alium'>[src.target] collapses under its own weight into a puddle of goop and undigested debris!</span>", 1)
|
||||||
|
|
||||||
|
if(istype(target, /turf/simulated/wall)) // I hate turf code.
|
||||||
|
var/turf/simulated/wall/W = target
|
||||||
|
W.dismantle_wall(1)
|
||||||
|
else
|
||||||
|
qdel(target)
|
||||||
|
qdel(src)
|
||||||
|
return
|
||||||
|
|
||||||
|
switch(target_strength - ticks)
|
||||||
|
if(6)
|
||||||
|
visible_message("<span class='alium'>[src.target] is holding up against the acid!</span>")
|
||||||
|
if(4)
|
||||||
|
visible_message("<span class='alium'>[src.target]\s structure is being melted by the acid!</span>")
|
||||||
|
if(2)
|
||||||
|
visible_message("<span class='alium'>[src.target] is struggling to withstand the acid!</span>")
|
||||||
|
if(0 to 1)
|
||||||
|
visible_message("<span class='alium'>[src.target] begins to crumble under the acid!</span>")
|
||||||
|
spawn(rand(150, 200)) tick()
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Egg
|
||||||
|
*/
|
||||||
|
/var/const //for the status var
|
||||||
|
BURST = 0
|
||||||
|
BURSTING = 1
|
||||||
|
GROWING = 2
|
||||||
|
GROWN = 3
|
||||||
|
|
||||||
|
MIN_GROWTH_TIME = 1800 //time it takes to grow a hugger
|
||||||
|
MAX_GROWTH_TIME = 3000
|
||||||
|
|
||||||
|
/obj/effect/alien/egg
|
||||||
|
desc = "It looks like a weird egg"
|
||||||
|
name = "egg"
|
||||||
|
// icon_state = "egg_growing" // So the egg looks 'grown', even though it's not.
|
||||||
|
icon_state = "egg"
|
||||||
|
density = 0
|
||||||
|
anchored = 1
|
||||||
|
|
||||||
|
var/health = 100
|
||||||
|
var/status = BURST //can be GROWING, GROWN or BURST; all mutually exclusive
|
||||||
|
flags = PROXMOVE
|
||||||
|
|
||||||
|
/obj/effect/alien/egg/New()
|
||||||
|
/*
|
||||||
|
if(config.aliens_allowed)
|
||||||
|
..()
|
||||||
|
spawn(rand(MIN_GROWTH_TIME,MAX_GROWTH_TIME))
|
||||||
|
Grow()
|
||||||
|
else
|
||||||
|
qdel(src)
|
||||||
|
*/
|
||||||
|
/obj/effect/alien/egg/attack_hand(user as mob)
|
||||||
|
|
||||||
|
var/mob/living/carbon/M = user
|
||||||
|
if(!istype(M) || !(locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs))
|
||||||
|
return attack_hand(user)
|
||||||
|
|
||||||
|
switch(status)
|
||||||
|
if(BURST)
|
||||||
|
user << "<span class='warning'>You clear the hatched egg.</span>"
|
||||||
|
qdel(src)
|
||||||
|
return
|
||||||
|
/* if(GROWING)
|
||||||
|
user << "<span class='warning'>The child is not developed yet.</span>"
|
||||||
|
return
|
||||||
|
if(GROWN)
|
||||||
|
user << "<span class='warning'>You retrieve the child.</span>"
|
||||||
|
Burst(0)
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/effect/alien/egg/proc/GetFacehugger() // Commented out for future edit.
|
||||||
|
return locate(/obj/item/clothing/mask/facehugger) in contents
|
||||||
|
|
||||||
|
/obj/effect/alien/egg/proc/Grow()
|
||||||
|
icon_state = "egg"
|
||||||
|
// status = GROWN
|
||||||
|
status = BURST
|
||||||
|
// new /obj/item/clothing/mask/facehugger(src)
|
||||||
|
return
|
||||||
|
*/
|
||||||
|
/obj/effect/alien/egg/proc/Burst(var/kill = 1) //drops and kills the hugger if any is remaining
|
||||||
|
if(status == GROWN || status == GROWING)
|
||||||
|
// var/obj/item/clothing/mask/facehugger/child = GetFacehugger()
|
||||||
|
icon_state = "egg_hatched"
|
||||||
|
/* flick("egg_opening", src)
|
||||||
|
status = BURSTING
|
||||||
|
spawn(15)
|
||||||
|
status = BURST
|
||||||
|
child.loc = get_turf(src)
|
||||||
|
|
||||||
|
if(kill && istype(child))
|
||||||
|
child.Die()
|
||||||
|
else
|
||||||
|
for(var/mob/M in range(1,src))
|
||||||
|
if(CanHug(M))
|
||||||
|
child.Attach(M)
|
||||||
|
break
|
||||||
|
*/
|
||||||
|
/obj/effect/alien/egg/bullet_act(var/obj/item/projectile/Proj)
|
||||||
|
health -= Proj.damage
|
||||||
|
..()
|
||||||
|
healthcheck()
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
/obj/effect/alien/egg/attackby(var/obj/item/weapon/W, var/mob/user)
|
||||||
|
if(health <= 0)
|
||||||
|
return
|
||||||
|
if(W.attack_verb.len)
|
||||||
|
src.visible_message("<span class='danger'>\The [src] has been [pick(W.attack_verb)] with \the [W][(user ? " by [user]." : ".")]</span>")
|
||||||
|
else
|
||||||
|
src.visible_message("<span class='danger'>\The [src] has been attacked with \the [W][(user ? " by [user]." : ".")]</span>")
|
||||||
|
var/damage = W.force / 4.0
|
||||||
|
|
||||||
|
if(istype(W, /obj/item/weapon/weldingtool))
|
||||||
|
var/obj/item/weapon/weldingtool/WT = W
|
||||||
|
|
||||||
|
if(WT.remove_fuel(0, user))
|
||||||
|
damage = 15
|
||||||
|
playsound(src.loc, 'sound/items/Welder.ogg', 100, 1)
|
||||||
|
|
||||||
|
src.health -= damage
|
||||||
|
src.healthcheck()
|
||||||
|
|
||||||
|
|
||||||
|
/obj/effect/alien/egg/proc/healthcheck()
|
||||||
|
if(health <= 0)
|
||||||
|
Burst()
|
||||||
|
|
||||||
|
/obj/effect/alien/egg/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||||
|
if(exposed_temperature > 500 + T0C)
|
||||||
|
health -= 5
|
||||||
|
healthcheck()
|
||||||
|
/*
|
||||||
|
/obj/effect/alien/egg/HasProximity(atom/movable/AM as mob|obj)
|
||||||
|
if(status == GROWN)
|
||||||
|
if(!CanHug(AM))
|
||||||
|
return
|
||||||
|
|
||||||
|
var/mob/living/carbon/C = AM
|
||||||
|
if(C.stat == CONSCIOUS && C.status_flags & XENO_HOST)
|
||||||
|
return
|
||||||
|
|
||||||
|
Burst(0)
|
||||||
|
*/
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
#define NEST_RESIST_TIME 1200
|
||||||
|
|
||||||
|
/obj/structure/bed/nest
|
||||||
|
name = "alien nest"
|
||||||
|
desc = "It's a gruesome pile of thick, sticky resin shaped like a nest."
|
||||||
|
icon = 'icons/mob/alien.dmi'
|
||||||
|
icon_state = "nest"
|
||||||
|
var/health = 100
|
||||||
|
|
||||||
|
/obj/structure/bed/nest/update_icon()
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/structure/bed/nest/user_unbuckle_mob(mob/user as mob)
|
||||||
|
if(buckled_mob)
|
||||||
|
if(buckled_mob.buckled == src)
|
||||||
|
if(buckled_mob != user)
|
||||||
|
buckled_mob.visible_message(\
|
||||||
|
"<span class='notice'>[user.name] pulls [buckled_mob.name] free from the sticky nest!</span>",\
|
||||||
|
"<span class='notice'>[user.name] pulls you free from the gelatinous resin.</span>",\
|
||||||
|
"<span class='notice'>You hear squelching...</span>")
|
||||||
|
buckled_mob.pixel_y = 0
|
||||||
|
buckled_mob.old_y = 0
|
||||||
|
unbuckle_mob()
|
||||||
|
else
|
||||||
|
if(world.time <= buckled_mob.last_special+NEST_RESIST_TIME)
|
||||||
|
return
|
||||||
|
buckled_mob.last_special = world.time
|
||||||
|
buckled_mob.visible_message(\
|
||||||
|
"<span class='warning'>[buckled_mob.name] struggles to break free of the gelatinous resin...</span>",\
|
||||||
|
"<span class='warning'>You struggle to break free from the gelatinous resin...</span>",\
|
||||||
|
"<span class='notice'>You hear squelching...</span>")
|
||||||
|
spawn(NEST_RESIST_TIME)
|
||||||
|
if(user && buckled_mob && user.buckled == src)
|
||||||
|
buckled_mob.last_special = world.time
|
||||||
|
buckled_mob.pixel_y = 0
|
||||||
|
buckled_mob.old_y = 0
|
||||||
|
unbuckle_mob()
|
||||||
|
src.add_fingerprint(user)
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/structure/bed/nest/user_buckle_mob(mob/M as mob, mob/user as mob)
|
||||||
|
if ( !ismob(M) || (get_dist(src, user) > 1) || (M.loc != src.loc) || user.restrained() || usr.stat || M.buckled || istype(user, /mob/living/silicon/pai) )
|
||||||
|
return
|
||||||
|
|
||||||
|
unbuckle_mob()
|
||||||
|
|
||||||
|
var/mob/living/carbon/xenos = user
|
||||||
|
var/mob/living/carbon/victim = M
|
||||||
|
|
||||||
|
if(istype(victim) && locate(/obj/item/organ/internal/xenos/hivenode) in victim.internal_organs)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(istype(xenos) && !(locate(/obj/item/organ/internal/xenos/hivenode) in xenos.internal_organs))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(M == usr)
|
||||||
|
return
|
||||||
|
else
|
||||||
|
M.visible_message(\
|
||||||
|
"<span class='notice'>[user.name] secretes a thick vile goo, securing [M.name] into [src]!</span>",\
|
||||||
|
"<span class='warning'>[user.name] drenches you in a foul-smelling resin, trapping you in the [src]!</span>",\
|
||||||
|
"<span class='notice'>You hear squelching...</span>")
|
||||||
|
M.buckled = src
|
||||||
|
M.loc = src.loc
|
||||||
|
M.set_dir(src.dir)
|
||||||
|
M.update_canmove()
|
||||||
|
M.pixel_y = 6
|
||||||
|
M.old_y = 6
|
||||||
|
src.buckled_mob = M
|
||||||
|
src.add_fingerprint(user)
|
||||||
|
return
|
||||||
|
|
||||||
|
/obj/structure/bed/nest/attackby(obj/item/weapon/W as obj, mob/user as mob)
|
||||||
|
var/aforce = W.force
|
||||||
|
health = max(0, health - aforce)
|
||||||
|
playsound(loc, 'sound/effects/attackblob.ogg', 100, 1)
|
||||||
|
for(var/mob/M in viewers(src, 7))
|
||||||
|
M.show_message("<span class='warning'>[user] hits [src] with [W]!</span>", 1)
|
||||||
|
healthcheck()
|
||||||
|
|
||||||
|
/obj/structure/bed/nest/proc/healthcheck()
|
||||||
|
if(health <=0)
|
||||||
|
density = 0
|
||||||
|
qdel(src)
|
||||||
|
return
|
||||||
@@ -146,6 +146,11 @@ proc/admin_notice(var/message, var/rights)
|
|||||||
body += {"<br><br>
|
body += {"<br><br>
|
||||||
<b>Rudimentary transformation:</b><font size=2><br>These transformations only create a new mob type and copy stuff over. They do not take into account MMIs and similar mob-specific things. The buttons in 'Transformations' are preferred, when possible.</font><br>
|
<b>Rudimentary transformation:</b><font size=2><br>These transformations only create a new mob type and copy stuff over. They do not take into account MMIs and similar mob-specific things. The buttons in 'Transformations' are preferred, when possible.</font><br>
|
||||||
<A href='?src=\ref[src];simplemake=observer;mob=\ref[M]'>Observer</A> |
|
<A href='?src=\ref[src];simplemake=observer;mob=\ref[M]'>Observer</A> |
|
||||||
|
\[ Xenos: <A href='?src=\ref[src];simplemake=larva;mob=\ref[M]'>Larva</A>
|
||||||
|
<A href='?src=\ref[src];simplemake=human;species=Xenomorph Drone;mob=\ref[M]'>Drone</A>
|
||||||
|
<A href='?src=\ref[src];simplemake=human;species=Xenomorph Hunter;mob=\ref[M]'>Hunter</A>
|
||||||
|
<A href='?src=\ref[src];simplemake=human;species=Xenomorph Sentinel;mob=\ref[M]'>Sentinel</A>
|
||||||
|
<A href='?src=\ref[src];simplemake=human;species=Xenomorph Queen;mob=\ref[M]'>Queen</A> \] |
|
||||||
\[ Crew: <A href='?src=\ref[src];simplemake=human;mob=\ref[M]'>Human</A>
|
\[ Crew: <A href='?src=\ref[src];simplemake=human;mob=\ref[M]'>Human</A>
|
||||||
<A href='?src=\ref[src];simplemake=human;species=Unathi;mob=\ref[M]'>Unathi</A>
|
<A href='?src=\ref[src];simplemake=human;species=Unathi;mob=\ref[M]'>Unathi</A>
|
||||||
<A href='?src=\ref[src];simplemake=human;species=Tajaran;mob=\ref[M]'>Tajaran</A>
|
<A href='?src=\ref[src];simplemake=human;species=Tajaran;mob=\ref[M]'>Tajaran</A>
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
/datum/admin_secret_item/random_event/trigger_xenomorph_infestation
|
||||||
|
name = "Trigger a Xenomorph Infestation"
|
||||||
|
|
||||||
|
/datum/admin_secret_item/random_event/trigger_xenomorph_infestation/execute(var/mob/user)
|
||||||
|
. = ..()
|
||||||
|
if(.)
|
||||||
|
return xenomorphs.attempt_random_spawn()
|
||||||
@@ -1146,6 +1146,16 @@
|
|||||||
log_admin("[key_name(usr)] AIized [key_name(H)]")
|
log_admin("[key_name(usr)] AIized [key_name(H)]")
|
||||||
H.AIize()
|
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"])
|
else if(href_list["makeslime"])
|
||||||
if(!check_rights(R_SPAWN)) return
|
if(!check_rights(R_SPAWN)) return
|
||||||
|
|
||||||
|
|||||||
@@ -100,6 +100,24 @@
|
|||||||
paiController.pai_candidates.Remove(candidate)
|
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!
|
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)
|
/client/proc/cmd_admin_slimeize(var/mob/M in mob_list)
|
||||||
set category = "Fun"
|
set category = "Fun"
|
||||||
set name = "Make slime"
|
set name = "Make slime"
|
||||||
|
|||||||
@@ -68,6 +68,7 @@
|
|||||||
<option value='?_src_=vars;makeai=\ref[src]'>Make AI</option>
|
<option value='?_src_=vars;makeai=\ref[src]'>Make AI</option>
|
||||||
<option value='?_src_=vars;makerobot=\ref[src]'>Make cyborg</option>
|
<option value='?_src_=vars;makerobot=\ref[src]'>Make cyborg</option>
|
||||||
<option value='?_src_=vars;makemonkey=\ref[src]'>Make monkey</option>
|
<option value='?_src_=vars;makemonkey=\ref[src]'>Make monkey</option>
|
||||||
|
<option value='?_src_=vars;makealien=\ref[src]'>Make alien</option>
|
||||||
<option value='?_src_=vars;makeslime=\ref[src]'>Make slime</option>
|
<option value='?_src_=vars;makeslime=\ref[src]'>Make slime</option>
|
||||||
"}
|
"}
|
||||||
|
|
||||||
|
|||||||
@@ -1170,3 +1170,23 @@
|
|||||||
set_trait(TRAIT_PRODUCTION,7)
|
set_trait(TRAIT_PRODUCTION,7)
|
||||||
set_trait(TRAIT_YIELD,3)
|
set_trait(TRAIT_YIELD,3)
|
||||||
set_trait(TRAIT_POTENCY,3)
|
set_trait(TRAIT_POTENCY,3)
|
||||||
|
|
||||||
|
// Alien weeds.
|
||||||
|
/datum/seed/xenomorph
|
||||||
|
name = "xenomorph"
|
||||||
|
seed_name = "alien weed"
|
||||||
|
display_name = "alien weeds"
|
||||||
|
force_layer = 3
|
||||||
|
chems = list("phoron" = list(1,3))
|
||||||
|
|
||||||
|
/datum/seed/xenomorph/New()
|
||||||
|
..()
|
||||||
|
set_trait(TRAIT_PLANT_ICON,"vine2")
|
||||||
|
set_trait(TRAIT_IMMUTABLE,1)
|
||||||
|
set_trait(TRAIT_PRODUCT_COLOUR,"#3D1934")
|
||||||
|
set_trait(TRAIT_FLESH_COLOUR,"#3D1934")
|
||||||
|
set_trait(TRAIT_PLANT_COLOUR,"#3D1934")
|
||||||
|
set_trait(TRAIT_PRODUCTION,1)
|
||||||
|
set_trait(TRAIT_YIELD,-1)
|
||||||
|
set_trait(TRAIT_SPREAD,2)
|
||||||
|
set_trait(TRAIT_POTENCY,50)
|
||||||
|
|||||||
@@ -642,6 +642,22 @@ var/list/name_to_material
|
|||||||
display_name = "elevator panelling"
|
display_name = "elevator panelling"
|
||||||
icon_colour = "#666666"
|
icon_colour = "#666666"
|
||||||
|
|
||||||
|
/material/resin
|
||||||
|
name = "resin"
|
||||||
|
icon_colour = "#E85DD8"
|
||||||
|
dooropen_noise = 'sound/effects/attackblob.ogg'
|
||||||
|
door_icon_base = "resin"
|
||||||
|
melting_point = T0C+300
|
||||||
|
sheet_singular_name = "blob"
|
||||||
|
sheet_plural_name = "blobs"
|
||||||
|
|
||||||
|
/material/resin/can_open_material_door(var/mob/living/user)
|
||||||
|
var/mob/living/carbon/M = user
|
||||||
|
if(istype(M) && locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs)
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
/material/wood
|
/material/wood
|
||||||
name = "wood"
|
name = "wood"
|
||||||
stack_type = /obj/item/stack/material/wood
|
stack_type = /obj/item/stack/material/wood
|
||||||
|
|||||||
@@ -84,3 +84,34 @@
|
|||||||
key = "y"
|
key = "y"
|
||||||
machine_understands = 0
|
machine_understands = 0
|
||||||
flags = RESTRICTED | HIVEMIND
|
flags = RESTRICTED | HIVEMIND
|
||||||
|
|
||||||
|
/datum/language/xenocommon
|
||||||
|
name = "Xenomorph"
|
||||||
|
colour = "alien"
|
||||||
|
desc = "The common tongue of the xenomorphs."
|
||||||
|
speech_verb = "hisses"
|
||||||
|
ask_verb = "hisses"
|
||||||
|
exclaim_verb = "hisses"
|
||||||
|
key = "4"
|
||||||
|
flags = RESTRICTED
|
||||||
|
syllables = list("sss","sSs","SSS")
|
||||||
|
|
||||||
|
/datum/language/xenos
|
||||||
|
name = "Hivemind"
|
||||||
|
desc = "Xenomorphs have the strange ability to commune over a psychic hivemind."
|
||||||
|
speech_verb = "hisses"
|
||||||
|
ask_verb = "hisses"
|
||||||
|
exclaim_verb = "hisses"
|
||||||
|
colour = "alien"
|
||||||
|
key = "a"
|
||||||
|
flags = RESTRICTED | HIVEMIND
|
||||||
|
|
||||||
|
/datum/language/xenos/check_special_condition(var/mob/other)
|
||||||
|
|
||||||
|
var/mob/living/carbon/M = other
|
||||||
|
if(!istype(M))
|
||||||
|
return 1
|
||||||
|
if(locate(/obj/item/organ/internal/xenos/hivenode) in M.internal_organs)
|
||||||
|
return 1
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|||||||
14
code/modules/mob/living/carbon/alien/larva/larva.dm
Normal file
14
code/modules/mob/living/carbon/alien/larva/larva.dm
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/mob/living/carbon/alien/larva
|
||||||
|
name = "alien larva"
|
||||||
|
real_name = "alien larva"
|
||||||
|
adult_form = /mob/living/carbon/human
|
||||||
|
speak_emote = list("hisses")
|
||||||
|
icon_state = "larva"
|
||||||
|
language = "Hivemind"
|
||||||
|
maxHealth = 25
|
||||||
|
health = 25
|
||||||
|
|
||||||
|
/mob/living/carbon/alien/larva/New()
|
||||||
|
..()
|
||||||
|
add_language("Xenomorph") //Bonus language.
|
||||||
|
internal_organs |= new /obj/item/organ/internal/xenos/hivenode(src)
|
||||||
13
code/modules/mob/living/carbon/alien/larva/life.dm
Normal file
13
code/modules/mob/living/carbon/alien/larva/life.dm
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
//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))
|
||||||
|
update_progression()
|
||||||
|
adjustBruteLoss(-1)
|
||||||
|
adjustFireLoss(-1)
|
||||||
|
adjustToxLoss(-1)
|
||||||
|
adjustOxyLoss(-1)
|
||||||
12
code/modules/mob/living/carbon/alien/larva/progression.dm
Normal file
12
code/modules/mob/living/carbon/alien/larva/progression.dm
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/mob/living/carbon/alien/larva/confirm_evolution()
|
||||||
|
|
||||||
|
src << "\blue <b>You are growing into a beautiful alien! It is time to choose a caste.</b>"
|
||||||
|
src << "\blue There are three to choose from:"
|
||||||
|
src << "<B>Hunters</B> \blue are strong and agile, able to hunt away from the hive and rapidly move through ventilation shafts. Hunters generate plasma slowly and have low reserves."
|
||||||
|
src << "<B>Sentinels</B> \blue are tasked with protecting the hive and are deadly up close and at a range. They are not as physically imposing nor fast as the hunters."
|
||||||
|
src << "<B>Drones</B> \blue are the working class, offering the largest plasma storage and generation. They are the only caste which may evolve again, turning into the dreaded alien queen."
|
||||||
|
var/alien_caste = alert(src, "Please choose which alien caste you shall belong to.",,"Hunter","Sentinel","Drone")
|
||||||
|
return alien_caste ? "Xenomorph [alien_caste]" : null
|
||||||
|
|
||||||
|
/mob/living/carbon/alien/larva/show_evolution_blurb()
|
||||||
|
return
|
||||||
@@ -78,6 +78,11 @@
|
|||||||
stat("Tank Pressure", internal.air_contents.return_pressure())
|
stat("Tank Pressure", internal.air_contents.return_pressure())
|
||||||
stat("Distribution Pressure", internal.distribute_pressure)
|
stat("Distribution Pressure", internal.distribute_pressure)
|
||||||
|
|
||||||
|
var/obj/item/organ/internal/xenos/plasmavessel/P = internal_organs_by_name[O_PLASMA] //Xenomorphs. Mech.
|
||||||
|
if(P)
|
||||||
|
stat(null, "Phoron Stored: [P.stored_plasma]/[P.max_plasma]")
|
||||||
|
|
||||||
|
|
||||||
if(back && istype(back,/obj/item/weapon/rig))
|
if(back && istype(back,/obj/item/weapon/rig))
|
||||||
var/obj/item/weapon/rig/suit = back
|
var/obj/item/weapon/rig/suit = back
|
||||||
var/cell_status = "ERROR"
|
var/cell_status = "ERROR"
|
||||||
|
|||||||
@@ -0,0 +1,161 @@
|
|||||||
|
// 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 //Commented out as reference for future reproduction methods, or addition later.
|
||||||
|
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/internal/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/internal/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/internal/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)
|
||||||
|
*/
|
||||||
@@ -0,0 +1,222 @@
|
|||||||
|
//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32
|
||||||
|
|
||||||
|
//TODO: Make these simple_animals
|
||||||
|
/* //Commented out as reference for future reproduction methods, or addition later if needed. - Mech
|
||||||
|
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/internal/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
|
||||||
|
|
||||||
|
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)
|
||||||
|
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"
|
||||||
|
|
||||||
|
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/internal/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
|
||||||
|
*/
|
||||||
@@ -0,0 +1,310 @@
|
|||||||
|
/proc/alien_queen_exists(var/ignore_self,var/mob/living/carbon/human/self)
|
||||||
|
for(var/mob/living/carbon/human/Q in living_mob_list)
|
||||||
|
if(self && ignore_self && self == Q)
|
||||||
|
continue
|
||||||
|
if(Q.species.name != "Xenomorph Queen")
|
||||||
|
continue
|
||||||
|
if(!Q.key || !Q.client || Q.stat)
|
||||||
|
continue
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
|
/mob/living/carbon/human/proc/gain_plasma(var/amount)
|
||||||
|
|
||||||
|
var/obj/item/organ/internal/xenos/plasmavessel/I = internal_organs_by_name[O_PLASMA]
|
||||||
|
if(!istype(I)) return
|
||||||
|
|
||||||
|
if(amount)
|
||||||
|
I.stored_plasma += amount
|
||||||
|
I.stored_plasma = max(0,min(I.stored_plasma,I.max_plasma))
|
||||||
|
|
||||||
|
/mob/living/carbon/human/proc/check_alien_ability(var/cost,var/needs_foundation,var/needs_organ)
|
||||||
|
|
||||||
|
var/obj/item/organ/internal/xenos/plasmavessel/P = internal_organs_by_name[O_PLASMA]
|
||||||
|
if(!istype(P))
|
||||||
|
src << "<span class='danger'>Your plasma vessel has been removed!</span>"
|
||||||
|
return
|
||||||
|
|
||||||
|
if(needs_organ)
|
||||||
|
var/obj/item/organ/internal/I = internal_organs_by_name[needs_organ]
|
||||||
|
if(!I)
|
||||||
|
src << "<span class='danger'>Your [needs_organ] has been removed!</span>"
|
||||||
|
return
|
||||||
|
else if((I.status & ORGAN_CUT_AWAY) || I.is_broken())
|
||||||
|
src << "<span class='danger'>Your [needs_organ] is too damaged to function!</span>"
|
||||||
|
return
|
||||||
|
|
||||||
|
if(P.stored_plasma < cost)
|
||||||
|
src << "\red You don't have enough phoron stored to do that."
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if(needs_foundation)
|
||||||
|
var/turf/T = get_turf(src)
|
||||||
|
var/has_foundation
|
||||||
|
if(T)
|
||||||
|
//TODO: Work out the actual conditions this needs.
|
||||||
|
if(!(istype(T,/turf/space)))
|
||||||
|
has_foundation = 1
|
||||||
|
if(!has_foundation)
|
||||||
|
src << "\red You need a solid foundation to do that on."
|
||||||
|
return 0
|
||||||
|
|
||||||
|
P.stored_plasma -= cost
|
||||||
|
return 1
|
||||||
|
|
||||||
|
// Free abilities.
|
||||||
|
/mob/living/carbon/human/proc/transfer_plasma(mob/living/carbon/human/M as mob in oview())
|
||||||
|
set name = "Transfer Plasma"
|
||||||
|
set desc = "Transfer Plasma to another alien"
|
||||||
|
set category = "Abilities"
|
||||||
|
|
||||||
|
if (get_dist(src,M) <= 1)
|
||||||
|
src << "<span class='alium'>You need to be closer.</span>"
|
||||||
|
return
|
||||||
|
|
||||||
|
var/obj/item/organ/internal/xenos/plasmavessel/I = M.internal_organs_by_name[O_PLASMA]
|
||||||
|
if(!istype(I))
|
||||||
|
src << "<span class='alium'>Their plasma vessel is missing.</span>"
|
||||||
|
return
|
||||||
|
|
||||||
|
var/amount = input("Amount:", "Transfer Plasma to [M]") as num
|
||||||
|
if (amount)
|
||||||
|
amount = abs(round(amount))
|
||||||
|
if(check_alien_ability(amount,0,O_PLASMA))
|
||||||
|
M.gain_plasma(amount)
|
||||||
|
M << "<span class='alium'>[src] has transfered [amount] plasma to you.</span>"
|
||||||
|
src << "<span class='alium'>You have transferred [amount] plasma to [M].</span>"
|
||||||
|
return
|
||||||
|
|
||||||
|
// Queen verbs.
|
||||||
|
/mob/living/carbon/human/proc/lay_egg()
|
||||||
|
|
||||||
|
set name = "Lay Egg (75)"
|
||||||
|
set desc = "Lay an egg to produce huggers to impregnate prey with."
|
||||||
|
set category = "Abilities"
|
||||||
|
|
||||||
|
if(!config.aliens_allowed)
|
||||||
|
src << "You begin to lay an egg, but hesitate. You suspect it isn't allowed."
|
||||||
|
verbs -= /mob/living/carbon/human/proc/lay_egg
|
||||||
|
return
|
||||||
|
|
||||||
|
if(locate(/obj/effect/alien/egg) in get_turf(src))
|
||||||
|
src << "There's already an egg here."
|
||||||
|
return
|
||||||
|
|
||||||
|
if(check_alien_ability(75,1,O_EGG))
|
||||||
|
visible_message("<span class='alium'><B>[src] has laid an egg!</B></span>")
|
||||||
|
new /obj/effect/alien/egg(loc)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
// Drone verbs.
|
||||||
|
/mob/living/carbon/human/proc/evolve()
|
||||||
|
set name = "Evolve (500)"
|
||||||
|
set desc = "Produce an interal egg sac capable of spawning children. Only one queen can exist at a time."
|
||||||
|
set category = "Abilities"
|
||||||
|
|
||||||
|
if(alien_queen_exists())
|
||||||
|
src << "<span class='notice'>We already have an active queen.</span>"
|
||||||
|
return
|
||||||
|
|
||||||
|
if(check_alien_ability(500))
|
||||||
|
visible_message("<span class='alium'><B>[src] begins to twist and contort!</B></span>", "<span class='alium'>You begin to evolve!</span>")
|
||||||
|
src.set_species("Xenomorph Queen")
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
/mob/living/carbon/human/proc/plant()
|
||||||
|
set name = "Plant Weeds (50)"
|
||||||
|
set desc = "Plants some alien weeds"
|
||||||
|
set category = "Abilities"
|
||||||
|
|
||||||
|
if(check_alien_ability(50,1,O_RESIN))
|
||||||
|
visible_message("<span class='alium'><B>[src] has planted some alien weeds!</B></span>")
|
||||||
|
new /obj/effect/alien/weeds/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
|
||||||
|
set name = "Corrosive Acid (200)"
|
||||||
|
set desc = "Drench an object in acid, destroying it over time."
|
||||||
|
set category = "Abilities"
|
||||||
|
|
||||||
|
if(!O in oview(1))
|
||||||
|
src << "<span class='alium'>[O] is too far away.</span>"
|
||||||
|
return
|
||||||
|
|
||||||
|
// OBJ CHECK
|
||||||
|
var/cannot_melt
|
||||||
|
if(isobj(O))
|
||||||
|
var/obj/I = O
|
||||||
|
if(I.unacidable)
|
||||||
|
cannot_melt = 1
|
||||||
|
else
|
||||||
|
if(istype(O, /turf/simulated/wall))
|
||||||
|
var/turf/simulated/wall/W = O
|
||||||
|
if(W.material.flags & MATERIAL_UNMELTABLE)
|
||||||
|
cannot_melt = 1
|
||||||
|
else if(istype(O, /turf/simulated/floor))
|
||||||
|
/* var/turf/simulated/floor/F = O //Turfs are qdel'd to space (Even asteroid tiles), will need to be touched by someone smarter than myself. -Mech
|
||||||
|
if(F.flooring && (F.flooring.flags & TURF_ACID_IMMUNE))
|
||||||
|
*/
|
||||||
|
cannot_melt = 1
|
||||||
|
|
||||||
|
if(cannot_melt)
|
||||||
|
src << "<span class='alium'>You cannot dissolve this object.</span>"
|
||||||
|
return
|
||||||
|
|
||||||
|
if(check_alien_ability(200,0,O_ACID))
|
||||||
|
new /obj/effect/alien/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
|
||||||
|
|
||||||
|
/mob/living/carbon/human/proc/neurotoxin(mob/target as mob in oview())
|
||||||
|
set name = "Spit Neurotoxin (50)"
|
||||||
|
set desc = "Spits neurotoxin at someone, paralyzing them for a short time if they are not wearing protective gear."
|
||||||
|
set category = "Abilities"
|
||||||
|
|
||||||
|
if(!check_alien_ability(50,0,O_ACID))
|
||||||
|
return
|
||||||
|
|
||||||
|
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
|
||||||
|
src << "You cannot spit neurotoxin in your current state."
|
||||||
|
return
|
||||||
|
|
||||||
|
visible_message("<span class='warning'>[src] spits neurotoxin at [target]!</span>", "<span class='alium'>You spit neurotoxin at [target].</span>")
|
||||||
|
|
||||||
|
var/obj/item/projectile/energy/neurotoxin/A = new(get_turf(src))
|
||||||
|
A.firer = src
|
||||||
|
A.launch(target)
|
||||||
|
return
|
||||||
|
|
||||||
|
/mob/living/carbon/human/proc/resin() // -- TLE
|
||||||
|
set name = "Secrete Resin (75)"
|
||||||
|
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
|
||||||
|
if(!choice)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(!check_alien_ability(75,1,O_RESIN))
|
||||||
|
return
|
||||||
|
|
||||||
|
visible_message("<span class='warning'><B>[src] vomits up a thick purple substance and begins to shape it!</B></span>", "<span class='alium'>You shape a [choice].</span>")
|
||||||
|
switch(choice)
|
||||||
|
if("resin door")
|
||||||
|
new /obj/structure/simple_door/resin(loc)
|
||||||
|
if("resin wall")
|
||||||
|
new /obj/effect/alien/resin/wall(loc)
|
||||||
|
if("resin membrane")
|
||||||
|
new /obj/effect/alien/resin/membrane(loc)
|
||||||
|
if("resin nest")
|
||||||
|
new /obj/structure/bed/nest(loc)
|
||||||
|
return
|
||||||
|
|
||||||
|
/mob/living/carbon/human/proc/leap()
|
||||||
|
set category = "Abilities"
|
||||||
|
set name = "Leap"
|
||||||
|
set desc = "Leap at a target and grab them aggressively."
|
||||||
|
|
||||||
|
if(last_special > world.time)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
|
||||||
|
src << "You cannot leap in your current state."
|
||||||
|
return
|
||||||
|
|
||||||
|
var/list/choices = list()
|
||||||
|
for(var/mob/living/M in view(6,src))
|
||||||
|
if(!istype(M,/mob/living/silicon))
|
||||||
|
choices += M
|
||||||
|
choices -= src
|
||||||
|
|
||||||
|
var/mob/living/T = input(src,"Who do you wish to leap at?") as null|anything in choices
|
||||||
|
|
||||||
|
if(!T || !src || src.stat) return
|
||||||
|
|
||||||
|
if(get_dist(get_turf(T), get_turf(src)) > 4) return
|
||||||
|
|
||||||
|
if(last_special > world.time)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(stat || paralysis || stunned || weakened || lying || restrained() || buckled)
|
||||||
|
src << "You cannot leap in your current state."
|
||||||
|
return
|
||||||
|
|
||||||
|
last_special = world.time + 75
|
||||||
|
status_flags |= LEAPING
|
||||||
|
|
||||||
|
src.visible_message("<span class='danger'>\The [src] leaps at [T]!</span>")
|
||||||
|
src.throw_at(get_step(get_turf(T),get_turf(src)), 4, 1, src)
|
||||||
|
playsound(src.loc, 'sound/voice/shriek1.ogg', 50, 1)
|
||||||
|
|
||||||
|
sleep(5)
|
||||||
|
|
||||||
|
if(status_flags & LEAPING) status_flags &= ~LEAPING
|
||||||
|
|
||||||
|
if(!src.Adjacent(T))
|
||||||
|
src << "<span class='warning'>You miss!</span>"
|
||||||
|
return
|
||||||
|
|
||||||
|
T.Weaken(3)
|
||||||
|
|
||||||
|
var/use_hand = "left"
|
||||||
|
if(l_hand)
|
||||||
|
if(r_hand)
|
||||||
|
src << "<span class='danger'>You need to have one hand free to grab someone.</span>"
|
||||||
|
return
|
||||||
|
else
|
||||||
|
use_hand = "right"
|
||||||
|
|
||||||
|
src.visible_message("<span class='warning'><b>\The [src]</b> seizes [T] aggressively!</span>")
|
||||||
|
|
||||||
|
var/obj/item/weapon/grab/G = new(src,T)
|
||||||
|
if(use_hand == "left")
|
||||||
|
l_hand = G
|
||||||
|
else
|
||||||
|
r_hand = G
|
||||||
|
|
||||||
|
G.state = GRAB_PASSIVE
|
||||||
|
G.icon_state = "grabbed1"
|
||||||
|
G.synch()
|
||||||
|
|
||||||
|
/mob/living/carbon/human/proc/gut()
|
||||||
|
set category = "Abilities"
|
||||||
|
set name = "Gut"
|
||||||
|
set desc = "While grabbing someone aggressively, rip their guts out or tear them apart."
|
||||||
|
|
||||||
|
if(last_special > world.time)
|
||||||
|
return
|
||||||
|
|
||||||
|
if(stat || paralysis || stunned || weakened || lying)
|
||||||
|
src << "\red You cannot do that in your current state."
|
||||||
|
return
|
||||||
|
|
||||||
|
var/obj/item/weapon/grab/G = locate() in src
|
||||||
|
if(!G || !istype(G))
|
||||||
|
src << "\red You are not grabbing anyone."
|
||||||
|
return
|
||||||
|
|
||||||
|
if(G.state < GRAB_AGGRESSIVE)
|
||||||
|
src << "\red You must have an aggressive grab to gut your prey!"
|
||||||
|
return
|
||||||
|
|
||||||
|
last_special = world.time + 50
|
||||||
|
|
||||||
|
visible_message("<span class='warning'><b>\The [src]</b> rips viciously at \the [G.affecting]'s body with its claws!</span>")
|
||||||
|
|
||||||
|
if(istype(G.affecting,/mob/living/carbon/human))
|
||||||
|
var/mob/living/carbon/human/H = G.affecting
|
||||||
|
H.apply_damage(50,BRUTE)
|
||||||
|
if(H.stat == 2)
|
||||||
|
H.gib()
|
||||||
|
|
||||||
|
else
|
||||||
|
var/mob/living/M = G.affecting
|
||||||
|
if(!istype(M)) return //wut
|
||||||
|
M.apply_damage(50,BRUTE)
|
||||||
|
if(M.stat == 2)
|
||||||
|
M.gib()
|
||||||
@@ -0,0 +1,326 @@
|
|||||||
|
//Stand-in until this is made more lore-friendly.
|
||||||
|
/datum/species/xenos
|
||||||
|
name = "Xenomorph"
|
||||||
|
name_plural = "Xenomorphs"
|
||||||
|
|
||||||
|
default_language = "Xenomorph"
|
||||||
|
language = "Hivemind"
|
||||||
|
unarmed_types = list(/datum/unarmed_attack/claws/strong, /datum/unarmed_attack/bite/strong)
|
||||||
|
hud_type = /datum/hud_data/alien
|
||||||
|
rarity_value = 3
|
||||||
|
|
||||||
|
has_fine_manipulation = 0
|
||||||
|
siemens_coefficient = 0
|
||||||
|
gluttonous = 3
|
||||||
|
|
||||||
|
brute_mod = 0.5 // Hardened carapace.
|
||||||
|
burn_mod = 2 // Weak to fire.
|
||||||
|
|
||||||
|
warning_low_pressure = 50
|
||||||
|
hazard_low_pressure = -1
|
||||||
|
|
||||||
|
cold_level_1 = 50
|
||||||
|
cold_level_2 = -1
|
||||||
|
cold_level_3 = -1
|
||||||
|
|
||||||
|
flags = NO_SCAN | NO_PAIN | NO_SLIP | NO_POISON | NO_MINOR_CUT
|
||||||
|
spawn_flags = SPECIES_IS_RESTRICTED
|
||||||
|
|
||||||
|
reagent_tag = IS_XENOS
|
||||||
|
|
||||||
|
blood_color = "#05EE05"
|
||||||
|
flesh_color = "#282846"
|
||||||
|
gibbed_anim = "gibbed-a"
|
||||||
|
dusted_anim = "dust-a"
|
||||||
|
death_message = "lets out a waning guttural screech, green blood bubbling from its maw."
|
||||||
|
death_sound = 'sound/voice/hiss6.ogg'
|
||||||
|
|
||||||
|
speech_sounds = list('sound/voice/hiss1.ogg','sound/voice/hiss2.ogg','sound/voice/hiss3.ogg','sound/voice/hiss4.ogg')
|
||||||
|
speech_chance = 100
|
||||||
|
|
||||||
|
breath_type = null
|
||||||
|
poison_type = null
|
||||||
|
|
||||||
|
vision_flags = SEE_SELF|SEE_MOBS
|
||||||
|
|
||||||
|
has_organ = list(
|
||||||
|
O_HEART = /obj/item/organ/internal/heart,
|
||||||
|
O_BRAIN = /obj/item/organ/internal/brain/xeno,
|
||||||
|
O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel,
|
||||||
|
O_HIVE = /obj/item/organ/internal/xenos/hivenode,
|
||||||
|
O_NUTRIENT = /obj/item/organ/internal/diona/nutrients
|
||||||
|
)
|
||||||
|
|
||||||
|
bump_flag = ALIEN
|
||||||
|
swap_flags = ~HEAVY
|
||||||
|
push_flags = (~HEAVY) ^ ROBOT
|
||||||
|
|
||||||
|
var/alien_number = 0
|
||||||
|
var/caste_name = "creature" // Used to update alien name.
|
||||||
|
var/weeds_heal_rate = 1 // Health regen on weeds.
|
||||||
|
var/weeds_plasma_rate = 5 // Plasma regen on weeds.
|
||||||
|
|
||||||
|
has_limbs = list(
|
||||||
|
BP_TORSO = list("path" = /obj/item/organ/external/chest),
|
||||||
|
BP_GROIN = list("path" = /obj/item/organ/external/groin),
|
||||||
|
BP_HEAD = list("path" = /obj/item/organ/external/head/no_eyes),
|
||||||
|
BP_L_ARM = list("path" = /obj/item/organ/external/arm),
|
||||||
|
BP_R_ARM = list("path" = /obj/item/organ/external/arm/right),
|
||||||
|
BP_L_LEG = list("path" = /obj/item/organ/external/leg),
|
||||||
|
BP_R_LEG = list("path" = /obj/item/organ/external/leg/right),
|
||||||
|
BP_L_HAND = list("path" = /obj/item/organ/external/hand),
|
||||||
|
BP_R_HAND = list("path" = /obj/item/organ/external/hand/right),
|
||||||
|
BP_L_FOOT = list("path" = /obj/item/organ/external/foot),
|
||||||
|
BP_R_FOOT = list("path" = /obj/item/organ/external/foot/right)
|
||||||
|
)
|
||||||
|
|
||||||
|
/datum/species/xenos/get_bodytype()
|
||||||
|
return "Xenomorph"
|
||||||
|
|
||||||
|
/datum/species/xenos/get_random_name()
|
||||||
|
return "alien [caste_name] ([alien_number])"
|
||||||
|
|
||||||
|
/datum/species/xenos/can_understand(var/mob/other)
|
||||||
|
|
||||||
|
if(istype(other,/mob/living/carbon/alien/larva))
|
||||||
|
return 1
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
/datum/species/xenos/hug(var/mob/living/carbon/human/H,var/mob/living/target)
|
||||||
|
H.visible_message("<span class='notice'>[H] caresses [target] with its scythe-like arm.</span>", \
|
||||||
|
"<span class='notice'>You caress [target] with your scythe-like arm.</span>")
|
||||||
|
|
||||||
|
/datum/species/xenos/handle_post_spawn(var/mob/living/carbon/human/H)
|
||||||
|
|
||||||
|
if(H.mind)
|
||||||
|
H.mind.assigned_role = "Alien"
|
||||||
|
H.mind.special_role = "Alien"
|
||||||
|
|
||||||
|
alien_number++ //Keep track of how many aliens we've had so far.
|
||||||
|
H.real_name = "alien [caste_name] ([alien_number])"
|
||||||
|
H.name = H.real_name
|
||||||
|
|
||||||
|
..()
|
||||||
|
|
||||||
|
/datum/species/xenos/handle_environment_special(var/mob/living/carbon/human/H)
|
||||||
|
|
||||||
|
var/turf/T = H.loc
|
||||||
|
if(!T) return
|
||||||
|
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/internal/xenos/plasmavessel/P = H.internal_organs_by_name[O_PLASMA]
|
||||||
|
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)
|
||||||
|
var/heal_rate = weeds_heal_rate
|
||||||
|
var/mend_prob = 10
|
||||||
|
if (!H.resting)
|
||||||
|
heal_rate = weeds_heal_rate / 3
|
||||||
|
mend_prob = 1
|
||||||
|
|
||||||
|
//first heal damages
|
||||||
|
if (H.getBruteLoss() || H.getFireLoss() || H.getOxyLoss() || H.getToxLoss())
|
||||||
|
H.adjustBruteLoss(-heal_rate)
|
||||||
|
H.adjustFireLoss(-heal_rate)
|
||||||
|
H.adjustOxyLoss(-heal_rate)
|
||||||
|
H.adjustToxLoss(-heal_rate)
|
||||||
|
if (prob(5))
|
||||||
|
H << "<span class='alium'>You feel a soothing sensation come over you...</span>"
|
||||||
|
return 1
|
||||||
|
|
||||||
|
//next internal organs
|
||||||
|
for(var/obj/item/organ/I in H.internal_organs)
|
||||||
|
if(I.damage > 0)
|
||||||
|
I.damage = max(I.damage - heal_rate, 0)
|
||||||
|
if (prob(5))
|
||||||
|
H << "<span class='alium'>You feel a soothing sensation within your [I.parent_organ]...</span>"
|
||||||
|
return 1
|
||||||
|
|
||||||
|
//next mend broken bones, approx 10 ticks each
|
||||||
|
for(var/obj/item/organ/external/E in H.bad_external_organs)
|
||||||
|
if (E.status & ORGAN_BROKEN)
|
||||||
|
if (prob(mend_prob))
|
||||||
|
if (E.mend_fracture())
|
||||||
|
H << "<span class='alium'>You feel something mend itself inside your [E.name].</span>"
|
||||||
|
return 1
|
||||||
|
|
||||||
|
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"
|
||||||
|
weeds_plasma_rate = 15
|
||||||
|
slowdown = 1
|
||||||
|
tail = "xenos_drone_tail"
|
||||||
|
rarity_value = 5
|
||||||
|
|
||||||
|
icobase = 'icons/mob/human_races/xenos/r_xenos_drone.dmi'
|
||||||
|
deform = 'icons/mob/human_races/xenos/r_xenos_drone.dmi'
|
||||||
|
|
||||||
|
has_organ = list(
|
||||||
|
O_HEART = /obj/item/organ/internal/heart,
|
||||||
|
O_BRAIN = /obj/item/organ/internal/brain/xeno,
|
||||||
|
O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/queen,
|
||||||
|
O_ACID = /obj/item/organ/internal/xenos/acidgland,
|
||||||
|
O_HIVE = /obj/item/organ/internal/xenos/hivenode,
|
||||||
|
O_RESIN = /obj/item/organ/internal/xenos/resinspinner,
|
||||||
|
O_NUTRIENT = /obj/item/organ/internal/diona/nutrients
|
||||||
|
)
|
||||||
|
|
||||||
|
inherent_verbs = list(
|
||||||
|
/mob/living/proc/ventcrawl,
|
||||||
|
/mob/living/carbon/human/proc/regurgitate,
|
||||||
|
/mob/living/carbon/human/proc/plant,
|
||||||
|
/mob/living/carbon/human/proc/transfer_plasma,
|
||||||
|
/mob/living/carbon/human/proc/evolve,
|
||||||
|
/mob/living/carbon/human/proc/resin,
|
||||||
|
/mob/living/carbon/human/proc/corrosive_acid
|
||||||
|
)
|
||||||
|
|
||||||
|
/datum/species/xenos/drone/handle_post_spawn(var/mob/living/carbon/human/H)
|
||||||
|
|
||||||
|
var/mob/living/carbon/human/A = H
|
||||||
|
if(!istype(A))
|
||||||
|
return ..()
|
||||||
|
..()
|
||||||
|
|
||||||
|
/datum/species/xenos/hunter
|
||||||
|
|
||||||
|
name = "Xenomorph Hunter"
|
||||||
|
weeds_plasma_rate = 5
|
||||||
|
caste_name = "hunter"
|
||||||
|
slowdown = -2
|
||||||
|
total_health = 150
|
||||||
|
tail = "xenos_hunter_tail"
|
||||||
|
|
||||||
|
icobase = 'icons/mob/human_races/xenos/r_xenos_hunter.dmi'
|
||||||
|
deform = 'icons/mob/human_races/xenos/r_xenos_hunter.dmi'
|
||||||
|
|
||||||
|
has_organ = list(
|
||||||
|
O_HEART = /obj/item/organ/internal/heart,
|
||||||
|
O_BRAIN = /obj/item/organ/internal/brain/xeno,
|
||||||
|
O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/hunter,
|
||||||
|
O_HIVE = /obj/item/organ/internal/xenos/hivenode,
|
||||||
|
O_NUTRIENT = /obj/item/organ/internal/diona/nutrients
|
||||||
|
)
|
||||||
|
|
||||||
|
inherent_verbs = list(
|
||||||
|
/mob/living/proc/ventcrawl,
|
||||||
|
/mob/living/carbon/human/proc/tackle,
|
||||||
|
/mob/living/carbon/human/proc/gut,
|
||||||
|
/mob/living/carbon/human/proc/leap,
|
||||||
|
/mob/living/carbon/human/proc/psychic_whisper,
|
||||||
|
/mob/living/carbon/human/proc/regurgitate
|
||||||
|
)
|
||||||
|
|
||||||
|
/datum/species/xenos/sentinel
|
||||||
|
name = "Xenomorph Sentinel"
|
||||||
|
weeds_plasma_rate = 10
|
||||||
|
caste_name = "sentinel"
|
||||||
|
slowdown = 0
|
||||||
|
total_health = 125
|
||||||
|
tail = "xenos_sentinel_tail"
|
||||||
|
|
||||||
|
icobase = 'icons/mob/human_races/xenos/r_xenos_sentinel.dmi'
|
||||||
|
deform = 'icons/mob/human_races/xenos/r_xenos_sentinel.dmi'
|
||||||
|
|
||||||
|
has_organ = list(
|
||||||
|
O_HEART = /obj/item/organ/internal/heart,
|
||||||
|
O_BRAIN = /obj/item/organ/internal/brain/xeno,
|
||||||
|
O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/sentinel,
|
||||||
|
O_ACID = /obj/item/organ/internal/xenos/acidgland,
|
||||||
|
O_HIVE = /obj/item/organ/internal/xenos/hivenode,
|
||||||
|
O_NUTRIENT = /obj/item/organ/internal/diona/nutrients
|
||||||
|
)
|
||||||
|
|
||||||
|
inherent_verbs = list(
|
||||||
|
/mob/living/proc/ventcrawl,
|
||||||
|
/mob/living/carbon/human/proc/tackle,
|
||||||
|
/mob/living/carbon/human/proc/regurgitate,
|
||||||
|
/mob/living/carbon/human/proc/transfer_plasma,
|
||||||
|
/mob/living/carbon/human/proc/corrosive_acid,
|
||||||
|
/mob/living/carbon/human/proc/neurotoxin
|
||||||
|
)
|
||||||
|
|
||||||
|
/datum/species/xenos/queen
|
||||||
|
|
||||||
|
name = "Xenomorph Queen"
|
||||||
|
total_health = 250
|
||||||
|
weeds_heal_rate = 5
|
||||||
|
weeds_plasma_rate = 20
|
||||||
|
caste_name = "queen"
|
||||||
|
slowdown = 4
|
||||||
|
tail = "xenos_queen_tail"
|
||||||
|
rarity_value = 10
|
||||||
|
|
||||||
|
icobase = 'icons/mob/human_races/xenos/r_xenos_queen.dmi'
|
||||||
|
deform = 'icons/mob/human_races/xenos/r_xenos_queen.dmi'
|
||||||
|
|
||||||
|
has_organ = list(
|
||||||
|
O_HEART = /obj/item/organ/internal/heart,
|
||||||
|
O_BRAIN = /obj/item/organ/internal/brain/xeno,
|
||||||
|
O_EGG = /obj/item/organ/internal/xenos/eggsac,
|
||||||
|
O_PLASMA = /obj/item/organ/internal/xenos/plasmavessel/queen,
|
||||||
|
O_ACID = /obj/item/organ/internal/xenos/acidgland,
|
||||||
|
O_HIVE = /obj/item/organ/internal/xenos/hivenode,
|
||||||
|
O_RESIN = /obj/item/organ/internal/xenos/resinspinner,
|
||||||
|
O_NUTRIENT = /obj/item/organ/internal/diona/nutrients
|
||||||
|
)
|
||||||
|
|
||||||
|
inherent_verbs = list(
|
||||||
|
/mob/living/proc/ventcrawl,
|
||||||
|
/mob/living/carbon/human/proc/psychic_whisper,
|
||||||
|
/mob/living/carbon/human/proc/regurgitate,
|
||||||
|
/mob/living/carbon/human/proc/lay_egg,
|
||||||
|
/mob/living/carbon/human/proc/plant,
|
||||||
|
/mob/living/carbon/human/proc/transfer_plasma,
|
||||||
|
/mob/living/carbon/human/proc/corrosive_acid,
|
||||||
|
/mob/living/carbon/human/proc/neurotoxin,
|
||||||
|
/mob/living/carbon/human/proc/resin
|
||||||
|
)
|
||||||
|
|
||||||
|
/datum/species/xenos/queen/handle_login_special(var/mob/living/carbon/human/H)
|
||||||
|
..()
|
||||||
|
// Make sure only one official queen exists at any point.
|
||||||
|
if(!alien_queen_exists(1,H))
|
||||||
|
H.real_name = "alien queen ([alien_number])"
|
||||||
|
H.name = H.real_name
|
||||||
|
else
|
||||||
|
H.real_name = "alien princess ([alien_number])"
|
||||||
|
H.name = H.real_name
|
||||||
|
|
||||||
|
/datum/hud_data/alien
|
||||||
|
|
||||||
|
icon = 'icons/mob/screen1_alien.dmi'
|
||||||
|
has_a_intent = 1
|
||||||
|
has_m_intent = 1
|
||||||
|
has_warnings = 1
|
||||||
|
has_hands = 1
|
||||||
|
has_drop = 1
|
||||||
|
has_throw = 1
|
||||||
|
has_resist = 1
|
||||||
|
has_pressure = 0
|
||||||
|
has_nutrition = 0
|
||||||
|
has_bodytemp = 0
|
||||||
|
has_internals = 0
|
||||||
|
|
||||||
|
gear = list(
|
||||||
|
"o_clothing" = list("loc" = ui_belt, "name" = "Suit", "slot" = slot_wear_suit, "state" = "equip", "dir" = SOUTH),
|
||||||
|
"head" = list("loc" = ui_id, "name" = "Hat", "slot" = slot_head, "state" = "hair"),
|
||||||
|
"storage1" = list("loc" = ui_storage1, "name" = "Left Pocket", "slot" = slot_l_store, "state" = "pocket"),
|
||||||
|
"storage2" = list("loc" = ui_storage2, "name" = "Right Pocket", "slot" = slot_r_store, "state" = "pocket"),
|
||||||
|
)
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
proc/create_new_xenomorph(var/alien_caste,var/target)
|
||||||
|
|
||||||
|
target = get_turf(target)
|
||||||
|
if(!target || !alien_caste) return
|
||||||
|
|
||||||
|
var/mob/living/carbon/human/new_alien = new(target)
|
||||||
|
new_alien.set_species("Xenomorph [alien_caste]")
|
||||||
|
return new_alien
|
||||||
|
|
||||||
|
/mob/living/carbon/human/xdrone/New(var/new_loc)
|
||||||
|
h_style = "Bald"
|
||||||
|
..(new_loc, "Xenomorph Drone")
|
||||||
|
|
||||||
|
/mob/living/carbon/human/xsentinel/New(var/new_loc)
|
||||||
|
h_style = "Bald"
|
||||||
|
..(new_loc, "Xenomorph Sentinel")
|
||||||
|
|
||||||
|
/mob/living/carbon/human/xhunter/New(var/new_loc)
|
||||||
|
h_style = "Bald"
|
||||||
|
..(new_loc, "Xenomorph Hunter")
|
||||||
|
|
||||||
|
/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
|
||||||
|
*/
|
||||||
@@ -1,4 +1,10 @@
|
|||||||
// fun if you want to typecast humans/monkeys/etc without writing long path-filled lines.
|
// fun if you want to typecast humans/monkeys/etc without writing long path-filled lines.
|
||||||
|
/proc/isxenomorph(A)
|
||||||
|
if(istype(A, /mob/living/carbon/human))
|
||||||
|
var/mob/living/carbon/human/H = A
|
||||||
|
return istype(H.species, /datum/species/xenos)
|
||||||
|
return 0
|
||||||
|
|
||||||
/proc/issmall(A)
|
/proc/issmall(A)
|
||||||
if(A && istype(A, /mob/living))
|
if(A && istype(A, /mob/living))
|
||||||
var/mob/living/L = A
|
var/mob/living/L = A
|
||||||
|
|||||||
@@ -161,6 +161,30 @@
|
|||||||
qdel(src)
|
qdel(src)
|
||||||
return O
|
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)
|
/mob/living/carbon/human/proc/slimeize(adult as num, reproduce as num)
|
||||||
if (transforming)
|
if (transforming)
|
||||||
return
|
return
|
||||||
|
|||||||
51
code/modules/organs/subtypes/xenos.dm
Normal file
51
code/modules/organs/subtypes/xenos.dm
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
//XENOMORPH ORGANS
|
||||||
|
/obj/item/organ/internal/xenos
|
||||||
|
name = "xeno organ"
|
||||||
|
icon = 'icons/effects/blood.dmi'
|
||||||
|
desc = "It smells like an accident in a chemical factory."
|
||||||
|
|
||||||
|
/obj/item/organ/internal/xenos/eggsac
|
||||||
|
name = "egg sac"
|
||||||
|
parent_organ = BP_GROIN
|
||||||
|
icon_state = "xgibmid1"
|
||||||
|
organ_tag = O_EGG
|
||||||
|
|
||||||
|
/obj/item/organ/internal/xenos/plasmavessel
|
||||||
|
name = "plasma vessel"
|
||||||
|
parent_organ = BP_TORSO
|
||||||
|
icon_state = "xgibdown1"
|
||||||
|
organ_tag = O_PLASMA
|
||||||
|
var/stored_plasma = 0
|
||||||
|
var/max_plasma = 500
|
||||||
|
|
||||||
|
/obj/item/organ/internal/xenos/plasmavessel/queen
|
||||||
|
name = "bloated plasma vessel"
|
||||||
|
stored_plasma = 200
|
||||||
|
max_plasma = 500
|
||||||
|
|
||||||
|
/obj/item/organ/internal/xenos/plasmavessel/sentinel
|
||||||
|
stored_plasma = 100
|
||||||
|
max_plasma = 250
|
||||||
|
|
||||||
|
/obj/item/organ/internal/xenos/plasmavessel/hunter
|
||||||
|
name = "tiny plasma vessel"
|
||||||
|
stored_plasma = 100
|
||||||
|
max_plasma = 150
|
||||||
|
|
||||||
|
/obj/item/organ/internal/xenos/acidgland
|
||||||
|
name = "acid gland"
|
||||||
|
parent_organ = BP_HEAD
|
||||||
|
icon_state = "xgibtorso"
|
||||||
|
organ_tag = O_ACID
|
||||||
|
|
||||||
|
/obj/item/organ/internal/xenos/hivenode
|
||||||
|
name = "hive node"
|
||||||
|
parent_organ = BP_TORSO
|
||||||
|
icon_state = "xgibmid2"
|
||||||
|
organ_tag = O_HIVE
|
||||||
|
|
||||||
|
/obj/item/organ/internal/xenos/resinspinner
|
||||||
|
name = "resin spinner"
|
||||||
|
parent_organ = BP_HEAD
|
||||||
|
icon_state = "xgibmid2"
|
||||||
|
organ_tag = O_RESIN
|
||||||
@@ -258,6 +258,10 @@
|
|||||||
/datum/reagent/toxin/plantbgone/touch_obj(var/obj/O, var/volume)
|
/datum/reagent/toxin/plantbgone/touch_obj(var/obj/O, var/volume)
|
||||||
if(istype(O, /obj/effect/plant))
|
if(istype(O, /obj/effect/plant))
|
||||||
qdel(O)
|
qdel(O)
|
||||||
|
else if(istype(O, /obj/effect/alien/weeds/))
|
||||||
|
var/obj/effect/alien/weeds/alien_weeds = O
|
||||||
|
alien_weeds.health -= rand(15, 35)
|
||||||
|
alien_weeds.healthcheck()
|
||||||
|
|
||||||
/datum/reagent/toxin/plantbgone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
/datum/reagent/toxin/plantbgone/affect_blood(var/mob/living/carbon/M, var/alien, var/removed)
|
||||||
if(alien == IS_DIONA)
|
if(alien == IS_DIONA)
|
||||||
|
|||||||
@@ -12,6 +12,47 @@
|
|||||||
var/obj/item/organ/external/affected = target.get_organ(target_zone)
|
var/obj/item/organ/external/affected = target.get_organ(target_zone)
|
||||||
return affected && affected.open == (affected.encased ? 3 : 2)
|
return affected && affected.open == (affected.encased ? 3 : 2)
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////
|
||||||
|
// ALIEN EMBRYO SURGERY //
|
||||||
|
////////////////////////////////////////////////////////////////// // Here for future reference incase it's needed. See: Alien_embryo.dm and Alien_facehugger.dm
|
||||||
|
/*
|
||||||
|
/datum/surgery_step/internal/remove_embryo
|
||||||
|
allowed_tools = list(
|
||||||
|
/obj/item/weapon/surgical/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 == BP_TORSO
|
||||||
|
|
||||||
|
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("<span class='warning'>[user] rips the larva out of [target]'s ribcage!</span>",
|
||||||
|
"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 //
|
// CHEST INTERNAL ORGAN SURGERY //
|
||||||
//////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
BIN
icons/mob/human_races/xenos/r_xenos_drone.dmi
Normal file
BIN
icons/mob/human_races/xenos/r_xenos_drone.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
BIN
icons/mob/human_races/xenos/r_xenos_hunter.dmi
Normal file
BIN
icons/mob/human_races/xenos/r_xenos_hunter.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
BIN
icons/mob/human_races/xenos/r_xenos_queen.dmi
Normal file
BIN
icons/mob/human_races/xenos/r_xenos_queen.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
BIN
icons/mob/human_races/xenos/r_xenos_sentinel.dmi
Normal file
BIN
icons/mob/human_races/xenos/r_xenos_sentinel.dmi
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 140 KiB |
11
polaris.dme
11
polaris.dme
@@ -315,6 +315,7 @@
|
|||||||
#include "code\game\antagonist\antagonist_print.dm"
|
#include "code\game\antagonist\antagonist_print.dm"
|
||||||
#include "code\game\antagonist\antagonist_update.dm"
|
#include "code\game\antagonist\antagonist_update.dm"
|
||||||
#include "code\game\antagonist\alien\borer.dm"
|
#include "code\game\antagonist\alien\borer.dm"
|
||||||
|
#include "code\game\antagonist\alien\xenomorph.dm"
|
||||||
#include "code\game\antagonist\outsider\commando.dm"
|
#include "code\game\antagonist\outsider\commando.dm"
|
||||||
#include "code\game\antagonist\outsider\deathsquad.dm"
|
#include "code\game\antagonist\outsider\deathsquad.dm"
|
||||||
#include "code\game\antagonist\outsider\ert.dm"
|
#include "code\game\antagonist\outsider\ert.dm"
|
||||||
@@ -747,6 +748,7 @@
|
|||||||
#include "code\game\objects\effects\spiders.dm"
|
#include "code\game\objects\effects\spiders.dm"
|
||||||
#include "code\game\objects\effects\step_triggers.dm"
|
#include "code\game\objects\effects\step_triggers.dm"
|
||||||
#include "code\game\objects\effects\zone_divider.dm"
|
#include "code\game\objects\effects\zone_divider.dm"
|
||||||
|
#include "code\game\objects\effects\alien\aliens.dm"
|
||||||
#include "code\game\objects\effects\chem\chemsmoke.dm"
|
#include "code\game\objects\effects\chem\chemsmoke.dm"
|
||||||
#include "code\game\objects\effects\chem\foam.dm"
|
#include "code\game\objects\effects\chem\foam.dm"
|
||||||
#include "code\game\objects\effects\chem\water.dm"
|
#include "code\game\objects\effects\chem\water.dm"
|
||||||
@@ -1009,6 +1011,7 @@
|
|||||||
#include "code\game\objects\structures\crates_lockers\closets\secure\scientist.dm"
|
#include "code\game\objects\structures\crates_lockers\closets\secure\scientist.dm"
|
||||||
#include "code\game\objects\structures\crates_lockers\closets\secure\secure_closets.dm"
|
#include "code\game\objects\structures\crates_lockers\closets\secure\secure_closets.dm"
|
||||||
#include "code\game\objects\structures\crates_lockers\closets\secure\security.dm"
|
#include "code\game\objects\structures\crates_lockers\closets\secure\security.dm"
|
||||||
|
#include "code\game\objects\structures\stool_bed_chair_nest\alien_nests.dm"
|
||||||
#include "code\game\objects\structures\stool_bed_chair_nest\bed.dm"
|
#include "code\game\objects\structures\stool_bed_chair_nest\bed.dm"
|
||||||
#include "code\game\objects\structures\stool_bed_chair_nest\chairs.dm"
|
#include "code\game\objects\structures\stool_bed_chair_nest\chairs.dm"
|
||||||
#include "code\game\objects\structures\stool_bed_chair_nest\stools.dm"
|
#include "code\game\objects\structures\stool_bed_chair_nest\stools.dm"
|
||||||
@@ -1115,6 +1118,7 @@
|
|||||||
#include "code\modules\admin\secrets\fun_secrets\turn_humans_into_monkeys.dm"
|
#include "code\modules\admin\secrets\fun_secrets\turn_humans_into_monkeys.dm"
|
||||||
#include "code\modules\admin\secrets\random_events\gravity.dm"
|
#include "code\modules\admin\secrets\random_events\gravity.dm"
|
||||||
#include "code\modules\admin\secrets\random_events\trigger_cordical_borer_infestation.dm"
|
#include "code\modules\admin\secrets\random_events\trigger_cordical_borer_infestation.dm"
|
||||||
|
#include "code\modules\admin\secrets\random_events\trigger_xenomorph_infestation.dm"
|
||||||
#include "code\modules\admin\verbs\adminhelp.dm"
|
#include "code\modules\admin\verbs\adminhelp.dm"
|
||||||
#include "code\modules\admin\verbs\adminjump.dm"
|
#include "code\modules\admin\verbs\adminjump.dm"
|
||||||
#include "code\modules\admin\verbs\adminpm.dm"
|
#include "code\modules\admin\verbs\adminpm.dm"
|
||||||
@@ -1620,6 +1624,9 @@
|
|||||||
#include "code\modules\mob\living\carbon\alien\diona\progression.dm"
|
#include "code\modules\mob\living\carbon\alien\diona\progression.dm"
|
||||||
#include "code\modules\mob\living\carbon\alien\diona\say_understands.dm"
|
#include "code\modules\mob\living\carbon\alien\diona\say_understands.dm"
|
||||||
#include "code\modules\mob\living\carbon\alien\diona\update_icons.dm"
|
#include "code\modules\mob\living\carbon\alien\diona\update_icons.dm"
|
||||||
|
#include "code\modules\mob\living\carbon\alien\larva\larva.dm"
|
||||||
|
#include "code\modules\mob\living\carbon\alien\larva\life.dm"
|
||||||
|
#include "code\modules\mob\living\carbon\alien\larva\progression.dm"
|
||||||
#include "code\modules\mob\living\carbon\brain\brain.dm"
|
#include "code\modules\mob\living\carbon\brain\brain.dm"
|
||||||
#include "code\modules\mob\living\carbon\brain\death.dm"
|
#include "code\modules\mob\living\carbon\brain\death.dm"
|
||||||
#include "code\modules\mob\living\carbon\brain\emote.dm"
|
#include "code\modules\mob\living\carbon\brain\emote.dm"
|
||||||
@@ -1664,6 +1671,9 @@
|
|||||||
#include "code\modules\mob\living\carbon\human\species\station\prometheans.dm"
|
#include "code\modules\mob\living\carbon\human\species\station\prometheans.dm"
|
||||||
#include "code\modules\mob\living\carbon\human\species\station\seromi.dm"
|
#include "code\modules\mob\living\carbon\human\species\station\seromi.dm"
|
||||||
#include "code\modules\mob\living\carbon\human\species\station\station.dm"
|
#include "code\modules\mob\living\carbon\human\species\station\station.dm"
|
||||||
|
#include "code\modules\mob\living\carbon\human\species\xenomorphs\alien_powers.dm"
|
||||||
|
#include "code\modules\mob\living\carbon\human\species\xenomorphs\alien_species.dm"
|
||||||
|
#include "code\modules\mob\living\carbon\human\species\xenomorphs\xenomorphs.dm"
|
||||||
#include "code\modules\mob\living\carbon\metroid\death.dm"
|
#include "code\modules\mob\living\carbon\metroid\death.dm"
|
||||||
#include "code\modules\mob\living\carbon\metroid\emote.dm"
|
#include "code\modules\mob\living\carbon\metroid\emote.dm"
|
||||||
#include "code\modules\mob\living\carbon\metroid\examine.dm"
|
#include "code\modules\mob\living\carbon\metroid\examine.dm"
|
||||||
@@ -1834,6 +1844,7 @@
|
|||||||
#include "code\modules\organs\subtypes\unathi.dm"
|
#include "code\modules\organs\subtypes\unathi.dm"
|
||||||
#include "code\modules\organs\subtypes\unbreakable.dm"
|
#include "code\modules\organs\subtypes\unbreakable.dm"
|
||||||
#include "code\modules\organs\subtypes\vox.dm"
|
#include "code\modules\organs\subtypes\vox.dm"
|
||||||
|
#include "code\modules\organs\subtypes\xenos.dm"
|
||||||
#include "code\modules\overmap\_defines.dm"
|
#include "code\modules\overmap\_defines.dm"
|
||||||
#include "code\modules\overmap\sectors.dm"
|
#include "code\modules\overmap\sectors.dm"
|
||||||
#include "code\modules\overmap\ships\ship.dm"
|
#include "code\modules\overmap\ships\ship.dm"
|
||||||
|
|||||||
Reference in New Issue
Block a user