diff --git a/baystation12.dme b/baystation12.dme
index 9de1e153ca6..5b0ad2d7923 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -25,6 +25,7 @@
#define FILE_DIR "icons/obj/atmospherics"
#define FILE_DIR "icons/obj/clothing"
#define FILE_DIR "icons/obj/doors"
+#define FILE_DIR "icons/obj/flora"
#define FILE_DIR "icons/obj/machines"
#define FILE_DIR "icons/obj/pipes"
#define FILE_DIR "icons/pda_icons"
@@ -67,7 +68,10 @@
#include "code\__HELPERS\icons.dm"
#include "code\__HELPERS\lists.dm"
#include "code\__HELPERS\logging.dm"
+#include "code\__HELPERS\maths.dm"
+#include "code\__HELPERS\mobs.dm"
#include "code\__HELPERS\names.dm"
+#include "code\__HELPERS\sanitize_values.dm"
#include "code\__HELPERS\text.dm"
#include "code\__HELPERS\time.dm"
#include "code\__HELPERS\type2type.dm"
@@ -140,8 +144,7 @@
#include "code\datums\diseases\wizarditis.dm"
#include "code\datums\diseases\xeno_transformation.dm"
#include "code\datums\diseases\advance\advance.dm"
-#include "code\datums\diseases\advance\cold.dm"
-#include "code\datums\diseases\advance\flu.dm"
+#include "code\datums\diseases\advance\presets.dm"
#include "code\datums\diseases\advance\symptoms\confusion.dm"
#include "code\datums\diseases\advance\symptoms\cough.dm"
#include "code\datums\diseases\advance\symptoms\damage_converter.dm"
@@ -149,10 +152,12 @@
#include "code\datums\diseases\advance\symptoms\fever.dm"
#include "code\datums\diseases\advance\symptoms\hallucigen.dm"
#include "code\datums\diseases\advance\symptoms\headache.dm"
+#include "code\datums\diseases\advance\symptoms\heal.dm"
#include "code\datums\diseases\advance\symptoms\itching.dm"
#include "code\datums\diseases\advance\symptoms\shivering.dm"
#include "code\datums\diseases\advance\symptoms\sneeze.dm"
#include "code\datums\diseases\advance\symptoms\symptoms.dm"
+#include "code\datums\diseases\advance\symptoms\voice_change.dm"
#include "code\datums\diseases\advance\symptoms\vomit.dm"
#include "code\datums\diseases\advance\symptoms\weight.dm"
#include "code\datums\helper_datums\construction_datum.dm"
@@ -374,6 +379,7 @@
#include "code\game\machinery\computer\syndicate_specops_shuttle.dm"
#include "code\game\machinery\doors\airlock.dm"
#include "code\game\machinery\doors\airlock_electronics.dm"
+#include "code\game\machinery\doors\alarmlock.dm"
#include "code\game\machinery\doors\brigdoors.dm"
#include "code\game\machinery\doors\checkForMultipleDoors.dm"
#include "code\game\machinery\doors\door.dm"
@@ -443,7 +449,6 @@
#include "code\game\objects\effects\misc.dm"
#include "code\game\objects\effects\overlays.dm"
#include "code\game\objects\effects\portals.dm"
-#include "code\game\objects\effects\signs.dm"
#include "code\game\objects\effects\step_triggers.dm"
#include "code\game\objects\effects\decals\cleanable.dm"
#include "code\game\objects\effects\decals\contraband.dm"
@@ -526,7 +531,6 @@
#include "code\game\objects\items\weapons\mop.dm"
#include "code\game\objects\items\weapons\paint.dm"
#include "code\game\objects\items\weapons\paiwire.dm"
-#include "code\game\objects\items\weapons\photography.dm"
#include "code\game\objects\items\weapons\RCD.dm"
#include "code\game\objects\items\weapons\RSF.dm"
#include "code\game\objects\items\weapons\scrolls.dm"
@@ -578,6 +582,7 @@
#include "code\game\objects\structures\electricchair.dm"
#include "code\game\objects\structures\extinguisher.dm"
#include "code\game\objects\structures\false_walls.dm"
+#include "code\game\objects\structures\flora.dm"
#include "code\game\objects\structures\girders.dm"
#include "code\game\objects\structures\grille.dm"
#include "code\game\objects\structures\kitchen_spike.dm"
@@ -590,7 +595,7 @@
#include "code\game\objects\structures\morgue.dm"
#include "code\game\objects\structures\musician.dm"
#include "code\game\objects\structures\noticeboard.dm"
-#include "code\game\objects\structures\shuttle_engines.dm"
+#include "code\game\objects\structures\signs.dm"
#include "code\game\objects\structures\tables_racks.dm"
#include "code\game\objects\structures\tank_dispenser.dm"
#include "code\game\objects\structures\target_stake.dm"
@@ -628,8 +633,6 @@
#include "code\game\turfs\simulated.dm"
#include "code\game\turfs\turf.dm"
#include "code\game\turfs\unsimulated.dm"
-#include "code\game\turfs\simulated\asteroid.dm"
-#include "code\game\turfs\simulated\beach.dm"
#include "code\game\turfs\simulated\floor.dm"
#include "code\game\turfs\simulated\floor_types.dm"
#include "code\game\turfs\simulated\walls.dm"
@@ -647,7 +650,6 @@
#include "code\game\vehicles\airtight\space.dm"
#include "code\game\verbs\atom_verbs.dm"
#include "code\game\verbs\ooc.dm"
-#include "code\game\verbs\sound.dm"
#include "code\game\verbs\suicide.dm"
#include "code\game\verbs\who.dm"
#include "code\js\byjax.dm"
@@ -710,6 +712,7 @@
#include "code\modules\assembly\timer.dm"
#include "code\modules\awaymissions\bluespaceartillery.dm"
#include "code\modules\awaymissions\corpse.dm"
+#include "code\modules\awaymissions\exile.dm"
#include "code\modules\awaymissions\gateway.dm"
#include "code\modules\awaymissions\loot.dm"
#include "code\modules\awaymissions\pamphlet.dm"
@@ -721,6 +724,9 @@
#include "code\modules\awaymissions\maploader\writer.dm"
#include "code\modules\client\client defines.dm"
#include "code\modules\client\client procs.dm"
+#include "code\modules\client\preferences.dm"
+#include "code\modules\client\preferences_savefile.dm"
+#include "code\modules\client\preferences_toggles.dm"
#include "code\modules\clothing\clothing.dm"
#include "code\modules\clothing\glasses\glasses.dm"
#include "code\modules\clothing\glasses\hud.dm"
@@ -770,7 +776,6 @@
#include "code\modules\critters\critter_AI.dm"
#include "code\modules\critters\critter_defenses.dm"
#include "code\modules\critters\critters.dm"
-#include "code\modules\critters\hivebots\hivebot.dm"
#include "code\modules\customitems\item_defines.dm"
#include "code\modules\customitems\item_spawning.dm"
#include "code\modules\DetectiveWork\detective_work.dm"
@@ -795,7 +800,7 @@
#include "code\modules\mining\mine_turfs.dm"
#include "code\modules\mining\mint.dm"
#include "code\modules\mining\money_bag.dm"
-#include "code\modules\mining\ores_materials_coins.dm"
+#include "code\modules\mining\ores_coins.dm"
#include "code\modules\mining\satchel_ore_boxdm.dm"
#include "code\modules\mob\death.dm"
#include "code\modules\mob\inventory.dm"
@@ -950,11 +955,8 @@
#include "code\modules\mob\living\silicon\robot\wires.dm"
#include "code\modules\mob\living\simple_animal\clown.dm"
#include "code\modules\mob\living\simple_animal\constructs.dm"
-#include "code\modules\mob\living\simple_animal\kobold.dm"
-#include "code\modules\mob\living\simple_animal\parrot.dm"
#include "code\modules\mob\living\simple_animal\shade.dm"
#include "code\modules\mob\living\simple_animal\simple_animal.dm"
-#include "code\modules\mob\living\simple_animal\syndicate.dm"
#include "code\modules\mob\living\simple_animal\worm.dm"
#include "code\modules\mob\living\simple_animal\friendly\cat.dm"
#include "code\modules\mob\living\simple_animal\friendly\corgi.dm"
@@ -964,15 +966,18 @@
#include "code\modules\mob\living\simple_animal\friendly\tomato.dm"
#include "code\modules\mob\living\simple_animal\hostile\bear.dm"
#include "code\modules\mob\living\simple_animal\hostile\carp.dm"
+#include "code\modules\mob\living\simple_animal\hostile\faithless.dm"
+#include "code\modules\mob\living\simple_animal\hostile\hivebot.dm"
#include "code\modules\mob\living\simple_animal\hostile\hostile.dm"
+#include "code\modules\mob\living\simple_animal\hostile\pirate.dm"
+#include "code\modules\mob\living\simple_animal\hostile\russian.dm"
+#include "code\modules\mob\living\simple_animal\hostile\syndicate.dm"
#include "code\modules\mob\new_player\hud.dm"
#include "code\modules\mob\new_player\login.dm"
#include "code\modules\mob\new_player\logout.dm"
#include "code\modules\mob\new_player\new_player.dm"
#include "code\modules\mob\new_player\poll.dm"
-#include "code\modules\mob\new_player\preferences.dm"
#include "code\modules\mob\new_player\preferences_setup.dm"
-#include "code\modules\mob\new_player\savefile.dm"
#include "code\modules\mob\new_player\skill.dm"
#include "code\modules\mob\new_player\sprite_accessories.dm"
#include "code\modules\mob\simple_animal\head.dm"
@@ -984,6 +989,7 @@
#include "code\modules\paperwork\paperbin.dm"
#include "code\modules\paperwork\pen.dm"
#include "code\modules\paperwork\photocopier.dm"
+#include "code\modules\paperwork\photography.dm"
#include "code\modules\paperwork\stamps.dm"
#include "code\modules\power\apc.dm"
#include "code\modules\power\cable.dm"
@@ -1177,5 +1183,7 @@
#include "interface\skin.dmf"
#include "maps\tgstation.2.0.9.1.dmm"
#include "maps\RandomZLevels\Academy.dm"
+#include "maps\RandomZLevels\challenge.dm"
#include "maps\RandomZLevels\stationCollision.dm"
+#include "maps\RandomZLevels\wildwest.dm"
// END_INCLUDE
diff --git a/code/__HELPERS/files.dm b/code/__HELPERS/files.dm
index 955c5ba300a..9d9a3140d26 100644
--- a/code/__HELPERS/files.dm
+++ b/code/__HELPERS/files.dm
@@ -13,6 +13,6 @@
return text
//Sends resource files to client cache
-/mob/proc/getFiles()
+/client/proc/getFiles()
for(var/file in args)
src << browse_rsc(file)
\ No newline at end of file
diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm
index ab258c8e328..51a3050c1c3 100644
--- a/code/__HELPERS/game.dm
+++ b/code/__HELPERS/game.dm
@@ -187,28 +187,23 @@
return hear
-/proc/get_mobs_in_radio_ranges(var/list/obj/item/device/radio/radios, var/level = 0)
+/proc/get_mobs_in_radio_ranges(var/list/obj/item/device/radio/radios)
. = list()
// Returns a list of mobs who can hear any of the radios given in @radios
var/list/speaker_coverage = list()
for(var/obj/item/device/radio/R in radios)
- // This is usually for headsets, which only the wearer can hear.
- if(R.canhear_range == 0)
- if(ismob(R.loc))
- . |= R.loc
- continue
var/turf/speaker = get_turf(R)
if(speaker)
for(var/turf/T in hear(R.canhear_range,speaker))
- speaker_coverage += T
+ speaker_coverage[T] = T
// Try to find all the players who can hear the message
for(var/mob/M in player_list)
var/turf/ear = get_turf(M)
- if(ear && (level == 0 || level == ear.z))
- if(ear in speaker_coverage)
+ if(ear)
+ if(speaker_coverage[ear])
. |= M
return .
@@ -342,7 +337,7 @@ var/list/DummyCache = list()
var/i = 0
while(candidates.len <= 0 && i < 5)
for(var/mob/dead/observer/G in player_list)
- if(G.client.be_alien)
+ if(G.client.prefs.be_special & BE_ALIEN)
if(((G.client.inactivity/10)/60) <= ALIEN_SELECT_AFK_BUFFER + i) // the most active players are more likely to become an alien
if(!(G.mind && G.mind.current && G.mind.current.stat != DEAD))
candidates += G.key
diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm
index 47f61c261af..46a623eff53 100644
--- a/code/__HELPERS/global_lists.dm
+++ b/code/__HELPERS/global_lists.dm
@@ -11,12 +11,24 @@ var/global/list/living_mob_list = list() //List of all alive mobs, including c
var/global/list/dead_mob_list = list() //List of all dead mobs, including clientless. Excludes /mob/new_player
var/global/list/cable_list = list() //Index for all cables, so that powernets don't have to look through the entire world all the time
-var/global/list/hair_styles_list = list() //stores /datum/sprite_accessory/hair indexed by name
-var/global/list/facial_hair_styles_list = list() //stores /datum/sprite_accessory/facial_hair indexed by name
var/global/list/chemical_reactions_list //list of all /datum/chemical_reaction datums. Used during chemical reactions
var/global/list/chemical_reagents_list //list of all /datum/reagent datums indexed by reagent id. Used by chemistry stuff
var/global/list/landmarks_list = list() //list of all landmarks created
var/global/list/surgery_steps = list() //list of all surgery steps |BS12
+//Preferences stuff
+ //Hairstyles
+var/global/list/hair_styles_list = list() //stores /datum/sprite_accessory/hair indexed by name
+var/global/list/hair_styles_male_list = list()
+var/global/list/hair_styles_female_list = list()
+var/global/list/facial_hair_styles_list = list() //stores /datum/sprite_accessory/facial_hair indexed by name
+var/global/list/facial_hair_styles_male_list = list()
+var/global/list/facial_hair_styles_female_list = list()
+ //Underwear
+var/global/list/underwear_m = list("White", "Grey", "Green", "Blue", "Black", "Mankini", "Love-Hearts", "Black2", "Grey2", "Stripey", "Kinky", "None") //Curse whoever made male/female underwear diffrent colours
+var/global/list/underwear_f = list("Red", "White", "Yellow", "Blue", "Black", "Thong", "Babydoll", "Baby-Blue", "Green", "Pink", "Kinky", "None")
+ //Backpacks
+var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel")
+
//////////////////////////
/////Initial Building/////
//////////////////////////
@@ -28,15 +40,27 @@ var/global/list/surgery_steps = list() //list of all surgery steps |BS12
for(var/path in paths)
var/datum/sprite_accessory/hair/H = new path()
hair_styles_list[H.name] = H
+ switch(H.gender)
+ if(MALE) hair_styles_male_list += H.name
+ if(FEMALE) hair_styles_female_list += H.name
+ else
+ hair_styles_male_list += H.name
+ hair_styles_female_list += H.name
//Facial Hair - Initialise all /datum/sprite_accessory/facial_hair into an list indexed by facialhair-style name
paths = typesof(/datum/sprite_accessory/facial_hair) - /datum/sprite_accessory/facial_hair
for(var/path in paths)
var/datum/sprite_accessory/facial_hair/H = new path()
facial_hair_styles_list[H.name] = H
+ switch(H.gender)
+ if(MALE) facial_hair_styles_male_list += H.name
+ if(FEMALE) facial_hair_styles_female_list += H.name
+ else
+ facial_hair_styles_male_list += H.name
+ facial_hair_styles_female_list += H.name
+
//Surgery Steps - Initialize all /datum/surgery_step into a list
paths = typesof(/datum/surgery_step)-/datum/surgery_step
for(var/T in paths)
var/datum/surgery_step/S = new T
surgery_steps += S
-
diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm
index 827a6348c26..cfb6d9d2108 100644
--- a/code/__HELPERS/lists.dm
+++ b/code/__HELPERS/lists.dm
@@ -10,7 +10,7 @@
*/
//Returns a list in plain english as a string
-/proc/english_list(var/list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "," )
+/proc/english_list(var/list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" )
var/total = input.len
if (!total)
return "[nothing_text]"
@@ -304,4 +304,13 @@ proc/listclearnulls(list/list)
if(bitfield & bit)
r += bit
- return r
\ No newline at end of file
+ return r
+
+// Returns the key based on the index
+/proc/get_key_by_index(var/list/L, var/index)
+ var/i = 1
+ for(var/key in L)
+ if(index == i)
+ return key
+ i++
+ return null
\ No newline at end of file
diff --git a/code/__HELPERS/maths.dm b/code/__HELPERS/maths.dm
new file mode 100644
index 00000000000..b174147d583
--- /dev/null
+++ b/code/__HELPERS/maths.dm
@@ -0,0 +1,114 @@
+// Credits to Nickr5 for the useful procs I've taken from his library resource.
+
+var/const/E = 2.71828183
+var/const/Sqrt2 = 1.41421356
+
+
+/proc/Atan2(x, y)
+ if(!x && !y) return 0
+ var/a = arccos(x / sqrt(x*x + y*y))
+ return y >= 0 ? a : -a
+
+/proc/Ceiling(x)
+ return -round(-x)
+
+/proc/Clamp(val, min, max)
+ return max(min, min(val, max))
+
+// cotangent
+/proc/Cot(x)
+ return 1 / Tan(x)
+
+// cosecant
+/proc/Csc(x)
+ return 1 / sin(x)
+
+/proc/Default(a, b)
+ return a ? a : b
+
+/proc/Floor(x)
+ return round(x)
+
+// Greatest Common Divisor - Euclid's algorithm
+/proc/Gcd(a, b)
+ return b ? Gcd(b, a % b) : a
+
+/proc/Inverse(x)
+ return 1 / x
+
+/proc/IsAboutEqual(a, b, deviation = 0.1)
+ return abs(a - b) <= deviation
+
+/proc/IsEven(x)
+ return x % 2 == 0
+
+// Returns true if val is from min to max, inclusive.
+/proc/IsInRange(val, min, max)
+ return min <= val && val <= max
+
+/proc/IsInteger(x)
+ return Floor(x) == x
+
+/proc/IsOdd(x)
+ return !IsEven(x)
+
+/proc/IsMultiple(x, y)
+ return x % y == 0
+
+// Least Common Multiple
+/proc/Lcm(a, b)
+ return abs(a) / Gcd(a, b) * abs(b)
+
+// Performs a linear interpolation between a and b.
+// Note that amount=0 returns a, amount=1 returns b, and
+// amount=0.5 returns the mean of a and b.
+/proc/Lerp(a, b, amount = 0.5)
+ return a + (b - a) * amount
+
+/proc/Mean(...)
+ var/values = 0
+ var/sum = 0
+ for(var/val in args)
+ values++
+ sum += val
+ return sum / values
+
+
+// Returns the nth root of x.
+/proc/Root(n, x)
+ return x ** (1 / n)
+
+// secant
+/proc/Sec(x)
+ return 1 / cos(x)
+
+// The quadratic formula. Returns a list with the solutions, or an empty list
+// if they are imaginary.
+/proc/SolveQuadratic(a, b, c)
+ ASSERT(a)
+ . = list()
+ var/d = b*b - 4 * a * c
+ var/bottom = 2 * a
+ if(d < 0) return
+ var/root = sqrt(d)
+ . += (-b + root) / bottom
+ if(!d) return
+ . += (-b - root) / bottom
+
+// tangent
+/proc/Tan(x)
+ return sin(x) / cos(x)
+
+/proc/ToDegrees(radians)
+ // 180 / Pi
+ return radians * 57.2957795
+
+/proc/ToRadians(degrees)
+ // Pi / 180
+ return degrees * 0.0174532925
+
+// min is inclusive, max is exclusive
+/proc/Wrap(val, min, max)
+ var/d = max - min
+ var/t = Floor((val - min) / d)
+ return val - (t * d)
\ No newline at end of file
diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm
new file mode 100644
index 00000000000..b3db4734960
--- /dev/null
+++ b/code/__HELPERS/mobs.dm
@@ -0,0 +1,50 @@
+proc/random_hair_style(gender)
+ switch(gender)
+ if(MALE) return pick(hair_styles_male_list)
+ if(FEMALE) return pick(hair_styles_female_list)
+ else return pick(hair_styles_list)
+
+proc/random_facial_hair_style(gender)
+ switch(gender)
+ if(MALE) return pick(facial_hair_styles_male_list)
+ if(FEMALE) return pick(facial_hair_styles_female_list)
+ else return pick(facial_hair_styles_list)
+
+proc/random_name(gender)
+ if(gender==FEMALE) return capitalize(pick(first_names_female)) + " " + capitalize(pick(last_names))
+ else return capitalize(pick(first_names_male)) + " " + capitalize(pick(last_names))
+
+proc/random_skin_tone()
+ switch(pick(55;"caucasian", 15;"afroamerican", 10;"african", 10;"latino", 5;"albino", 5;"weird"))
+ if("caucasian") . = -10
+ if("afroamerican") . = -115
+ if("african") . = -165
+ if("latino") . = -55
+ if("albino") . = 34
+ else . = rand(-185,34)
+ return min(max( .+rand(-25, 25), -185),34)
+
+proc/skintone2racedescription(tone)
+ switch (tone)
+ if(30 to INFINITY) return "albino"
+ if(20 to 30) return "pale"
+ if(5 to 15) return "light skinned"
+ if(-10 to 5) return "white"
+ if(-25 to -10) return "tan"
+ if(-45 to -25) return "darker skinned"
+ if(-65 to -45) return "brown"
+ if(-INFINITY to -65) return "black"
+ else return "unknown"
+
+proc/age2agedescription(age)
+ switch(age)
+ if(0 to 1) return "infant"
+ if(1 to 3) return "toddler"
+ if(3 to 13) return "child"
+ if(13 to 19) return "teenager"
+ if(19 to 30) return "young adult"
+ if(30 to 45) return "adult"
+ if(45 to 60) return "middle-aged"
+ if(60 to 70) return "aging"
+ if(70 to INFINITY) return "elderly"
+ else return "unknown"
\ No newline at end of file
diff --git a/code/__HELPERS/sanitize_values.dm b/code/__HELPERS/sanitize_values.dm
new file mode 100644
index 00000000000..4b521f9bfbb
--- /dev/null
+++ b/code/__HELPERS/sanitize_values.dm
@@ -0,0 +1,46 @@
+//general stuff
+/proc/sanitize_integer(number, min=0, max=1, default=0)
+ if(isnum(number))
+ number = round(number)
+ if(min <= number && number <= max)
+ return number
+ return default
+
+/proc/sanitize_text(text, default="")
+ if(istext(text))
+ return text
+ return default
+
+/proc/sanitize_inlist(value, list/List, default)
+ if(value in List) return value
+ if(default) return default
+ if(List && List.len)return List[1]
+
+
+
+//more specialised stuff
+/proc/sanitize_gender(gender,neuter=0,plural=0, default="male")
+ switch(gender)
+ if(MALE, FEMALE)return gender
+ if(NEUTER)
+ if(neuter) return gender
+ else return default
+ if(PLURAL)
+ if(plural) return gender
+ else return default
+ return default
+
+/proc/sanitize_hexcolor(color, default="#000000")
+ if(!istext(color)) return default
+ var/len = length(color)
+ if(len != 7 && len !=4) return default
+ if(text2ascii(color,1) != 35) return default //35 is the ascii code for "#"
+ . = "#"
+ for(var/i=2,i<=len,i++)
+ var/ascii = text2ascii(color,i)
+ switch(ascii)
+ if(48 to 57) . += ascii2text(ascii) //numbers 0 to 9
+ if(97 to 102) . += ascii2text(ascii) //letters a to f
+ if(65 to 70) . += ascii2text(ascii+32) //letters A to F - translates to lowercase
+ else return default
+ return .
diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm
index 0134bd6de8b..da9d8b34bce 100644
--- a/code/__HELPERS/text.dm
+++ b/code/__HELPERS/text.dm
@@ -323,4 +323,10 @@
var/a = copytext(text,i,i+1)
if(a == character)
count++
- return count
\ No newline at end of file
+ return count
+
+/proc/reverse_text(var/text = "")
+ var/new_text = ""
+ for(var/i = length(text); i > 0; i--)
+ new_text += copytext(text, i, i+1)
+ return new_text
\ No newline at end of file
diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm
index 7fa78d0375b..fc0ce947216 100644
--- a/code/__HELPERS/type2type.dm
+++ b/code/__HELPERS/type2type.dm
@@ -238,19 +238,26 @@ proc/tg_list2text(list/list, glue=",")
/proc/angle2text(var/degree)
return dir2text(angle2dir(degree))
+
//Converts a rights bitfield into a string
-/proc/rights2text(rights)
- if(rights & R_BUILDMODE) . += "+BUILDMODE"
- if(rights & R_ADMIN) . += "+ADMIN"
- if(rights & R_BAN) . += "+BAN"
- if(rights & R_FUN) . += "+FUN"
- if(rights & R_SERVER) . += "+SERVER"
- if(rights & R_DEBUG) . += "+DEBUG"
- if(rights & R_POSSESS) . += "+POSSESS"
- if(rights & R_PERMISSIONS) . += "+PERMISSIONS"
- if(rights & R_STEALTH) . += "+STEALTH"
- if(rights & R_REJUVINATE) . += "+REJUVINATE"
- if(rights & R_VAREDIT) . += "+VAREDIT"
- if(rights & R_SOUNDS) . += "+SOUND"
- if(rights & R_SPAWN) . += "+SPAWN"
+/proc/rights2text(rights,seperator="")
+ if(rights & R_BUILDMODE) . += "[seperator]+BUILDMODE"
+ if(rights & R_ADMIN) . += "[seperator]+ADMIN"
+ if(rights & R_BAN) . += "[seperator]+BAN"
+ if(rights & R_FUN) . += "[seperator]+FUN"
+ if(rights & R_SERVER) . += "[seperator]+SERVER"
+ if(rights & R_DEBUG) . += "[seperator]+DEBUG"
+ if(rights & R_POSSESS) . += "[seperator]+POSSESS"
+ if(rights & R_PERMISSIONS) . += "[seperator]+PERMISSIONS"
+ if(rights & R_STEALTH) . += "[seperator]+STEALTH"
+ if(rights & R_REJUVINATE) . += "[seperator]+REJUVINATE"
+ if(rights & R_VAREDIT) . += "[seperator]+VAREDIT"
+ if(rights & R_SOUNDS) . += "[seperator]+SOUND"
+ if(rights & R_SPAWN) . += "[seperator]+SPAWN"
return .
+
+/proc/ui_style2icon(ui_style)
+ switch(ui_style)
+ if("old") return 'icons/mob/screen1_old.dmi'
+ if("Orange") return 'icons/mob/screen1_Orange.dmi'
+ else return 'icons/mob/screen1_Midnight.dmi'
diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index cf8831dd76e..58150d4ab18 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -503,68 +503,52 @@ Turf and target are seperate in case you want to teleport some distance from a t
/proc/key_name(var/whom, var/include_link = null, var/include_name = 1)
- var/mob/the_mob = null
- var/client/the_client = null
- var/the_key = ""
+ var/mob/M
+ var/client/C
+ var/key
- if (isnull(whom))
- return "*null*"
- else if (istype(whom, /client))
- the_client = whom
- the_mob = the_client.mob
- the_key = the_client.key
- else if (ismob(whom))
- the_mob = whom
- the_client = the_mob.client
- the_key = the_mob.key
- else if (istype(whom, /datum))
- var/datum/the_datum = whom
- return "*invalid:[the_datum.type]*"
+ if(!whom) return "*null*"
+ if(istype(whom, /client))
+ C = whom
+ M = C.mob
+ key = C.key
+ else if(ismob(whom))
+ M = whom
+ C = M.client
+ key = M.key
+ else if(istype(whom, /datum))
+ var/datum/D = whom
+ return "*invalid:[D.type]*"
else
return "*invalid*"
- var/text = ""
+ . = ""
- if (!the_key)
- text += "*no client*"
- else
- var/linked = 1
- if (include_link && !isnull(the_mob))
- if (istext(include_link))
- text += ""
- else
- if(ismob(include_link))
- var/mob/MM = include_link
- if(MM.client)
- text += ""
- else
- linked = 0
- else if (istype(include_link, /client))
- text += ""
- else
- linked = 0
+ if(key)
+ if(include_link && C)
+ . += ""
- if (the_client && the_client.holder && the_client.holder.fakekey && !include_name)
- text += "Administrator"
+ if(C && C.holder && C.holder.fakekey && !include_name)
+ . += "Administrator"
else
- text += "[the_key]"
+ . += key
- if (!isnull(include_link) && !isnull(the_mob))
- if(linked)
- text += ""
- else
- text += " (DC)"
+ if(include_link)
+ if(C) . += ""
+ else . += " (DC)"
+ else
+ . += "*no key*"
- if (include_name && !isnull(the_mob))
- if (the_mob.real_name)
- text += "/([the_mob.real_name])"
- else if (the_mob.name)
- text += "/([the_mob.name])"
+ if(include_name && M)
+ if(M.real_name)
+ . += "/([M.real_name])"
+ else if(M.name)
+ . += "/([M.name])"
- return text
+ return .
/proc/key_name_admin(var/whom, var/include_name = 1)
- return key_name(whom, "%admin_ref%", include_name)
+ return key_name(whom, 1, include_name)
// Registers the on-close verb for a browse window (client/verb/.windowclose)
@@ -1353,6 +1337,7 @@ proc/is_hot(obj/item/W as obj)
istype(W, /obj/item/weapon/kitchen/utensil/fork) && W.icon_state != "forkloaded" || \
istype(W, /obj/item/weapon/twohanded/fireaxe) \
)
+
/proc/is_surgery_tool(obj/item/W as obj)
return ( \
istype(W, /obj/item/weapon/scalpel) || \
@@ -1389,3 +1374,47 @@ proc/is_hot(obj/item/W as obj)
return EAST
if(NORTHWEST)
return SOUTHEAST
+
+/*
+Checks if that loc and dir has a item on the wall
+*/
+var/list/WALLITEMS = list(
+ "/obj/machinery/power/apc", "/obj/machinery/alarm", "/obj/item/device/radio/intercom",
+ "/obj/structure/extinguisher_cabinet", "/obj/structure/reagent_dispensers/peppertank",
+ "/obj/machinery/status_display", "/obj/machinery/requests_console", "/obj/machinery/light_switch", "/obj/effect/sign",
+ "/obj/machinery/newscaster", "/obj/machinery/firealarm", "/obj/structure/noticeboard", "/obj/machinery/door_control",
+ "/obj/machinery/computer/security/telescreen", "/obj/machinery/embedded_controller/radio/simple_vent_controller",
+ "/obj/item/weapon/secstorage/ssafe", "/obj/machinery/door_timer", "/obj/machinery/flasher", "/obj/machinery/keycard_auth",
+ "/obj/structure/mirror", "/obj/structure/closet/fireaxecabinet", "/obj/machinery/computer/security/telescreen/entertainment"
+ )
+/proc/gotwallitem(loc, dir)
+ for(var/obj/O in loc)
+ for(var/item in WALLITEMS)
+ if(istype(O, text2path(item)))
+ //Direction works sometimes
+ if(O.dir == dir)
+ return 1
+
+ //Some stuff doesn't use dir properly, so we need to check pixel instead
+ switch(dir)
+ if(SOUTH)
+ if(O.pixel_y > 10)
+ return 1
+ if(NORTH)
+ if(O.pixel_y < -10)
+ return 1
+ if(WEST)
+ if(O.pixel_x > 10)
+ return 1
+ if(EAST)
+ if(O.pixel_x < -10)
+ return 1
+
+
+ //Some stuff is placed directly on the wallturf (signs)
+ for(var/obj/O in get_step(loc, dir))
+ for(var/item in WALLITEMS)
+ if(istype(O, text2path(item)))
+ if(O.pixel_x == 0 && O.pixel_y == 0)
+ return 1
+ return 0
diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm
index 17b25c6757f..8febf1f0c1e 100644
--- a/code/controllers/master_controller.dm
+++ b/code/controllers/master_controller.dm
@@ -42,9 +42,9 @@ datum/controller/game_controller/New()
if(!job_master)
job_master = new /datum/controller/occupations()
- if(job_master.SetupOccupations())
- world << "\red \b Job setup complete"
- job_master.LoadJobs("config/jobs.txt")
+ job_master.SetupOccupations()
+ job_master.LoadJobs("config/jobs.txt")
+ world << "\red \b Job setup complete"
if(!syndicate_code_phrase) syndicate_code_phrase = generate_code_phrase()
if(!syndicate_code_response) syndicate_code_response = generate_code_phrase()
diff --git a/code/controllers/verbs.dm b/code/controllers/verbs.dm
index fcd2c73012f..d659d2fa68c 100644
--- a/code/controllers/verbs.dm
+++ b/code/controllers/verbs.dm
@@ -24,7 +24,7 @@
if("Supply Shuttle")
supply_shuttle.process()
feedback_add_details("admin_verb","RSupply")
- message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.", 1)
+ message_admins("Admin [key_name_admin(usr)] has restarted the [controller] controller.")
return
@@ -74,5 +74,5 @@
if("Cameras")
debug_variables(cameranet)
feedback_add_details("admin_verb","DCameras")
- message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.", 1)
+ message_admins("Admin [key_name_admin(usr)] is debugging the [controller] controller.")
return
diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm
index 424f3fabaff..30b166862bc 100644
--- a/code/datums/datumvars.dm
+++ b/code/datums/datumvars.dm
@@ -173,27 +173,27 @@ client
if(istype(D,/atom))
var/atom/A = D
if(isliving(A))
- body += "[D]"
+ body += "[D]"
if(A.dir)
- body += "
<< [dir2text(A.dir)] >>"
+ body += "
<< [dir2text(A.dir)] >>"
var/mob/living/M = A
- body += "
[M.ckey ? M.ckey : "No ckey"] / [M.real_name ? M.real_name : "No real name"]"
+ body += "
[M.ckey ? M.ckey : "No ckey"] / [M.real_name ? M.real_name : "No real name"]"
body += {"
- BRUTE:[M.getBruteLoss()]
- FIRE:[M.getFireLoss()]
- TOXIN:[M.getToxLoss()]
- OXY:[M.getOxyLoss()]
- CLONE:[M.getCloneLoss()]
- BRAIN:[M.getBrainLoss()]
+ BRUTE:[M.getBruteLoss()]
+ FIRE:[M.getFireLoss()]
+ TOXIN:[M.getToxLoss()]
+ OXY:[M.getOxyLoss()]
+ CLONE:[M.getCloneLoss()]
+ BRAIN:[M.getBrainLoss()]
"}
else
- body += "[D]"
+ body += "[D]"
if(A.dir)
- body += "
<< [dir2text(A.dir)] >>"
+ body += "
<< [dir2text(A.dir)] >>"
else
body += "[D]"
@@ -219,10 +219,10 @@ client
body += ""
- body += "
"
+ // body += " Show player panel |
"
body += {" "
@@ -327,7 +327,7 @@ client
var/html = ""
if(DA)
- html += "(E) (C) (M) "
+ html += "(E) (C) (M) "
else
html += ""
@@ -364,11 +364,11 @@ client
else if (istype(value, /datum))
var/datum/D = value
- html += "[name] \ref[value] = [D.type]"
+ html += "[name] \ref[value] = [D.type]"
else if (istype(value, /client))
var/client/C = value
- html += "[name] \ref[value] = [C] [C.type]"
+ html += "[name] \ref[value] = [C] [C.type]"
//
else if (istype(value, /list))
var/list/L = value
@@ -398,393 +398,390 @@ client
return html
-/client/proc/view_var_Topic(href,href_list,hsrc)
+/client/proc/view_var_Topic(href, href_list, hsrc)
//This should all be moved over to datum/admins/Topic() or something ~Carn
- if( (usr.client == src) && src.holder )
- . = 1 //default return
- if(href_list["Vars"])
- debug_variables(locate(href_list["Vars"]))
-
- //~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records).
- else if(href_list["rename"])
- if(!check_rights(0)) return
-
- var/mob/M = locate(href_list["rename"])
- if(!istype(M))
- usr << "This can only be used on instances of type /mob"
- return
-
- var/new_name = copytext(sanitize(input(usr,"What would you like to name this mob?","Input a name",M.real_name) as text|null),1,MAX_NAME_LEN)
- if( !new_name || !M ) return
-
- message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].", 1)
- M.fully_replace_character_name(M.real_name,new_name)
- href_list["datumrefresh"] = href_list["rename"]
-
- else if(href_list["varnameedit"] && href_list["datumedit"])
- if(!check_rights(0)) return
-
- var/D = locate(href_list["datumedit"])
- if(!istype(D,/datum) && !istype(D,/client))
- usr << "This can only be used on instances of types /client or /datum"
- return
-
- modify_variables(D, href_list["varnameedit"], 1)
-
- else if(href_list["varnamechange"] && href_list["datumchange"])
- if(!check_rights(0)) return
-
- var/D = locate(href_list["datumchange"])
- if(!istype(D,/datum) && !istype(D,/client))
- usr << "This can only be used on instances of types /client or /datum"
- return
-
- modify_variables(D, href_list["varnamechange"], 0)
-
- else if(href_list["varnamemass"] && href_list["datummass"])
- if(!check_rights(0)) return
-
- var/atom/A = locate(href_list["datummass"])
- if(!istype(A))
- usr << "This can only be used on instances of type /atom"
- return
-
- cmd_mass_modify_object_variables(A, href_list["varnamemass"])
-
- else if(href_list["mob_player_panel"])
- if(!check_rights(0)) return
-
- var/mob/M = locate(href_list["mob_player_panel"])
- if(!istype(M))
- usr << "This can only be used on instances of type /mob"
- return
-
- src.holder.show_player_panel(M)
- href_list["datumrefresh"] = href_list["mob_player_panel"]
-
- else if(href_list["give_spell"])
- if(!check_rights(0)) return
-
- var/mob/M = locate(href_list["give_spell"])
- if(!istype(M))
- usr << "This can only be used on instances of type /mob"
- return
-
- src.give_spell(M)
- href_list["datumrefresh"] = href_list["give_spell"]
-
- else if(href_list["give_disease"])
- if(!check_rights(0)) return
-
- var/mob/M = locate(href_list["give_disease"])
- if(!istype(M))
- usr << "This can only be used on instances of type /mob"
- return
-
- src.give_disease(M)
- href_list["datumrefresh"] = href_list["give_spell"]
-
- else if(href_list["ninja"])
- if(!check_rights(0)) return
-
- var/mob/M = locate(href_list["ninja"])
- if(!istype(M))
- usr << "This can only be used on instances of type /mob"
- return
-
- src.cmd_admin_ninjafy(M)
- href_list["datumrefresh"] = href_list["ninja"]
-
- else if(href_list["godmode"])
- if(!check_rights(R_REJUVINATE)) return
-
- var/mob/M = locate(href_list["godmode"])
- if(!istype(M))
- usr << "This can only be used on instances of type /mob"
- return
-
- src.cmd_admin_godmode(M)
- href_list["datumrefresh"] = href_list["godmode"]
-
- else if(href_list["gib"])
- if(!check_rights(0)) return
-
- var/mob/M = locate(href_list["gib"])
- if(!istype(M))
- usr << "This can only be used on instances of type /mob"
- return
-
- src.cmd_admin_gib(M)
-
- else if(href_list["build_mode"])
- if(!check_rights(R_BUILDMODE)) return
-
- var/mob/M = locate(href_list["build_mode"])
- if(!istype(M))
- usr << "This can only be used on instances of type /mob"
- return
-
- togglebuildmode(M)
- href_list["datumrefresh"] = href_list["build_mode"]
-
- else if(href_list["drop_everything"])
- if(!check_rights(0)) return
-
- var/mob/M = locate(href_list["drop_everything"])
- if(!istype(M))
- usr << "This can only be used on instances of type /mob"
- return
-
- if(usr.client)
- usr.client.cmd_admin_drop_everything(M)
-
- else if(href_list["direct_control"])
- if(!check_rights(0)) return
-
- var/mob/M = locate(href_list["direct_control"])
- if(!istype(M))
- usr << "This can only be used on instances of type /mob"
- return
-
- if(usr.client)
- usr.client.cmd_assume_direct_control(M)
-
- else if(href_list["make_skeleton"])
- if(!check_rights(0)) return
-
- var/mob/living/carbon/human/H = locate(href_list["make_skeleton"])
- if(!istype(H))
- usr << "This can only be used on instances of type /mob/living/carbon/human"
- return
-
- H.makeSkeleton()
- href_list["datumrefresh"] = href_list["make_skeleton"]
-
- else if(href_list["delall"])
- if(!check_rights(R_DEBUG|R_SERVER)) return
-
- var/obj/O = locate(href_list["delall"])
- if(!isobj(O))
- usr << "This can only be used on instances of type /obj"
- return
-
- var/action_type = alert("Strict type ([O.type]) or type and all subtypes?",,"Strict type","Type and subtypes","Cancel")
- if(action_type == "Cancel" || !action_type)
- return
-
- if(alert("Are you really sure you want to delete all objects of type [O.type]?",,"Yes","No") != "Yes")
- return
-
- if(alert("Second confirmation required. Delete?",,"Yes","No") != "Yes")
- return
-
- var/O_type = O.type
- switch(action_type)
- if("Strict type")
- var/i = 0
- for(var/obj/Obj in world)
- if(Obj.type == O_type)
- i++
- del(Obj)
- if(!i)
- usr << "No objects of this type exist"
- return
- log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ")
- message_admins("\blue [key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ", 1)
- if("Type and subtypes")
- var/i = 0
- for(var/obj/Obj in world)
- if(istype(Obj,O_type))
- i++
- del(Obj)
- if(!i)
- usr << "No objects of this type exist"
- return
- log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ")
- message_admins("\blue [key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ", 1)
-
- else if(href_list["explode"])
- if(!check_rights(0)) return
-
- var/atom/A = locate(href_list["explode"])
- if(!isobj(A) && !ismob(A) && !isturf(A))
- usr << "This can only be done to instances of type /obj, /mob and /turf"
- return
-
- src.cmd_admin_explosion(A)
- href_list["datumrefresh"] = href_list["explode"]
-
- else if(href_list["emp"])
- if(!check_rights(0)) return
-
- var/atom/A = locate(href_list["emp"])
- if(!isobj(A) && !ismob(A) && !isturf(A))
- usr << "This can only be done to instances of type /obj, /mob and /turf"
- return
-
- src.cmd_admin_emp(A)
- href_list["datumrefresh"] = href_list["emp"]
-
- else if(href_list["mark_object"])
- if(!check_rights(0)) return
-
- var/datum/D = locate(href_list["mark_object"])
- if(!istype(D))
- usr << "This can only be done to instances of type /datum"
- return
-
- src.holder.marked_datum = D
- href_list["datumrefresh"] = href_list["mark_object"]
-
- else if(href_list["rotatedatum"])
- if(!check_rights(0)) return
-
- var/atom/A = locate(href_list["rotatedatum"])
- if(!istype(A))
- usr << "This can only be done to instances of type /atom"
- return
-
- switch(href_list["rotatedir"])
- if("right") A.dir = turn(A.dir, -45)
- if("left") A.dir = turn(A.dir, 45)
- href_list["datumrefresh"] = href_list["rotatedatum"]
-
- else if(href_list["makemonkey"])
- if(!check_rights(0)) return
-
- var/mob/living/carbon/human/H = locate(href_list["makemonkey"])
- if(!istype(H))
- usr << "This can only be done to instances of type /mob/living/carbon/human"
- return
-
- if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return
- if(!H)
- usr << "Mob doesn't exist anymore"
- return
- holder.Topic(href, list("monkeyone"=href_list["makemonkey"]))
-
- else if(href_list["makerobot"])
- if(!check_rights(0)) return
-
- var/mob/living/carbon/human/H = locate(href_list["makerobot"])
- if(!istype(H))
- usr << "This can only be done to instances of type /mob/living/carbon/human"
- return
-
- if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return
- if(!H)
- usr << "Mob doesn't exist anymore"
- return
- holder.Topic(href, list("makerobot"=href_list["makerobot"]))
-
- else if(href_list["makealien"])
- if(!check_rights(0)) return
-
- var/mob/living/carbon/human/H = locate(href_list["makealien"])
- if(!istype(H))
- usr << "This can only be done to instances of type /mob/living/carbon/human"
- return
-
- if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return
- if(!H)
- usr << "Mob doesn't exist anymore"
- return
- holder.Topic(href, list("makealien"=href_list["makealien"]))
-
- else if(href_list["makemetroid"])
- if(!check_rights(0)) return
-
- var/mob/living/carbon/human/H = locate(href_list["makemetroid"])
- if(!istype(H))
- usr << "This can only be done to instances of type /mob/living/carbon/human"
- return
-
- if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return
- if(!H)
- usr << "Mob doesn't exist anymore"
- return
- holder.Topic(href, list("makemetroid"=href_list["makemetroid"]))
-
- else if(href_list["makeai"])
- if(!check_rights(0)) return
-
- var/mob/living/carbon/human/H = locate(href_list["makeai"])
- if(!istype(H))
- usr << "This can only be done to instances of type /mob/living/carbon/human"
- return
-
- if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return
- if(!H)
- usr << "Mob doesn't exist anymore"
- return
- holder.Topic(href, list("makeai"=href_list["makeai"]))
-
- else if(href_list["setmutantrace"])
- if(!check_rights(0)) return
-
- var/mob/living/carbon/human/H = locate(href_list["setmutantrace"])
- if(!istype(H))
- usr << "This can only be done to instances of type /mob/living/carbon/human"
- return
-
- var/new_mutantrace = input("Please choose a new mutantrace","Mutantrace",null) as null|anything in list("NONE","golem","lizard","metroid","plant","tajaran","skrell") //BS12 EDIT TAJ EDIT SKR
- switch(new_mutantrace)
- if(null) return
- if("NONE") new_mutantrace = ""
- if(!H)
- usr << "Mob doesn't exist anymore"
- return
- if(H.dna)
- H.dna.mutantrace = new_mutantrace
- H.update_mutantrace()
-
- else if(href_list["regenerateicons"])
- if(!check_rights(0)) return
-
- var/mob/M = locate(href_list["regenerateicons"])
- if(!ismob(M))
- usr << "This can only be done to instances of type /mob"
- return
- M.regenerate_icons()
-
- else if(href_list["adjustDamage"] && href_list["mobToDamage"])
- if(!check_rights(0)) return
-
- var/mob/living/L = locate(href_list["mobToDamage"])
- if(!istype(L)) return
-
- var/Text = href_list["adjustDamage"]
-
- var/amount = input("Deal how much damage to mob? (Negative values here heal)","Adjust [Text]loss",0) as num
-
- if(!L)
- usr << "Mob doesn't exist anymore"
- return
-
- switch(Text)
- if("brute") L.adjustBruteLoss(amount)
- if("fire") L.adjustFireLoss(amount)
- if("toxin") L.adjustToxLoss(amount)
- if("oxygen")L.adjustOxyLoss(amount)
- if("brain") L.adjustBrainLoss(amount)
- if("clone") L.adjustCloneLoss(amount)
- else
- usr << "You caused an error. DEBUG: Text:[Text] Mob:[L]"
- return
-
- if(amount != 0)
- log_admin("[key_name(usr)] dealt [amount] amount of [Text] damage to [L] ")
- message_admins("\blue [key_name(usr)] dealt [amount] amount of [Text] damage to [L] ", 1)
- href_list["datumrefresh"] = href_list["mobToDamage"]
- else
- . = 0
-
- if(href_list["datumrefresh"])
- var/datum/DAT = locate(href_list["datumrefresh"])
- if(!istype(DAT, /datum))
- return
- src.debug_variables(DAT)
- . = 1
-
+ if( (usr.client != src) || !src.holder )
return
+ if(href_list["Vars"])
+ debug_variables(locate(href_list["Vars"]))
+
+ //~CARN: for renaming mobs (updates their name, real_name, mind.name, their ID/PDA and datacore records).
+ else if(href_list["rename"])
+ if(!check_rights(0)) return
+
+ var/mob/M = locate(href_list["rename"])
+ if(!istype(M))
+ usr << "This can only be used on instances of type /mob"
+ return
+
+ var/new_name = copytext(sanitize(input(usr,"What would you like to name this mob?","Input a name",M.real_name) as text|null),1,MAX_NAME_LEN)
+ if( !new_name || !M ) return
+
+ message_admins("Admin [key_name_admin(usr)] renamed [key_name_admin(M)] to [new_name].")
+ M.fully_replace_character_name(M.real_name,new_name)
+ href_list["datumrefresh"] = href_list["rename"]
+
+ else if(href_list["varnameedit"] && href_list["datumedit"])
+ if(!check_rights(0)) return
+
+ var/D = locate(href_list["datumedit"])
+ if(!istype(D,/datum) && !istype(D,/client))
+ usr << "This can only be used on instances of types /client or /datum"
+ return
+
+ modify_variables(D, href_list["varnameedit"], 1)
+
+ else if(href_list["varnamechange"] && href_list["datumchange"])
+ if(!check_rights(0)) return
+
+ var/D = locate(href_list["datumchange"])
+ if(!istype(D,/datum) && !istype(D,/client))
+ usr << "This can only be used on instances of types /client or /datum"
+ return
+
+ modify_variables(D, href_list["varnamechange"], 0)
+
+ else if(href_list["varnamemass"] && href_list["datummass"])
+ if(!check_rights(0)) return
+
+ var/atom/A = locate(href_list["datummass"])
+ if(!istype(A))
+ usr << "This can only be used on instances of type /atom"
+ return
+
+ cmd_mass_modify_object_variables(A, href_list["varnamemass"])
+
+ else if(href_list["mob_player_panel"])
+ if(!check_rights(0)) return
+
+ var/mob/M = locate(href_list["mob_player_panel"])
+ if(!istype(M))
+ usr << "This can only be used on instances of type /mob"
+ return
+
+ src.holder.show_player_panel(M)
+ href_list["datumrefresh"] = href_list["mob_player_panel"]
+
+ else if(href_list["give_spell"])
+ if(!check_rights(0)) return
+
+ var/mob/M = locate(href_list["give_spell"])
+ if(!istype(M))
+ usr << "This can only be used on instances of type /mob"
+ return
+
+ src.give_spell(M)
+ href_list["datumrefresh"] = href_list["give_spell"]
+
+ else if(href_list["give_disease"])
+ if(!check_rights(0)) return
+
+ var/mob/M = locate(href_list["give_disease"])
+ if(!istype(M))
+ usr << "This can only be used on instances of type /mob"
+ return
+
+ src.give_disease(M)
+ href_list["datumrefresh"] = href_list["give_spell"]
+
+ else if(href_list["ninja"])
+ if(!check_rights(0)) return
+
+ var/mob/M = locate(href_list["ninja"])
+ if(!istype(M))
+ usr << "This can only be used on instances of type /mob"
+ return
+
+ src.cmd_admin_ninjafy(M)
+ href_list["datumrefresh"] = href_list["ninja"]
+
+ else if(href_list["godmode"])
+ if(!check_rights(R_REJUVINATE)) return
+
+ var/mob/M = locate(href_list["godmode"])
+ if(!istype(M))
+ usr << "This can only be used on instances of type /mob"
+ return
+
+ src.cmd_admin_godmode(M)
+ href_list["datumrefresh"] = href_list["godmode"]
+
+ else if(href_list["gib"])
+ if(!check_rights(0)) return
+
+ var/mob/M = locate(href_list["gib"])
+ if(!istype(M))
+ usr << "This can only be used on instances of type /mob"
+ return
+
+ src.cmd_admin_gib(M)
+
+ else if(href_list["build_mode"])
+ if(!check_rights(R_BUILDMODE)) return
+
+ var/mob/M = locate(href_list["build_mode"])
+ if(!istype(M))
+ usr << "This can only be used on instances of type /mob"
+ return
+
+ togglebuildmode(M)
+ href_list["datumrefresh"] = href_list["build_mode"]
+
+ else if(href_list["drop_everything"])
+ if(!check_rights(0)) return
+
+ var/mob/M = locate(href_list["drop_everything"])
+ if(!istype(M))
+ usr << "This can only be used on instances of type /mob"
+ return
+
+ if(usr.client)
+ usr.client.cmd_admin_drop_everything(M)
+
+ else if(href_list["direct_control"])
+ if(!check_rights(0)) return
+
+ var/mob/M = locate(href_list["direct_control"])
+ if(!istype(M))
+ usr << "This can only be used on instances of type /mob"
+ return
+
+ if(usr.client)
+ usr.client.cmd_assume_direct_control(M)
+
+ else if(href_list["make_skeleton"])
+ if(!check_rights(0)) return
+
+ var/mob/living/carbon/human/H = locate(href_list["make_skeleton"])
+ if(!istype(H))
+ usr << "This can only be used on instances of type /mob/living/carbon/human"
+ return
+
+ H.makeSkeleton()
+ href_list["datumrefresh"] = href_list["make_skeleton"]
+
+ else if(href_list["delall"])
+ if(!check_rights(R_DEBUG|R_SERVER)) return
+
+ var/obj/O = locate(href_list["delall"])
+ if(!isobj(O))
+ usr << "This can only be used on instances of type /obj"
+ return
+
+ var/action_type = alert("Strict type ([O.type]) or type and all subtypes?",,"Strict type","Type and subtypes","Cancel")
+ if(action_type == "Cancel" || !action_type)
+ return
+
+ if(alert("Are you really sure you want to delete all objects of type [O.type]?",,"Yes","No") != "Yes")
+ return
+
+ if(alert("Second confirmation required. Delete?",,"Yes","No") != "Yes")
+ return
+
+ var/O_type = O.type
+ switch(action_type)
+ if("Strict type")
+ var/i = 0
+ for(var/obj/Obj in world)
+ if(Obj.type == O_type)
+ i++
+ del(Obj)
+ if(!i)
+ usr << "No objects of this type exist"
+ return
+ log_admin("[key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ")
+ message_admins("\blue [key_name(usr)] deleted all objects of type [O_type] ([i] objects deleted) ")
+ if("Type and subtypes")
+ var/i = 0
+ for(var/obj/Obj in world)
+ if(istype(Obj,O_type))
+ i++
+ del(Obj)
+ if(!i)
+ usr << "No objects of this type exist"
+ return
+ log_admin("[key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ")
+ message_admins("\blue [key_name(usr)] deleted all objects of type or subtype of [O_type] ([i] objects deleted) ")
+
+ else if(href_list["explode"])
+ if(!check_rights(0)) return
+
+ var/atom/A = locate(href_list["explode"])
+ if(!isobj(A) && !ismob(A) && !isturf(A))
+ usr << "This can only be done to instances of type /obj, /mob and /turf"
+ return
+
+ src.cmd_admin_explosion(A)
+ href_list["datumrefresh"] = href_list["explode"]
+
+ else if(href_list["emp"])
+ if(!check_rights(0)) return
+
+ var/atom/A = locate(href_list["emp"])
+ if(!isobj(A) && !ismob(A) && !isturf(A))
+ usr << "This can only be done to instances of type /obj, /mob and /turf"
+ return
+
+ src.cmd_admin_emp(A)
+ href_list["datumrefresh"] = href_list["emp"]
+
+ else if(href_list["mark_object"])
+ if(!check_rights(0)) return
+
+ var/datum/D = locate(href_list["mark_object"])
+ if(!istype(D))
+ usr << "This can only be done to instances of type /datum"
+ return
+
+ src.holder.marked_datum = D
+ href_list["datumrefresh"] = href_list["mark_object"]
+
+ else if(href_list["rotatedatum"])
+ if(!check_rights(0)) return
+
+ var/atom/A = locate(href_list["rotatedatum"])
+ if(!istype(A))
+ usr << "This can only be done to instances of type /atom"
+ return
+
+ switch(href_list["rotatedir"])
+ if("right") A.dir = turn(A.dir, -45)
+ if("left") A.dir = turn(A.dir, 45)
+ href_list["datumrefresh"] = href_list["rotatedatum"]
+
+ else if(href_list["makemonkey"])
+ if(!check_rights(0)) return
+
+ var/mob/living/carbon/human/H = locate(href_list["makemonkey"])
+ if(!istype(H))
+ usr << "This can only be done to instances of type /mob/living/carbon/human"
+ return
+
+ if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return
+ if(!H)
+ usr << "Mob doesn't exist anymore"
+ return
+ holder.Topic(href, list("monkeyone"=href_list["makemonkey"]))
+
+ else if(href_list["makerobot"])
+ if(!check_rights(0)) return
+
+ var/mob/living/carbon/human/H = locate(href_list["makerobot"])
+ if(!istype(H))
+ usr << "This can only be done to instances of type /mob/living/carbon/human"
+ return
+
+ if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return
+ if(!H)
+ usr << "Mob doesn't exist anymore"
+ return
+ holder.Topic(href, list("makerobot"=href_list["makerobot"]))
+
+ else if(href_list["makealien"])
+ if(!check_rights(0)) return
+
+ var/mob/living/carbon/human/H = locate(href_list["makealien"])
+ if(!istype(H))
+ usr << "This can only be done to instances of type /mob/living/carbon/human"
+ return
+
+ if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return
+ if(!H)
+ usr << "Mob doesn't exist anymore"
+ return
+ holder.Topic(href, list("makealien"=href_list["makealien"]))
+
+ else if(href_list["makemetroid"])
+ if(!check_rights(0)) return
+
+ var/mob/living/carbon/human/H = locate(href_list["makemetroid"])
+ if(!istype(H))
+ usr << "This can only be done to instances of type /mob/living/carbon/human"
+ return
+
+ if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return
+ if(!H)
+ usr << "Mob doesn't exist anymore"
+ return
+ holder.Topic(href, list("makemetroid"=href_list["makemetroid"]))
+
+ else if(href_list["makeai"])
+ if(!check_rights(0)) return
+
+ var/mob/living/carbon/human/H = locate(href_list["makeai"])
+ if(!istype(H))
+ usr << "This can only be done to instances of type /mob/living/carbon/human"
+ return
+
+ if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform") return
+ if(!H)
+ usr << "Mob doesn't exist anymore"
+ return
+ holder.Topic(href, list("makeai"=href_list["makeai"]))
+
+ else if(href_list["setmutantrace"])
+ if(!check_rights(0)) return
+
+ var/mob/living/carbon/human/H = locate(href_list["setmutantrace"])
+ if(!istype(H))
+ usr << "This can only be done to instances of type /mob/living/carbon/human"
+ return
+
+ var/new_mutantrace = input("Please choose a new mutantrace","Mutantrace",null) as null|anything in list("NONE","golem","lizard","metroid","plant","shadow","tajaran","skrell")
+ switch(new_mutantrace)
+ if(null) return
+ if("NONE") new_mutantrace = ""
+ if(!H)
+ usr << "Mob doesn't exist anymore"
+ return
+ if(H.dna)
+ H.dna.mutantrace = new_mutantrace
+ H.update_mutantrace()
+
+ else if(href_list["regenerateicons"])
+ if(!check_rights(0)) return
+
+ var/mob/M = locate(href_list["regenerateicons"])
+ if(!ismob(M))
+ usr << "This can only be done to instances of type /mob"
+ return
+ M.regenerate_icons()
+
+ else if(href_list["adjustDamage"] && href_list["mobToDamage"])
+ if(!check_rights(0)) return
+
+ var/mob/living/L = locate(href_list["mobToDamage"])
+ if(!istype(L)) return
+
+ var/Text = href_list["adjustDamage"]
+
+ var/amount = input("Deal how much damage to mob? (Negative values here heal)","Adjust [Text]loss",0) as num
+
+ if(!L)
+ usr << "Mob doesn't exist anymore"
+ return
+
+ switch(Text)
+ if("brute") L.adjustBruteLoss(amount)
+ if("fire") L.adjustFireLoss(amount)
+ if("toxin") L.adjustToxLoss(amount)
+ if("oxygen")L.adjustOxyLoss(amount)
+ if("brain") L.adjustBrainLoss(amount)
+ if("clone") L.adjustCloneLoss(amount)
+ else
+ usr << "You caused an error. DEBUG: Text:[Text] Mob:[L]"
+ return
+
+ if(amount != 0)
+ log_admin("[key_name(usr)] dealt [amount] amount of [Text] damage to [L] ")
+ message_admins("\blue [key_name(usr)] dealt [amount] amount of [Text] damage to [L] ")
+ href_list["datumrefresh"] = href_list["mobToDamage"]
+
+ if(href_list["datumrefresh"])
+ var/datum/DAT = locate(href_list["datumrefresh"])
+ if(!istype(DAT, /datum))
+ return
+ src.debug_variables(DAT)
+
+ return
diff --git a/code/datums/disease.dm b/code/datums/disease.dm
index 3e9129009a0..fd24c795272 100644
--- a/code/datums/disease.dm
+++ b/code/datums/disease.dm
@@ -65,11 +65,14 @@ var/list/diseases = typesof(/datum/disease) - /datum/disease
if(stage > max_stages)
stage = max_stages
- if(stage_prob != 0 && prob(stage_prob) && stage != max_stages && !cure_present && age > stage_minimum_age * stage) //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))))
+
+ if(stage < max_stages && prob(stage_prob) && !cure_present) //now the disease shouldn't get back up to stage 4 in no time stage++
+ //world << "up"
+ if(stage > 0 && (cure_present && prob(cure_chance)))
stage--
- else if(stage <= 1 && ((prob(1) && curable) || (cure_present && prob(cure_chance))))
+ //world << "down"
+
+ if(stage <= 1 && ((prob(1) && curable) || (cure_present && prob(cure_chance))))
// world << "Cured as stage act"
cure()
return
@@ -96,6 +99,11 @@ var/list/diseases = typesof(/datum/disease) - /datum/disease
return result
+/datum/disease/proc/spread_by_touch()
+ switch(spread_type)
+ if(CONTACT_FEET, CONTACT_HANDS, CONTACT_GENERAL)
+ return 1
+ return 0
/datum/disease/proc/spread(var/atom/source=null, var/airborne_range = 2, var/force_spread)
//world << "Disease [src] proc spread was called from holder [source]"
@@ -105,7 +113,7 @@ var/list/diseases = typesof(/datum/disease) - /datum/disease
if(force_spread)
how_spread = force_spread
- if(how_spread == SPECIAL || how_spread == NON_CONTAGIOUS)//does not spread
+ if(how_spread == SPECIAL || how_spread == NON_CONTAGIOUS || how_spread == BLOOD)//does not spread
return
if(stage < contagious_period) //the disease is not contagious at this stage
@@ -117,6 +125,9 @@ var/list/diseases = typesof(/datum/disease) - /datum/disease
else //no source and no mob affected. Rogue disease. Break
return
+ if(affected_mob)
+ if(affected_mob.reagents.has_reagent("spaceacillin"))
+ return // Don't spread if we have spaceacillin in our system.
var/check_range = airborne_range//defaults to airborne - range 2
@@ -184,8 +195,8 @@ var/list/diseases = typesof(/datum/disease) - /datum/disease
return 1
return 0
-/datum/disease/proc/Copy()
- return new type(0, src)
+/datum/disease/proc/Copy(var/process = 0)
+ return new type(process, src)
/*
/datum/disease/Del()
diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm
index 4ea713bb2b7..939960d5fe9 100644
--- a/code/datums/diseases/advance/advance.dm
+++ b/code/datums/diseases/advance/advance.dm
@@ -11,6 +11,13 @@
var/list/archive_diseases = list()
+// The order goes from easy to cure to hard to cure.
+var/list/advance_cures = list(
+ "nutriment", "sugar", "orangejuice",
+ "spaceacillin", "kelotane", "ethanol",
+ "leporazine", "synaptizine", "lipozine",
+ "silver", "gold", "plasma"
+ )
/*
@@ -31,6 +38,8 @@ var/list/archive_diseases = list()
// NEW VARS
var/list/symptoms = list() // The symptoms of the disease.
+ var/id = ""
+ var/processing = 0
/*
@@ -38,7 +47,7 @@ var/list/archive_diseases = list()
*/
-/datum/disease/advance/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
+/datum/disease/advance/New(var/process = 1, var/datum/disease/advance/D)
// Setup our dictionary if it hasn't already.
if(!dictionary_symptoms.len)
@@ -57,16 +66,27 @@ var/list/archive_diseases = list()
else
for(var/datum/symptom/S in D.symptoms)
symptoms += new S.type
- name = D.name
- Refresh(!copy)
+ Refresh()
..(process, D)
return
+/datum/disease/advance/Del()
+ if(processing)
+ for(var/datum/symptom/S in symptoms)
+ S.End(src)
+ ..()
+
// Randomly pick a symptom to activate.
/datum/disease/advance/stage_act()
..()
if(symptoms && symptoms.len)
+
+ if(!processing)
+ processing = 1
+ for(var/datum/symptom/S in symptoms)
+ S.Start(src)
+
for(var/datum/symptom/S in symptoms)
S.Activate(src)
else
@@ -96,8 +116,8 @@ var/list/archive_diseases = list()
return
// Returns the advance disease with a different reference memory.
-/datum/disease/advance/Copy()
- return new /datum/disease/advance(0, src, 1)
+/datum/disease/advance/Copy(var/process = 0)
+ return new /datum/disease/advance(process, src, 1)
/*
@@ -149,13 +169,20 @@ var/list/archive_diseases = list()
return generated
-/datum/disease/advance/proc/Refresh(var/save = 1)
+/datum/disease/advance/proc/Refresh(var/new_name = 0)
//world << "[src.name] \ref[src] - REFRESH!"
var/list/properties = GenerateProperties()
AssignProperties(properties)
- if(save)
+
+ if(!archive_diseases[GetDiseaseID()])
+ if(new_name)
+ AssignName()
+ archive_diseases[GetDiseaseID()] = src // So we don't infinite loop
archive_diseases[GetDiseaseID()] = new /datum/disease/advance(0, src, 1)
+ var/datum/disease/advance/A = archive_diseases[GetDiseaseID()]
+ AssignName(A.name)
+
//Generate disease properties based on the effects. Returns an associated list.
/datum/disease/advance/proc/GenerateProperties()
@@ -182,9 +209,10 @@ var/list/archive_diseases = list()
hidden = list( (properties["stealth"] > 2), (properties["stealth"] > 3) )
// The more symptoms we have, the less transmittable it is but some symptoms can make up for it.
- SetSpread(max(BLOOD, min(properties["transmittable"] - symptoms.len, AIRBORNE)))
- permeability_mod = max(round(0.5 * properties["transmittable"]), 1)
- stage_prob = max(properties["stage_rate"], 1)
+ SetSpread(Clamp(properties["transmittable"] - symptoms.len, BLOOD, AIRBORNE))
+ permeability_mod = max(Ceiling(0.4 * properties["transmittable"]), 1)
+ cure_chance = 15 - Clamp(properties["resistance"], -5, 5) // can be between 10 and 20
+ stage_prob = max(properties["stage_rate"], 2)
SetSeverity(properties["severity"])
GenerateCure(properties)
else
@@ -213,7 +241,7 @@ var/list/archive_diseases = list()
switch(level_sev)
- if(0)
+ if(-INFINITY to 0)
severity = "Non-Threat"
if(1)
severity = "Minor"
@@ -223,7 +251,7 @@ var/list/archive_diseases = list()
severity = "Harmful"
if(4)
severity = "Dangerous!"
- if(5)
+ if(5 to INFINITY)
severity = "BIOHAZARD THREAT!"
else
severity = "Unknown"
@@ -232,42 +260,9 @@ var/list/archive_diseases = list()
// Will generate a random cure, the less resistance the symptoms have, the harder the cure.
/datum/disease/advance/proc/GenerateCure(var/list/properties = list())
if(properties && properties.len)
- var/res = max(properties["resistance"] - (symptoms.len / 2), 0)
+ var/res = Clamp(properties["resistance"] - (symptoms.len / 2), 1, advance_cures.len)
//world << "Res = [res]"
- switch(round(res))
- // Due to complications, I cannot randomly generate cures or randomly give cures.
- if(0)
- cure_id = "nutriment"
-
- if(1)
- cure_id = "sodiumchloride"
-
- if(2)
- cure_id = "orangejuice"
-
- if(3)
- cure_id = "spaceacillin"
-
- if(4)
- cure_id = "ethanol"
-
- if(5)
- cure_id = "ethylredoxrazine"
-
- if(6)
- cure_id = "synaptizine"
-
- if(7)
- cure_id = "silver"
-
- if(8)
- cure_id = "gold"
-
- if(9)
- cure_id = "mindbreaker"
-
- else
- cure_id = "plasma"
+ cure_id = advance_cures[res]
// Get the cure name from the cure_id
var/datum/reagent/D = chemical_reagents_list[cure_id]
@@ -281,7 +276,7 @@ var/list/archive_diseases = list()
var/s = safepick(GenerateSymptoms(level, 1))
if(s)
AddSymptom(s)
- Refresh()
+ Refresh(1)
return
// Randomly remove a symptom.
@@ -290,7 +285,7 @@ var/list/archive_diseases = list()
var/s = safepick(symptoms)
if(s)
RemoveSymptom(s)
- Refresh()
+ Refresh(1)
return
// Name the disease.
@@ -300,11 +295,15 @@ var/list/archive_diseases = list()
// Return a unique ID of the disease.
/datum/disease/advance/proc/GetDiseaseID()
+
var/list/L = list()
for(var/datum/symptom/S in symptoms)
L += S.id
L = sortList(L) // Sort the list so it doesn't matter which order the symptoms are in.
- return dd_list2text(L, ":")
+ var/result = dd_list2text(L, ":")
+ id = result
+ return result
+
// Add a symptom, if it is over the limit (with a small chance to be able to go over)
// we take a random symptom away and add the new one.
@@ -313,7 +312,7 @@ var/list/archive_diseases = list()
if(HasSymptom(S))
return
- if(symptoms.len < 3 + rand(-1, 1))
+ if(symptoms.len < 5 + rand(-1, 1))
symptoms += S
else
RemoveSymptom(pick(symptoms))
@@ -338,7 +337,7 @@ var/list/archive_diseases = list()
var/list/diseases = list()
- for(var/datum/disease/advance/A in D_list.Copy())
+ for(var/datum/disease/advance/A in D_list)
diseases += A.Copy()
if(!diseases.len)
@@ -361,7 +360,7 @@ var/list/archive_diseases = list()
// Should be only 1 entry left, but if not let's only return a single entry
//world << "END MIXING!!!!!"
var/datum/disease/advance/to_return = pick(diseases)
- to_return.Refresh()
+ to_return.Refresh(1)
return to_return
/proc/SetViruses(var/datum/reagent/R, var/list/data)
@@ -376,4 +375,45 @@ var/list/archive_diseases = list()
if(preserve.len)
R.data["viruses"] = preserve
+/proc/AdminCreateVirus(var/mob/user)
+ var/i = 5
+
+ var/datum/disease/advance/D = new(0, null)
+ D.symptoms = list()
+
+ var/list/symptoms = list()
+ symptoms += "Done"
+ symptoms += list_symptoms.Copy()
+ do
+ var/symptom = input(user, "Choose a symptom to add ([i] remaining)", "Choose a Symptom") in symptoms
+ if(istext(symptom))
+ i = 0
+ else if(ispath(symptom))
+ var/datum/symptom/S = new symptom
+ if(!D.HasSymptom(S))
+ D.symptoms += S
+ i -= 1
+ while(i > 0)
+
+ if(D.symptoms.len > 0)
+
+ var/new_name = input(user, "Name your new disease.", "New Name")
+ D.AssignName(new_name)
+ D.Refresh()
+
+ for(var/datum/disease/advance/AD in active_diseases)
+ AD.Refresh()
+
+ for(var/mob/living/carbon/human/H in shuffle(living_mob_list))
+ if(H.z != 1)
+ continue
+ if(!H.has_disease(D))
+ H.contract_disease(D, 1)
+ break
+
+ var/list/name_symptoms = list()
+ for(var/datum/symptom/S in D.symptoms)
+ name_symptoms += S.name
+ message_admins("[key_name_admin(user)] has triggered a custom virus outbreak of [D.name]! It has these symptoms: [english_list(name_symptoms)]")
+
#undef RANDOM_STARTING_LEVEL
\ No newline at end of file
diff --git a/code/datums/diseases/advance/cold.dm b/code/datums/diseases/advance/cold.dm
deleted file mode 100644
index 3392b5f7ecf..00000000000
--- a/code/datums/diseases/advance/cold.dm
+++ /dev/null
@@ -1,5 +0,0 @@
-/datum/disease/advance/cold/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
- if(!D)
- name = "Cold"
- symptoms = list(new/datum/symptom/sneeze)
- ..(process, D, copy)
diff --git a/code/datums/diseases/advance/flu.dm b/code/datums/diseases/advance/flu.dm
deleted file mode 100644
index b661f4f1bfd..00000000000
--- a/code/datums/diseases/advance/flu.dm
+++ /dev/null
@@ -1,5 +0,0 @@
-/datum/disease/advance/flu/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
- if(!D)
- name = "Flu"
- symptoms = list(new/datum/symptom/cough)
- ..(process, D, copy)
diff --git a/code/datums/diseases/advance/presets.dm b/code/datums/diseases/advance/presets.dm
new file mode 100644
index 00000000000..b62b18e306c
--- /dev/null
+++ b/code/datums/diseases/advance/presets.dm
@@ -0,0 +1,43 @@
+// Cold
+
+/datum/disease/advance/cold/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
+ if(!D)
+ name = "Cold"
+ symptoms = list(new/datum/symptom/sneeze)
+ ..(process, D, copy)
+
+
+// Flu
+
+/datum/disease/advance/flu/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
+ if(!D)
+ name = "Flu"
+ symptoms = list(new/datum/symptom/cough)
+ ..(process, D, copy)
+
+
+// Voice Changing
+
+/datum/disease/advance/voice_change/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
+ if(!D)
+ name = "Epiglottis Mutation"
+ symptoms = list(new/datum/symptom/voice_change)
+ ..(process, D, copy)
+
+
+// Toxin Filter
+
+/datum/disease/advance/heal/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
+ if(!D)
+ name = "Liver Enhancer"
+ symptoms = list(new/datum/symptom/heal)
+ ..(process, D, copy)
+
+
+// Hullucigen
+
+/datum/disease/advance/hullucigen/New(var/process = 1, var/datum/disease/advance/D, var/copy = 0)
+ if(!D)
+ name = "Reality Impairment"
+ symptoms = list(new/datum/symptom/hallucigen)
+ ..(process, D, copy)
\ No newline at end of file
diff --git a/code/datums/diseases/advance/symptoms/cough.dm b/code/datums/diseases/advance/symptoms/cough.dm
index 5d36b4b2682..ad36d3300e5 100644
--- a/code/datums/diseases/advance/symptoms/cough.dm
+++ b/code/datums/diseases/advance/symptoms/cough.dm
@@ -4,13 +4,13 @@
Coughing
Noticable.
- No Resistance.
- Doesn't increase stage speed.
+ Little Resistance.
+ Doesn't increase stage speed much.
Transmittable.
Low Level.
BONUS
- Will force the affected mob to drop items!
+ Will force the affected mob to drop small items!
//////////////////////////////////////
*/
@@ -19,8 +19,8 @@ BONUS
name = "Cough"
stealth = -1
- resistance = 0
- stage_speed = 0
+ resistance = 3
+ stage_speed = 1
transmittable = 2
level = 1
@@ -33,5 +33,7 @@ BONUS
M << "[pick("You swallow excess mucus.", "You lightly cough.")]"
else
M.emote("cough")
- M.drop_item()
+ var/obj/item/I = M.get_active_hand()
+ if(I && I.w_class < 3)
+ M.drop_item()
return
\ No newline at end of file
diff --git a/code/datums/diseases/advance/symptoms/damage_converter.dm b/code/datums/diseases/advance/symptoms/damage_converter.dm
index 163b2a3bc79..6e31e363c8a 100644
--- a/code/datums/diseases/advance/symptoms/damage_converter.dm
+++ b/code/datums/diseases/advance/symptoms/damage_converter.dm
@@ -15,7 +15,7 @@ Bonus
//////////////////////////////////////
*/
-/datum/symptom/damage_converter // Not the egg
+/datum/symptom/damage_converter
name = "Toxic Compensation"
stealth = 1
@@ -29,7 +29,7 @@ Bonus
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
- if(5)
+ if(4, 5)
Convert(M)
return
@@ -39,5 +39,5 @@ Bonus
var/get_damage = rand(1, 2)
M.adjustFireLoss(-get_damage)
M.adjustBruteLoss(-get_damage)
- M.adjustToxLoss(get_damage * 2)
+ M.adjustToxLoss(get_damage)
return 1
\ No newline at end of file
diff --git a/code/datums/diseases/advance/symptoms/dizzy.dm b/code/datums/diseases/advance/symptoms/dizzy.dm
index cca159c8d47..0a10a7bd066 100644
--- a/code/datums/diseases/advance/symptoms/dizzy.dm
+++ b/code/datums/diseases/advance/symptoms/dizzy.dm
@@ -3,7 +3,7 @@
Dizziness
- Little bit hidden.
+ Hidden.
Lowers resistance considerably.
Decreases stage speed.
Reduced transmittability
@@ -18,7 +18,7 @@ Bonus
/datum/symptom/dizzy // Not the egg
name = "Dizziness"
- stealth = 1
+ stealth = 2
resistance = -2
stage_speed = -3
transmittable = -1
diff --git a/code/datums/diseases/advance/symptoms/fever.dm b/code/datums/diseases/advance/symptoms/fever.dm
index e53e36bf159..f24e789810f 100644
--- a/code/datums/diseases/advance/symptoms/fever.dm
+++ b/code/datums/diseases/advance/symptoms/fever.dm
@@ -21,7 +21,7 @@ Bonus
stealth = 0
resistance = 3
stage_speed = 3
- transmittable = 1
+ transmittable = 2
level = 2
/datum/symptom/fever/Activate(var/datum/disease/advance/A)
@@ -29,6 +29,7 @@ Bonus
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/carbon/M = A.affected_mob
M << "[pick("You feel hot.", "You feel like you're burning.")]"
- M.bodytemperature += 20 * A.stage
+ if(M.bodytemperature < BODYTEMP_HEAT_DAMAGE_LIMIT)
+ M.bodytemperature = min(M.bodytemperature + (20 * A.stage), BODYTEMP_HEAT_DAMAGE_LIMIT - 1)
return
diff --git a/code/datums/diseases/advance/symptoms/heal.dm b/code/datums/diseases/advance/symptoms/heal.dm
new file mode 100644
index 00000000000..0584dc76110
--- /dev/null
+++ b/code/datums/diseases/advance/symptoms/heal.dm
@@ -0,0 +1,40 @@
+/*
+//////////////////////////////////////
+
+Healing
+
+ Little bit hidden.
+ Lowers resistance tremendously.
+ Decreases stage speed tremendously.
+ Decreases transmittablity temrendously.
+ Fatal Level.
+
+Bonus
+ Heals toxins in the affected mob's blood stream.
+
+//////////////////////////////////////
+*/
+
+/datum/symptom/heal
+
+ name = "Toxic Filter"
+ stealth = 1
+ resistance = -4
+ stage_speed = -4
+ transmittable = -4
+ level = 6
+
+/datum/symptom/heal/Activate(var/datum/disease/advance/A)
+ ..()
+ if(prob(SYMPTOM_ACTIVATION_PROB))
+ var/mob/living/M = A.affected_mob
+ switch(A.stage)
+ if(4, 5)
+ Heal(M)
+ return
+
+/datum/symptom/heal/proc/Heal(var/mob/living/M)
+
+ var/get_damage = rand(1, 2)
+ M.adjustToxLoss(-get_damage)
+ return 1
\ No newline at end of file
diff --git a/code/datums/diseases/advance/symptoms/shivering.dm b/code/datums/diseases/advance/symptoms/shivering.dm
index ba7c4d0c870..e87b395b13a 100644
--- a/code/datums/diseases/advance/symptoms/shivering.dm
+++ b/code/datums/diseases/advance/symptoms/shivering.dm
@@ -21,7 +21,7 @@ Bonus
stealth = 0
resistance = 2
stage_speed = 2
- transmittable = 1
+ transmittable = 2
level = 2
/datum/symptom/shivering/Activate(var/datum/disease/advance/A)
@@ -29,6 +29,7 @@ Bonus
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/carbon/M = A.affected_mob
M << "[pick("You feel cold.", "You start shaking from the cold.")]"
- M.bodytemperature -= 20 * A.stage
+ if(M.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT)
+ M.bodytemperature = min(M.bodytemperature - (20 * A.stage), BODYTEMP_COLD_DAMAGE_LIMIT + 1)
return
diff --git a/code/datums/diseases/advance/symptoms/sneeze.dm b/code/datums/diseases/advance/symptoms/sneeze.dm
index a745ae26db9..155e71839a4 100644
--- a/code/datums/diseases/advance/symptoms/sneeze.dm
+++ b/code/datums/diseases/advance/symptoms/sneeze.dm
@@ -20,9 +20,9 @@ Bonus
name = "Sneezing"
stealth = -2
- resistance = 2
+ resistance = 3
stage_speed = 0
- transmittable = 3
+ transmittable = 4
level = 1
/datum/symptom/sneeze/Activate(var/datum/disease/advance/A)
diff --git a/code/datums/diseases/advance/symptoms/symptoms.dm b/code/datums/diseases/advance/symptoms/symptoms.dm
index da2109c81e0..349809b973e 100644
--- a/code/datums/diseases/advance/symptoms/symptoms.dm
+++ b/code/datums/diseases/advance/symptoms/symptoms.dm
@@ -25,7 +25,14 @@ var/global/const/SYMPTOM_ACTIVATION_PROB = 3
return
CRASH("We couldn't assign an ID!")
-
-/datum/symptom/proc/Activate(var/mob/living/M, var/stage)
+// Called when processing of the advance disease, which holds this symptom, starts.
+/datum/symptom/proc/Start(var/datum/disease/advance/A)
+ return
+
+// Called when the advance disease is going to be deleted or when the advance disease stops processing.
+/datum/symptom/proc/End(var/datum/disease/advance/A)
+ return
+
+/datum/symptom/proc/Activate(var/datum/disease/advance/A)
return
diff --git a/code/datums/diseases/advance/symptoms/voice_change.dm b/code/datums/diseases/advance/symptoms/voice_change.dm
new file mode 100644
index 00000000000..655cbc65c10
--- /dev/null
+++ b/code/datums/diseases/advance/symptoms/voice_change.dm
@@ -0,0 +1,54 @@
+/*
+//////////////////////////////////////
+
+Voice Change
+
+ Very Very noticable.
+ Lowers resistance considerably.
+ Decreases stage speed.
+ Reduced transmittable.
+ Fatal Level.
+
+Bonus
+ Changes the voice of the affected mob. Causing confusion in communication.
+
+//////////////////////////////////////
+*/
+
+/datum/symptom/voice_change
+
+ name = "Voice Change"
+ stealth = -2
+ resistance = -3
+ stage_speed = -3
+ transmittable = -1
+ level = 6
+
+/datum/symptom/voice_change/Activate(var/datum/disease/advance/A)
+ ..()
+ if(prob(SYMPTOM_ACTIVATION_PROB))
+
+ var/mob/living/carbon/M = A.affected_mob
+ switch(A.stage)
+ if(1, 2, 3, 4)
+ M << "[pick("Your throat hurts.", "You clear your throat.")]"
+ else
+ if(ishuman(M))
+ var/mob/living/carbon/human/H = M
+ var/random_name = ""
+ switch(H.gender)
+ if(MALE)
+ random_name = pick(first_names_male)
+ else
+ random_name = pick(first_names_female)
+ random_name += " [pick(last_names)]"
+ H.SetSpecialVoice(random_name)
+
+ return
+
+/datum/symptom/voice_change/End(var/datum/disease/advance/A)
+ ..()
+ if(ishuman(A.affected_mob))
+ var/mob/living/carbon/human/H = A.affected_mob
+ H.UnsetSpecialVoice()
+ return
diff --git a/code/datums/diseases/advance/symptoms/vomit.dm b/code/datums/diseases/advance/symptoms/vomit.dm
index d97ca858f9b..1fe08646e88 100644
--- a/code/datums/diseases/advance/symptoms/vomit.dm
+++ b/code/datums/diseases/advance/symptoms/vomit.dm
@@ -30,7 +30,7 @@ Bonus
/datum/symptom/vomit/Activate(var/datum/disease/advance/A)
..()
- if(prob(SYMPTOM_ACTIVATION_PROB))
+ if(prob(SYMPTOM_ACTIVATION_PROB / 2))
var/mob/living/M = A.affected_mob
switch(A.stage)
if(1, 2, 3, 4)
@@ -42,7 +42,6 @@ Bonus
/datum/symptom/vomit/proc/Vomit(var/mob/living/M)
- M.Stun(5)
M.visible_message("[M] vomits on the floor!")
M.nutrition -= 20
@@ -82,7 +81,7 @@ Bonus
/datum/symptom/vomit/blood/Vomit(var/mob/living/M)
- M.Stun(5)
+ M.Stun(1)
M.visible_message("[M] vomits on the floor!")
// They lose blood and health.
diff --git a/code/datums/diseases/advance/symptoms/weight.dm b/code/datums/diseases/advance/symptoms/weight.dm
index db05bae5deb..4abf89240b5 100644
--- a/code/datums/diseases/advance/symptoms/weight.dm
+++ b/code/datums/diseases/advance/symptoms/weight.dm
@@ -112,7 +112,7 @@ Bonus
if(prob(SYMPTOM_ACTIVATION_PROB))
var/mob/living/M = A.affected_mob
switch(A.stage)
- if(5)
+ if(4, 5)
M.overeatduration = 0
M.nutrition = 400
diff --git a/code/datums/diseases/retrovirus.dm b/code/datums/diseases/retrovirus.dm
index 4230547f5d1..9ab69e217a8 100644
--- a/code/datums/diseases/retrovirus.dm
+++ b/code/datums/diseases/retrovirus.dm
@@ -19,6 +19,7 @@
agent = "Virus class [pick("A","B","C","D","E","F")][pick("A","B","C","D","E","F")]-[rand(50,300)]"
if(prob(40))
cure_id = list("ryetalyn")
+ cure_list = list("ryetalyn")
else
restcure = 1
diff --git a/code/datums/mind.dm b/code/datums/mind.dm
index 2012ed49c12..3902fb2ce4d 100644
--- a/code/datums/mind.dm
+++ b/code/datums/mind.dm
@@ -331,7 +331,7 @@ datum/mind
else
var/obj_count = 1
for(var/datum/objective/objective in objectives)
- out += "[obj_count]: [objective.explanation_text] Edit Delete
"
+ out += "[obj_count]: [objective.explanation_text] Edit Delete Toggle Completion
"
obj_count++
out += "Add objective
"
@@ -471,9 +471,14 @@ datum/mind
else if (href_list["obj_delete"])
var/datum/objective/objective = locate(href_list["obj_delete"])
- if (!objective) return
+ if(!istype(objective)) return
objectives -= objective
+ else if(href_list["obj_completed"])
+ var/datum/objective/objective = locate(href_list["obj_completed"])
+ if(!istype(objective)) return
+ objective.completed = !objective.completed
+
else if (href_list["revolution"])
switch(href_list["revolution"])
if("clear")
@@ -757,7 +762,7 @@ datum/mind
var/mob/living/carbon/monkey/M = current
if (istype(H))
log_admin("[key_name(usr)] attempting to monkeyize [key_name(current)]")
- message_admins("\blue [key_name_admin(usr)] attempting to monkeyize [key_name_admin(current)]", 1)
+ message_admins("\blue [key_name_admin(usr)] attempting to monkeyize [key_name_admin(current)]")
src = null
M = H.monkeyize()
src = M.mind
@@ -787,7 +792,7 @@ datum/mind
D.cure(0)
sleep(0) //because deleting of virus is doing throught spawn(0)
log_admin("[key_name(usr)] attempting to humanize [key_name(current)]")
- message_admins("\blue [key_name_admin(usr)] attempting to humanize [key_name_admin(current)]", 1)
+ message_admins("\blue [key_name_admin(usr)] attempting to humanize [key_name_admin(current)]")
var/obj/item/weapon/dnainjector/m2h/m2h = new
var/obj/item/weapon/implant/mobfinder = new(M) //hack because humanizing deletes mind --rastaf0
src = null
diff --git a/code/datums/organs/organ_external.dm b/code/datums/organs/organ_external.dm
index 06f46ed1927..7cd6c5cbe3c 100644
--- a/code/datums/organs/organ_external.dm
+++ b/code/datums/organs/organ_external.dm
@@ -701,6 +701,18 @@
obj/item/weapon/organ
icon = 'icons/mob/human_races/r_human.dmi'
+/*
+//Damage will not exceed max_damage using this proc
+//Cannot apply negative damage
+/datum/organ/external/proc/take_damage(brute, burn)
+ if(owner && (owner.status_flags & GODMODE)) return 0 //godmode
+ brute = max(brute,0)
+ burn = max(burn,0)
+
+ var/can_inflict = max_damage - (brute_dam + burn_dam)
+ if(!can_inflict) return 0
+*/
+
obj/item/weapon/organ/New(loc, mob/living/carbon/human/H)
..(loc)
if(!istype(H))
diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm
index c83c138750b..b38cd80d748 100755
--- a/code/datums/supplypacks.dm
+++ b/code/datums/supplypacks.dm
@@ -291,18 +291,17 @@
/* VIRUS2 4LIFE
/obj/item/weapon/reagent_containers/glass/bottle/flu_virion,
/obj/item/weapon/reagent_containers/glass/bottle/cold,
+ /obj/item/weapon/reagent_containers/glass/bottle/epiglottis_virion,
+ /obj/item/weapon/reagent_containers/glass/bottle/liver_enhance_virion,
/obj/item/weapon/reagent_containers/glass/bottle/fake_gbs,
/obj/item/weapon/reagent_containers/glass/bottle/magnitis,
- /obj/item/weapon/reagent_containers/glass/bottle/wizarditis, worse than GBS if anything
- /obj/item/weapon/reagent_containers/glass/bottle/gbs, No. Just no.
/obj/item/weapon/reagent_containers/glass/bottle/pierrot_throat,
/obj/item/weapon/reagent_containers/glass/bottle/brainrot,
+ /obj/item/weapon/reagent_containers/glass/bottle/hullucigen_virion,
/obj/item/weapon/storage/syringes,
- /obj/item/weapon/storage/beakerbox
-*/
- )
- cost = 20
- containertype = /obj/structure/closet/crate/secure/weapon
+ /obj/item/weapon/storage/beakerbox)
+ /obj/item/weapon/reagent_containers/glass/bottle/mutagen)
+ cost = 25 containertype = /obj/structure/closet/crate/secure/weapon
containername = "Virus crate"
access = access_cmo
diff --git a/code/defines/obj.dm b/code/defines/obj.dm
index a8786ed608b..ef02659b30c 100644
--- a/code/defines/obj.dm
+++ b/code/defines/obj.dm
@@ -61,7 +61,6 @@
var/list/bot = new()
var/list/misc = new()
var/list/isactive = new()
-
var/dat = {"