From 4d60c67d1af5d55fdaf17725b3a5e100517e2746 Mon Sep 17 00:00:00 2001 From: "vageyenaman@gmail.com" Date: Sat, 9 Jul 2011 22:11:46 +0000 Subject: [PATCH] Viruses: For some reason, viruses were being "cured" just a bit too fast. I lowered the rate which a virus advanced through stages. I also fixed vaccines; they now actually cure viruses as well as providing immunity to any further infection. Metroids: The beginning of my Metroid ranching phase; Metroids may now, theoretically, be tamed to an extent. Baby Metroids are suceptible to simulated discipline, meaning if you beat them over the head with a toolbox for trying to eat your fellow scientists they will probably get the message. This also works when you're trying to wrestle a metroid off of someone's head. Additionally, they may also identify who the people who feed them are and in a situation where they have to fight to defend themselves or eat, they will spare their "friends". This is a pretty big AI change, so if you see any bugs please report them immediately! Metroids can also "vent-crawl" like monkies, but fully-grown adults are too big to do this. NPC Metroids will never vent-crawl. Weapons/Guns: A lot of you are going to like this one; you can no longer shoot yourself with your own gun! This happens sometimes when the game lags up for a bit, but no more! Additionally, you can now shoot people who are on the ground simply by clicking them. I can only imagine how easy this will make being an officer (or traitor/syndicate) now. This applies to both handheld guns and mecha weapon installments. Xenobiology: Scientists now, hopefully, have proper Xenobio access. Metroid dissection has been slightly changed; you can extract Metroid cores from dead Metroids no matter where you're aiming. You will not see me talk about metroid cores anymore because they're a secret. I haven't done anything with them yet, however. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@1813 316c924e-a436-60f5-8080-3fe189b3f50e --- code/WorkInProgress/Chemistry-Reagents.dm | 5 +- code/WorkInProgress/Chemistry-Tools.dm | 2 +- code/WorkInProgress/recycling/disposal.dm | 1 + code/datums/disease.dm | 6 +- code/datums/diseases/cold.dm | 2 +- code/defines/mob/living/carbon/metroid.dm | 7 +- code/defines/mob/mob.dm | 5 +- code/defines/obj/clothing/suit.dm | 2 +- code/game/jobs/access.dm | 2 +- code/game/mecha/equipment/weapons/weapons.dm | 5 ++ code/game/objects/items/item.dm | 11 +++ code/game/objects/items/weapons/guns_new.dm | 41 +++++++++- .../objects/items/weapons/surgery_tools.dm | 15 ++-- code/game/verbs/suicide.dm | 24 +++++- .../living/carbon/alien/humanoid/humanoid.dm | 8 ++ .../mob/living/carbon/alien/larva/larva.dm | 5 ++ code/modules/mob/living/carbon/human/human.dm | 10 +++ .../modules/mob/living/carbon/metroid/life.dm | 80 ++++++++++++++++--- .../mob/living/carbon/metroid/metroid.dm | 36 +++++++-- .../mob/living/carbon/metroid/powers.dm | 76 +++++++++++++++++- .../mob/living/carbon/monkey/monkey.dm | 9 +++ code/modules/mob/mob.dm | 6 ++ 22 files changed, 320 insertions(+), 38 deletions(-) diff --git a/code/WorkInProgress/Chemistry-Reagents.dm b/code/WorkInProgress/Chemistry-Reagents.dm index 4fd74460bb1..27ea5b6a4c2 100644 --- a/code/WorkInProgress/Chemistry-Reagents.dm +++ b/code/WorkInProgress/Chemistry-Reagents.dm @@ -175,8 +175,9 @@ datum src = null if(self.data&&method == INGEST) for(var/datum/disease/D in M.viruses) - if(M.virus && D.type == self.data["viruses"]) - D.cure() + if(D.type == self.data) + D.stage-- + if(D.stage <= 0) D.cure() M.resistances += self.data return diff --git a/code/WorkInProgress/Chemistry-Tools.dm b/code/WorkInProgress/Chemistry-Tools.dm index 8d3e29260b4..5380a44ac3d 100644 --- a/code/WorkInProgress/Chemistry-Tools.dm +++ b/code/WorkInProgress/Chemistry-Tools.dm @@ -855,7 +855,7 @@ if(istype(target, /obj/item/metroid_core)) var/obj/item/metroid_core/core = target - core.Flush = 30 + core.Flush = 30 // reset flush counter if(ismob(target) && target != user) for(var/mob/O in viewers(world.view, user)) diff --git a/code/WorkInProgress/recycling/disposal.dm b/code/WorkInProgress/recycling/disposal.dm index b1f4144b0b5..c24ad1b1b68 100644 --- a/code/WorkInProgress/recycling/disposal.dm +++ b/code/WorkInProgress/recycling/disposal.dm @@ -83,6 +83,7 @@ if(target == user && !user.stat) V.show_message("[usr] starts climbing into the disposal.", 3) if(target != user && !user.restrained()) + if(target.anchored) return V.show_message("[usr] starts stuffing [target.name] into the disposal.", 3) if(!do_after(usr, 20)) return diff --git a/code/datums/disease.dm b/code/datums/disease.dm index af7746eede5..cb774751546 100644 --- a/code/datums/disease.dm +++ b/code/datums/disease.dm @@ -28,9 +28,9 @@ to null does not delete the object itself. Thank you. var/mob/living/carbon/affected_mob = null //the mob which is affected by disease. var/holder = null //the atom containing the disease (mob or obj) var/carrier = 0.0 //there will be a small chance that the person will be a carrier - var/curable = 1 //can this disease be cured? (By itself...) + var/curable = 0 //can this disease be cured? (By itself...) var/list/strain_data = list() //This is passed on to infectees - var/stage_prob = 5 // probability of advancing to next stage, default 5% per check + var/stage_prob = 4 // probability of advancing to next stage, default 5% per check var/agent = "some microbes"//name of the disease agent var/permeability_mod = 1//permeability modifier coefficient. var/desc = null//description. Leave it null and this disease won't show in med records. @@ -49,7 +49,7 @@ to null does not delete the object itself. Thank you. if(stage > max_stages) stage = max_stages - if(prob(stage_prob) && stage != max_stages && !cure_present) //now the disease shouldn't get back up to stage 4 in no time + if(stage_prob != 0 && prob(stage_prob) && stage != max_stages && !cure_present) //now the disease shouldn't get back up to stage 4 in no time stage++ if(stage != 1 && (prob(1) || (cure_present && prob(cure_chance)))) stage-- diff --git a/code/datums/diseases/cold.dm b/code/datums/diseases/cold.dm index 798ddb4a947..7fdfe1cb24e 100644 --- a/code/datums/diseases/cold.dm +++ b/code/datums/diseases/cold.dm @@ -33,7 +33,7 @@ if(3) if(affected_mob.sleeping && prob(25)) affected_mob << "\blue You feel better." - affected_mob.virus.cure() + src.cure() return if(prob(1) && prob(10)) affected_mob << "\blue You feel better." diff --git a/code/defines/mob/living/carbon/metroid.dm b/code/defines/mob/living/carbon/metroid.dm index 8f73b455af7..81ebd8da5b4 100644 --- a/code/defines/mob/living/carbon/metroid.dm +++ b/code/defines/mob/living/carbon/metroid.dm @@ -31,9 +31,12 @@ var/tame = 0 // if set to 1, the Metroid will not eat humans ever, or attack them - var/list/Friends = list() // Anything on this list the Metroid will never eat, or attack + var/rabid = 0 // if set to 1, the Metroid will attack and eat anything it comes in contact with - // Metroids pass on genetic data, so all their offspring have the same "Friends" + var/list/Friends = list() // A list of potential friends + var/list/FriendsWeight = list() // A list containing values respective to Friends. This determines how many times a Metroid "likes" something. If the Metroid likes it more than 2 times, it becomes a friend + + // Metroids pass on genetic data, so all their offspring have the same "Friends", /mob/living/carbon/metroid/adult name = "adult metroid" diff --git a/code/defines/mob/mob.dm b/code/defines/mob/mob.dm index a9135e83c5f..5f653ee1607 100644 --- a/code/defines/mob/mob.dm +++ b/code/defines/mob/mob.dm @@ -181,6 +181,9 @@ statpanel("[P.panel]","",P) */ +//The last mob/living/carbon to push/drag/grab this mob (mostly used by Metroids friend recognition) + var/mob/living/carbon/LAssailant = null + //Wizard mode, but can be used in other modes thanks to the brand new "Give Spell" badmin button var/obj/proc_holder/spell/list/spell_list = list() @@ -220,4 +223,4 @@ the mob is also allowed to move without any sort of restriction. For instance, i var/UI = 'screen1_old.dmi' // For changing the UI from preferences - var/obj/organstructure/organStructure = null //for dem organs \ No newline at end of file + var/obj/organstructure/organStructure = null //for dem organs diff --git a/code/defines/obj/clothing/suit.dm b/code/defines/obj/clothing/suit.dm index 9e1da7079e9..0eba5e9b10c 100644 --- a/code/defines/obj/clothing/suit.dm +++ b/code/defines/obj/clothing/suit.dm @@ -267,7 +267,7 @@ item_state = "caparmor" w_class = 4//bulky item gas_transfer_coefficient = 0.01 - permeability_coefficient = 0.02 + //permeability_coefficient = 0.02 // HAHAHA no captain's armor is not a bio suit heat_transfer_coefficient = 0.02 radiation_protection = 0.25 protective_temperature = 1000 diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index 1de4870dd97..520215293bb 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -157,7 +157,7 @@ if("Warden") return list(access_security, access_brig, access_armory, access_court) if("Scientist") - return list(access_tox, access_tox_storage, access_research, access_medical) + return list(access_tox, access_tox_storage, access_research, access_medical, access_xenobiology) if("Head of Security") return list(access_medical, access_morgue, access_tox, access_tox_storage, access_chemistry, access_medlab, access_court, access_teleporter, access_heads, access_tech_storage, access_security, access_brig, access_atmospherics, diff --git a/code/game/mecha/equipment/weapons/weapons.dm b/code/game/mecha/equipment/weapons/weapons.dm index f91bfbd05a4..6e6b7e643d8 100644 --- a/code/game/mecha/equipment/weapons/weapons.dm +++ b/code/game/mecha/equipment/weapons/weapons.dm @@ -27,6 +27,7 @@ set_ready_state(0) playsound(chassis, 'Laser.ogg', 50, 1) var/obj/item/projectile/beam/A = new /obj/item/projectile/beam(curloc) + A.original = targloc A.current = curloc A.yo = targloc.y - curloc.y A.xo = targloc.x - curloc.x @@ -56,6 +57,7 @@ playsound(chassis, 'marauder.ogg', 50, 1) var/obj/item/projectile/beam/pulse/A = new /obj/item/projectile/beam/pulse/heavy(curloc) + A.original = targloc A.current = curloc A.yo = targloc.y - curloc.y A.xo = targloc.x - curloc.x @@ -97,6 +99,7 @@ playsound(chassis, 'Laser.ogg', 50, 1) var/obj/item/projectile/electrode/A = new /obj/item/projectile/electrode(curloc) + A.original = targloc A.current = curloc A.yo = targloc.y - curloc.y A.xo = targloc.x - curloc.x @@ -221,6 +224,7 @@ playsound(chassis, 'Gunshot.ogg', 80, 1) var/obj/item/projectile/A = new /obj/item/projectile(curloc) src.projectiles-- + A.original = targloc A.current = curloc A.yo = targloc.y - curloc.y A.xo = targloc.x - curloc.x @@ -259,6 +263,7 @@ playsound(chassis, 'Gunshot.ogg', 50, 1) var/obj/item/projectile/weakbullet/A = new /obj/item/projectile/weakbullet(curloc) src.projectiles-- + A.original = targloc A.current = curloc A.yo = targloc.y - curloc.y A.xo = targloc.x - curloc.x diff --git a/code/game/objects/items/item.dm b/code/game/objects/items/item.dm index c72f51746ef..82cabe51b9d 100644 --- a/code/game/objects/items/item.dm +++ b/code/game/objects/items/item.dm @@ -237,6 +237,10 @@ if(prob(5 + round(power/2))) Metroid.Victim = null Metroid.anchored = 0 + + if(prob(80) && !Metroid.client) + Metroid.Discipline++ + spawn(0) Metroid.canmove = 0 step_away(Metroid, user) @@ -249,6 +253,13 @@ if(prob(10 + power*2)) Metroid.Victim = null Metroid.anchored = 0 + + if(prob(80) && !Metroid.client) + Metroid.Discipline++ + + if(Metroid.Discipline == 1) + Metroid.attacked = 0 + spawn(0) step_away(Metroid, user) Metroid.canmove = 0 diff --git a/code/game/objects/items/weapons/guns_new.dm b/code/game/objects/items/weapons/guns_new.dm index 0891387553f..e0e01e53aaf 100644 --- a/code/game/objects/items/weapons/guns_new.dm +++ b/code/game/objects/items/weapons/guns_new.dm @@ -28,6 +28,10 @@ var/const/PROJECTILE_DART = 8 yo = null xo = null current = null + turf/original = null + + bumped = 0 + weakbullet damage_type = PROJECTILE_WEAKBULLET @@ -59,10 +63,20 @@ var/const/PROJECTILE_DART = 8 icon_state = "cbbolt" Bump(atom/A as mob|obj|turf|area) + if(A == firer) + loc = A.loc + return // cannot shoot yourself! NO! + if(bumped) return + + bumped = 1 if(firer && istype(A, /mob)) var/mob/M = A if(!silenced) - visible_message("\red [A.name] has been shot by [firer.name].", "\blue You hear a [istype(src, /obj/item/projectile/beam) ? "gunshot" : "laser blast"].") + /* + for(var/mob/O in viewers(M)) + O.show_message("\red [A.name] has been shot by [firer.name]!", 1) */ + + visible_message("\red [A.name] has been shot by [firer.name]!", "\blue You hear a [istype(src, /obj/item/projectile/beam) ? "gunshot" : "laser blast"]!") else M << "\red You've been shot!" if(istype(firer, /mob)) @@ -89,13 +103,22 @@ var/const/PROJECTILE_DART = 8 process() spawn while(src) + if ((!( current ) || loc == current)) current = locate(min(max(x + xo, 1), world.maxx), min(max(y + yo, 1), world.maxy), z) if ((x == 1 || x == world.maxx || y == 1 || y == world.maxy)) del(src) return step_towards(src, current) + sleep( 1 ) + + if(!bumped) + if(loc == original) + for(var/mob/M in original) + Bump(M) + sleep( 1 ) + return /obj/item/ammo_casing @@ -468,8 +491,8 @@ var/const/PROJECTILE_DART = 8 update_icon() energy - icon_state = "energy" - name = "Energy Gun" + icon_state = "energy gun" + name = "energy gun" desc = "A basic energy-based gun with two settings: Stun and kill." fire_sound = 'Taser.ogg' var @@ -718,6 +741,16 @@ var/const/PROJECTILE_DART = 8 return 1 return 0 + freeze + name = "freeze gun" + icon_state = "freezegun100" + fire_sound = 'pulse3.ogg' + + attack_self(mob/living/user as mob) + return + + + crossbow name = "mini energy-crossbow" desc = "A weapon favored by many of the syndicates stealth specialists." @@ -767,6 +800,7 @@ var/const/PROJECTILE_DART = 8 in_chamber = new /obj/item/projectile/electrode(src) return 1 return 0 + proc load_into_chamber() in_chamber = new /obj/item/projectile/weakbullet(src) @@ -847,6 +881,7 @@ var/const/PROJECTILE_DART = 8 user.bullet_act(in_chamber.damage_type) del(in_chamber) else + in_chamber.original = targloc in_chamber.loc = get_turf(user) user.next_move = world.time + 4 in_chamber.silenced = silenced diff --git a/code/game/objects/items/weapons/surgery_tools.dm b/code/game/objects/items/weapons/surgery_tools.dm index bb03ecb0ce2..7d42e0f1c00 100644 --- a/code/game/objects/items/weapons/surgery_tools.dm +++ b/code/game/objects/items/weapons/surgery_tools.dm @@ -210,7 +210,7 @@ CIRCULAR SAW src.add_fingerprint(user) - if(user.zone_sel.selecting == "head") + if(user.zone_sel.selecting == "head" || istype(M, /mob/living/carbon/metroid)) var/mob/living/carbon/human/H = M if(istype(H) && ( \ @@ -237,7 +237,8 @@ CIRCULAR SAW M << "\red [user] begins to cut open your flesh with [src]!" user << "\red You cut [M]'s flesh open with [src]!" M:brain_op_stage = 1.0 - return + + return if(M != user) for(var/mob/O in (viewers(M) - user - M)) @@ -275,15 +276,15 @@ CIRCULAR SAW M << "\red [user] begins to cut apart your innards with [src]!" user << "\red You cut [M]'s silky innards apart with [src]!" M:brain_op_stage = 2.0 - return + return if(2.0) if(istype(M, /mob/living/carbon/metroid)) if(M.stat == 2) var/mob/living/carbon/metroid/Metroid = M if(Metroid.cores > 0) if(istype(M, /mob/living/carbon/metroid)) - user << "\red You attempt to remove [M]'s core, but your [src] is ineffective!" - return + user << "\red You attempt to remove [M]'s core, but [src] is ineffective!" + return if(M != user) for(var/mob/O in (viewers(M) - user - M)) @@ -387,7 +388,7 @@ CIRCULAR SAW src.add_fingerprint(user) - if(user.zone_sel.selecting == "head") + if(user.zone_sel.selecting == "head" || istype(M, /mob/living/carbon/metroid)) var/mob/living/carbon/human/H = M if(istype(H) && ( \ @@ -454,7 +455,7 @@ CIRCULAR SAW if(Metroid.cores <= 0) M.icon_state = "baby metroid dead-nocore" - return + return if(3.0) if(M != user) diff --git a/code/game/verbs/suicide.dm b/code/game/verbs/suicide.dm index 80f2e3753cf..604b832b44a 100644 --- a/code/game/verbs/suicide.dm +++ b/code/game/verbs/suicide.dm @@ -150,4 +150,26 @@ viewers(src) << "\red [src] is thrashing wildly! It looks like \he's trying to commit suicide." //put em at -175 oxyloss = max(100 - fireloss - bruteloss, oxyloss) - updatehealth() \ No newline at end of file + updatehealth() + + +/mob/living/carbon/metroid/verb/suicide() + set hidden = 1 + if (stat == 2) + src << "You're already dead!" + return + + if (suiciding) + src << "You're already committing suicide! Be patient!" + return + + var/confirm = alert("Are you sure you want to commit suicide?", "Confirm Suicide", "Yes", "No") + + if(confirm == "Yes") + suiciding = 1 + oxyloss = 100 + bruteloss = 100 + toxloss = 100 + cloneloss = 100 + + updatehealth() diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index 323e2021126..22ec882e6a3 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -31,6 +31,11 @@ ..() if (!istype(AM, /atom/movable)) return + + if (ismob(AM)) + var/mob/tmob = AM + tmob.LAssailant = src + if (!now_pushing) now_pushing = 1 if (!AM.anchored) @@ -701,6 +706,9 @@ G.affecting = src grabbed_by += G G.synch() + + LAssailant = M + playsound(loc, 'thudswoosh.ogg', 50, 1, -1) for(var/mob/O in viewers(src, null)) if ((O.client && !( O.blinded ))) diff --git a/code/modules/mob/living/carbon/alien/larva/larva.dm b/code/modules/mob/living/carbon/alien/larva/larva.dm index 2800e956000..ca5f4e61ed7 100644 --- a/code/modules/mob/living/carbon/alien/larva/larva.dm +++ b/code/modules/mob/living/carbon/alien/larva/larva.dm @@ -35,6 +35,8 @@ M << "\red [src] fails to push [tmob]'s fat ass out of the way." now_pushing = 0 return + tmob.LAssailant = src + now_pushing = 0 ..() if (!( istype(AM, /atom/movable) )) @@ -464,6 +466,9 @@ G.affecting = src grabbed_by += G G.synch() + + LAssailant = M + playsound(loc, 'thudswoosh.ogg', 50, 1, -1) for(var/mob/O in viewers(src, null)) if ((O.client && !( O.blinded ))) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 037b40a7f18..40e8c0d78f6 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -112,6 +112,9 @@ "\red You fail to push [tmob]'s fat ass out of the way.") now_pushing = 0 return + + tmob.LAssailant = src + now_pushing = 0 spawn(0) ..() @@ -119,6 +122,7 @@ return if (!now_pushing) now_pushing = 1 + if (!AM.anchored) var/t = get_dir(src, AM) if (istype(AM, /obj/window)) @@ -1546,6 +1550,9 @@ G.affecting = src grabbed_by += G G.synch() + + LAssailant = M + playsound(loc, 'thudswoosh.ogg', 50, 1, -1) for(var/mob/O in viewers(src, null)) if ((O.client && !( O.blinded ))) @@ -1810,6 +1817,9 @@ G.affecting = src grabbed_by += G G.synch() + + LAssailant = M + playsound(loc, 'thudswoosh.ogg', 50, 1, -1) for(var/mob/O in viewers(src, null)) O.show_message(text("\red [] has grabbed [] passively!", M, src), 1) diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm index 326bfc96312..3e0c03bf55f 100644 --- a/code/modules/mob/living/carbon/metroid/life.dm +++ b/code/modules/mob/living/carbon/metroid/life.dm @@ -53,6 +53,14 @@ if(prob(85)) attacked-- + if(Discipline > 0) + + if(Discipline >= 5 && rabid) + if(prob(60)) rabid = 0 + + if(prob(20)) + Discipline-- + // Grabbing @@ -77,8 +85,9 @@ var/starving = 0 // determines if the metroid is starving-hungry if(istype(src, /mob/living/carbon/metroid/adult)) switch(nutrition) - if(200 to 600) hungry = 1 - if(0 to 199) starving = 1 + if(400 to 800) hungry = 1 + if(0 to 399) + starving = 1 else switch(nutrition) @@ -86,6 +95,11 @@ if(0 to 149) starving = 1 + if(starving && !client) // if a metroid is starving, it starts losing its friends + if(prob(45)) + var/mob/nofriend = pick(Friends) + Friends -= nofriend + if(!Target) var/list/targets = list() @@ -98,11 +112,24 @@ if(H.mutantrace == "metroid") notarget = 1 // don't hurt metroidmen! + if(!istype(src, /mob/living/carbon/metroid/adult)) + if(!starving && Discipline > 0) + notarget = 1 + break + if(!C.canmove) for(var/mob/living/carbon/metroid/M in view(1,C)) if(M.Victim == C) notarget = 1 + if(C in Friends) + notarget = 1 + + if(tame && istype(C, /mob/living/carbon/human)) + notarget = 1 + + + if(!notarget) targets += C @@ -118,7 +145,7 @@ for(var/mob/living/carbon/alien/larva/L in targets) Target = L break - if(prob(1)) + if(prob(5)) for(var/mob/living/carbon/alien/humanoid/H in targets) Target = H break @@ -132,8 +159,9 @@ else Target = pick(targets) - if(attacked > 0 && targets.len > 0) - Target = targets[1] // should be the closest target + if(targets.len > 0) + if(attacked > 0 || rabid) + Target = targets[1] // should be the closest target @@ -158,6 +186,8 @@ var/AIproc = 0 // determines if the AI loop is activated var/Atkcool = 0 // attack cooldown var/Tempstun = 0 // temporary temperature stuns + var/Discipline = 0 // if a metroid has been hit with a freeze gun, or wrestled/attacked off a human, they become disciplined and don't attack anymore for a while + var/turf/Charging = null // turf a metroid is "charging" at proc AIprocess() // the master AI process @@ -167,6 +197,23 @@ if(Victim) // can't eat AND have this little process at the same time break + + if(Charging) + step_to(src,Charging) + if(Charging == loc) + Charging = null + sleep(15) + + if(Target in view(1,src)) + Charging = null + if(prob(90)) Feedon(Target) + else + Target.attack_metroid(src) + sleep(5) + + sleep(2) + continue + if(Target.health <= -70 || Target.stat == 2) Target = null AIproc = 0 @@ -207,7 +254,14 @@ else if(Target in view(30, src)) - step_to(src, Target) + if(get_dist(Target,src) >= 5 && prob(45)) + Charging = Target.loc + for(var/mob/O in viewers(src, null)) + O.show_message("The [src.name] lunges swiftly at [Target]!", 1) + continue + + else + step_to(src, Target) else Target = null @@ -319,7 +373,7 @@ death() return - else if(src.health < 0) + else if(src.health < -50) // if(src.health <= 20 && prob(1)) spawn(0) emote("gasp") //if(!src.rejuv) src.oxyloss++ @@ -388,7 +442,7 @@ handle_nutrition() if(prob(30)) - if(istype(src, /mob/living/carbon/metroid/adult)) nutrition-=rand(2,6) + if(istype(src, /mob/living/carbon/metroid/adult)) nutrition-=rand(4,7) else nutrition-=rand(1,4) if(nutrition <= 0) @@ -413,7 +467,11 @@ for(var/i=1,i<=number,i++) // reproduce (has a small chance of producing 3 or 4 offspring) var/mob/living/carbon/metroid/M = new/mob/living/carbon/metroid(loc) M.nutrition = round(nutrition/number) - step_away(M,src) + M.powerlevel = round(powerlevel / number) + M.Friends = Friends + M.tame = tame + M.rabid = rabid + if(i != 1) step_away(M,src) del(src) @@ -421,6 +479,10 @@ if(!client) var/mob/living/carbon/metroid/adult/A = new/mob/living/carbon/metroid/adult(src.loc) A.nutrition = nutrition + A.powerlevel = max(0, powerlevel-1) + A.Friends = Friends + A.tame = tame + A.rabid = rabid del(src) diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm index 3acf033d086..97faeba2adf 100644 --- a/code/modules/mob/living/carbon/metroid/metroid.dm +++ b/code/modules/mob/living/carbon/metroid/metroid.dm @@ -33,8 +33,8 @@ if(reagents.has_reagent("hyperzine")) // hyperzine slows Metroids down tally *= 2 // moves twice as slow - if(reagents.has_reagent("frostoil")) // frostoil also makes them move pretty slow - tally *= 3 + if(reagents.has_reagent("frostoil")) // frostoil also makes them move VEEERRYYYYY slow + tally *= 5 if(health <= 0) // if damaged, the metroid moves twice as slow tally *= 2 @@ -61,7 +61,9 @@ if(7 to 8) probab = 60 if(9) probab = 70 if(10) probab = 95 - if(prob(probab)) + if(prob(probab) || Charging) + if(Charging) Charging = null + if(istype(AM, /obj/window) || istype(AM, /obj/grille)) if(istype(src, /mob/living/carbon/metroid/adult)) if(nutrition <= 600 && !Atkcool) @@ -444,6 +446,9 @@ O.show_message("\red [M] manages to wrestle \the [name] off!", 1) playsound(loc, 'thudswoosh.ogg', 50, 1, -1) + if(prob(90) && !client) + Discipline++ + Victim = null anchored = 0 step_away(src,M) @@ -463,6 +468,9 @@ O.show_message("\red [M] manages to wrestle \the [name] off of [Victim]!", 1) playsound(loc, 'thudswoosh.ogg', 50, 1, -1) + if(prob(50) && !client) + Discipline++ + Victim = null anchored = 0 step_away(src,M) @@ -496,6 +504,9 @@ G.affecting = src grabbed_by += G G.synch() + + LAssailant = M + playsound(loc, 'thudswoosh.ogg', 50, 1, -1) for(var/mob/O in viewers(src, null)) if ((O.client && !( O.blinded ))) @@ -511,11 +522,15 @@ if(Victim) Victim = null anchored = 0 + if(prob(80) && !client) + Discipline++ spawn(0) step_away(src,M,15) sleep(3) step_away(src,M,15) + + playsound(loc, "punch", 25, 1, -1) for(var/mob/O in viewers(src, null)) if ((O.client && !( O.blinded ))) @@ -583,6 +598,9 @@ G.affecting = src grabbed_by += G G.synch() + + LAssailant = M + playsound(loc, 'thudswoosh.ogg', 50, 1, -1) for(var/mob/O in viewers(src, null)) O.show_message(text("\red [] has grabbed [name] passively!", M), 1) @@ -600,6 +618,8 @@ if(Victim) Victim = null anchored = 0 + if(prob(80) && !client) + Discipline++ spawn(0) @@ -640,7 +660,13 @@ mob/living/carbon/metroid/var/temperature_resistance = T0C+75 /mob/living/carbon/metroid/updatehealth() if (nodamage == 0) // metroids can't suffocate unless they suicide. They are also not harmed by fire - health = 25 - oxyloss - bruteloss + if(istype(src, /mob/living/carbon/metroid/adult)) + health = 200 - (oxyloss + toxloss + fireloss + bruteloss + cloneloss) + else + health = 150 - (oxyloss + toxloss + fireloss + bruteloss + cloneloss) else - health = 25 + if(istype(src, /mob/living/carbon/metroid/adult)) + health = 200 + else + health = 150 stat = 0 \ No newline at end of file diff --git a/code/modules/mob/living/carbon/metroid/powers.dm b/code/modules/mob/living/carbon/metroid/powers.dm index 2c639867f78..ed8b49f8d0a 100644 --- a/code/modules/mob/living/carbon/metroid/powers.dm +++ b/code/modules/mob/living/carbon/metroid/powers.dm @@ -124,6 +124,22 @@ if(M.health <= -70) M.canmove = 0 + if(!client) + if(Victim && !rabid && !attacked) + if(Victim.LAssailant && Victim.LAssailant != Victim) + if(prob(50)) + var/Found = 0 + for(var/mob/F in Friends) + if(F == Victim.LAssailant) + Found = 1 + + if(!Found) + Friends += Victim.LAssailant + + if(M.client && istype(src, /mob/living/carbon/human)) + if(prob(85)) + rabid = 1 // UUUNNBGHHHH GONNA EAT JUUUUUU + if(client) src << "This subject does not have a strong enough life energy anymore..." else M.canmove = 1 @@ -150,6 +166,7 @@ new_metroid.mind_initialize(src) new_metroid.key = key new_metroid.nutrition = nutrition + new_metroid.powerlevel = max(0, powerlevel-1) new_metroid.a_intent = "hurt" new_metroid << "You are now an adult Metroid." @@ -171,7 +188,8 @@ for(var/i=1,i<=number,i++) // reproduce (has a small chance of producing 3 or 4 offspring) var/mob/living/carbon/metroid/M = new/mob/living/carbon/metroid(loc) M.nutrition = round(nutrition/number) - step_away(M,src) + M.powerlevel = round(powerlevel / number) + if(i != 1) step_away(M,src) babies += M @@ -190,4 +208,60 @@ +/mob/living/carbon/metroid/verb/ventcrawl() + set name = "Crawl through Vent" + set desc = "Enter an air vent and crawl through the pipe system." + set category = "Metroid" + + + if(istype(src, /mob/living/carbon/metroid/adult)) + src << "I am much too big to fit in this small vent..." + return + + if(!stat) + + if(Victim) + src << "Not while I am a feeding..." + return + var/obj/machinery/atmospherics/unary/vent_pump/vent_found + for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src)) + if(!v.welded) + vent_found = v + else + src << "\red That vent is welded..." + if(vent_found) + if(vent_found.network&&vent_found.network.normal_members.len) + var/list/vents = list() + for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members) + if(temp_vent.loc == loc) + continue + vents.Add(temp_vent) + var/list/choices = list() + for(var/obj/machinery/atmospherics/unary/vent_pump/vent in vents) + if(vent.loc.z != loc.z) + continue + var/atom/a = get_turf_loc(vent) + choices.Add(a.loc) + var/turf/startloc = loc + var/obj/selection = input("Select a destination.", "Duct System") in choices + var/selection_position = choices.Find(selection) + if(loc==startloc) + var/obj/target_vent = vents[selection_position] + if(target_vent) + for(var/mob/O in oviewers()) + if ((O.client && !( O.blinded ))) + O.show_message(text("[src] scrambles into the ventillation ducts!"), 1) + loc = target_vent.loc + else + src << "I must remain still while entering a vent..." + else + src << "This vent is not connected to anything..." + else + src << "I must be standing on or beside an air vent to enter it..." + else + src << "I must be conscious to do this..." + return + + + diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index 58b201556c8..62406272f12 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -52,6 +52,8 @@ M << "\red [src] fails to push [tmob]'s fat ass out of the way." now_pushing = 0 return + + tmob.LAssailant = src now_pushing = 0 ..() if (!( istype(AM, /atom/movable) )) @@ -254,6 +256,7 @@ if (M.a_intent == "grab") if (M == src) return + var/obj/item/weapon/grab/G = new /obj/item/weapon/grab( M ) G.assailant = M if (M.hand) @@ -264,6 +267,9 @@ G.affecting = src grabbed_by += G G.synch() + + LAssailant = M + playsound(loc, 'thudswoosh.ogg', 50, 1, -1) for(var/mob/O in viewers(src, null)) O.show_message(text("\red [] has grabbed [name] passively!", M), 1) @@ -334,6 +340,9 @@ G.affecting = src grabbed_by += G G.synch() + + LAssailant = M + playsound(loc, 'thudswoosh.ogg', 50, 1, -1) for(var/mob/O in viewers(src, null)) O.show_message(text("\red [] has grabbed [name] passively!", M), 1) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 1564d91307f..cea7892ef32 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1675,6 +1675,12 @@ It's fairly easy to fix if dealing with single letters but not so much with comp return if (!( anchored )) usr.pulling = src + if(ismob(src)) + var/mob/M = src + if(!istype(usr, /mob/living/carbon)) + M.LAssailant = null + else + M.LAssailant = usr return /atom/verb/examine()