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...