From 7e77eb4a8545ad845cfb36e0ed9d904bb9cdf779 Mon Sep 17 00:00:00 2001 From: "vageyenaman@gmail.com" Date: Fri, 29 Jul 2011 22:08:52 +0000 Subject: [PATCH] Metroids: - Their AI has been fixed. Previously, when they began "starving" they would lock up when they located a target. This was because I was only allowing Metroids to attack people when they were only attacked themselves. - Small stun time added to wrestling Metroids off or beating them off with objects. - You should now not be able to enter mechas, cryos and sleepers if you have Metroid on your head. Cargo: - You can now cancel cargo orders. Miscellaneous: - Manifests no longer show "unassigned" for everyone on round start. - The manifest is updated realtime, in that when new arrivals arrive or a job is changed, the information gets passed onto the central database. - New arrivals now generate security records, medical records, etc. Jubilations! - I, perhaps, have increased the efficiency of the reaction system. Preliminary tests confirmed that it's slightly faster, but I worry about whether I may have ruined someone's vision of a perfect multiple reaction system. This "change" is nothing more than adding a break; line to the end of a loop. If this proves too buggy, I'll just revert it. git-svn-id: http://tgstation13.googlecode.com/svn/trunk@1952 316c924e-a436-60f5-8080-3fe189b3f50e --- code/WorkInProgress/Chemistry-Holder.dm | 3 + code/WorkInProgress/Chemistry-Recipes.dm | 2 + code/game/machinery/Sleeper.dm | 8 + code/game/machinery/computer/computer.dm | 201 +++++++++++++----- code/game/machinery/cryo.dm | 8 + code/game/mecha/mecha.dm | 4 + code/game/objects/items/item.dm | 10 + .../objects/items/weapons/mops_cleaners.dm | 4 +- code/game/supplyshuttle.dm | 13 +- .../modules/mob/living/carbon/metroid/life.dm | 46 +++- .../mob/living/carbon/metroid/metroid.dm | 10 + code/modules/mob/new_player/new_player.dm | 2 + icons/changelog.html | 7 + 13 files changed, 248 insertions(+), 70 deletions(-) diff --git a/code/WorkInProgress/Chemistry-Holder.dm b/code/WorkInProgress/Chemistry-Holder.dm index 7d7b1921c9..a5b5532b84 100644 --- a/code/WorkInProgress/Chemistry-Holder.dm +++ b/code/WorkInProgress/Chemistry-Holder.dm @@ -213,6 +213,8 @@ datum C.on_reaction(src, created_volume) reaction_occured = 1 + break + while(reaction_occured) update_total() return 0 @@ -374,6 +376,7 @@ datum return res + /////////////////////////////////////////////////////////////////////////////////// diff --git a/code/WorkInProgress/Chemistry-Recipes.dm b/code/WorkInProgress/Chemistry-Recipes.dm index a22c9da029..c5b0af08d8 100644 --- a/code/WorkInProgress/Chemistry-Recipes.dm +++ b/code/WorkInProgress/Chemistry-Recipes.dm @@ -12,6 +12,7 @@ datum var/required_other = 0 // an integer required for the reaction to happen var/result_amount = 0 + var/secondary = 0 // set to nonzero if secondary reaction proc on_reaction(var/datum/reagents/holder, var/created_volume) @@ -347,6 +348,7 @@ datum result = null required_reagents = list("potassium" = 1, "sugar" = 1, "phosphorus" = 1 ) result_amount = null + secondary = 1 on_reaction(var/datum/reagents/holder, var/created_volume) var/location = get_turf(holder.my_atom) var/datum/effects/system/bad_smoke_spread/S = new /datum/effects/system/bad_smoke_spread diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index 5d19aad27f..a680b39ac8 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -185,6 +185,10 @@ /* if (G.affecting.abiotic()) user << "Subject may not have abiotic items on." return */ + for(var/mob/living/carbon/metroid/M in range(1,G.affecting)) + if(M.Victim == G.affecting) + usr << "[G.affecting.name] will not fit into the sleeper because they have a Metroid latched onto their head." + return for (var/mob/V in viewers(user)) V.show_message("[user] starts putting [G.affecting.name] into the sleeper.", 3) if(do_after(user, 20)) @@ -376,6 +380,10 @@ /* if (usr.abiotic()) // Removing the requirement for user to be naked -- TLE usr << "Subject may not have abiotic items on." return*/ + for(var/mob/living/carbon/metroid/M in range(1,usr)) + if(M.Victim == usr) + usr << "You're too busy getting your life sucked out of you." + return for (var/mob/V in viewers(usr)) occupied = 1 V.show_message("[usr] starts climbing into the sleeper.", 3) diff --git a/code/game/machinery/computer/computer.dm b/code/game/machinery/computer/computer.dm index 960164d417..2989cd5309 100644 --- a/code/game/machinery/computer/computer.dm +++ b/code/game/machinery/computer/computer.dm @@ -218,6 +218,7 @@ Pod/Blast Doors computer switch(href_list["choice"]) if ("modify") if (modify) + data_core.manifest_modify(modify.registered, modify.assignment) modify.name = text("[]'s ID Card ([])", modify.registered, modify.assignment) modify.loc = loc modify = null @@ -228,6 +229,7 @@ Pod/Blast Doors computer I.loc = src modify = I authenticated = 0 + if ("scan") if (scan) scan.loc = loc @@ -287,68 +289,151 @@ Pod/Blast Doors computer updateUsrDialog() return -/obj/datacore/proc/manifest() - for(var/mob/living/carbon/human/H in world) - if (!isnull(H.mind) && (H.mind.assigned_role != "MODE")) - var/datum/data/record/G = new() - var/datum/data/record/M = new() - var/datum/data/record/S = new() - var/datum/data/record/L = new() - var/obj/item/weapon/card/id/C = H.wear_id - if (C) - G.fields["rank"] = C.assignment +/obj/datacore/proc/manifest(var/nosleep = 0) + spawn() + if(!nosleep) + sleep(40) + for(var/mob/living/carbon/human/H in world) + if (!isnull(H.mind) && (H.mind.assigned_role != "MODE")) + var/datum/data/record/G = new() + var/datum/data/record/M = new() + var/datum/data/record/S = new() + var/datum/data/record/L = new() + var/obj/item/weapon/card/id/C = H.wear_id + if (C) + G.fields["rank"] = C.assignment + else + if(H.job) + G.fields["rank"] = H.job + else + G.fields["rank"] = "Unassigned" + G.fields["name"] = H.real_name + G.fields["id"] = text("[]", add_zero(num2hex(rand(1, 1.6777215E7)), 6)) + M.fields["name"] = G.fields["name"] + M.fields["id"] = G.fields["id"] + S.fields["name"] = G.fields["name"] + S.fields["id"] = G.fields["id"] + if (H.gender == FEMALE) + G.fields["sex"] = "Female" + else + G.fields["sex"] = "Male" + G.fields["age"] = text("[]", H.age) + G.fields["fingerprint"] = text("[]", md5(H.dna.uni_identity)) + G.fields["p_stat"] = "Active" + G.fields["m_stat"] = "Stable" + M.fields["b_type"] = text("[]", H.b_type) + M.fields["b_dna"] = H.dna.unique_enzymes + M.fields["mi_dis"] = "None" + M.fields["mi_dis_d"] = "No minor disabilities have been declared." + M.fields["ma_dis"] = "None" + M.fields["ma_dis_d"] = "No major disabilities have been diagnosed." + M.fields["alg"] = "None" + M.fields["alg_d"] = "No allergies have been detected in this patient." + M.fields["cdi"] = "None" + M.fields["cdi_d"] = "No diseases have been diagnosed at the moment." + M.fields["notes"] = "No notes." + S.fields["criminal"] = "None" + S.fields["mi_crim"] = "None" + S.fields["mi_crim_d"] = "No minor crime convictions." + S.fields["ma_crim"] = "None" + S.fields["ma_crim_d"] = "No major crime convictions." + S.fields["notes"] = "No notes." + + //Begin locked reporting + L.fields["name"] = H.real_name + L.fields["sex"] = H.gender + L.fields["age"] = H.age + L.fields["id"] = md5("[H.real_name][H.mind.assigned_role]") + L.fields["rank"] = H.mind.assigned_role + L.fields["b_type"] = H.b_type + L.fields["b_dna"] = H.dna.unique_enzymes + L.fields["enzymes"] = H.dna.struc_enzymes + L.fields["identity"] = H.dna.uni_identity + L.fields["image"] = getFlatIcon(H,0) + //End locked reporting + + general += G + medical += M + security += S + locked += L + return + +/obj/datacore/proc/manifest_modify(var/name, var/assignment) + var/datum/data/record/foundrecord + + for(var/datum/data/record/t in data_core.general) + if(t.fields["name"] == name) + foundrecord = t + break + + if(foundrecord) + foundrecord.fields["rank"] = assignment + + +/obj/datacore/proc/manifest_inject(var/mob/living/carbon/human/H) + if (!isnull(H.mind) && (H.mind.assigned_role != "MODE")) + var/datum/data/record/G = new() + var/datum/data/record/M = new() + var/datum/data/record/S = new() + var/datum/data/record/L = new() + var/obj/item/weapon/card/id/C = H.wear_id + if (C) + G.fields["rank"] = C.assignment + else + if(H.job) + G.fields["rank"] = H.job else G.fields["rank"] = "Unassigned" - G.fields["name"] = H.real_name - G.fields["id"] = text("[]", add_zero(num2hex(rand(1, 1.6777215E7)), 6)) - M.fields["name"] = G.fields["name"] - M.fields["id"] = G.fields["id"] - S.fields["name"] = G.fields["name"] - S.fields["id"] = G.fields["id"] - if (H.gender == FEMALE) - G.fields["sex"] = "Female" - else - G.fields["sex"] = "Male" - G.fields["age"] = text("[]", H.age) - G.fields["fingerprint"] = text("[]", md5(H.dna.uni_identity)) - G.fields["p_stat"] = "Active" - G.fields["m_stat"] = "Stable" - M.fields["b_type"] = text("[]", H.b_type) - M.fields["b_dna"] = H.dna.unique_enzymes - M.fields["mi_dis"] = "None" - M.fields["mi_dis_d"] = "No minor disabilities have been declared." - M.fields["ma_dis"] = "None" - M.fields["ma_dis_d"] = "No major disabilities have been diagnosed." - M.fields["alg"] = "None" - M.fields["alg_d"] = "No allergies have been detected in this patient." - M.fields["cdi"] = "None" - M.fields["cdi_d"] = "No diseases have been diagnosed at the moment." - M.fields["notes"] = "No notes." - S.fields["criminal"] = "None" - S.fields["mi_crim"] = "None" - S.fields["mi_crim_d"] = "No minor crime convictions." - S.fields["ma_crim"] = "None" - S.fields["ma_crim_d"] = "No major crime convictions." - S.fields["notes"] = "No notes." + G.fields["name"] = H.real_name + G.fields["id"] = text("[]", add_zero(num2hex(rand(1, 1.6777215E7)), 6)) + M.fields["name"] = G.fields["name"] + M.fields["id"] = G.fields["id"] + S.fields["name"] = G.fields["name"] + S.fields["id"] = G.fields["id"] + if (H.gender == FEMALE) + G.fields["sex"] = "Female" + else + G.fields["sex"] = "Male" + G.fields["age"] = text("[]", H.age) + G.fields["fingerprint"] = text("[]", md5(H.dna.uni_identity)) + G.fields["p_stat"] = "Active" + G.fields["m_stat"] = "Stable" + M.fields["b_type"] = text("[]", H.b_type) + M.fields["b_dna"] = H.dna.unique_enzymes + M.fields["mi_dis"] = "None" + M.fields["mi_dis_d"] = "No minor disabilities have been declared." + M.fields["ma_dis"] = "None" + M.fields["ma_dis_d"] = "No major disabilities have been diagnosed." + M.fields["alg"] = "None" + M.fields["alg_d"] = "No allergies have been detected in this patient." + M.fields["cdi"] = "None" + M.fields["cdi_d"] = "No diseases have been diagnosed at the moment." + M.fields["notes"] = "No notes." + S.fields["criminal"] = "None" + S.fields["mi_crim"] = "None" + S.fields["mi_crim_d"] = "No minor crime convictions." + S.fields["ma_crim"] = "None" + S.fields["ma_crim_d"] = "No major crime convictions." + S.fields["notes"] = "No notes." - //Begin locked reporting - L.fields["name"] = H.real_name - L.fields["sex"] = H.gender - L.fields["age"] = H.age - L.fields["id"] = md5("[H.real_name][H.mind.assigned_role]") - L.fields["rank"] = H.mind.assigned_role - L.fields["b_type"] = H.b_type - L.fields["b_dna"] = H.dna.unique_enzymes - L.fields["enzymes"] = H.dna.struc_enzymes - L.fields["identity"] = H.dna.uni_identity - L.fields["image"] = getFlatIcon(H,0) - //End locked reporting + //Begin locked reporting + L.fields["name"] = H.real_name + L.fields["sex"] = H.gender + L.fields["age"] = H.age + L.fields["id"] = md5("[H.real_name][H.mind.assigned_role]") + L.fields["rank"] = H.mind.assigned_role + L.fields["b_type"] = H.b_type + L.fields["b_dna"] = H.dna.unique_enzymes + L.fields["enzymes"] = H.dna.struc_enzymes + L.fields["identity"] = H.dna.uni_identity + L.fields["image"] = getFlatIcon(H,0) + //End locked reporting + + general += G + medical += M + security += S + locked += L - general += G - medical += M - security += S - locked += L - return /obj/machinery/computer/pod/proc/alarm() if(stat & (NOPOWER|BROKEN)) diff --git a/code/game/machinery/cryo.dm b/code/game/machinery/cryo.dm index a9d6494607..cdad34db61 100644 --- a/code/game/machinery/cryo.dm +++ b/code/game/machinery/cryo.dm @@ -123,6 +123,10 @@ else if(istype(G, /obj/item/weapon/grab)) if(!ismob(G:affecting)) return + for(var/mob/living/carbon/metroid/M in range(1,G:affecting)) + if(M.Victim == G:affecting) + usr << "[G:affecting:name] will not fit into the cryo because they have a Metroid latched onto their head." + return var/mob/M = G:affecting if(put_mob(M)) del(G) @@ -253,6 +257,10 @@ set name = "Move Inside" set category = "Object" set src in oview(1) + for(var/mob/living/carbon/metroid/M in range(1,usr)) + if(M.Victim == usr) + usr << "You're too busy getting your life sucked out of you." + return if (usr.stat != 0 || stat & (NOPOWER|BROKEN)) return put_mob(usr) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 6008b67dc0..414be9f539 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -647,6 +647,10 @@ usr << "\red Access denied" src.log_append_to_last("Permission denied.") return + for(var/mob/living/carbon/metroid/M in range(1,usr)) + if(M.Victim == usr) + usr << "You're too busy getting your life sucked out of you." + return usr << "You start climbing into [src.name]" if(do_after(20)) if(!src.occupant) diff --git a/code/game/objects/items/item.dm b/code/game/objects/items/item.dm index f8dc3c7517..3851d065fe 100644 --- a/code/game/objects/items/item.dm +++ b/code/game/objects/items/item.dm @@ -252,6 +252,11 @@ if(prob(80) && !Metroid.client) Metroid.Discipline++ + spawn() + Metroid.SStun = 1 + sleep(rand(5,20)) + Metroid.SStun = 0 + spawn(0) Metroid.canmove = 0 step_away(Metroid, user) @@ -270,6 +275,11 @@ if(Metroid.Discipline == 1) Metroid.attacked = 0 + spawn() + Metroid.SStun = 1 + sleep(rand(5,20)) + Metroid.SStun = 0 + Metroid.Victim = null Metroid.anchored = 0 diff --git a/code/game/objects/items/weapons/mops_cleaners.dm b/code/game/objects/items/weapons/mops_cleaners.dm index 01d5c616e7..227785eba5 100644 --- a/code/game/objects/items/weapons/mops_cleaners.dm +++ b/code/game/objects/items/weapons/mops_cleaners.dm @@ -17,7 +17,7 @@ MOP if (istype(A, /obj/item/weapon/storage/backpack )) return else if (src.reagents.total_volume < 1) - user << "\blue Add more cleaner!" + user << "\blue [src] is empty!" return var/obj/decal/D = new/obj/decal(get_turf(src)) @@ -92,7 +92,7 @@ MOP if (istype(A, /obj/item/weapon/storage/backpack )) return else if (src.reagents.total_volume < 1) - user << "\blue Add more cleaner!" + user << "\blue [src] is empty!" return playsound(src.loc, 'spray2.ogg', 50, 1, -6) diff --git a/code/game/supplyshuttle.dm b/code/game/supplyshuttle.dm index 124f042966..78d0f26b53 100644 --- a/code/game/supplyshuttle.dm +++ b/code/game/supplyshuttle.dm @@ -482,7 +482,18 @@ var/ordernum=0 src.temp = "Current approved orders:

