From 9424e05a6f897c2e76d5ae3f199dfba5241ac9e7 Mon Sep 17 00:00:00 2001 From: Terilia Date: Tue, 11 Jun 2019 21:23:28 +0100 Subject: [PATCH] First release --- .../powers/{headcrab.dm => headslug.dm} | 8 +- code/modules/events/headcrabs.dm | 63 ++++++++ .../living/simple_animal/hostile/headcrab.dm | 153 ++++++++---------- .../living/simple_animal/hostile/headslug.dm | 100 ++++++++++++ icons/mob/headcrab.dmi | Bin 0 -> 519 bytes icons/mob/mob.dmi | Bin 285554 -> 285554 bytes paradise.dme | 4 +- 7 files changed, 233 insertions(+), 95 deletions(-) rename code/game/gamemodes/changeling/powers/{headcrab.dm => headslug.dm} (88%) create mode 100644 code/modules/events/headcrabs.dm create mode 100644 code/modules/mob/living/simple_animal/hostile/headslug.dm create mode 100644 icons/mob/headcrab.dmi diff --git a/code/game/gamemodes/changeling/powers/headcrab.dm b/code/game/gamemodes/changeling/powers/headslug.dm similarity index 88% rename from code/game/gamemodes/changeling/powers/headcrab.dm rename to code/game/gamemodes/changeling/powers/headslug.dm index b39a2bba0d5..f29ec02db54 100644 --- a/code/game/gamemodes/changeling/powers/headcrab.dm +++ b/code/game/gamemodes/changeling/powers/headslug.dm @@ -1,4 +1,4 @@ -/datum/action/changeling/headcrab +/datum/action/changeling/headslug name = "Last Resort" desc = "We sacrifice our current body in a moment of need, placing us in control of a vessel that can plant our likeness in a new host. Costs 20 chemicals." helptext = "We will be placed in control of a small, fragile creature. We may attack a corpse like this to plant an egg which will slowly mature into a new form for us." @@ -7,12 +7,12 @@ dna_cost = 1 req_human = 1 -/datum/action/changeling/headcrab/try_to_sting(mob/user, mob/target) +/datum/action/changeling/headslug/try_to_sting(mob/user, mob/target) if(alert("Are you sure you wish to do this? This action cannot be undone.",,"Yes","No")=="No") return ..() -/datum/action/changeling/headcrab/sting_action(mob/user) +/datum/action/changeling/headslug/sting_action(mob/user) var/datum/mind/M = user.mind var/list/organs = user.get_organs_zone("head", 1) @@ -33,7 +33,7 @@ S.Weaken(3) var/new_location = user.drop_location() spawn(5) // So it's not killed in explosion - var/mob/living/simple_animal/hostile/headcrab/crab = new(new_location) + var/mob/living/simple_animal/hostile/headslug/crab = new(new_location) for(var/obj/item/organ/internal/I in organs) I.loc = crab crab.origin = M diff --git a/code/modules/events/headcrabs.dm b/code/modules/events/headcrabs.dm new file mode 100644 index 00000000000..58c3e918b0a --- /dev/null +++ b/code/modules/events/headcrabs.dm @@ -0,0 +1,63 @@ +#define LOC_FPMAINT 0 +#define LOC_FPMAINT1 1 + +#define HEADCRAB_NORMAL 0 +#define HEADCRAB_SPECIAL 1 +#define HEADCRAB_CLOWN 2 + +/datum/event/headcrabs + announceWhen = 10 + endWhen = 11 + var/location + var/locstring + var/headcrab + +/datum/event/headcrabs/start() + + location = rand(0,1) + var/list/turf/simulated/floor/turfs = list() + var/spawn_area_type + switch(location) + if(LOC_FPMAINT) + spawn_area_type = /area/maintenance/fpmaint2 + locstring = "Arrivals North Maintenance" + if(LOC_FPMAINT1) + spawn_area_type = /area/maintenance/fpmaint2 + locstring = "Arrivals North Maintenance" + + 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 = rand(0,1) + switch(headcrab) + if(HEADCRAB_NORMAL) + spawn_types = list(/mob/living/simple_animal/hostile/headcrab) + max_number = 12 + if(HEADCRAB_SPECIAL) + spawn_types = list(/mob/living/simple_animal/hostile/headcrab) + max_number = 12 + + spawn(0) + 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 creatues have been breeding in [locstring]. Clear them out, before this starts to affect productivity.", "Lifesign Alert") + +#undef LOC_FPMAINT +#undef LOC_FPMAINT1 + +#undef HEADCRAB_NORMAL +#undef HEADCRAB_SPECIAL +#undef HEADCRAB_CLOWN \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm index c82a0ee7806..d80e6df1ef9 100644 --- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm +++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm @@ -1,100 +1,73 @@ -#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 headcrab. Run!" + icon = 'icons/mob/headcrab.dmi' icon_state = "headcrab" icon_living = "headcrab" - icon_dead = "headcrab_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 + health = 40 + maxHealth = 40 + melee_damage_lower = 8 + melee_damage_upper = 16 + attacktext = "bites" + attack_sound = 'sound/effects/bite.ogg' + speak_emote = list("hisses") + var/is_zombie = 0 + stat_attack = 1 //so they continue to attack when they are on the ground. + 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)) + 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("[src] plants something in [victim]'s flesh!", \ - "We inject our egg into [victim]'s body!") - egg_lain = 1 +/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 += 40 + health = maxHealth + name = "zombie" + desc = "A corpse animated by the alien being on its head." + melee_damage_lower = 10 + melee_damage_upper = 15 + icon = H.icon + speak_emote = list("groans") + attack_sound = 'sound/weapons/genhit1.ogg' + icon_state = "zombie2_s" + if(head_organ) + head_organ.h_style = null + H.update_hair() + human_overlays = H.overlays + update_icons() + H.forceMove(src) + visible_message("The corpse of [H.name] suddenly rises!") -/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, "A foreign presence repels us from this body. Perhaps we should try to infest another?") - return - Infect(target) - to_chat(src, "With our egg laid, our death approaches rapidly...") - spawn(100) - death() - return - target.attack_animal(src) +/mob/living/simple_animal/hostile/headcrab/death(gibbed) + // Only execute the below if we successfuly died + . = ..() + // Setup up the smoke spreader and start it. + qdel(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 +/mob/living/simple_animal/hostile/headcrab/Destroy() + if(contents) + for(var/mob/M in contents) + M.loc = get_turf(src) + return ..() -/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 +/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") + overlays += I diff --git a/code/modules/mob/living/simple_animal/hostile/headslug.dm b/code/modules/mob/living/simple_animal/hostile/headslug.dm new file mode 100644 index 00000000000..e2fc98c483f --- /dev/null +++ b/code/modules/mob/living/simple_animal/hostile/headslug.dm @@ -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("[src] plants something in [victim]'s flesh!", \ + "We inject our egg into [victim]'s body!") + 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, "A foreign presence repels us from this body. Perhaps we should try to infest another?") + return + Infect(target) + to_chat(src, "With our egg laid, our death approaches rapidly...") + 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 diff --git a/icons/mob/headcrab.dmi b/icons/mob/headcrab.dmi new file mode 100644 index 0000000000000000000000000000000000000000..27d05247da4a067012f72ed60454441546b1e9e5 GIT binary patch literal 519 zcmV+i0{H!jP)`)Hvj*CbaZsg008IH_;Asms{jB10d!JMQvg8b*k%9#0CRd&Sad{Xb7OL8aCB*J zZU6vyoKseCa&`CgQ*iP1eD2$6mlmD%4!tm{6yPYUNBuB>c zB_R4qgR^snbm#$u=MBC-CPxK=ObI8J=_9DuNW#@Ma4Yer^^faE3qsJXgoMj>H##=x zRzkuxH0V}B!qqp}`u{VEmMlu~l70{^ZYGLWLc(>rXe}1!-lG5j literal 0 HcmV?d00001 diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi index 014242b9d90f7aab25aea42cf60229bb5e595383..ed1939270046be26c10cd358f0b9912ad8aa189c 100644 GIT binary patch delta 867 zcmV-p1DyQwwh{8S5s*-SZf5tkN2)<>OM|TTN-{3**YAPJ*noQ^5(*Ab_4L$w{nTpd zqxkLH?@!NS^ZjXlMCUbGu@;Y?9_F)7%b>(sEQ|R}p{`Uo{qX?;inaLgVLp@Ed9fCY z`K)wM8}EBmrx(QA5erha8xAmaG6HDbA_X{ite&Y7wEjpmBGJ2Z3J}lB;#WZZR^i{UXR?`lu6#1aRrcI^6GP7MG4`%{# zNWI&kWSv<=lXpeMIrF;iB++s1yvQLWNd zRpcDSVVcu^fV@C!!!&BtVHDZo)9N}kFVNc1Hqi#9$X*FfBm;rL>Ro9ju!IOOadeU?~`!?8-J4t81WYOC)P}Bc3aQcDDX%vv+$d_{v#`D430EY23O}> zv&f39m~I}<*+gZi`(;XP4{7z#Av6sFW4QDSki%otvks4G=Z3>0TCid3@Q7eAUSi)y zNC(=oUDLS>Cx&ZjFnux~TBhY=Cn84zt17P?bt%o=*?@R|>2s^?3x7nH@QN$rKm{_c zh*uzSoAi3%709u{e|{I9m`sX_zPItnf^xvU1dL#lFI>mA$W)nri#?8B3cfN= zLe!-^2b9`j=Rk8;f(BTVUuuUhlaK=DGk!n!e(jcq7l8npw`W%>y4dWh(gn|Q9Jw3HvKebwV zFaG-S_rs&ue0!K5(Roc)ti}C@yZNlsGAOYY%VIuLs4Epte|&&|VlCdio6n?nUaZAp zJ}Vv6c>4VU0NI)#961`G_c5qI2-D2Pd?wLAFV^B?wzwM&b~UwsE=PDHJ}Ra}PPFs=J%hK3<(4P$`|(D$#K zB;3|dhqWBSDtMWHBw$T8YAD(IkOLFXk`-Vi#W|I_9aYUxEh1DGH0~x5Vcmp2nzqsq z1Z}Hn*~bpQ%YJ=_(Ul?}w@{_XheaB!n1+p(zRFhFYT7}SA|Eu^w5c>$X0}V@;Y=V7 zsdqb+tTT&f@?KGK&U{^WlIS>hUT3RkGR~t{Ez?k!r=O&Mm7y+AK6ffZUH*seHq_+` z+!1|9iH{_MxqDNT5re}%Xc<4ne*w2DrBhHvP4<9HF(~3Gn@r=xfug|5eOs1`s8;E! zDsqnEFwJQ{K%StrVH!2+Fp6yPVf8vSPte-XHqi#9$esyKBm;rL>P=}Tu!IOOadeUZSS%=58bHm{gE!ePictkK5FR?Ep zqyuf)uIb!`6T`JMm_C^gEz|O`6Oki3gp<}zrPDlOeRG|-`jX(K{?=F0!Fab-s~QHgu2oE+X*uwF;1^QB6rV7 zZVVOqkXvwGGcK5Tix@%(V41x;+91npIqJF)mA$W)nri#?8B3O+MW zLe!-^2b9`j=Rk8;f(BTVUuuU>laK=ofjde0ki6&9{g7PuPYu!|9p`%7fwqhvEYPhvEYQhvEYRx8ef?kXH@Mr11a% diff --git a/paradise.dme b/paradise.dme index c49361b8e20..24320509982 100644 --- a/paradise.dme +++ b/paradise.dme @@ -477,7 +477,7 @@ #include "code\game\gamemodes\changeling\powers\epinephrine.dm" #include "code\game\gamemodes\changeling\powers\fakedeath.dm" #include "code\game\gamemodes\changeling\powers\fleshmend.dm" -#include "code\game\gamemodes\changeling\powers\headcrab.dm" +#include "code\game\gamemodes\changeling\powers\headslug.dm" #include "code\game\gamemodes\changeling\powers\hivemind.dm" #include "code\game\gamemodes\changeling\powers\humanform.dm" #include "code\game\gamemodes\changeling\powers\lesserform.dm" @@ -1436,6 +1436,7 @@ #include "code\modules\events\false_alarm.dm" #include "code\modules\events\floorcluwne.dm" #include "code\modules\events\grid_check.dm" +#include "code\modules\events\headcrabs.dm" #include "code\modules\events\immovable_rod.dm" #include "code\modules\events\infestation.dm" #include "code\modules\events\ion_storm.dm" @@ -1903,6 +1904,7 @@ #include "code\modules\mob\living\simple_animal\hostile\floorcluwne.dm" #include "code\modules\mob\living\simple_animal\hostile\giant_spider.dm" #include "code\modules\mob\living\simple_animal\hostile\headcrab.dm" +#include "code\modules\mob\living\simple_animal\hostile\headslug.dm" #include "code\modules\mob\living\simple_animal\hostile\hellhound.dm" #include "code\modules\mob\living\simple_animal\hostile\hivebot.dm" #include "code\modules\mob\living\simple_animal\hostile\hostile.dm"