July 5th TG sync (#1883)

July 5th TG sync
This commit is contained in:
Poojawa
2017-07-05 22:14:19 -05:00
committed by GitHub
parent 454b9c3d68
commit b1b4826c0c
1264 changed files with 149689 additions and 570309 deletions
+154 -154
View File
@@ -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)
+12 -12
View File
@@ -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
+21 -21
View File
@@ -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
+31 -31
View File
@@ -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)