mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-08-22 03:27:05 +01:00
@@ -0,0 +1,146 @@
|
||||
#define LOC_ATMOS_CONTROL 0
|
||||
#define LOC_FPMAINT 1
|
||||
#define LOC_FPMAINT2 2
|
||||
#define LOC_FSMAINT 3
|
||||
#define LOC_FSMAINT2 4
|
||||
#define LOC_ASMAINT 5
|
||||
#define LOC_ASMAINT2 6
|
||||
#define LOC_APMAINT 7
|
||||
#define LOC_MAINTCENTRAL 8
|
||||
#define LOC_FORE 9
|
||||
#define LOC_STARBOARD 10
|
||||
#define LOC_PORT 11
|
||||
#define LOC_AFT 12
|
||||
#define LOC_STORAGE 13
|
||||
#define LOC_DISPOSAL 14
|
||||
#define LOC_GENETICS 15
|
||||
#define LOC_ELECTRICAL 16
|
||||
#define LOC_ABANDONEDBAR 17
|
||||
#define LOC_ELECTRICAL_SHOP 18
|
||||
#define LOC_GAMBLING_DEN 19
|
||||
|
||||
#define HEADCRAB_NORMAL 0
|
||||
/*#define HEADCRAB_SPECIAL 1
|
||||
#define HEADCRAB_CLOWN 2 */ //Planned for the future
|
||||
|
||||
/datum/event/headcrabs
|
||||
announceWhen = 10
|
||||
endWhen = 11
|
||||
var/location
|
||||
var/locstring
|
||||
var/headcrab
|
||||
|
||||
/datum/event/headcrabs/start()
|
||||
|
||||
location = rand(0,19)
|
||||
var/list/turf/simulated/floor/turfs = list()
|
||||
var/spawn_area_type
|
||||
switch(location)
|
||||
if(LOC_ATMOS_CONTROL)
|
||||
spawn_area_type = /area/maintenance/atmos_control
|
||||
locstring = "Atmospherics Maintenance"
|
||||
if(LOC_FPMAINT)
|
||||
spawn_area_type = /area/maintenance/fpmaint
|
||||
locstring = "EVA Maintenance"
|
||||
if(LOC_FPMAINT2)
|
||||
spawn_area_type = /area/maintenance/fpmaint2
|
||||
locstring = "Arrivals North Maintenance"
|
||||
if(LOC_FSMAINT)
|
||||
spawn_area_type = /area/maintenance/fsmaint
|
||||
locstring = "Dormitory Maintenance"
|
||||
if(LOC_FSMAINT2)
|
||||
spawn_area_type = /area/maintenance/fsmaint2
|
||||
locstring = "Bar Maintenance"
|
||||
if(LOC_ASMAINT)
|
||||
spawn_area_type = /area/maintenance/asmaint
|
||||
locstring = "Medbay Maintenance"
|
||||
if(LOC_ASMAINT2)
|
||||
spawn_area_type = /area/maintenance/asmaint2
|
||||
locstring = "Science Maintenance"
|
||||
if(LOC_APMAINT)
|
||||
spawn_area_type = /area/maintenance/apmaint
|
||||
locstring = "Cargo Maintenance"
|
||||
if(LOC_MAINTCENTRAL)
|
||||
spawn_area_type = /area/maintenance/maintcentral
|
||||
locstring = "Bridge Maintenance"
|
||||
if(LOC_FORE)
|
||||
spawn_area_type = /area/maintenance/fore
|
||||
locstring = "Fore Maintenance"
|
||||
if(LOC_STARBOARD)
|
||||
spawn_area_type = /area/maintenance/starboard
|
||||
locstring = "Starboard Maintenance"
|
||||
if(LOC_PORT)
|
||||
spawn_area_type = /area/maintenance/port
|
||||
locstring = "Locker Room Maintenance"
|
||||
if(LOC_AFT)
|
||||
spawn_area_type = /area/maintenance/aft
|
||||
locstring = "Engineering Maintenance"
|
||||
if(LOC_STORAGE)
|
||||
spawn_area_type = /area/maintenance/storage
|
||||
locstring = "Atmospherics Maintenance"
|
||||
if(LOC_DISPOSAL)
|
||||
spawn_area_type = /area/maintenance/disposal
|
||||
locstring = "Waste Disposal"
|
||||
if(LOC_GENETICS)
|
||||
spawn_area_type = /area/maintenance/genetics
|
||||
locstring = "Genetics Maintenance"
|
||||
if(LOC_ELECTRICAL)
|
||||
spawn_area_type = /area/maintenance/electrical
|
||||
locstring = "Electrical Maintenance"
|
||||
if(LOC_ABANDONEDBAR)
|
||||
spawn_area_type = /area/maintenance/abandonedbar
|
||||
locstring = "Maintenance Bar"
|
||||
if(LOC_ELECTRICAL_SHOP)
|
||||
spawn_area_type = /area/maintenance/electrical_shop
|
||||
locstring ="Electronics Den"
|
||||
if(LOC_GAMBLING_DEN)
|
||||
spawn_area_type = /area/maintenance/gambling_den
|
||||
locstring = "Gambling Den"
|
||||
for(var/areapath in typesof(spawn_area_type))
|
||||
var/area/A = locate(areapath)
|
||||
for(var/turf/simulated/floor/F in A.contents)
|
||||
if(turf_clear(F))
|
||||
turfs += F
|
||||
|
||||
var/list/spawn_types = list()
|
||||
var/max_number
|
||||
headcrab = 0 //rand(0,x) for the future
|
||||
switch(headcrab) //Switch is for the future
|
||||
if(HEADCRAB_NORMAL)
|
||||
spawn_types = list(/mob/living/simple_animal/hostile/headcrab)
|
||||
max_number = 6
|
||||
|
||||
var/num = rand(2,max_number)
|
||||
while(turfs.len > 0 && num > 0)
|
||||
var/turf/simulated/floor/T = pick(turfs)
|
||||
turfs.Remove(T)
|
||||
num--
|
||||
var/spawn_type = pick(spawn_types)
|
||||
new spawn_type(T)
|
||||
|
||||
|
||||
/datum/event/headcrabs/announce()
|
||||
event_announcement.Announce("Bioscans indicate that creatures have been breeding in [locstring]. Clear them out, before this starts to affect productivity", "Lifesign Alert")
|
||||
|
||||
#undef LOC_ATMOS_CONTROL
|
||||
#undef LOC_FPMAINT
|
||||
#undef LOC_FPMAINT2
|
||||
#undef LOC_FSMAINT
|
||||
#undef LOC_FSMAINT2
|
||||
#undef LOC_ASMAINT
|
||||
#undef LOC_ASMAINT2
|
||||
#undef LOC_APMAINT
|
||||
#undef LOC_MAINTCENTRAL
|
||||
#undef LOC_FORE
|
||||
#undef LOC_STARBOARD
|
||||
#undef LOC_PORT
|
||||
#undef LOC_AFT
|
||||
#undef LOC_STORAGE
|
||||
#undef LOC_DISPOSAL
|
||||
#undef LOC_GENETICS
|
||||
#undef LOC_ELECTRICAL
|
||||
#undef LOC_ABANDONEDBAR
|
||||
#undef LOC_ELECTRICAL_SHOP
|
||||
#undef LOC_GAMBLING_DEN
|
||||
|
||||
#undef HEADCRAB_NORMAL
|
||||
@@ -1,100 +1,106 @@
|
||||
#define EGG_INCUBATION_TIME 120
|
||||
|
||||
/mob/living/simple_animal/hostile/headcrab
|
||||
name = "headslug"
|
||||
desc = "Absolutely not de-beaked or harmless. Keep away from corpses."
|
||||
name = "headcrab"
|
||||
desc = "A small parasitic creature that would like to connect with your brain stem."
|
||||
icon = 'icons/mob/headcrab.dmi'
|
||||
icon_state = "headcrab"
|
||||
icon_living = "headcrab"
|
||||
icon_dead = "headcrab_dead"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
health = 50
|
||||
maxHealth = 50
|
||||
health = 40
|
||||
maxHealth = 40
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 5
|
||||
attacktext = "chomps"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
faction = list("creature")
|
||||
robust_searching = 1
|
||||
stat_attack = 2
|
||||
obj_damage = 0
|
||||
environment_smash = 0
|
||||
speak_emote = list("squeaks")
|
||||
ventcrawler = 2
|
||||
var/datum/mind/origin
|
||||
var/egg_lain = 0
|
||||
melee_damage_upper = 10
|
||||
ranged = 1
|
||||
ranged_message = "leaps"
|
||||
ranged_cooldown_time = 40
|
||||
var/jumpdistance = 4
|
||||
var/jumpspeed = 1
|
||||
attacktext = "bites"
|
||||
attack_sound = 'sound/creatures/headcrab_attack.ogg'
|
||||
speak_emote = list("hisses")
|
||||
var/is_zombie = 0
|
||||
stat_attack = 1 //so they continue to attack when they are on the ground.
|
||||
var/host_species = ""
|
||||
var/list/human_overlays = list()
|
||||
|
||||
/mob/living/simple_animal/hostile/headcrab/examine(mob/user)
|
||||
/mob/living/simple_animal/hostile/headcrab/Life(seconds, times_fired)
|
||||
if(!is_zombie && isturf(src.loc) && stat != DEAD)
|
||||
for(var/mob/living/carbon/human/H in oview(src, 1)) //Only for corpse right next to/on same tile
|
||||
if(H.stat == DEAD || (!H.check_death_method() && H.health <= HEALTH_THRESHOLD_DEAD))
|
||||
Zombify(H)
|
||||
break
|
||||
..()
|
||||
if(stat == DEAD)
|
||||
to_chat(desc = "It appears to be dead.")
|
||||
|
||||
/mob/living/simple_animal/hostile/headcrab/proc/Infect(mob/living/carbon/victim)
|
||||
var/obj/item/organ/internal/body_egg/changeling_egg/egg = new(victim)
|
||||
egg.insert(victim)
|
||||
if(origin)
|
||||
egg.origin = origin
|
||||
else if(mind) // Let's make this a feature
|
||||
egg.origin = mind
|
||||
for(var/obj/item/organ/internal/I in src)
|
||||
I.loc = egg
|
||||
visible_message("<span class='warning'>[src] plants something in [victim]'s flesh!</span>", \
|
||||
"<span class='danger'>We inject our egg into [victim]'s body!</span>")
|
||||
egg_lain = 1
|
||||
/mob/living/simple_animal/hostile/headcrab/OpenFire(atom/A)
|
||||
if(check_friendly_fire)
|
||||
for(var/turf/T in getline(src,A)) // Not 100% reliable but this is faster than simulating actual trajectory
|
||||
for(var/mob/living/L in T)
|
||||
if(L == src || L == A)
|
||||
continue
|
||||
if(faction_check(L) && !attack_same)
|
||||
return
|
||||
visible_message("<span class='danger'><b>[src]</b> [ranged_message] at [A]!</span>")
|
||||
throw_at(A, jumpdistance, jumpspeed, spin = FALSE, diagonals_first = TRUE)
|
||||
ranged_cooldown = world.time + ranged_cooldown_time
|
||||
|
||||
/mob/living/simple_animal/hostile/headcrab/AttackingTarget()
|
||||
if(egg_lain)
|
||||
target.attack_animal(src)
|
||||
return
|
||||
if(iscarbon(target) && !issmall(target))
|
||||
// Changeling egg can survive in aliens!
|
||||
var/mob/living/carbon/C = target
|
||||
if(C.stat == DEAD)
|
||||
if(C.status_flags & XENO_HOST)
|
||||
to_chat(src, "<span class='userdanger'>A foreign presence repels us from this body. Perhaps we should try to infest another?</span>")
|
||||
return
|
||||
Infect(target)
|
||||
to_chat(src, "<span class='userdanger'>With our egg laid, our death approaches rapidly...</span>")
|
||||
spawn(100)
|
||||
death()
|
||||
return
|
||||
target.attack_animal(src)
|
||||
/mob/living/simple_animal/hostile/headcrab/proc/Zombify(mob/living/carbon/human/H)
|
||||
if(!H.check_death_method())
|
||||
H.death()
|
||||
var/obj/item/organ/external/head/head_organ = H.get_organ("head")
|
||||
is_zombie = TRUE
|
||||
if(H.wear_suit)
|
||||
var/obj/item/clothing/suit/armor/A = H.wear_suit
|
||||
if(A.armor && A.armor["melee"])
|
||||
maxHealth += A.armor["melee"] //That zombie's got armor, I want armor!
|
||||
maxHealth += 50
|
||||
health = maxHealth
|
||||
name = "zombie"
|
||||
desc = "A corpse animated by the alien being on its head."
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 15
|
||||
ranged = 0
|
||||
icon = H.icon
|
||||
speak = list('sound/creatures/zombie_idle1.ogg','sound/creatures/zombie_idle2.ogg','sound/creatures/zombie_idle3.ogg')
|
||||
speak_chance = 50
|
||||
speak_emote = list("groans")
|
||||
attacktext = "bites"
|
||||
attack_sound = 'sound/creatures/zombie_attack.ogg'
|
||||
icon_state = "zombie2_s"
|
||||
if(head_organ)
|
||||
head_organ.h_style = null
|
||||
H.update_hair()
|
||||
host_species = H.dna.species.name
|
||||
human_overlays = H.overlays
|
||||
update_icons()
|
||||
H.forceMove(src)
|
||||
visible_message("<span class='warning'>The corpse of [H.name] suddenly rises!</span>")
|
||||
|
||||
/obj/item/organ/internal/body_egg/changeling_egg
|
||||
name = "changeling egg"
|
||||
desc = "Twitching and disgusting."
|
||||
origin_tech = "biotech=7" // You need to be really lucky to obtain it.
|
||||
var/datum/mind/origin
|
||||
var/time
|
||||
|
||||
/obj/item/organ/internal/body_egg/changeling_egg/egg_process()
|
||||
// Changeling eggs grow in dead people
|
||||
time++
|
||||
if(time >= EGG_INCUBATION_TIME)
|
||||
Pop()
|
||||
remove(owner)
|
||||
/mob/living/simple_animal/hostile/headcrab/death()
|
||||
..()
|
||||
if(is_zombie)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/organ/internal/body_egg/changeling_egg/proc/Pop()
|
||||
var/mob/living/carbon/human/monkey/M = new(owner)
|
||||
owner.stomach_contents += M
|
||||
|
||||
for(var/obj/item/organ/internal/I in src)
|
||||
I.insert(M, 1)
|
||||
/mob/living/simple_animal/hostile/headcrab/handle_automated_speech() // This way they have different screams when attacking, sometimes. Might be seen as sphagetthi code though.
|
||||
if(speak_chance)
|
||||
if(rand(0,200) < speak_chance)
|
||||
if(speak && speak.len)
|
||||
playsound(get_turf(src), pick(speak), 200, 1)
|
||||
|
||||
if(origin && origin.current && (origin.current.stat == DEAD))
|
||||
origin.transfer_to(M)
|
||||
if(!origin.changeling)
|
||||
M.make_changeling()
|
||||
if(origin.changeling.can_absorb_dna(M, owner))
|
||||
origin.changeling.absorb_dna(owner, M)
|
||||
/mob/living/simple_animal/hostile/headcrab/Destroy()
|
||||
if(contents)
|
||||
for(var/mob/M in contents)
|
||||
M.loc = get_turf(src)
|
||||
return ..()
|
||||
|
||||
var/datum/action/changeling/humanform/HF = new
|
||||
HF.Grant(M)
|
||||
for(var/power in origin.changeling.purchasedpowers)
|
||||
var/datum/action/changeling/S = power
|
||||
if(istype(S) && S.needs_button)
|
||||
S.Grant(M)
|
||||
M.key = origin.key
|
||||
owner.gib()
|
||||
|
||||
#undef EGG_INCUBATION_TIME
|
||||
/mob/living/simple_animal/hostile/headcrab/update_icons()
|
||||
..()
|
||||
if(is_zombie)
|
||||
overlays.Cut()
|
||||
overlays = human_overlays
|
||||
var/image/I = image('icons/mob/headcrab.dmi', icon_state = "headcrabpod")
|
||||
if(host_species == "Vox")
|
||||
I = image('icons/mob/headcrab.dmi', icon_state = "headcrabpod_vox")
|
||||
else if(host_species == "Gray")
|
||||
I = image('icons/mob/headcrab.dmi', icon_state = "headcrabpod_gray")
|
||||
overlays += I
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
#define EGG_INCUBATION_TIME 120
|
||||
|
||||
/mob/living/simple_animal/hostile/headslug
|
||||
name = "headslug"
|
||||
desc = "Absolutely not de-beaked or harmless. Keep away from corpses."
|
||||
icon_state = "headslug"
|
||||
icon_living = "headslug"
|
||||
icon_dead = "headslug_dead"
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
health = 50
|
||||
maxHealth = 50
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 5
|
||||
attacktext = "chomps"
|
||||
attack_sound = 'sound/weapons/bite.ogg'
|
||||
faction = list("creature")
|
||||
robust_searching = 1
|
||||
stat_attack = 2
|
||||
obj_damage = 0
|
||||
environment_smash = 0
|
||||
speak_emote = list("squeaks")
|
||||
ventcrawler = 2
|
||||
var/datum/mind/origin
|
||||
var/egg_lain = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/headslug/examine(mob/user)
|
||||
..()
|
||||
if(stat == DEAD)
|
||||
to_chat(desc = "It appears to be dead.")
|
||||
|
||||
/mob/living/simple_animal/hostile/headslug/proc/Infect(mob/living/carbon/victim)
|
||||
var/obj/item/organ/internal/body_egg/changeling_egg/egg = new(victim)
|
||||
egg.insert(victim)
|
||||
if(origin)
|
||||
egg.origin = origin
|
||||
else if(mind) // Let's make this a feature
|
||||
egg.origin = mind
|
||||
for(var/obj/item/organ/internal/I in src)
|
||||
I.loc = egg
|
||||
visible_message("<span class='warning'>[src] plants something in [victim]'s flesh!</span>", \
|
||||
"<span class='danger'>We inject our egg into [victim]'s body!</span>")
|
||||
egg_lain = 1
|
||||
|
||||
/mob/living/simple_animal/hostile/headslug/AttackingTarget()
|
||||
if(egg_lain)
|
||||
target.attack_animal(src)
|
||||
return
|
||||
if(iscarbon(target) && !issmall(target))
|
||||
// Changeling egg can survive in aliens!
|
||||
var/mob/living/carbon/C = target
|
||||
if(C.stat == DEAD)
|
||||
if(C.status_flags & XENO_HOST)
|
||||
to_chat(src, "<span class='userdanger'>A foreign presence repels us from this body. Perhaps we should try to infest another?</span>")
|
||||
return
|
||||
Infect(target)
|
||||
to_chat(src, "<span class='userdanger'>With our egg laid, our death approaches rapidly...</span>")
|
||||
spawn(100)
|
||||
death()
|
||||
return
|
||||
target.attack_animal(src)
|
||||
|
||||
/obj/item/organ/internal/body_egg/changeling_egg
|
||||
name = "changeling egg"
|
||||
desc = "Twitching and disgusting."
|
||||
origin_tech = "biotech=7" // You need to be really lucky to obtain it.
|
||||
var/datum/mind/origin
|
||||
var/time
|
||||
|
||||
/obj/item/organ/internal/body_egg/changeling_egg/egg_process()
|
||||
// Changeling eggs grow in dead people
|
||||
time++
|
||||
if(time >= EGG_INCUBATION_TIME)
|
||||
Pop()
|
||||
remove(owner)
|
||||
qdel(src)
|
||||
|
||||
/obj/item/organ/internal/body_egg/changeling_egg/proc/Pop()
|
||||
var/mob/living/carbon/human/monkey/M = new(owner)
|
||||
owner.stomach_contents += M
|
||||
|
||||
for(var/obj/item/organ/internal/I in src)
|
||||
I.insert(M, 1)
|
||||
|
||||
if(origin && origin.current && (origin.current.stat == DEAD))
|
||||
origin.transfer_to(M)
|
||||
if(!origin.changeling)
|
||||
M.make_changeling()
|
||||
if(origin.changeling.can_absorb_dna(M, owner))
|
||||
origin.changeling.absorb_dna(owner, M)
|
||||
|
||||
var/datum/action/changeling/humanform/HF = new
|
||||
HF.Grant(M)
|
||||
for(var/power in origin.changeling.purchasedpowers)
|
||||
var/datum/action/changeling/S = power
|
||||
if(istype(S) && S.needs_button)
|
||||
S.Grant(M)
|
||||
M.key = origin.key
|
||||
owner.gib()
|
||||
|
||||
#undef EGG_INCUBATION_TIME
|
||||
Reference in New Issue
Block a user