" for(var/S in supply_shuttle_shoppinglist) var/datum/supply_order/SO = S - src.temp += "[SO.object.name] approved by [SO.orderedby] [SO.comment ? "([SO.comment])":""]
" + src.temp += "[SO.object.name] approved by [SO.orderedby][SO.comment ? " ([SO.comment])":""] (Cancel)
" + src.temp += "
OK" + + else if (href_list["cancelorder"]) + var/datum/supply_order/remove_supply = href_list["cancelorder"] + supply_shuttle_shoppinglist -= remove_supply + supply_shuttle_points += remove_supply.object.cost + src.temp += "Canceled: [remove_supply.object.name]


" + + for(var/S in supply_shuttle_shoppinglist) + var/datum/supply_order/SO = S + src.temp += "[SO.object.name] approved by [SO.orderedby][SO.comment ? " ([SO.comment])":""] (Cancel)
" src.temp += "
OK" else if (href_list["viewrequests"]) diff --git a/code/modules/mob/living/carbon/metroid/life.dm b/code/modules/mob/living/carbon/metroid/life.dm index 677a583e8a..3f5ab39ef5 100644 --- a/code/modules/mob/living/carbon/metroid/life.dm +++ b/code/modules/mob/living/carbon/metroid/life.dm @@ -74,16 +74,13 @@ if(attacked <= 0) Target = null - if(Victim && !Target) - Victim = null - if(Victim) return // if it's eating someone already, continue eating! if(prob(5)) emote(pick("click","chatter","sway","light","vibrate","chatter","shriek")) - if(AIproc) return + if(AIproc && SStun) return var/hungry = 0 // determines if the metroid is hungry @@ -101,8 +98,12 @@ if(starving && !client) // if a metroid is starving, it starts losing its friends - if(prob(45)) - if(Friends.len > 0) + if(prob(45) && Friends.len > 0) + var/friendnum = 0 + for(var/mob/M in Friends) + friendnum++ + + if(friendnum > 0) var/mob/nofriend = pick(Friends) Friends -= nofriend @@ -138,6 +139,22 @@ if(!notarget) targets += C + for(var/mob/living/silicon/C in view(12,src)) + if(C.stat != 2) + var/notarget = 0 + if(C in Friends) + notarget = 1 + + if(!istype(src, /mob/living/carbon/metroid/adult)) + if(!starving && Discipline > 0) + notarget = 1 + break + + if(tame) + notarget = 1 + + if(!notarget) targets += C + @@ -199,22 +216,33 @@ 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 + var/SStun = 0 // stun variable proc AIprocess() // the master AI process if(AIproc) return + var/hungry = 0 + var/starving = 0 + if(istype(src, /mob/living/carbon/metroid/adult)) + switch(nutrition) + if(400 to 800) hungry = 1 + if(0 to 399) + starving = 1 + else + switch(nutrition) + if(150 to 500) hungry = 1 + if(0 to 149) starving = 1 AIproc = 1 - while(AIproc && stat != 2 && attacked > 0) + while(AIproc && stat != 2 && (attacked > 0 || starving || hungry)) if(Victim) // can't eat AND have this little process at the same time break - if(attacked <= 0 || !Target) + if(!Target) break - if(Target.health <= -70 || Target.stat == 2) Target = null AIproc = 0 diff --git a/code/modules/mob/living/carbon/metroid/metroid.dm b/code/modules/mob/living/carbon/metroid/metroid.dm index 77ff9a2380..4caf5d50dd 100644 --- a/code/modules/mob/living/carbon/metroid/metroid.dm +++ b/code/modules/mob/living/carbon/metroid/metroid.dm @@ -449,6 +449,11 @@ if(prob(90) && !client) Discipline++ + spawn() + SStun = 1 + sleep(rand(25,50)) + SStun = 0 + Victim = null anchored = 0 step_away(src,M) @@ -629,6 +634,11 @@ if(Discipline == 1) attacked = 0 + spawn() + SStun = 1 + sleep(rand(5,20)) + SStun = 0 + spawn(0) step_away(src,M,15) diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 82859c6879..2f9276bd9a 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -286,6 +286,8 @@ mob/new_player character.Robotize() else//Adds late joiners to minds so they can be linked to objectives. ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. + + data_core.manifest_inject(character) // add all the necessary stuff into the manifest del(src) else diff --git a/icons/changelog.html b/icons/changelog.html index 757e3b7b4a..e95b8b4e6b 100644 --- a/icons/changelog.html +++ b/icons/changelog.html @@ -47,6 +47,13 @@ should be listed in the changelog upon commit tho. Thanks. --> 29 July 2011. - Day of Forum revival!
    +
  • Doohl updated +
      +
    • Bugfix: Metroids should never "shut down" and just die in a corner when they begin starving. And so, hungry Metroids are a force to be feared.
    • +
    • The Cargo computers now have the ability to cancel pending orders to refund credits. This was put in place so that idiots couldn't waste all the cargo points and run off. However, if the shuttle is en route to the station you won't be able to cancel orders.
    • +
    • Bugfix: the manifest has been fixed! Additionally, the manfiest is now updated realtime; job changes and new arrivals will be automatically updated into the manifest. Joy!
    • +
    • Metroids, when wrestled off of someone's head or beaten off, now get stunned for a few seconds.
    • +
  • Agouri updated
    • I was always bothered by how unprofessional it was of Nanotransen (in before >Nanotransen >professionalism) to just lay expensive spacesuits in racks and just let them be. Well, no more. Introducing...