diff --git a/code/game/dna.dm b/code/game/dna.dm index ccbe421d0c8..6ec002b2ec5 100644 --- a/code/game/dna.dm +++ b/code/game/dna.dm @@ -718,7 +718,7 @@ var/mob/occupant = src.connected.occupant dat = "Occupant Statistics:
" //Blah obvious if(occupant && occupant.dna) //is there REALLY someone in there? - if(occupant.mutations & HUSK) + if(occupant.mutations & NOCLONE) dat += "The occupant's DNA structure is ruined beyond recognition, please insert a subject with an intact DNA structure.

" //NOPE. -Pete dat += text("View/Edit/Transfer Buffer

", src) dat += text("Radiation Emitter Settings

", src) @@ -993,7 +993,7 @@ src.temphtml += text("Data: []
", src.buffer1) src.temphtml += text("By: []
", src.buffer1owner) src.temphtml += text("Label: []
", src.buffer1label) - if (src.connected.occupant && !(src.connected.occupant.mutations & HUSK)) src.temphtml += text("Save : UI - UI+UE - SE
", src, src, src) + if (src.connected.occupant && !(src.connected.occupant.mutations & NOCLONE)) src.temphtml += text("Save : UI - UI+UE - SE
", src, src, src) if (src.buffer1) src.temphtml += text("Transfer to: Occupant - Injector
", src, src) //if (src.buffer1) src.temphtml += text("Isolate Block
", src) if (src.buffer1) src.temphtml += "Disk: Save To | Load From
" @@ -1007,7 +1007,7 @@ src.temphtml += text("Data: []
", src.buffer2) src.temphtml += text("By: []
", src.buffer2owner) src.temphtml += text("Label: []
", src.buffer2label) - if (src.connected.occupant && !(src.connected.occupant.mutations & HUSK)) src.temphtml += text("Save : UI - UI+UE - SE
", src, src, src) + if (src.connected.occupant && !(src.connected.occupant.mutations & NOCLONE)) src.temphtml += text("Save : UI - UI+UE - SE
", src, src, src) if (src.buffer2) src.temphtml += text("Transfer to: Occupant - Injector
", src, src) //if (src.buffer2) src.temphtml += text("Isolate Block
", src) if (src.buffer2) src.temphtml += "Disk: Save To | Load From
" @@ -1021,7 +1021,7 @@ src.temphtml += text("Data: []
", src.buffer3) src.temphtml += text("By: []
", src.buffer3owner) src.temphtml += text("Label: []
", src.buffer3label) - if (src.connected.occupant && !(src.connected.occupant.mutations & HUSK)) src.temphtml += text("Save : UI - UI+UE - SE
", src, src, src) + if (src.connected.occupant && !(src.connected.occupant.mutations & NOCLONE)) src.temphtml += text("Save : UI - UI+UE - SE
", src, src, src) if (src.buffer3) src.temphtml += text("Transfer to: Occupant - Injector
", src, src) //if (src.buffer3) src.temphtml += text("Isolate Block
", src) if (src.buffer3) src.temphtml += "Disk: Save To | Load From
" @@ -1155,7 +1155,7 @@ src.buffer3label = sanitize(input("New Label:","Edit Label","Infos here")) dopage(src,"buffermenu") if (href_list["b1transfer"]) - if (!src.connected.occupant || src.connected.occupant.mutations & HUSK) + if (!src.connected.occupant || src.connected.occupant.mutations & NOCLONE) return if (src.buffer1type == "ui") if (src.buffer1iue) @@ -1170,7 +1170,7 @@ src.connected.occupant.radiation += rand(20,50) src.delete = 0 if (href_list["b2transfer"]) - if (!src.connected.occupant || src.connected.occupant.mutations & HUSK) + if (!src.connected.occupant || src.connected.occupant.mutations & NOCLONE) return if (src.buffer2type == "ui") if (src.buffer2iue) @@ -1185,7 +1185,7 @@ src.connected.occupant.radiation += rand(20,50) src.delete = 0 if (href_list["b3transfer"]) - if (!src.connected.occupant || src.connected.occupant.mutations & HUSK) + if (!src.connected.occupant || src.connected.occupant.mutations & NOCLONE) return if (src.buffer3type == "ui") if (src.buffer3iue) diff --git a/code/game/gamemodes/changeling/changeling_powers.dm b/code/game/gamemodes/changeling/changeling_powers.dm index 460f3a67ea3..8f54c8586ad 100644 --- a/code/game/gamemodes/changeling/changeling_powers.dm +++ b/code/game/gamemodes/changeling/changeling_powers.dm @@ -79,7 +79,7 @@ usr << "\red This creature is not compatible with our biology." return - if (M.mutations & HUSK) + if (M.mutations & NOCLONE) usr << "\red This creature's DNA is ruined beyond useability!" return @@ -137,7 +137,7 @@ usr.changeling.isabsorbing = 0 T.death(0) - T.ChangeToHusk() + T.Drain() return diff --git a/code/game/machinery/computer/cloning.dm b/code/game/machinery/computer/cloning.dm index 0bec1cc5b21..532df625ba3 100644 --- a/code/game/machinery/computer/cloning.dm +++ b/code/game/machinery/computer/cloning.dm @@ -391,7 +391,7 @@ if ((!subject.ckey) || (!subject.client)) src.temp = "Error: Mental interface failure." return - if (subject.mutations & HUSK) + if (subject.mutations & NOCLONE) src.temp = "Error: Mental interface failure." return if (!isnull(find_record(subject.ckey))) diff --git a/code/game/objects/alien/facehugger.dm b/code/game/objects/alien/facehugger.dm index ec6cbdfece8..ac5fd7e49fc 100644 --- a/code/game/objects/alien/facehugger.dm +++ b/code/game/objects/alien/facehugger.dm @@ -213,408 +213,9 @@ var/const proc/RemoveActiveIndicators() //removes the "active" facehugger indicator from all aliens in the world for this hugger for(var/mob/living/carbon/alien/alien in world) - for(var/image/image in alien.client.images) - if(image.icon_state == "facehugger_active" && image.loc == src) - del(image) + if(alien.client) + for(var/image/image in alien.client.images) + if(image.icon_state == "facehugger_active" && image.loc == src) + del(image) - return - -/* NOPE.png -- Urist - -// Returns the surrounding cardinal turfs with open links -// Including through doors openable with the ID -// Includes spacetiles -/turf/proc/CardinalTurfsWithAccessSpace(var/obj/item/weapon/card/id/ID) - var/L[] = new() - for(var/d in cardinal) - var/turf/simulated/T = get_step(src, d) - if((istype(T) || istype(T,/turf/space))&& !T.density) - if(!LinkBlockedWithAccess(src, T, ID)) - L.Add(T) - return L - -/obj/effect/alien/facehugger - name = "alien" - desc = "An alien, looks pretty scary!" - icon_state = "facehugger" - layer = 5.0 - density = 1 - anchored = 0 - - var/state = 0 - - var/list/path = new/list() - - var/frustration = 0 - var/mob/living/carbon/target - var/list/path_target = new/list() - - var/turf/trg_idle - var/list/path_idle = new/list() - - var/alive = 1 //1 alive, 0 dead - var/health = 10 - var/maxhealth = 10 - var/lamarr = 0 - flags = 258.0 - - - - - - New() - ..() - if(aliens_allowed) - health = maxhealth - process() - else - del(src) - - examine() - set src in view() - ..() - if(!alive) - usr << text("\red The alien is not moving.") - else if (health > 5) - usr << text("\red The alien looks fresh, just out of the egg.") - else - usr << text("\red The alien looks injured.") - if (lamarr) - usr << text("\red It looks like the proboscis has been removed.") - return - - - attack_hand(user as mob) - return - - attackby(obj/item/weapon/W as obj, mob/user as mob) - switch(W.damtype) - if("fire") - health -= W.force * 0.75 - if("brute") - health -= W.force * 0.5 - else - if (health <= 0) - death() - else if (W.force) - if(ishuman(user) || ismonkey(user)) - target = user - state = 1 - ..() - - bullet_act(var/obj/item/projectile/Proj) - health -= round(Proj.damage / 2) - ..() - healthcheck() - - ex_act(severity) - switch(severity) - if(1.0) - death() - if(2.0) - health -= 15 - healthcheck() - return - - meteorhit() - death() - return - - blob_act() - if(prob(50)) - death() - return - - Bumped(AM as mob|obj) - if(ismob(AM) && (ishuman(AM) || ismonkey(AM)) ) - target = AM - set_attack() - else if(ismob(AM)) - spawn(0) - var/turf/T = get_turf(src) - AM:loc = T - - Bump(atom/A) - if(ismob(A) && (ishuman(A) || ismonkey(A))) - target = A - set_attack() - else if(ismob(A)) - loc = A:loc - - temperature_expose(datum/gas_mixture/air, exposed_temperature, exposed_volume) - if(exposed_temperature > 300) - health -= 5 - healthcheck() - - - - - verb/follow() - set src in view() //set src in get_aliens(view()) - does not work, damn shitty byond :( -- rastaf0 - set name = "Follow Me" - set category = "Object" //"Alien" does not work perfect - humans get "Alien" tab too, that's annoying - if(!alive) return - if(!isalien(usr)) - usr << text("\red The alien ignores you.") - return - if(state != 2 || health < maxhealth) - usr << text("\red The alien is too busy to follow you.") - return - usr << text("\green The alien will now try to follow you.") - trg_idle = usr - path_idle = new/list() - return - - verb/stop() - set src in view() - set name = "Stop Following" - set category = "Object" - if(!alive) return - if(!isalien(usr)) - usr << text("\red The alien ignores you.") - return - if(state != 2) - usr << text("\red The alien is too busy to follow you.") - return - usr << text("\green The alien stops following you.") - set_null() - return - - - - - proc/call_to(var/mob/user) - if(!alive || !isalien(user) || state != 2) return - trg_idle = user - path_idle = new/list() - return - - proc/set_attack() - state = 1 - if(path_idle.len) path_idle = new/list() - trg_idle = null - - proc/set_idle() - state = 2 - if (path_target.len) path_target = new/list() - target = null - frustration = 0 - - proc/set_null() - state = 0 - if (path_target.len) path_target = new/list() - if (path_idle.len) path_idle = new/list() - target = null - trg_idle = null - frustration = 0 - - process() - set background = 1 - var/quick_move = 0 - - if (!alive) - return - - if (!target) - if (path_target.len) path_target = new/list() - - var/last_health = INFINITY - var/view - if (lamarr) - view = 1 - else - view = viewrange-2 - for (var/mob/living/carbon/C in range(view,loc)) - if (C.stat == 2 || isalien(C) || C.alien_egg_flag || !can_see(src,C,viewrange) || istype(C, /mob/living/carbon/metroid)) - continue - if(C:stunned || C:paralysis || C:weakened) - target = C - - break - if(C:health < last_health) - last_health = C:health - target = C - - if(target) - if (!lamarr || prob(10)) - set_attack() - else if(state != 2) - set_idle() - idle() - - else if(target) - var/turf/distance = get_dist(src, target) - if (!lamarr || prob(10)) - set_attack() - - if(can_see(src,target,viewrange)) - if(distance <= 1 && (!lamarr || prob(20))) - for(var/mob/O in viewers(world.view,src)) - O.show_message("\red [target] has been leapt on by [lamarr ? name : "the alien"]!", 1, "\red You hear someone fall", 2) - if (!lamarr) - target:take_overall_damage(5) - if(prob(70)) - target:paralysis = max(target:paralysis, 5) - loc = target.loc - - if(!target.alien_egg_flag && ( ishuman(target) || ismonkey(target) ) ) - if (!lamarr && target) - var/mob/trg = target - death() - //if(trg.virus)//Viruses are stored in a global database. - //trg.virus.cure(0)//You need to either cure() or del() them to stop their processing. - trg.contract_disease(new /datum/disease/alien_embryo(0))//So after that you need to infect the target anew. - for(var/datum/disease/alien_embryo/A in trg.viruses) - trg.alien_egg_flag = 1//We finally set their flag to 1. - return - else - sleep(50) - else - set_null() - spawn(cycle_pause) process() - return - - step_towards(src,get_step_towards2(src , target)) - else - if( !path_target.len ) - - path_attack(target) - if(!path_target.len) - set_null() - spawn(cycle_pause) process() - return - else - var/turf/next = path_target[1] - - if(next in range(1,src)) - path_attack(target) - - if(!path_target.len) - frustration += 5 - else - next = path_target[1] - path_target -= next - step_towards(src,next) - quick_move = 1 - - if (get_dist(src, target) >= distance) frustration++ - else frustration-- - if(frustration >= 35 || lamarr) set_null() - - if(quick_move) - spawn(cycle_pause/2) - process() - else - spawn(cycle_pause) - process() - - proc/idle() - set background = 1 - var/quick_move = 0 - - if(state != 2 || !alive || target) return - - if(locate(/obj/effect/alien/weeds) in loc && health < maxhealth) - health++ - spawn(cycle_pause) idle() - return - - if(!path_idle.len) - - if(isalien(trg_idle)) - if(can_see(src,trg_idle,viewrange)) - step_towards(src,get_step_towards2(src , trg_idle)) - else - path_idle(trg_idle) - if(!path_idle.len) - trg_idle = null - set_idle() - spawn(cycle_pause) idle() - return - else - var/obj/effect/alien/weeds/W = null - if(health < maxhealth) - var/list/the_weeds = new/list() - - find_weeds: - for(var/obj/effect/alien/weeds/weed in range(viewrange,loc)) - if(!can_see(src,weed,viewrange)) continue - for(var/atom/A in get_turf(weed)) - if(A.density) continue find_weeds - the_weeds += weed - if(the_weeds.len) - W = pick(the_weeds) - - if(W) - path_idle(W) - if(!path_idle.len) - trg_idle = null - spawn(cycle_pause) idle() - return - else - for(var/mob/living/carbon/alien/humanoid/H in range(1,src)) - spawn(cycle_pause) idle() - return - step(src,pick(cardinal)) - - else - - if(can_see(src,trg_idle,viewrange)) - switch(get_dist(src, trg_idle)) - if(1) - if(istype(trg_idle,/obj/effect/alien/weeds)) - step_towards(src,get_step_towards2(src , trg_idle)) - if(2 to INFINITY) - step_towards(src,get_step_towards2(src , trg_idle)) - if(path_idle.len) path_idle = new/list() - /* - if(viewrange+1 to INFINITY) - step_towards(src,get_step_towards2(src , trg_idle)) - if(path_idle.len) path_idle = new/list() - quick_move = 1 - */ - else - var/turf/next = path_idle[1] - if(!next in range(1,src)) - path_idle(trg_idle) - - if(!path_idle.len) - spawn(cycle_pause) idle() - return - else - next = path_idle[1] - path_idle -= next - step_towards(src,next) - quick_move = 1 - - if(quick_move) - spawn(cycle_pause/2) - idle() - else - spawn(cycle_pause) - idle() - - proc/path_idle(var/atom/trg) - path_idle = AStar(loc, get_turf(trg), /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 250, null, null) - path_idle = reverselist(path_idle) - - proc/path_attack(var/atom/trg) - target = trg - path_target = AStar(loc, target.loc, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 250, null, null) - path_target = reverselist(path_target) - - - proc/death() - if(!alive) return - alive = 0 - density = 0 - icon_state = "facehugger_l" - set_null() - for(var/mob/O in hearers(src, null)) - O.show_message("\red [src] curls up into a ball!", 1) - - proc/healthcheck() - if (health <= 0) - death() - -*/ \ No newline at end of file + return \ No newline at end of file diff --git a/code/game/objects/items/weapons/dna_injector.dm b/code/game/objects/items/weapons/dna_injector.dm index 848327c6da4..2150fb31881 100644 --- a/code/game/objects/items/weapons/dna_injector.dm +++ b/code/game/objects/items/weapons/dna_injector.dm @@ -23,7 +23,7 @@ /obj/item/weapon/dnainjector/proc/inject(mob/M as mob) M.radiation += rand(20,50) - if (!(M.mutations & HUSK)) // prevents husks from having their DNA changed + if (!(M.mutations & NOCLONE)) // prevents drained people from having their DNA changed if (dnatype == "ui") if (!block) //isolated block? if (ue) //unique enzymes? yes diff --git a/code/game/turf.dm b/code/game/turf.dm index 9445e0b0d5f..093569186a2 100644 --- a/code/game/turf.dm +++ b/code/game/turf.dm @@ -348,7 +348,7 @@ /turf/simulated/wall/attack_animal(mob/living/simple_animal/M as mob) - if((M.destroyer)) + if(M.wall_smash) if (istype(src, /turf/simulated/wall/r_wall)) M << text("\blue This wall is far too strong for you to destroy.") return diff --git a/code/modules/chemical/Chemistry-Tools.dm b/code/modules/chemical/Chemistry-Tools.dm index f96b30676f0..dd311a5cde3 100644 --- a/code/modules/chemical/Chemistry-Tools.dm +++ b/code/modules/chemical/Chemistry-Tools.dm @@ -905,7 +905,7 @@ if(!T.dna) usr << "You are unable to locate any blood. (To be specific, your target seems to be missing their DNA datum)" return - if(T.mutations & HUSK) //target done been et, no more blood in him + if(T.mutations & NOCLONE) //target done been et, no more blood in him user << "\red You are unable to locate any blood." return B.holder = src diff --git a/code/modules/mob/living/carbon/human/death.dm b/code/modules/mob/living/carbon/human/death.dm index 2bdb087c462..9c37f06d9c7 100644 --- a/code/modules/mob/living/carbon/human/death.dm +++ b/code/modules/mob/living/carbon/human/death.dm @@ -55,4 +55,9 @@ mutations |= HUSK real_name = "Unknown" update_body() + return + +/mob/living/carbon/human/proc/Drain() + ChangeToHusk() + mutations |= NOCLONE return \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 5e875733f4d..619e1fedf9d 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -2222,8 +2222,8 @@ It can still be worn/put on as normal. src.stat = 0 return src.health = 100 - src.getOxyLoss() - src.getToxLoss() - src.getFireLoss() - src.getBruteLoss() - src.getCloneLoss() - //if(getFireLoss() > 100 && stat == DEAD) - // ChangeToHusk() // Commented out due to lasers and fire also husking you and making you unclonable. + if(getFireLoss() > (100 - config.health_threshold_dead) && stat == DEAD) //100 only being used as the magic human max health number, feel free to change it if you add a var for it -- Urist + ChangeToHusk() return diff --git a/code/modules/mob/simple_animal/constructs.dm b/code/modules/mob/simple_animal/constructs.dm index 181d26101ae..beaaf0c7059 100644 --- a/code/modules/mob/simple_animal/constructs.dm +++ b/code/modules/mob/simple_animal/constructs.dm @@ -22,7 +22,7 @@ max_co2 = 0 max_tox = 0 speed = 3 - destroyer = 1 + wall_smash = 1 nopush = 1 a_intent = "harm" stop_automated_movement = 1 diff --git a/code/modules/mob/simple_animal/life.dm b/code/modules/mob/simple_animal/life.dm index b98578a7628..3b2c3c0fb4e 100644 --- a/code/modules/mob/simple_animal/life.dm +++ b/code/modules/mob/simple_animal/life.dm @@ -47,7 +47,7 @@ var/attacktext = "attacks" var/attack_sound = null var/friendly = "nuzzles" //If the mob does no damage with it's attack - var/destroyer = 0 //if they can smash walls + var/wall_smash = 0 //if they can smash walls var/speed = 0 //LETS SEE IF I CAN SET SPEEDS FOR SIMPLE MOBS WITHOUT DESTROYING EVERYTHING. Higher speed is slower, negative speed is faster /mob/living/simple_animal/New() @@ -66,16 +66,12 @@ if(health > 0) icon_state = icon_living alive = 1 - stat = 0 //Alive - conscious + stat = CONSCIOUS density = 1 return if(health < 1) - alive = 0 - icon_state = icon_dead - stat = 2 //Dead - density = 0 - return + Die() if(health > maxHealth) health = maxHealth @@ -91,35 +87,37 @@ //Speaking if(speak_chance) if(prob(speak_chance)) - if(speak && (emote_hear || emote_see) ) - var/length = speak.len - if(emote_hear) - length += emote_hear.len - if(emote_see) - length += emote_see.len - var/pick = rand(1,length) - if(pick <= speak.len) - say(pick(speak)) - else - pick -= speak.len - if(emote_see && pick <= emote_see.len) - emote(pick(emote_see),1) + if(speak && speak.len) + if((emote_hear && emote_hear.len) || (emote_see && emote_see.len)) + var/length = speak.len + if(emote_hear && emote_hear.len) + length += emote_hear.len + if(emote_see && emote_see.len) + length += emote_see.len + var/randomValue = rand(1,length) + if(randomValue <= speak.len) + say(pick(speak)) else - emote(pick(emote_hear),2) - if(!speak) - if(!emote_hear && emote_see) + randomValue -= speak.len + if(emote_see && randomValue <= emote_see.len) + emote(pick(emote_see),1) + else + emote(pick(emote_hear),2) + else + say(pick(speak)) + else + if(!(emote_hear && emote_hear.len) && (emote_see && emote_see.len)) emote(pick(emote_see),1) - if(emote_hear && !emote_see) + if((emote_hear && emote_hear.len) && !(emote_see && emote_see.len)) emote(pick(emote_hear),2) - if(emote_hear && emote_see) + if((emote_hear && emote_hear.len) && (emote_see && emote_see.len)) var/length = emote_hear.len + emote_see.len var/pick = rand(1,length) if(pick <= emote_see.len) emote(pick(emote_see),1) else emote(pick(emote_hear),2) - if(speak && !(emote_see || emote_hear)) - say(pick(speak)) + //Atmos var/atmos_suitable = 1 @@ -193,7 +191,7 @@ ..() /mob/living/simple_animal/say_quote(var/text) - if(speak_emote) + if(speak_emote && speak_emote.len) var/emote = pick(speak_emote) if(emote) return "[emote], \"[text]\"" @@ -300,3 +298,10 @@ tally = speed return tally + +/mob/living/simple_animal/proc/Die() + alive = 0 + icon_state = icon_dead + stat = DEAD + density = 0 + return diff --git a/code/modules/mob/simple_animal/worm.dm b/code/modules/mob/simple_animal/worm.dm new file mode 100644 index 00000000000..57ee59b5e2f --- /dev/null +++ b/code/modules/mob/simple_animal/worm.dm @@ -0,0 +1,183 @@ +/mob/living/simple_animal/space_worm + name = "space worm segment" + desc = "A part of a space worm." + icon = 'critter.dmi' + icon_state = "spaceworm" + icon_living = "spaceworm" + icon_dead = "spacewormdead" + + speak_emote = list("transmits") //not supposed to be used under AI control + emote_hear = list("transmits") //I'm just adding it so it doesn't runtime if controlled by player who speaks + + response_help = "touches" + response_disarm = "flails at" + response_harm = "punches the" + + harm_intent_damage = 2 + + maxHealth = 30 + health = 30 + + stop_automated_movement = 1 + animate_movement = SYNC_STEPS + + minbodytemp = 0 + maxbodytemp = 350 + min_oxy = 0 + max_co2 = 0 + max_tox = 0 + + a_intent = "harm" //so they don't get pushed around + + nopush = 1 + wall_smash = 1 + + speed = -1 + + var/mob/living/simple_animal/space_worm/previous //next/previous segments, correspondingly + var/mob/living/simple_animal/space_worm/next //head is the nextest segment + + var/stomach_process_probability = 50 + var/digestion_probability = 20 + var/flat_plasma_value = 5 //flat plasma amount given for non-items + + head + name = "space worm head" + icon_state = "spacewormhead" + icon_living = "spacewormhead" + icon_dead = "spacewormdead" + + maxHealth = 20 + health = 20 + + melee_damage_lower = 10 + melee_damage_upper = 15 + attacktext = "bites" + + animate_movement = SLIDE_STEPS + + New(var/location, var/segments = 6) + ..() + + var/mob/living/simple_animal/space_worm/current = src + + for(var/i = 1 to segments) + var/mob/living/simple_animal/space_worm/newSegment = new /mob/living/simple_animal/space_worm(loc) + current.Attach(newSegment) + current = newSegment + + update_icon() + if(stat == CONSCIOUS || stat == UNCONSCIOUS) + icon_state = "spacewormhead[previous?1:0]" + if(previous) + dir = get_dir(previous,src) + else + icon_state = "spacewormheaddead" + + Life() + ..() + + if(next && !(next in view(src,1))) + Detach() + + if(stat == DEAD) //dead chunks fall off and die immediately + if(previous) + previous.Detach() + if(next) + Detach(1) + + if(prob(stomach_process_probability)) + ProcessStomach() + + update_icon() + + return + + Del() //if a chunk a destroyed, make a new worm out of the split halves + if(previous) + previous.Detach() + ..() + + Move() + var/attachementNextPosition = loc + if(..()) + if(previous) + previous.Move(attachementNextPosition) + update_icon() + + Bump(atom/obstacle) + AttemptToEat(obstacle) + return + + proc/update_icon() //only for the sake of consistency with the other update icon procs + if(stat == CONSCIOUS || stat == UNCONSCIOUS) + if(previous) //midsection + icon_state = "spaceworm[get_dir(src,previous) | get_dir(src,next)]" //see 3 lines below + else //tail + icon_state = "spacewormtail" + dir = get_dir(src,next) //next will always be present since it's not a head and if it's dead, it goes in the other if branch + else + icon_state = "spacewormdead" + + return + + proc/AttemptToEat(var/atom/target) //will take time later, prototype right now + if(istype(target,/turf/simulated/wall)) + var/turf/simulated/wall/wall = target + wall.ReplaceWithFloor() + new /obj/item/stack/sheet/metal(src, 5) //will depend on wall type later, of course + else if(istype(target,/atom/movable)) + var/atom/movable/objectOrMob = target + contents += objectOrMob + + return + + proc/Attach(var/mob/living/simple_animal/space_worm/attachement) + if(!attachement) + return + + previous = attachement + attachement.next = src + + return + + proc/Detach(die = 0) + var/mob/living/simple_animal/space_worm/newHead = new /mob/living/simple_animal/space_worm/head(loc,0) + var/mob/living/simple_animal/space_worm/newHeadPrevious = previous + + previous = null //so that no extra heads are spawned + + newHead.Attach(newHeadPrevious) + + if(die) + newHead.Die() + + del(src) + + proc/ProcessStomach() + for(var/atom/movable/stomachContent in contents) + if(prob(digestion_probability)) + if(istype(stomachContent,/obj/item/stack)) //converts to plasma, keeping the stack value + if(!istype(stomachContent,/obj/item/stack/sheet/plasma)) + var/obj/item/stack/oldStack = stomachContent + new /obj/item/stack/sheet/plasma(src, oldStack.amount) + del(oldStack) + continue + else if(istype(stomachContent,/obj/item)) //converts to plasma, keeping the w_class + var/obj/item/oldItem = stomachContent + new /obj/item/stack/sheet/plasma(src, oldItem.w_class) + del(oldItem) + continue + else + new /obj/item/stack/sheet/plasma(src, flat_plasma_value) //just flat amount + del(stomachContent) + continue + + if(previous) + for(var/atom/movable/stomachContent in contents) //transfer it along the digestive tract + previous.contents += stomachContent + else + for(var/atom/movable/stomachContent in contents) //or poop it out + loc.contents += stomachContent + + return \ No newline at end of file diff --git a/code/setup.dm b/code/setup.dm index 393aee41b62..f7c87ada011 100644 --- a/code/setup.dm +++ b/code/setup.dm @@ -179,6 +179,7 @@ var/const HUSK =(1<<6) LASER =(1<<7) HEAL =(1<<8) + NOCLONE =(1<<9) //mob/var/stat things diff --git a/icons/mob/critter.dmi b/icons/mob/critter.dmi index 61f9cc096f8..d17796be3f2 100644 Binary files a/icons/mob/critter.dmi and b/icons/mob/critter.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 7b5716dbaeb..0c24cb69b4f 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -925,6 +925,7 @@ #include "code\modules\mob\simple_animal\crab.dm" #include "code\modules\mob\simple_animal\life.dm" #include "code\modules\mob\simple_animal\shade.dm" +#include "code\modules\mob\simple_animal\worm.dm" #include "code\modules\power\apc.dm" #include "code\modules\power\cable.dm" #include "code\modules\power\cell.dm"