@@ -1,158 +1,158 @@
|
||||
#define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point
|
||||
#define HEAT_DAMAGE_LEVEL_2 3 //Amount of damage applied when your body temperature passes the 400K point
|
||||
#define HEAT_DAMAGE_LEVEL_3 8 //Amount of damage applied when your body temperature passes the 460K point and you are on fire
|
||||
|
||||
|
||||
/mob/living/carbon/alien
|
||||
name = "alien"
|
||||
voice_name = "alien"
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
gender = FEMALE //All xenos are girls!!
|
||||
dna = null
|
||||
faction = list("alien")
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
sight = SEE_MOBS
|
||||
see_in_dark = 4
|
||||
verb_say = "hisses"
|
||||
#define HEAT_DAMAGE_LEVEL_1 2 //Amount of damage applied when your body temperature just passes the 360.15k safety point
|
||||
#define HEAT_DAMAGE_LEVEL_2 3 //Amount of damage applied when your body temperature passes the 400K point
|
||||
#define HEAT_DAMAGE_LEVEL_3 8 //Amount of damage applied when your body temperature passes the 460K point and you are on fire
|
||||
|
||||
|
||||
/mob/living/carbon/alien
|
||||
name = "alien"
|
||||
voice_name = "alien"
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
gender = FEMALE //All xenos are girls!!
|
||||
dna = null
|
||||
faction = list("alien")
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
sight = SEE_MOBS
|
||||
see_in_dark = 4
|
||||
verb_say = "hisses"
|
||||
initial_language_holder = /datum/language_holder/alien
|
||||
bubble_icon = "alien"
|
||||
type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno
|
||||
var/nightvision = 1
|
||||
|
||||
var/obj/item/weapon/card/id/wear_id = null // Fix for station bounced radios -- Skie
|
||||
var/has_fine_manipulation = 0
|
||||
var/move_delay_add = 0 // movement delay to add
|
||||
|
||||
status_flags = CANPARALYSE|CANPUSH
|
||||
|
||||
var/heat_protection = 0.5
|
||||
var/leaping = 0
|
||||
gib_type = /obj/effect/decal/cleanable/xenoblood/xgibs
|
||||
unique_name = 1
|
||||
devourable = TRUE
|
||||
|
||||
var/static/regex/alien_name_regex = new("alien (larva|sentinel|drone|hunter|praetorian|queen)( \\(\\d+\\))?")
|
||||
|
||||
/mob/living/carbon/alien/Initialize()
|
||||
verbs += /mob/living/proc/mob_sleep
|
||||
verbs += /mob/living/proc/lay_down
|
||||
|
||||
create_bodyparts() //initialize bodyparts
|
||||
|
||||
create_internal_organs()
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/brain/alien
|
||||
internal_organs += new /obj/item/organ/alien/hivenode
|
||||
internal_organs += new /obj/item/organ/tongue/alien
|
||||
internal_organs += new /obj/item/organ/eyes/night_vision/alien
|
||||
bubble_icon = "alien"
|
||||
type_of_meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno
|
||||
var/nightvision = 1
|
||||
|
||||
var/obj/item/weapon/card/id/wear_id = null // Fix for station bounced radios -- Skie
|
||||
var/has_fine_manipulation = 0
|
||||
var/move_delay_add = 0 // movement delay to add
|
||||
|
||||
status_flags = CANUNCONSCIOUS|CANPUSH
|
||||
|
||||
var/heat_protection = 0.5
|
||||
var/leaping = 0
|
||||
gib_type = /obj/effect/decal/cleanable/xenoblood/xgibs
|
||||
unique_name = 1
|
||||
|
||||
var/static/regex/alien_name_regex = new("alien (larva|sentinel|drone|hunter|praetorian|queen)( \\(\\d+\\))?")
|
||||
devourable = TRUE
|
||||
|
||||
/mob/living/carbon/alien/Initialize()
|
||||
verbs += /mob/living/proc/mob_sleep
|
||||
verbs += /mob/living/proc/lay_down
|
||||
|
||||
create_bodyparts() //initialize bodyparts
|
||||
|
||||
create_internal_organs()
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/brain/alien
|
||||
internal_organs += new /obj/item/organ/alien/hivenode
|
||||
internal_organs += new /obj/item/organ/tongue/alien
|
||||
internal_organs += new /obj/item/organ/eyes/night_vision/alien
|
||||
internal_organs += new /obj/item/organ/ears
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/assess_threat() // beepsky won't hunt aliums
|
||||
return -10
|
||||
|
||||
/mob/living/carbon/alien/handle_environment(datum/gas_mixture/environment)
|
||||
if(!environment)
|
||||
return
|
||||
|
||||
var/loc_temp = get_temperature(environment)
|
||||
|
||||
// Aliens are now weak to fire.
|
||||
|
||||
//After then, it reacts to the surrounding atmosphere based on your thermal protection
|
||||
if(!on_fire) // If you're on fire, ignore local air temperature
|
||||
if(loc_temp > bodytemperature)
|
||||
//Place is hotter than we are
|
||||
var/thermal_protection = heat_protection //This returns a 0 - 1 value, which corresponds to the percentage of heat protection.
|
||||
if(thermal_protection < 1)
|
||||
bodytemperature += (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR)
|
||||
else
|
||||
bodytemperature += 1 * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR)
|
||||
|
||||
if(bodytemperature > 360.15)
|
||||
//Body temperature is too hot.
|
||||
throw_alert("alien_fire", /obj/screen/alert/alien_fire)
|
||||
switch(bodytemperature)
|
||||
if(360 to 400)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_1, BURN)
|
||||
if(400 to 460)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
|
||||
if(460 to INFINITY)
|
||||
if(on_fire)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_3, BURN)
|
||||
else
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
|
||||
else
|
||||
clear_alert("alien_fire")
|
||||
|
||||
/mob/living/carbon/alien/reagent_check(datum/reagent/R) //can metabolize all reagents
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/alien/IsAdvancedToolUser()
|
||||
return has_fine_manipulation
|
||||
|
||||
/mob/living/carbon/alien/Stat()
|
||||
..()
|
||||
|
||||
if(statpanel("Status"))
|
||||
stat(null, "Intent: [a_intent]")
|
||||
|
||||
/mob/living/carbon/alien/getTrail()
|
||||
if(getBruteLoss() < 200)
|
||||
return pick (list("xltrails_1", "xltrails2"))
|
||||
else
|
||||
return pick (list("xttrails_1", "xttrails2"))
|
||||
/*----------------------------------------
|
||||
Proc: AddInfectionImages()
|
||||
Des: Gives the client of the alien an image on each infected mob.
|
||||
----------------------------------------*/
|
||||
/mob/living/carbon/alien/proc/AddInfectionImages()
|
||||
if (client)
|
||||
for (var/mob/living/C in GLOB.mob_list)
|
||||
if(C.status_flags & XENO_HOST)
|
||||
var/obj/item/organ/body_egg/alien_embryo/A = C.getorgan(/obj/item/organ/body_egg/alien_embryo)
|
||||
if(A)
|
||||
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/alien/proc/RemoveInfectionImages()
|
||||
if (client)
|
||||
for(var/image/I in client.images)
|
||||
if(dd_hasprefix_case(I.icon_state, "infected"))
|
||||
qdel(I)
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/canBeHandcuffed()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/get_standard_pixel_y_offset(lying = 0)
|
||||
return initial(pixel_y)
|
||||
|
||||
/mob/living/carbon/alien/proc/alien_evolve(mob/living/carbon/alien/new_xeno)
|
||||
to_chat(src, "<span class='noticealien'>You begin to evolve!</span>")
|
||||
visible_message("<span class='alertalien'>[src] begins to twist and contort!</span>")
|
||||
new_xeno.setDir(dir)
|
||||
if(!alien_name_regex.Find(name))
|
||||
new_xeno.name = name
|
||||
new_xeno.real_name = real_name
|
||||
if(mind)
|
||||
mind.transfer_to(new_xeno)
|
||||
qdel(src)
|
||||
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/assess_threat(judgement_criteria, lasercolor = "", datum/callback/weaponcheck=null) // beepsky won't hunt aliums
|
||||
return -10
|
||||
|
||||
/mob/living/carbon/alien/handle_environment(datum/gas_mixture/environment)
|
||||
if(!environment)
|
||||
return
|
||||
|
||||
var/loc_temp = get_temperature(environment)
|
||||
|
||||
// Aliens are now weak to fire.
|
||||
|
||||
//After then, it reacts to the surrounding atmosphere based on your thermal protection
|
||||
if(!on_fire) // If you're on fire, ignore local air temperature
|
||||
if(loc_temp > bodytemperature)
|
||||
//Place is hotter than we are
|
||||
var/thermal_protection = heat_protection //This returns a 0 - 1 value, which corresponds to the percentage of heat protection.
|
||||
if(thermal_protection < 1)
|
||||
bodytemperature += (1-thermal_protection) * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR)
|
||||
else
|
||||
bodytemperature += 1 * ((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR)
|
||||
|
||||
if(bodytemperature > 360.15)
|
||||
//Body temperature is too hot.
|
||||
throw_alert("alien_fire", /obj/screen/alert/alien_fire)
|
||||
switch(bodytemperature)
|
||||
if(360 to 400)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_1, BURN)
|
||||
if(400 to 460)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
|
||||
if(460 to INFINITY)
|
||||
if(on_fire)
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_3, BURN)
|
||||
else
|
||||
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
|
||||
else
|
||||
clear_alert("alien_fire")
|
||||
|
||||
/mob/living/carbon/alien/reagent_check(datum/reagent/R) //can metabolize all reagents
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/alien/IsAdvancedToolUser()
|
||||
return has_fine_manipulation
|
||||
|
||||
/mob/living/carbon/alien/Stat()
|
||||
..()
|
||||
|
||||
if(statpanel("Status"))
|
||||
stat(null, "Intent: [a_intent]")
|
||||
|
||||
/mob/living/carbon/alien/getTrail()
|
||||
if(getBruteLoss() < 200)
|
||||
return pick (list("xltrails_1", "xltrails2"))
|
||||
else
|
||||
return pick (list("xttrails_1", "xttrails2"))
|
||||
/*----------------------------------------
|
||||
Proc: AddInfectionImages()
|
||||
Des: Gives the client of the alien an image on each infected mob.
|
||||
----------------------------------------*/
|
||||
/mob/living/carbon/alien/proc/AddInfectionImages()
|
||||
if (client)
|
||||
for (var/mob/living/C in GLOB.mob_list)
|
||||
if(C.status_flags & XENO_HOST)
|
||||
var/obj/item/organ/body_egg/alien_embryo/A = C.getorgan(/obj/item/organ/body_egg/alien_embryo)
|
||||
if(A)
|
||||
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/alien/proc/RemoveInfectionImages()
|
||||
if (client)
|
||||
for(var/image/I in client.images)
|
||||
if(dd_hasprefix_case(I.icon_state, "infected"))
|
||||
qdel(I)
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/canBeHandcuffed()
|
||||
return 1
|
||||
|
||||
/mob/living/carbon/alien/get_standard_pixel_y_offset(lying = 0)
|
||||
return initial(pixel_y)
|
||||
|
||||
/mob/living/carbon/alien/proc/alien_evolve(mob/living/carbon/alien/new_xeno)
|
||||
to_chat(src, "<span class='noticealien'>You begin to evolve!</span>")
|
||||
visible_message("<span class='alertalien'>[src] begins to twist and contort!</span>")
|
||||
new_xeno.setDir(dir)
|
||||
if(!alien_name_regex.Find(name))
|
||||
new_xeno.name = name
|
||||
new_xeno.real_name = real_name
|
||||
if(mind)
|
||||
mind.transfer_to(new_xeno)
|
||||
qdel(src)
|
||||
|
||||
// TODO make orbiters orbit the new xeno, or make xenos species rather than types
|
||||
|
||||
#undef HEAT_DAMAGE_LEVEL_1
|
||||
#undef HEAT_DAMAGE_LEVEL_2
|
||||
#undef HEAT_DAMAGE_LEVEL_3
|
||||
|
||||
/mob/living/carbon/alien/can_hold_items()
|
||||
return has_fine_manipulation
|
||||
#undef HEAT_DAMAGE_LEVEL_1
|
||||
#undef HEAT_DAMAGE_LEVEL_2
|
||||
#undef HEAT_DAMAGE_LEVEL_3
|
||||
|
||||
/mob/living/carbon/alien/can_hold_items()
|
||||
return has_fine_manipulation
|
||||
|
||||
@@ -21,11 +21,11 @@ In all, this is a lot like the monkey code. /N
|
||||
switch(M.a_intent)
|
||||
|
||||
if ("help")
|
||||
AdjustSleeping(-5)
|
||||
resting = 0
|
||||
AdjustParalysis(-3)
|
||||
AdjustStunned(-3)
|
||||
AdjustWeakened(-3)
|
||||
AdjustStun(-60)
|
||||
AdjustKnockdown(-60)
|
||||
AdjustUnconscious(-60)
|
||||
AdjustSleeping(-100)
|
||||
visible_message("<span class='notice'>[M.name] nuzzles [src] trying to wake [p_them()] up!</span>")
|
||||
|
||||
if ("grab")
|
||||
@@ -116,10 +116,10 @@ In all, this is a lot like the monkey code. /N
|
||||
if(3)
|
||||
take_overall_damage(30,0)
|
||||
if(prob(50))
|
||||
Paralyse(1)
|
||||
Unconscious(20)
|
||||
adjustEarDamage(15,60)
|
||||
|
||||
/mob/living/carbon/alien/soundbang_act(intensity = 1, stun_pwr = 1, damage_pwr = 5, deafen_pwr = 15)
|
||||
/mob/living/carbon/alien/soundbang_act(intensity = 1, stun_pwr = 20, damage_pwr = 5, deafen_pwr = 15)
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/alien/acid_act(acidpwr, acid_volume)
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
/mob/living/carbon/alien/spawn_gibs(with_bodyparts)
|
||||
if(with_bodyparts)
|
||||
new /obj/effect/gibspawner/xeno(loc,viruses)
|
||||
else
|
||||
new /obj/effect/gibspawner/xenobodypartless(loc,viruses)
|
||||
|
||||
/mob/living/carbon/alien/gib_animation()
|
||||
/mob/living/carbon/alien/spawn_gibs(with_bodyparts)
|
||||
if(with_bodyparts)
|
||||
new /obj/effect/gibspawner/xeno(loc,viruses)
|
||||
else
|
||||
new /obj/effect/gibspawner/xenobodypartless(loc,viruses)
|
||||
|
||||
/mob/living/carbon/alien/gib_animation()
|
||||
new /obj/effect/temp_visual/gib_animation(loc, "gibbed-a")
|
||||
|
||||
/mob/living/carbon/alien/spawn_dust()
|
||||
new /obj/effect/decal/remains/xeno(loc)
|
||||
|
||||
/mob/living/carbon/alien/dust_animation()
|
||||
|
||||
/mob/living/carbon/alien/spawn_dust()
|
||||
new /obj/effect/decal/remains/xeno(loc)
|
||||
|
||||
/mob/living/carbon/alien/dust_animation()
|
||||
new /obj/effect/temp_visual/dust_animation(loc, "dust-a")
|
||||
|
||||
@@ -22,7 +22,7 @@ Doesn't work on other aliens/AI.*/
|
||||
action = new(src)
|
||||
|
||||
/obj/effect/proc_holder/alien/Click()
|
||||
if(!istype(usr,/mob/living/carbon))
|
||||
if(!iscarbon(usr))
|
||||
return 1
|
||||
var/mob/living/carbon/user = usr
|
||||
if(cost_check(check_turf,user))
|
||||
|
||||
@@ -1,102 +1,102 @@
|
||||
/mob/living/carbon/alien/humanoid/hunter
|
||||
name = "alien hunter"
|
||||
caste = "h"
|
||||
maxHealth = 125
|
||||
health = 125
|
||||
icon_state = "alienh"
|
||||
var/obj/screen/leap_icon = null
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel/small
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/movement_delay()
|
||||
. = -1 //hunters are sanic
|
||||
. += ..() //but they still need to slow down on stun
|
||||
|
||||
|
||||
//Hunter verbs
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/proc/toggle_leap(message = 1)
|
||||
leap_on_click = !leap_on_click
|
||||
leap_icon.icon_state = "leap_[leap_on_click ? "on":"off"]"
|
||||
update_icons()
|
||||
if(message)
|
||||
to_chat(src, "<span class='noticealien'>You will now [leap_on_click ? "leap at":"slash at"] enemies!</span>")
|
||||
else
|
||||
return
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/ClickOn(atom/A, params)
|
||||
face_atom(A)
|
||||
if(leap_on_click)
|
||||
leap_at(A)
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
#define MAX_ALIEN_LEAP_DIST 7
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/proc/leap_at(atom/A)
|
||||
/mob/living/carbon/alien/humanoid/hunter
|
||||
name = "alien hunter"
|
||||
caste = "h"
|
||||
maxHealth = 125
|
||||
health = 125
|
||||
icon_state = "alienh"
|
||||
var/obj/screen/leap_icon = null
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel/small
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/movement_delay()
|
||||
. = -1 //hunters are sanic
|
||||
. += ..() //but they still need to slow down on stun
|
||||
|
||||
|
||||
//Hunter verbs
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/proc/toggle_leap(message = 1)
|
||||
leap_on_click = !leap_on_click
|
||||
leap_icon.icon_state = "leap_[leap_on_click ? "on":"off"]"
|
||||
update_icons()
|
||||
if(message)
|
||||
to_chat(src, "<span class='noticealien'>You will now [leap_on_click ? "leap at":"slash at"] enemies!</span>")
|
||||
else
|
||||
return
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/ClickOn(atom/A, params)
|
||||
face_atom(A)
|
||||
if(leap_on_click)
|
||||
leap_at(A)
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
#define MAX_ALIEN_LEAP_DIST 7
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/proc/leap_at(atom/A)
|
||||
if(pounce_cooldown > world.time)
|
||||
to_chat(src, "<span class='alertalien'>You are too fatigued to pounce right now!</span>")
|
||||
return
|
||||
|
||||
if(leaping || stat || buckled || lying)
|
||||
return
|
||||
|
||||
if(!has_gravity() || !A.has_gravity())
|
||||
to_chat(src, "<span class='alertalien'>It is unsafe to leap without gravity!</span>")
|
||||
//It's also extremely buggy visually, so it's balance+bugfix
|
||||
return
|
||||
|
||||
else //Maybe uses plasma in the future, although that wouldn't make any sense...
|
||||
leaping = 1
|
||||
weather_immunities += "lava"
|
||||
update_icons()
|
||||
throw_at(A, MAX_ALIEN_LEAP_DIST, 1, spin=0, diagonals_first = 1, callback = CALLBACK(src, .leap_end))
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/proc/leap_end()
|
||||
leaping = 0
|
||||
weather_immunities -= "lava"
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/A)
|
||||
|
||||
if(!leaping)
|
||||
return ..()
|
||||
|
||||
if(A)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
var/blocked = 0
|
||||
if(ishuman(A))
|
||||
var/mob/living/carbon/human/H = A
|
||||
if(H.check_shields(0, "the [name]", src, attack_type = LEAP_ATTACK))
|
||||
blocked = 1
|
||||
if(!blocked)
|
||||
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
|
||||
L.Weaken(5)
|
||||
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
|
||||
step_towards(src,L)
|
||||
else
|
||||
Weaken(2, 1, 1)
|
||||
|
||||
toggle_leap(0)
|
||||
to_chat(src, "<span class='alertalien'>You are too fatigued to pounce right now!</span>")
|
||||
return
|
||||
|
||||
if(leaping || stat || buckled || lying)
|
||||
return
|
||||
|
||||
if(!has_gravity() || !A.has_gravity())
|
||||
to_chat(src, "<span class='alertalien'>It is unsafe to leap without gravity!</span>")
|
||||
//It's also extremely buggy visually, so it's balance+bugfix
|
||||
return
|
||||
|
||||
else //Maybe uses plasma in the future, although that wouldn't make any sense...
|
||||
leaping = 1
|
||||
weather_immunities += "lava"
|
||||
update_icons()
|
||||
throw_at(A, MAX_ALIEN_LEAP_DIST, 1, spin=0, diagonals_first = 1, callback = CALLBACK(src, .leap_end))
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/proc/leap_end()
|
||||
leaping = 0
|
||||
weather_immunities -= "lava"
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/hunter/throw_impact(atom/A)
|
||||
|
||||
if(!leaping)
|
||||
return ..()
|
||||
|
||||
if(A)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
var/blocked = 0
|
||||
if(ishuman(A))
|
||||
var/mob/living/carbon/human/H = A
|
||||
if(H.check_shields(0, "the [name]", src, attack_type = LEAP_ATTACK))
|
||||
blocked = 1
|
||||
if(!blocked)
|
||||
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
|
||||
L.Knockdown(100)
|
||||
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
|
||||
step_towards(src,L)
|
||||
else
|
||||
Knockdown(40, 1, 1)
|
||||
|
||||
toggle_leap(0)
|
||||
pounce_cooldown = world.time + pounce_cooldown_time
|
||||
else if(A.density && !A.CanPass(src))
|
||||
visible_message("<span class ='danger'>[src] smashes into [A]!</span>", "<span class ='alertalien'>[src] smashes into [A]!</span>")
|
||||
Weaken(2, 1, 1)
|
||||
|
||||
if(leaping)
|
||||
leaping = 0
|
||||
update_icons()
|
||||
update_canmove()
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/float(on)
|
||||
if(leaping)
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
else if(A.density && !A.CanPass(src))
|
||||
visible_message("<span class ='danger'>[src] smashes into [A]!</span>", "<span class ='alertalien'>[src] smashes into [A]!</span>")
|
||||
Knockdown(40, 1, 1)
|
||||
|
||||
if(leaping)
|
||||
leaping = 0
|
||||
update_icons()
|
||||
update_canmove()
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/float(on)
|
||||
if(leaping)
|
||||
return
|
||||
..()
|
||||
|
||||
|
||||
|
||||
@@ -45,9 +45,6 @@
|
||||
if(!get_alien_type(/mob/living/carbon/alien/humanoid/royal/queen))
|
||||
var/mob/living/carbon/alien/humanoid/royal/queen/new_xeno = new (user.loc)
|
||||
user.alien_evolve(new_xeno)
|
||||
if(new_xeno.client.prefs.unlock_content)
|
||||
var/datum/action/innate/maid/M = new()
|
||||
M.Grant(new_xeno)
|
||||
return 1
|
||||
else
|
||||
to_chat(user, "<span class='notice'>We already have an alive queen.</span>")
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
|
||||
/mob/living/carbon/alien/humanoid/movement_delay()
|
||||
. = ..()
|
||||
. += move_delay_add + config.alien_delay + sneaking //move_delay_add is used to slow aliens with stuns
|
||||
. += move_delay_add + config.alien_delay + sneaking //move_delay_add is used to slow aliens with stun
|
||||
|
||||
/mob/living/carbon/alien/humanoid/restrained(ignore_grab)
|
||||
. = handcuffed
|
||||
|
||||
@@ -29,10 +29,10 @@
|
||||
playsound(loc, "punch", 25, 1, -1)
|
||||
visible_message("<span class='danger'>[M] has punched [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has punched [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
if ((stat != DEAD) && (damage > 9 || prob(5)))//Regular humans have a very small chance of weakening an alien.
|
||||
Paralyse(2)
|
||||
visible_message("<span class='danger'>[M] has weakened [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has weakened [src]!</span>")
|
||||
if ((stat != DEAD) && (damage > 9 || prob(5)))//Regular humans have a very small chance of knocking an alien down.
|
||||
Unconscious(40)
|
||||
visible_message("<span class='danger'>[M] has knocked [src] down!</span>", \
|
||||
"<span class='userdanger'>[M] has knocked [src] down!</span>")
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
apply_damage(damage, BRUTE, affecting)
|
||||
add_logs(M, src, "attacked")
|
||||
@@ -44,7 +44,7 @@
|
||||
if ("disarm")
|
||||
if (!lying)
|
||||
if (prob(5))
|
||||
Paralyse(2)
|
||||
Unconscious(40)
|
||||
playsound(loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
add_logs(M, src, "pushed")
|
||||
visible_message("<span class='danger'>[M] has pushed down [src]!</span>", \
|
||||
|
||||
@@ -1,188 +1,155 @@
|
||||
/mob/living/carbon/alien/humanoid/royal
|
||||
//Common stuffs for Praetorian and Queen
|
||||
icon = 'icons/mob/alienqueen.dmi'
|
||||
status_flags = 0
|
||||
ventcrawler = VENTCRAWLER_NONE //pull over that ass too fat
|
||||
unique_name = 0
|
||||
pixel_x = -16
|
||||
bubble_icon = "alienroyal"
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
layer = LARGE_MOB_LAYER //above most mobs, but below speechbubbles
|
||||
pressure_resistance = 200 //Because big, stompy xenos should not be blown around like paper.
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno = 20, /obj/item/stack/sheet/animalhide/xeno = 3)
|
||||
|
||||
var/alt_inhands_file = 'icons/mob/alienqueen.dmi'
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/can_inject()
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen
|
||||
name = "alien queen"
|
||||
caste = "q"
|
||||
maxHealth = 400
|
||||
health = 400
|
||||
icon_state = "alienq"
|
||||
var/datum/action/small_sprite/smallsprite = new/datum/action/small_sprite()
|
||||
|
||||
/datum/action/small_sprite
|
||||
name = "Toggle Giant Sprite - Others will always see you as giant"
|
||||
button_icon_state = "smallqueen"
|
||||
background_icon_state = "bg_alien"
|
||||
var/small = 0
|
||||
|
||||
/datum/action/small_sprite/Trigger()
|
||||
..()
|
||||
if(!small)
|
||||
var/image/I = image(icon = 'icons/mob/alien.dmi' , icon_state = "alienq", loc = owner)
|
||||
I.override = 1
|
||||
I.pixel_x -= owner.pixel_x
|
||||
I.pixel_y -= owner.pixel_y
|
||||
/mob/living/carbon/alien/humanoid/royal
|
||||
//Common stuffs for Praetorian and Queen
|
||||
icon = 'icons/mob/alienqueen.dmi'
|
||||
status_flags = 0
|
||||
ventcrawler = VENTCRAWLER_NONE //pull over that ass too fat
|
||||
unique_name = 0
|
||||
pixel_x = -16
|
||||
bubble_icon = "alienroyal"
|
||||
mob_size = MOB_SIZE_LARGE
|
||||
layer = LARGE_MOB_LAYER //above most mobs, but below speechbubbles
|
||||
pressure_resistance = 200 //Because big, stompy xenos should not be blown around like paper.
|
||||
butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno = 20, /obj/item/stack/sheet/animalhide/xeno = 3)
|
||||
|
||||
var/alt_inhands_file = 'icons/mob/alienqueen.dmi'
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/can_inject()
|
||||
return 0
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen
|
||||
name = "alien queen"
|
||||
caste = "q"
|
||||
maxHealth = 400
|
||||
health = 400
|
||||
icon_state = "alienq"
|
||||
var/datum/action/small_sprite/smallsprite = new/datum/action/small_sprite()
|
||||
|
||||
/datum/action/small_sprite
|
||||
name = "Toggle Giant Sprite - Others will always see you as giant"
|
||||
button_icon_state = "smallqueen"
|
||||
background_icon_state = "bg_alien"
|
||||
var/small = 0
|
||||
|
||||
/datum/action/small_sprite/Trigger()
|
||||
..()
|
||||
if(!small)
|
||||
var/image/I = image(icon = 'icons/mob/alien.dmi' , icon_state = "alienq", loc = owner)
|
||||
I.override = 1
|
||||
I.pixel_x -= owner.pixel_x
|
||||
I.pixel_y -= owner.pixel_y
|
||||
owner.add_alt_appearance(/datum/atom_hud/alternate_appearance/basic, "smallqueen", I)
|
||||
|
||||
small = 1
|
||||
else
|
||||
owner.remove_alt_appearance("smallqueen")
|
||||
small = 0
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/Initialize()
|
||||
//there should only be one queen
|
||||
for(var/mob/living/carbon/alien/humanoid/royal/queen/Q in GLOB.living_mob_list)
|
||||
if(Q == src)
|
||||
continue
|
||||
if(Q.stat == DEAD)
|
||||
continue
|
||||
if(Q.client)
|
||||
name = "alien princess ([rand(1, 999)])" //if this is too cutesy feel free to change it/remove it.
|
||||
break
|
||||
|
||||
real_name = src.name
|
||||
|
||||
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src))
|
||||
AddAbility(new/obj/effect/proc_holder/alien/royal/queen/promote())
|
||||
smallsprite.Grant(src)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel/large/queen
|
||||
internal_organs += new /obj/item/organ/alien/resinspinner
|
||||
internal_organs += new /obj/item/organ/alien/acid
|
||||
internal_organs += new /obj/item/organ/alien/neurotoxin
|
||||
internal_organs += new /obj/item/organ/alien/eggsac
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/movement_delay()
|
||||
. = ..()
|
||||
. += 3
|
||||
|
||||
//Queen verbs
|
||||
/obj/effect/proc_holder/alien/lay_egg
|
||||
name = "Lay Egg"
|
||||
desc = "Lay an egg to produce huggers to impregnate prey with."
|
||||
plasma_cost = 75
|
||||
check_turf = 1
|
||||
action_icon_state = "alien_egg"
|
||||
|
||||
/obj/effect/proc_holder/alien/lay_egg/fire(mob/living/carbon/user)
|
||||
if(locate(/obj/structure/alien/egg) in get_turf(user))
|
||||
to_chat(user, "There's already an egg here.")
|
||||
return 0
|
||||
user.visible_message("<span class='alertalien'>[user] has laid an egg!</span>")
|
||||
new /obj/structure/alien/egg(user.loc)
|
||||
return 1
|
||||
|
||||
//Button to let queen choose her praetorian.
|
||||
/obj/effect/proc_holder/alien/royal/queen/promote
|
||||
name = "Create Royal Parasite"
|
||||
desc = "Produce a royal parasite to grant one of your children the honor of being your Praetorian."
|
||||
plasma_cost = 500 //Plasma cost used on promotion, not spawning the parasite.
|
||||
|
||||
action_icon_state = "alien_queen_promote"
|
||||
|
||||
|
||||
|
||||
/obj/effect/proc_holder/alien/royal/queen/promote/fire(mob/living/carbon/alien/user)
|
||||
var/obj/item/queenpromote/prom
|
||||
if(get_alien_type(/mob/living/carbon/alien/humanoid/royal/praetorian/))
|
||||
to_chat(user, "<span class='noticealien'>You already have a Praetorian!</span>")
|
||||
return 0
|
||||
else
|
||||
for(prom in user)
|
||||
to_chat(user, "<span class='noticealien'>You discard [prom].</span>")
|
||||
qdel(prom)
|
||||
return 0
|
||||
|
||||
prom = new (user.loc)
|
||||
if(!user.put_in_active_hand(prom, 1))
|
||||
to_chat(user, "<span class='warning'>You must empty your hands before preparing the parasite.</span>")
|
||||
return 0
|
||||
else //Just in case telling the player only once is not enough!
|
||||
to_chat(user, "<span class='noticealien'>Use the royal parasite on one of your children to promote her to Praetorian!</span>")
|
||||
return 0
|
||||
|
||||
/obj/item/queenpromote
|
||||
name = "\improper royal parasite"
|
||||
desc = "Inject this into one of your grown children to promote her to a Praetorian!"
|
||||
icon_state = "alien_medal"
|
||||
flags = ABSTRACT|NODROP|DROPDEL
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
|
||||
/obj/item/queenpromote/attack(mob/living/M, mob/living/carbon/alien/humanoid/user)
|
||||
if(!isalienadult(M) || istype(M, /mob/living/carbon/alien/humanoid/royal))
|
||||
to_chat(user, "<span class='noticealien'>You may only use this with your adult, non-royal children!</span>")
|
||||
return
|
||||
if(get_alien_type(/mob/living/carbon/alien/humanoid/royal/praetorian/))
|
||||
to_chat(user, "<span class='noticealien'>You already have a Praetorian!</span>")
|
||||
return
|
||||
|
||||
var/mob/living/carbon/alien/humanoid/A = M
|
||||
if(A.stat == CONSCIOUS && A.mind && A.key)
|
||||
if(!user.usePlasma(500))
|
||||
to_chat(user, "<span class='noticealien'>You must have 500 plasma stored to use this!</span>")
|
||||
return
|
||||
|
||||
to_chat(A, "<span class='noticealien'>The queen has granted you a promotion to Praetorian!</span>")
|
||||
user.visible_message("<span class='alertalien'>[A] begins to expand, twist and contort!</span>")
|
||||
var/mob/living/carbon/alien/humanoid/royal/praetorian/new_prae = new (A.loc)
|
||||
A.mind.transfer_to(new_prae)
|
||||
qdel(A)
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>This child must be alert and responsive to become a Praetorian!</span>")
|
||||
|
||||
/obj/item/queenpromote/attack_self(mob/user)
|
||||
to_chat(user, "<span class='noticealien'>You discard [src].</span>")
|
||||
qdel(src)
|
||||
|
||||
//:^)
|
||||
/datum/action/innate/maid
|
||||
name = "Maidify"
|
||||
button_icon_state = "alien_queen_maidify"
|
||||
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUNNED|AB_CHECK_CONSCIOUS|AB_CHECK_LYING
|
||||
background_icon_state = "bg_alien"
|
||||
|
||||
/datum/action/innate/maid/Activate()
|
||||
var/mob/living/carbon/alien/humanoid/royal/queen/A = owner
|
||||
A.maidify()
|
||||
active = TRUE
|
||||
|
||||
/datum/action/innate/maid/Deactivate()
|
||||
var/mob/living/carbon/alien/humanoid/royal/queen/A = owner
|
||||
A.unmaidify()
|
||||
active = FALSE
|
||||
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/proc/maidify()
|
||||
name = "alien queen maid"
|
||||
desc = "Lusty, Sexy"
|
||||
icon_state = "alienqmaid"
|
||||
caste = "qmaid"
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/proc/unmaidify()
|
||||
name = "alien queen"
|
||||
desc = ""
|
||||
icon_state = "alienq"
|
||||
caste = "q"
|
||||
update_icons()
|
||||
|
||||
small = 1
|
||||
else
|
||||
owner.remove_alt_appearance("smallqueen")
|
||||
small = 0
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/Initialize()
|
||||
//there should only be one queen
|
||||
for(var/mob/living/carbon/alien/humanoid/royal/queen/Q in GLOB.living_mob_list)
|
||||
if(Q == src)
|
||||
continue
|
||||
if(Q.stat == DEAD)
|
||||
continue
|
||||
if(Q.client)
|
||||
name = "alien princess ([rand(1, 999)])" //if this is too cutesy feel free to change it/remove it.
|
||||
break
|
||||
|
||||
real_name = src.name
|
||||
|
||||
AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/repulse/xeno(src))
|
||||
AddAbility(new/obj/effect/proc_holder/alien/royal/queen/promote())
|
||||
smallsprite.Grant(src)
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/create_internal_organs()
|
||||
internal_organs += new /obj/item/organ/alien/plasmavessel/large/queen
|
||||
internal_organs += new /obj/item/organ/alien/resinspinner
|
||||
internal_organs += new /obj/item/organ/alien/acid
|
||||
internal_organs += new /obj/item/organ/alien/neurotoxin
|
||||
internal_organs += new /obj/item/organ/alien/eggsac
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/movement_delay()
|
||||
. = ..()
|
||||
. += 3
|
||||
|
||||
//Queen verbs
|
||||
/obj/effect/proc_holder/alien/lay_egg
|
||||
name = "Lay Egg"
|
||||
desc = "Lay an egg to produce huggers to impregnate prey with."
|
||||
plasma_cost = 75
|
||||
check_turf = 1
|
||||
action_icon_state = "alien_egg"
|
||||
|
||||
/obj/effect/proc_holder/alien/lay_egg/fire(mob/living/carbon/user)
|
||||
if(locate(/obj/structure/alien/egg) in get_turf(user))
|
||||
to_chat(user, "There's already an egg here.")
|
||||
return 0
|
||||
user.visible_message("<span class='alertalien'>[user] has laid an egg!</span>")
|
||||
new /obj/structure/alien/egg(user.loc)
|
||||
return 1
|
||||
|
||||
//Button to let queen choose her praetorian.
|
||||
/obj/effect/proc_holder/alien/royal/queen/promote
|
||||
name = "Create Royal Parasite"
|
||||
desc = "Produce a royal parasite to grant one of your children the honor of being your Praetorian."
|
||||
plasma_cost = 500 //Plasma cost used on promotion, not spawning the parasite.
|
||||
|
||||
action_icon_state = "alien_queen_promote"
|
||||
|
||||
|
||||
|
||||
/obj/effect/proc_holder/alien/royal/queen/promote/fire(mob/living/carbon/alien/user)
|
||||
var/obj/item/queenpromote/prom
|
||||
if(get_alien_type(/mob/living/carbon/alien/humanoid/royal/praetorian/))
|
||||
to_chat(user, "<span class='noticealien'>You already have a Praetorian!</span>")
|
||||
return 0
|
||||
else
|
||||
for(prom in user)
|
||||
to_chat(user, "<span class='noticealien'>You discard [prom].</span>")
|
||||
qdel(prom)
|
||||
return 0
|
||||
|
||||
prom = new (user.loc)
|
||||
if(!user.put_in_active_hand(prom, 1))
|
||||
to_chat(user, "<span class='warning'>You must empty your hands before preparing the parasite.</span>")
|
||||
return 0
|
||||
else //Just in case telling the player only once is not enough!
|
||||
to_chat(user, "<span class='noticealien'>Use the royal parasite on one of your children to promote her to Praetorian!</span>")
|
||||
return 0
|
||||
|
||||
/obj/item/queenpromote
|
||||
name = "\improper royal parasite"
|
||||
desc = "Inject this into one of your grown children to promote her to a Praetorian!"
|
||||
icon_state = "alien_medal"
|
||||
flags = ABSTRACT|NODROP|DROPDEL
|
||||
icon = 'icons/mob/alien.dmi'
|
||||
|
||||
/obj/item/queenpromote/attack(mob/living/M, mob/living/carbon/alien/humanoid/user)
|
||||
if(!isalienadult(M) || isalienroyal(M))
|
||||
to_chat(user, "<span class='noticealien'>You may only use this with your adult, non-royal children!</span>")
|
||||
return
|
||||
if(get_alien_type(/mob/living/carbon/alien/humanoid/royal/praetorian/))
|
||||
to_chat(user, "<span class='noticealien'>You already have a Praetorian!</span>")
|
||||
return
|
||||
|
||||
var/mob/living/carbon/alien/humanoid/A = M
|
||||
if(A.stat == CONSCIOUS && A.mind && A.key)
|
||||
if(!user.usePlasma(500))
|
||||
to_chat(user, "<span class='noticealien'>You must have 500 plasma stored to use this!</span>")
|
||||
return
|
||||
|
||||
to_chat(A, "<span class='noticealien'>The queen has granted you a promotion to Praetorian!</span>")
|
||||
user.visible_message("<span class='alertalien'>[A] begins to expand, twist and contort!</span>")
|
||||
var/mob/living/carbon/alien/humanoid/royal/praetorian/new_prae = new (A.loc)
|
||||
A.mind.transfer_to(new_prae)
|
||||
qdel(A)
|
||||
qdel(src)
|
||||
return
|
||||
else
|
||||
to_chat(user, "<span class='warning'>This child must be alert and responsive to become a Praetorian!</span>")
|
||||
|
||||
/obj/item/queenpromote/attack_self(mob/user)
|
||||
to_chat(user, "<span class='noticealien'>You discard [src].</span>")
|
||||
qdel(src)
|
||||
|
||||
@@ -1,93 +1,94 @@
|
||||
|
||||
/mob/living/carbon/alien/humanoid/update_icons()
|
||||
cut_overlays()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/update_icons()
|
||||
cut_overlays()
|
||||
for(var/I in overlays_standing)
|
||||
add_overlay(I)
|
||||
|
||||
if(stat == DEAD)
|
||||
//If we mostly took damage from fire
|
||||
if(fireloss > 125)
|
||||
icon_state = "alien[caste]_husked"
|
||||
else
|
||||
icon_state = "alien[caste]_dead"
|
||||
|
||||
else if((stat == UNCONSCIOUS && !sleeping) || weakened)
|
||||
icon_state = "alien[caste]_unconscious"
|
||||
else if(leap_on_click)
|
||||
icon_state = "alien[caste]_pounce"
|
||||
|
||||
else if(lying || resting || sleeping)
|
||||
icon_state = "alien[caste]_sleep"
|
||||
else if(mob_size == MOB_SIZE_LARGE)
|
||||
icon_state = "alien[caste]"
|
||||
if(drooling)
|
||||
add_overlay("alienspit_[caste]")
|
||||
else
|
||||
icon_state = "alien[caste]"
|
||||
if(drooling)
|
||||
add_overlay("alienspit")
|
||||
|
||||
if(leaping)
|
||||
if(alt_icon == initial(alt_icon))
|
||||
var/old_icon = icon
|
||||
icon = alt_icon
|
||||
alt_icon = old_icon
|
||||
icon_state = "alien[caste]_leap"
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
else
|
||||
if(alt_icon != initial(alt_icon))
|
||||
var/old_icon = icon
|
||||
icon = alt_icon
|
||||
alt_icon = old_icon
|
||||
pixel_x = get_standard_pixel_x_offset(lying)
|
||||
pixel_y = get_standard_pixel_y_offset(lying)
|
||||
update_inv_hands()
|
||||
update_inv_handcuffed()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/regenerate_icons()
|
||||
if(!..())
|
||||
// update_icons() //Handled in update_transform(), leaving this here as a reminder
|
||||
update_transform()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/update_transform() //The old method of updating lying/standing was update_icons(). Aliens still expect that.
|
||||
if(lying > 0)
|
||||
lying = 90 //Anything else looks retarded
|
||||
..()
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/update_inv_handcuffed()
|
||||
remove_overlay(HANDCUFF_LAYER)
|
||||
var/cuff_icon = "aliencuff"
|
||||
var/dmi_file = 'icons/mob/alien.dmi'
|
||||
|
||||
if(mob_size == MOB_SIZE_LARGE)
|
||||
cuff_icon = "aliencuff_[caste]"
|
||||
dmi_file = 'icons/mob/alienqueen.dmi'
|
||||
|
||||
if(handcuffed)
|
||||
add_overlay(I)
|
||||
|
||||
var/asleep = IsSleeping()
|
||||
if(stat == DEAD)
|
||||
//If we mostly took damage from fire
|
||||
if(fireloss > 125)
|
||||
icon_state = "alien[caste]_husked"
|
||||
else
|
||||
icon_state = "alien[caste]_dead"
|
||||
|
||||
else if((stat == UNCONSCIOUS && !asleep) || IsKnockdown())
|
||||
icon_state = "alien[caste]_unconscious"
|
||||
else if(leap_on_click)
|
||||
icon_state = "alien[caste]_pounce"
|
||||
|
||||
else if(lying || resting || asleep)
|
||||
icon_state = "alien[caste]_sleep"
|
||||
else if(mob_size == MOB_SIZE_LARGE)
|
||||
icon_state = "alien[caste]"
|
||||
if(drooling)
|
||||
add_overlay("alienspit_[caste]")
|
||||
else
|
||||
icon_state = "alien[caste]"
|
||||
if(drooling)
|
||||
add_overlay("alienspit")
|
||||
|
||||
if(leaping)
|
||||
if(alt_icon == initial(alt_icon))
|
||||
var/old_icon = icon
|
||||
icon = alt_icon
|
||||
alt_icon = old_icon
|
||||
icon_state = "alien[caste]_leap"
|
||||
pixel_x = -32
|
||||
pixel_y = -32
|
||||
else
|
||||
if(alt_icon != initial(alt_icon))
|
||||
var/old_icon = icon
|
||||
icon = alt_icon
|
||||
alt_icon = old_icon
|
||||
pixel_x = get_standard_pixel_x_offset(lying)
|
||||
pixel_y = get_standard_pixel_y_offset(lying)
|
||||
update_inv_hands()
|
||||
update_inv_handcuffed()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/regenerate_icons()
|
||||
if(!..())
|
||||
// update_icons() //Handled in update_transform(), leaving this here as a reminder
|
||||
update_transform()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/update_transform() //The old method of updating lying/standing was update_icons(). Aliens still expect that.
|
||||
if(lying > 0)
|
||||
lying = 90 //Anything else looks retarded
|
||||
..()
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/humanoid/update_inv_handcuffed()
|
||||
remove_overlay(HANDCUFF_LAYER)
|
||||
var/cuff_icon = "aliencuff"
|
||||
var/dmi_file = 'icons/mob/alien.dmi'
|
||||
|
||||
if(mob_size == MOB_SIZE_LARGE)
|
||||
cuff_icon = "aliencuff_[caste]"
|
||||
dmi_file = 'icons/mob/alienqueen.dmi'
|
||||
|
||||
if(handcuffed)
|
||||
overlays_standing[HANDCUFF_LAYER] = mutable_appearance(dmi_file, cuff_icon, -HANDCUFF_LAYER)
|
||||
apply_overlay(HANDCUFF_LAYER)
|
||||
|
||||
//Royals have bigger sprites, so inhand things must be handled differently.
|
||||
/mob/living/carbon/alien/humanoid/royal/update_inv_hands()
|
||||
..()
|
||||
remove_overlay(HANDS_LAYER)
|
||||
var/list/hands = list()
|
||||
|
||||
var/obj/item/l_hand = get_item_for_held_index(1)
|
||||
if(l_hand)
|
||||
var/itm_state = l_hand.item_state
|
||||
if(!itm_state)
|
||||
itm_state = l_hand.icon_state
|
||||
apply_overlay(HANDCUFF_LAYER)
|
||||
|
||||
//Royals have bigger sprites, so inhand things must be handled differently.
|
||||
/mob/living/carbon/alien/humanoid/royal/update_inv_hands()
|
||||
..()
|
||||
remove_overlay(HANDS_LAYER)
|
||||
var/list/hands = list()
|
||||
|
||||
var/obj/item/l_hand = get_item_for_held_index(1)
|
||||
if(l_hand)
|
||||
var/itm_state = l_hand.item_state
|
||||
if(!itm_state)
|
||||
itm_state = l_hand.icon_state
|
||||
hands += mutable_appearance(alt_inhands_file, "[itm_state][caste]_l", -HANDS_LAYER)
|
||||
|
||||
var/obj/item/r_hand = get_item_for_held_index(2)
|
||||
if(r_hand)
|
||||
var/itm_state = r_hand.item_state
|
||||
if(!itm_state)
|
||||
itm_state = r_hand.icon_state
|
||||
|
||||
var/obj/item/r_hand = get_item_for_held_index(2)
|
||||
if(r_hand)
|
||||
var/itm_state = r_hand.item_state
|
||||
if(!itm_state)
|
||||
itm_state = r_hand.icon_state
|
||||
hands += mutable_appearance(alt_inhands_file, "[itm_state][caste]_r", -HANDS_LAYER)
|
||||
|
||||
overlays_standing[HANDS_LAYER] = hands
|
||||
|
||||
overlays_standing[HANDS_LAYER] = hands
|
||||
apply_overlay(HANDS_LAYER)
|
||||
@@ -1,22 +1,22 @@
|
||||
/mob/living/carbon/alien/larva/death(gibbed)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
|
||||
. = ..()
|
||||
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/larva/spawn_gibs(with_bodyparts)
|
||||
if(with_bodyparts)
|
||||
new /obj/effect/gibspawner/larva(loc,viruses)
|
||||
else
|
||||
new /obj/effect/gibspawner/larvabodypartless(loc,viruses)
|
||||
|
||||
/mob/living/carbon/alien/larva/gib_animation()
|
||||
/mob/living/carbon/alien/larva/death(gibbed)
|
||||
if(stat == DEAD)
|
||||
return
|
||||
|
||||
. = ..()
|
||||
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/larva/spawn_gibs(with_bodyparts)
|
||||
if(with_bodyparts)
|
||||
new /obj/effect/gibspawner/larva(loc,viruses)
|
||||
else
|
||||
new /obj/effect/gibspawner/larvabodypartless(loc,viruses)
|
||||
|
||||
/mob/living/carbon/alien/larva/gib_animation()
|
||||
new /obj/effect/temp_visual/gib_animation(loc, "gibbed-l")
|
||||
|
||||
/mob/living/carbon/alien/larva/spawn_dust()
|
||||
new /obj/effect/decal/remains/xeno(loc)
|
||||
|
||||
/mob/living/carbon/alien/larva/dust_animation()
|
||||
|
||||
/mob/living/carbon/alien/larva/spawn_dust()
|
||||
new /obj/effect/decal/remains/xeno(loc)
|
||||
|
||||
/mob/living/carbon/alien/larva/dust_animation()
|
||||
new /obj/effect/temp_visual/dust_animation(loc, "dust-l")
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
visible_message("<span class='danger'>[M] has kicked [src]!</span>", \
|
||||
"<span class='userdanger'>[M] has kicked [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
if ((stat != DEAD) && (damage > 4.9))
|
||||
Paralyse(rand(5,10))
|
||||
Unconscious(rand(100,200))
|
||||
|
||||
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
|
||||
apply_damage(damage, BRUTE, affecting)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
if(health<= -maxHealth || !getorgan(/obj/item/organ/brain))
|
||||
death()
|
||||
return
|
||||
if(paralysis || sleeping || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT)
|
||||
if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (status_flags & FAKEDEATH) || health <= HEALTH_THRESHOLD_CRIT)
|
||||
if(stat == CONSCIOUS)
|
||||
stat = UNCONSCIOUS
|
||||
blind_eyes(1)
|
||||
|
||||
@@ -12,11 +12,11 @@
|
||||
|
||||
if(stat == DEAD)
|
||||
icon_state = "larva[state]_dead"
|
||||
else if (handcuffed || legcuffed) //This should be an overlay. Who made this an icon_state?
|
||||
else if(handcuffed || legcuffed) //This should be an overlay. Who made this an icon_state?
|
||||
icon_state = "larva[state]_cuff"
|
||||
else if(stat == UNCONSCIOUS || lying || resting)
|
||||
icon_state = "larva[state]_sleep"
|
||||
else if (stunned)
|
||||
else if(IsStun())
|
||||
icon_state = "larva[state]_stun"
|
||||
else
|
||||
icon_state = "larva[state]"
|
||||
|
||||
@@ -130,12 +130,12 @@
|
||||
to_chat(owner, "<span class='userdanger'>Your Queen has been struck down!</span>")
|
||||
to_chat(owner, "<span class='danger'>You are struck with overwhelming agony! You feel confused, and your connection to the hivemind is severed.")
|
||||
owner.emote("roar")
|
||||
owner.Stun(10) //Actually just slows them down a bit.
|
||||
owner.Stun(200) //Actually just slows them down a bit.
|
||||
|
||||
else if(ishuman(owner)) //Humans, being more fragile, are more overwhelmed by the mental backlash.
|
||||
to_chat(owner, "<span class='danger'>You feel a splitting pain in your head, and are struck with a wave of nausea. You cannot hear the hivemind anymore!")
|
||||
owner.emote("scream")
|
||||
owner.Weaken(5)
|
||||
owner.Knockdown(100)
|
||||
|
||||
owner.jitteriness += 30
|
||||
owner.confused += 30
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
/mob/living/proc/alien_talk(message, shown_name = real_name)
|
||||
log_say("[key_name(src)] : [message]")
|
||||
message = trim(message)
|
||||
if(!message) return
|
||||
|
||||
var/message_a = say_quote(message, get_spans())
|
||||
var/rendered = "<i><span class='alien'>Hivemind, <span class='name'>[shown_name]</span> <span class='message'>[message_a]</span></span></i>"
|
||||
for(var/mob/S in GLOB.player_list)
|
||||
if(!S.stat && S.hivecheck())
|
||||
to_chat(S, rendered)
|
||||
if(S in GLOB.dead_mob_list)
|
||||
var/link = FOLLOW_LINK(S, src)
|
||||
to_chat(S, "[link] [rendered]")
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/alien_talk(message, shown_name = name)
|
||||
shown_name = "<FONT size = 3>[shown_name]</FONT>"
|
||||
..(message, shown_name)
|
||||
|
||||
/mob/living/carbon/hivecheck()
|
||||
var/obj/item/organ/alien/hivenode/N = getorgan(/obj/item/organ/alien/hivenode)
|
||||
if(N && !N.recent_queen_death) //Mob has alien hive node and is not under the dead queen special effect.
|
||||
return N
|
||||
log_say("[key_name(src)] : [message]")
|
||||
message = trim(message)
|
||||
if(!message) return
|
||||
|
||||
var/message_a = say_quote(message, get_spans())
|
||||
var/rendered = "<i><span class='alien'>Hivemind, <span class='name'>[shown_name]</span> <span class='message'>[message_a]</span></span></i>"
|
||||
for(var/mob/S in GLOB.player_list)
|
||||
if(!S.stat && S.hivecheck())
|
||||
to_chat(S, rendered)
|
||||
if(S in GLOB.dead_mob_list)
|
||||
var/link = FOLLOW_LINK(S, src)
|
||||
to_chat(S, "[link] [rendered]")
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/alien_talk(message, shown_name = name)
|
||||
shown_name = "<FONT size = 3>[shown_name]</FONT>"
|
||||
..(message, shown_name)
|
||||
|
||||
/mob/living/carbon/hivecheck()
|
||||
var/obj/item/organ/alien/hivenode/N = getorgan(/obj/item/organ/alien/hivenode)
|
||||
if(N && !N.recent_queen_death) //Mob has alien hive node and is not under the dead queen special effect.
|
||||
return N
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
|
||||
/mob/living/carbon/alien/proc/updatePlasmaDisplay()
|
||||
if(hud_used) //clientless aliens
|
||||
hud_used.alien_plasma_display.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='magenta'>[round(getPlasma())]</font></div>"
|
||||
|
||||
/mob/living/carbon/alien/larva/updatePlasmaDisplay()
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/proc/findQueen()
|
||||
if(hud_used)
|
||||
hud_used.alien_queen_finder.cut_overlays()
|
||||
var/mob/queen = get_alien_type(/mob/living/carbon/alien/humanoid/royal/queen)
|
||||
if(!queen)
|
||||
return
|
||||
var/turf/Q = get_turf(queen)
|
||||
var/turf/A = get_turf(src)
|
||||
if(Q.z != A.z) //The queen is on a different Z level, we cannot sense that far.
|
||||
return
|
||||
var/Qdir = get_dir(src, Q)
|
||||
var/Qdist = get_dist(src, Q)
|
||||
var/finder_icon = "finder_center" //Overlay showed when adjacent to or on top of the queen!
|
||||
switch(Qdist)
|
||||
if(2 to 7)
|
||||
finder_icon = "finder_near"
|
||||
if(8 to 20)
|
||||
finder_icon = "finder_med"
|
||||
if(21 to INFINITY)
|
||||
finder_icon = "finder_far"
|
||||
|
||||
/mob/living/carbon/alien/proc/updatePlasmaDisplay()
|
||||
if(hud_used) //clientless aliens
|
||||
hud_used.alien_plasma_display.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'><font color='magenta'>[round(getPlasma())]</font></div>"
|
||||
|
||||
/mob/living/carbon/alien/larva/updatePlasmaDisplay()
|
||||
return
|
||||
|
||||
/mob/living/carbon/alien/proc/findQueen()
|
||||
if(hud_used)
|
||||
hud_used.alien_queen_finder.cut_overlays()
|
||||
var/mob/queen = get_alien_type(/mob/living/carbon/alien/humanoid/royal/queen)
|
||||
if(!queen)
|
||||
return
|
||||
var/turf/Q = get_turf(queen)
|
||||
var/turf/A = get_turf(src)
|
||||
if(Q.z != A.z) //The queen is on a different Z level, we cannot sense that far.
|
||||
return
|
||||
var/Qdir = get_dir(src, Q)
|
||||
var/Qdist = get_dist(src, Q)
|
||||
var/finder_icon = "finder_center" //Overlay showed when adjacent to or on top of the queen!
|
||||
switch(Qdist)
|
||||
if(2 to 7)
|
||||
finder_icon = "finder_near"
|
||||
if(8 to 20)
|
||||
finder_icon = "finder_med"
|
||||
if(21 to INFINITY)
|
||||
finder_icon = "finder_far"
|
||||
var/image/finder_eye = image('icons/mob/screen_alien.dmi', finder_icon, dir = Qdir)
|
||||
hud_used.alien_queen_finder.add_overlay(finder_eye)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/findQueen()
|
||||
hud_used.alien_queen_finder.add_overlay(finder_eye)
|
||||
|
||||
/mob/living/carbon/alien/humanoid/royal/queen/findQueen()
|
||||
return //Queen already knows where she is. Hopefully.
|
||||
@@ -1,50 +1,50 @@
|
||||
|
||||
|
||||
//TODO: Make these simple_animals
|
||||
|
||||
#define MIN_IMPREGNATION_TIME 100 //time it takes to impregnate someone
|
||||
#define MAX_IMPREGNATION_TIME 150
|
||||
|
||||
#define MIN_ACTIVE_TIME 200 //time between being dropped and going idle
|
||||
#define 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 = WEIGHT_CLASS_TINY //note: can be picked up by aliens unlike most other items of w_class below 4
|
||||
flags = MASKINTERNALS
|
||||
throw_range = 5
|
||||
tint = 3
|
||||
flags_cover = MASKCOVERSEYES | MASKCOVERSMOUTH
|
||||
layer = MOB_LAYER
|
||||
|
||||
|
||||
//TODO: Make these simple_animals
|
||||
|
||||
#define MIN_IMPREGNATION_TIME 100 //time it takes to impregnate someone
|
||||
#define MAX_IMPREGNATION_TIME 150
|
||||
|
||||
#define MIN_ACTIVE_TIME 200 //time between being dropped and going idle
|
||||
#define 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 = WEIGHT_CLASS_TINY //note: can be picked up by aliens unlike most other items of w_class below 4
|
||||
flags = MASKINTERNALS
|
||||
throw_range = 5
|
||||
tint = 3
|
||||
flags_cover = MASKCOVERSEYES | MASKCOVERSMOUTH
|
||||
layer = MOB_LAYER
|
||||
obj_integrity = 100
|
||||
max_integrity = 100
|
||||
|
||||
var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
|
||||
|
||||
var/sterile = FALSE
|
||||
var/real = TRUE //0 for the toy, 1 for real. Sure I could istype, but fuck that.
|
||||
var/strength = 5
|
||||
|
||||
var/attached = 0
|
||||
|
||||
/obj/item/clothing/mask/facehugger/lamarr
|
||||
name = "Lamarr"
|
||||
sterile = 1
|
||||
|
||||
/obj/item/clothing/mask/facehugger/dead
|
||||
icon_state = "facehugger_dead"
|
||||
item_state = "facehugger_inactive"
|
||||
stat = DEAD
|
||||
|
||||
/obj/item/clothing/mask/facehugger/impregnated
|
||||
icon_state = "facehugger_impregnated"
|
||||
item_state = "facehugger_impregnated"
|
||||
stat = DEAD
|
||||
|
||||
|
||||
var/stat = CONSCIOUS //UNCONSCIOUS is the idle state in this case
|
||||
|
||||
var/sterile = FALSE
|
||||
var/real = TRUE //0 for the toy, 1 for real. Sure I could istype, but fuck that.
|
||||
var/strength = 5
|
||||
|
||||
var/attached = 0
|
||||
|
||||
/obj/item/clothing/mask/facehugger/lamarr
|
||||
name = "Lamarr"
|
||||
sterile = 1
|
||||
|
||||
/obj/item/clothing/mask/facehugger/dead
|
||||
icon_state = "facehugger_dead"
|
||||
item_state = "facehugger_inactive"
|
||||
stat = DEAD
|
||||
|
||||
/obj/item/clothing/mask/facehugger/impregnated
|
||||
icon_state = "facehugger_impregnated"
|
||||
item_state = "facehugger_impregnated"
|
||||
stat = DEAD
|
||||
|
||||
/obj/item/clothing/mask/facehugger/take_damage(damage_amount, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
|
||||
..()
|
||||
if(obj_integrity < 90)
|
||||
@@ -53,227 +53,227 @@
|
||||
/obj/item/clothing/mask/facehugger/attackby(obj/item/O, mob/user, params)
|
||||
return O.attack_obj(src, user)
|
||||
|
||||
/obj/item/clothing/mask/facehugger/attack_alien(mob/user) //can be picked up by aliens
|
||||
attack_hand(user)
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/attack_hand(mob/user)
|
||||
if((stat == CONSCIOUS && !sterile) && !isalien(user))
|
||||
/obj/item/clothing/mask/facehugger/attack_alien(mob/user) //can be picked up by aliens
|
||||
attack_hand(user)
|
||||
return
|
||||
|
||||
/obj/item/clothing/mask/facehugger/attack_hand(mob/user)
|
||||
if((stat == CONSCIOUS && !sterile) && !isalien(user))
|
||||
if(Leap(user))
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/clothing/mask/facehugger/attack(mob/living/M, mob/user)
|
||||
..()
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/clothing/mask/facehugger/attack(mob/living/M, mob/user)
|
||||
..()
|
||||
if(user.transferItemToLoc(src, get_turf(M)))
|
||||
Leap(M)
|
||||
|
||||
/obj/item/clothing/mask/facehugger/examine(mob/user)
|
||||
..()
|
||||
if(!real)//So that giant red text about probisci doesn't show up.
|
||||
return
|
||||
switch(stat)
|
||||
if(DEAD,UNCONSCIOUS)
|
||||
to_chat(user, "<span class='boldannounce'>[src] is not moving.</span>")
|
||||
if(CONSCIOUS)
|
||||
to_chat(user, "<span class='boldannounce'>[src] seems to be active!</span>")
|
||||
if (sterile)
|
||||
to_chat(user, "<span class='boldannounce'>It looks like the proboscis has been removed.</span>")
|
||||
|
||||
|
||||
/obj/item/clothing/mask/facehugger/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature > 300)
|
||||
Die()
|
||||
|
||||
/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)
|
||||
if(stat == CONSCIOUS)
|
||||
return HasProximity(finder)
|
||||
return 0
|
||||
|
||||
/obj/item/clothing/mask/facehugger/HasProximity(atom/movable/AM as mob|obj)
|
||||
if(CanHug(AM) && Adjacent(AM))
|
||||
|
||||
/obj/item/clothing/mask/facehugger/examine(mob/user)
|
||||
..()
|
||||
if(!real)//So that giant red text about probisci doesn't show up.
|
||||
return
|
||||
switch(stat)
|
||||
if(DEAD,UNCONSCIOUS)
|
||||
to_chat(user, "<span class='boldannounce'>[src] is not moving.</span>")
|
||||
if(CONSCIOUS)
|
||||
to_chat(user, "<span class='boldannounce'>[src] seems to be active!</span>")
|
||||
if (sterile)
|
||||
to_chat(user, "<span class='boldannounce'>It looks like the proboscis has been removed.</span>")
|
||||
|
||||
|
||||
/obj/item/clothing/mask/facehugger/temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
if(exposed_temperature > 300)
|
||||
Die()
|
||||
|
||||
/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)
|
||||
if(stat == CONSCIOUS)
|
||||
return HasProximity(finder)
|
||||
return 0
|
||||
|
||||
/obj/item/clothing/mask/facehugger/HasProximity(atom/movable/AM as mob|obj)
|
||||
if(CanHug(AM) && Adjacent(AM))
|
||||
return Leap(AM)
|
||||
return 0
|
||||
|
||||
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
|
||||
if(!..())
|
||||
return
|
||||
if(stat == CONSCIOUS)
|
||||
icon_state = "[initial(icon_state)]_thrown"
|
||||
return 0
|
||||
|
||||
/obj/item/clothing/mask/facehugger/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
|
||||
if(!..())
|
||||
return
|
||||
if(stat == CONSCIOUS)
|
||||
icon_state = "[initial(icon_state)]_thrown"
|
||||
addtimer(CALLBACK(src, .proc/clear_throw_icon_state), 15)
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/clear_throw_icon_state()
|
||||
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)]"
|
||||
|
||||
/obj/item/clothing/mask/facehugger/throw_impact(atom/hit_atom)
|
||||
..()
|
||||
if(stat == CONSCIOUS)
|
||||
icon_state = "[initial(icon_state)]"
|
||||
Leap(hit_atom)
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/valid_to_attach(mob/living/M)
|
||||
// valid targets: corgis, carbons except aliens and devils
|
||||
// facehugger state early exit checks
|
||||
if(stat != CONSCIOUS)
|
||||
return FALSE
|
||||
if(attached)
|
||||
return FALSE
|
||||
if(!iscorgi(M) && !iscarbon(M))
|
||||
return FALSE
|
||||
if(iscarbon(M))
|
||||
// disallowed carbons
|
||||
if(isalien(M) || isdevil(M))
|
||||
return FALSE
|
||||
var/mob/living/carbon/target = M
|
||||
// gotta have a head to be implanted (no changelings or sentient plants)
|
||||
if(!target.get_bodypart("head"))
|
||||
return FALSE
|
||||
|
||||
if(target.getorgan(/obj/item/organ/alien/hivenode) || target.getorgan(/obj/item/organ/body_egg/alien_embryo))
|
||||
return FALSE
|
||||
// carbon, has head, not alien or devil, has no hivenode or embryo: valid
|
||||
return TRUE
|
||||
else if(iscorgi(M))
|
||||
// corgi: valid
|
||||
return TRUE
|
||||
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/valid_to_attach(mob/living/M)
|
||||
// valid targets: corgis, carbons except aliens and devils
|
||||
// facehugger state early exit checks
|
||||
if(stat != CONSCIOUS)
|
||||
return FALSE
|
||||
if(attached)
|
||||
return FALSE
|
||||
if(!iscorgi(M) && !iscarbon(M))
|
||||
return FALSE
|
||||
if(iscarbon(M))
|
||||
// disallowed carbons
|
||||
if(isalien(M) || isdevil(M))
|
||||
return FALSE
|
||||
var/mob/living/carbon/target = M
|
||||
// gotta have a head to be implanted (no changelings or sentient plants)
|
||||
if(!target.get_bodypart("head"))
|
||||
return FALSE
|
||||
|
||||
if(target.getorgan(/obj/item/organ/alien/hivenode) || target.getorgan(/obj/item/organ/body_egg/alien_embryo))
|
||||
return FALSE
|
||||
// carbon, has head, not alien or devil, has no hivenode or embryo: valid
|
||||
return TRUE
|
||||
else if(iscorgi(M))
|
||||
// corgi: valid
|
||||
return TRUE
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/Leap(mob/living/M)
|
||||
if(!valid_to_attach(M))
|
||||
return FALSE
|
||||
if(!valid_to_attach(M))
|
||||
return FALSE
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/target = M
|
||||
if(target.wear_mask && istype(target.wear_mask, /obj/item/clothing/mask/facehugger))
|
||||
return FALSE
|
||||
// passed initial checks - time to leap!
|
||||
M.visible_message("<span class='danger'>[src] leaps at [M]'s face!</span>", \
|
||||
"<span class='userdanger'>[src] leaps at [M]'s face!</span>")
|
||||
|
||||
// probiscis-blocker handling
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/target = M
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.is_mouth_covered(head_only = 1))
|
||||
H.visible_message("<span class='danger'>[src] smashes against [H]'s [H.head]!</span>", \
|
||||
"<span class='userdanger'>[src] smashes against [H]'s [H.head]!</span>")
|
||||
Die()
|
||||
return FALSE
|
||||
|
||||
if(target.wear_mask)
|
||||
var/obj/item/clothing/W = target.wear_mask
|
||||
// passed initial checks - time to leap!
|
||||
M.visible_message("<span class='danger'>[src] leaps at [M]'s face!</span>", \
|
||||
"<span class='userdanger'>[src] leaps at [M]'s face!</span>")
|
||||
|
||||
// probiscis-blocker handling
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/target = M
|
||||
|
||||
if(ishuman(M))
|
||||
var/mob/living/carbon/human/H = M
|
||||
if(H.is_mouth_covered(head_only = 1))
|
||||
H.visible_message("<span class='danger'>[src] smashes against [H]'s [H.head]!</span>", \
|
||||
"<span class='userdanger'>[src] smashes against [H]'s [H.head]!</span>")
|
||||
Die()
|
||||
return FALSE
|
||||
|
||||
if(target.wear_mask)
|
||||
var/obj/item/clothing/W = target.wear_mask
|
||||
if(target.dropItemToGround(W))
|
||||
target.visible_message("<span class='danger'>[src] tears [W] off of [target]'s face!</span>", \
|
||||
"<span class='userdanger'>[src] tears [W] off of [target]'s face!</span>")
|
||||
target.equip_to_slot_if_possible(src, slot_wear_mask, 0, 1, 1)
|
||||
target.visible_message("<span class='danger'>[src] tears [W] off of [target]'s face!</span>", \
|
||||
"<span class='userdanger'>[src] tears [W] off of [target]'s face!</span>")
|
||||
target.equip_to_slot_if_possible(src, slot_wear_mask, 0, 1, 1)
|
||||
return TRUE // time for a smoke
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/Attach(mob/living/M)
|
||||
if(!valid_to_attach(M))
|
||||
return
|
||||
// early returns and validity checks done: attach.
|
||||
attached++
|
||||
//ensure we detach once we no longer need to be attached
|
||||
// early returns and validity checks done: attach.
|
||||
attached++
|
||||
//ensure we detach once we no longer need to be attached
|
||||
addtimer(CALLBACK(src, .proc/detach), MAX_IMPREGNATION_TIME)
|
||||
|
||||
if (iscorgi(M))
|
||||
var/mob/living/simple_animal/pet/dog/corgi/C = M
|
||||
loc = C
|
||||
C.facehugger = src
|
||||
C.regenerate_icons()
|
||||
|
||||
if(!sterile)
|
||||
M.take_bodypart_damage(strength,0) //done here so that humans in helmets take damage
|
||||
M.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
|
||||
|
||||
|
||||
if (iscorgi(M))
|
||||
var/mob/living/simple_animal/pet/dog/corgi/C = M
|
||||
loc = C
|
||||
C.facehugger = src
|
||||
C.regenerate_icons()
|
||||
|
||||
if(!sterile)
|
||||
M.take_bodypart_damage(strength,0) //done here so that humans in helmets take damage
|
||||
M.Unconscious(MAX_IMPREGNATION_TIME/0.3) //something like 25 ticks = 20 seconds with the default settings
|
||||
|
||||
GoIdle() //so it doesn't jump the people that tear it off
|
||||
|
||||
addtimer(CALLBACK(src, .proc/Impregnate, M), rand(MIN_IMPREGNATION_TIME, MAX_IMPREGNATION_TIME))
|
||||
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/detach()
|
||||
attached = 0
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/Impregnate(mob/living/target)
|
||||
if(!target || target.stat == DEAD) //was taken off or something
|
||||
return
|
||||
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
if(C.wear_mask != src)
|
||||
return
|
||||
|
||||
if(!sterile)
|
||||
//target.contract_disease(new /datum/disease/alien_embryo(0)) //so infection chance is same as virus infection chance
|
||||
target.visible_message("<span class='danger'>[src] falls limp after violating [target]'s face!</span>", \
|
||||
"<span class='userdanger'>[src] falls limp after violating [target]'s face!</span>")
|
||||
|
||||
Die()
|
||||
icon_state = "[initial(icon_state)]_impregnated"
|
||||
|
||||
var/obj/item/bodypart/chest/LC = target.get_bodypart("chest")
|
||||
if((!LC || LC.status != BODYPART_ROBOTIC) && !target.getorgan(/obj/item/organ/body_egg/alien_embryo))
|
||||
new /obj/item/organ/body_egg/alien_embryo(target)
|
||||
|
||||
if(iscorgi(target))
|
||||
var/mob/living/simple_animal/pet/dog/corgi/C = target
|
||||
src.loc = get_turf(C)
|
||||
C.facehugger = null
|
||||
else
|
||||
target.visible_message("<span class='danger'>[src] violates [target]'s face!</span>", \
|
||||
"<span class='userdanger'>[src] violates [target]'s face!</span>")
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/GoActive()
|
||||
if(stat == DEAD || stat == CONSCIOUS)
|
||||
return
|
||||
|
||||
stat = CONSCIOUS
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/GoIdle()
|
||||
if(stat == DEAD || stat == UNCONSCIOUS)
|
||||
return
|
||||
|
||||
stat = UNCONSCIOUS
|
||||
icon_state = "[initial(icon_state)]_inactive"
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/Impregnate(mob/living/target)
|
||||
if(!target || target.stat == DEAD) //was taken off or something
|
||||
return
|
||||
|
||||
if(iscarbon(target))
|
||||
var/mob/living/carbon/C = target
|
||||
if(C.wear_mask != src)
|
||||
return
|
||||
|
||||
if(!sterile)
|
||||
//target.contract_disease(new /datum/disease/alien_embryo(0)) //so infection chance is same as virus infection chance
|
||||
target.visible_message("<span class='danger'>[src] falls limp after violating [target]'s face!</span>", \
|
||||
"<span class='userdanger'>[src] falls limp after violating [target]'s face!</span>")
|
||||
|
||||
Die()
|
||||
icon_state = "[initial(icon_state)]_impregnated"
|
||||
|
||||
var/obj/item/bodypart/chest/LC = target.get_bodypart("chest")
|
||||
if((!LC || LC.status != BODYPART_ROBOTIC) && !target.getorgan(/obj/item/organ/body_egg/alien_embryo))
|
||||
new /obj/item/organ/body_egg/alien_embryo(target)
|
||||
|
||||
if(iscorgi(target))
|
||||
var/mob/living/simple_animal/pet/dog/corgi/C = target
|
||||
src.loc = get_turf(C)
|
||||
C.facehugger = null
|
||||
else
|
||||
target.visible_message("<span class='danger'>[src] violates [target]'s face!</span>", \
|
||||
"<span class='userdanger'>[src] violates [target]'s face!</span>")
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/GoActive()
|
||||
if(stat == DEAD || stat == CONSCIOUS)
|
||||
return
|
||||
|
||||
stat = CONSCIOUS
|
||||
icon_state = "[initial(icon_state)]"
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/GoIdle()
|
||||
if(stat == DEAD || stat == UNCONSCIOUS)
|
||||
return
|
||||
|
||||
stat = UNCONSCIOUS
|
||||
icon_state = "[initial(icon_state)]_inactive"
|
||||
|
||||
addtimer(CALLBACK(src, .proc/GoActive), rand(MIN_ACTIVE_TIME, MAX_ACTIVE_TIME))
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/Die()
|
||||
if(stat == DEAD)
|
||||
return
|
||||
|
||||
icon_state = "[initial(icon_state)]_dead"
|
||||
item_state = "facehugger_inactive"
|
||||
stat = DEAD
|
||||
|
||||
visible_message("<span class='danger'>[src] curls up into a ball!</span>")
|
||||
|
||||
/proc/CanHug(mob/living/M)
|
||||
if(!istype(M))
|
||||
return 0
|
||||
if(M.stat == DEAD)
|
||||
return 0
|
||||
if(M.getorgan(/obj/item/organ/alien/hivenode))
|
||||
return 0
|
||||
|
||||
if(iscorgi(M) || ismonkey(M))
|
||||
return 1
|
||||
|
||||
var/mob/living/carbon/C = M
|
||||
if(ishuman(C) && !(slot_wear_mask in C.dna.species.no_equip))
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(H.is_mouth_covered(head_only = 1))
|
||||
return 0
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/obj/item/clothing/mask/facehugger/proc/Die()
|
||||
if(stat == DEAD)
|
||||
return
|
||||
|
||||
icon_state = "[initial(icon_state)]_dead"
|
||||
item_state = "facehugger_inactive"
|
||||
stat = DEAD
|
||||
|
||||
visible_message("<span class='danger'>[src] curls up into a ball!</span>")
|
||||
|
||||
/proc/CanHug(mob/living/M)
|
||||
if(!istype(M))
|
||||
return 0
|
||||
if(M.stat == DEAD)
|
||||
return 0
|
||||
if(M.getorgan(/obj/item/organ/alien/hivenode))
|
||||
return 0
|
||||
|
||||
if(iscorgi(M) || ismonkey(M))
|
||||
return 1
|
||||
|
||||
var/mob/living/carbon/C = M
|
||||
if(ishuman(C) && !(slot_wear_mask in C.dna.species.no_equip))
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(H.is_mouth_covered(head_only = 1))
|
||||
return 0
|
||||
return 1
|
||||
return 0
|
||||
|
||||
#undef MIN_ACTIVE_TIME
|
||||
#undef MAX_ACTIVE_TIME
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
//Here are the procs used to modify status effects of a mob.
|
||||
//The effects include: stunned, weakened, paralysis, sleeping, resting, jitteriness, dizziness, ear damage,
|
||||
//The effects include: stun, knockdown, unconscious, sleeping, resting, jitteriness, dizziness, ear damage,
|
||||
// eye damage, eye_blind, eye_blurry, druggy, BLIND disability, and NEARSIGHT disability.
|
||||
|
||||
/////////////////////////////////// STUNNED ////////////////////////////////////
|
||||
/////////////////////////////////// STUN ////////////////////////////////////
|
||||
|
||||
/mob/living/carbon/alien/Stun(amount, updating = 1, ignore_canstun = 0)
|
||||
. = ..()
|
||||
if(!.)
|
||||
move_delay_add = min(move_delay_add + round(amount / 2), 10) //a maximum delay of 10
|
||||
|
||||
/mob/living/carbon/alien/SetStunned(amount, updating = 1, ignore_canstun = 0)
|
||||
/mob/living/carbon/alien/SetStun(amount, updating = 1, ignore_canstun = 0)
|
||||
. = ..()
|
||||
if(!.)
|
||||
move_delay_add = min(move_delay_add + round(amount / 2), 10)
|
||||
|
||||
/mob/living/carbon/alien/AdjustStunned(amount, updating = 1, ignore_canstun = 0)
|
||||
/mob/living/carbon/alien/AdjustStun(amount, updating = 1, ignore_canstun = 0)
|
||||
. = ..()
|
||||
if(!.)
|
||||
move_delay_add = Clamp(move_delay_add + round(amount/2), 0, 10)
|
||||
|
||||
Reference in New Issue
Block a user