diff --git a/baystation12.dme b/baystation12.dme
index 836d71bd40..22785146a6 100644
--- a/baystation12.dme
+++ b/baystation12.dme
@@ -112,7 +112,7 @@
#define FILE_DIR "code/modules/critters"
#define FILE_DIR "code/modules/critters/hivebots"
#define FILE_DIR "code/modules/customitems"
-#define FILE_DIR "code/modules/detectivework"
+#define FILE_DIR "code/modules/DetectiveWork"
#define FILE_DIR "code/modules/flufftext"
#define FILE_DIR "code/modules/food"
#define FILE_DIR "code/modules/icon generation"
@@ -891,10 +891,10 @@
#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"
-#include "code\modules\detectivework\evidence.dm"
-#include "code\modules\detectivework\footprints_and_rag.dm"
-#include "code\modules\detectivework\scanner.dm"
+#include "code\modules\DetectiveWork\detective_work.dm"
+#include "code\modules\DetectiveWork\evidence.dm"
+#include "code\modules\DetectiveWork\footprints_and_rag.dm"
+#include "code\modules\DetectiveWork\scanner.dm"
#include "code\modules\flufftext\Dreaming.dm"
#include "code\modules\flufftext\Hallucination.dm"
#include "code\modules\flufftext\TextFilters.dm"
@@ -945,6 +945,7 @@
#include "code\modules\mob\living\blob\blob.dm"
#include "code\modules\mob\living\carbon\carbon.dm"
#include "code\modules\mob\living\carbon\carbon_defines.dm"
+#include "code\modules\mob\living\carbon\give.dm"
#include "code\modules\mob\living\carbon\alien\alien.dm"
#include "code\modules\mob\living\carbon\alien\death.dm"
#include "code\modules\mob\living\carbon\alien\powers.dm"
@@ -1062,6 +1063,7 @@
#include "code\modules\mob\living\simple_animal\constructs.dm"
#include "code\modules\mob\living\simple_animal\corgi.dm"
#include "code\modules\mob\living\simple_animal\crab.dm"
+#include "code\modules\mob\living\simple_animal\kobold.dm"
#include "code\modules\mob\living\simple_animal\life.dm"
#include "code\modules\mob\living\simple_animal\mouse.dm"
#include "code\modules\mob\living\simple_animal\mushroom.dm"
diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm
index 03732d6873..434ba91c4f 100644
--- a/code/datums/helper_datums/getrev.dm
+++ b/code/datums/helper_datums/getrev.dm
@@ -14,7 +14,6 @@ var/global/datum/getrev/revdata = new("config/svndir.txt")
var/revhref
proc/abort()
- world.log << "Unable to get revision info."
spawn()
del src
@@ -25,7 +24,7 @@ var/global/datum/getrev/revdata = new("config/svndir.txt")
var/text = file2text(file(filename))
if(!text)
- world.log << "Unable to get [filename] contents, aborting"
+ diary << "Unable to get [filename] contents, aborting"
return abort()
var/list/CL = tg_text2list(text, "\n")
@@ -59,7 +58,6 @@ var/global/datum/getrev/revdata = new("config/svndir.txt")
return abort()
revision = filelist[4]
commiter = filelist[12]
- world.log << "Running TG Revision Number: [revision]."
diary << "Revision info loaded succesfully"
return
return abort()
@@ -86,10 +84,8 @@ client/verb/showrevinfo()
set category = "OOC"
set name = "Show Server Revision"
var/output = "Sorry, the revision info is unavailable."
- if(revdata)
- output = revdata.showInfo()
-
- output += "Current Infomational Settings:
"
- output += "Protect Authority Roles From Tratior: [config.protect_roles_from_antagonist]
"
+ output = file2text("/home/bay12/live/data/gitcommit")
+ output += "Current Infomational Settings:
"
+ output += "Protect Authority Roles From Tratior: [config.protect_roles_from_antagonist]
"
usr << browse(output,"window=revdata");
return
diff --git a/code/defines/obj/vending.dm b/code/defines/obj/vending.dm
index ccbdde555c..6b0043bc42 100755
--- a/code/defines/obj/vending.dm
+++ b/code/defines/obj/vending.dm
@@ -31,7 +31,7 @@
//var/emagged = 0 //Ignores if somebody doesn't have card access to that machine.
var/seconds_electrified = 0 //Shock customers like an airlock.
var/shoot_inventory = 0 //Fire items at customers! We're broken!
- var/shut_up = 0 //Stop spouting those godawful pitches!
+ var/shut_up = 1 //Stop spouting those godawful pitches!
var/extended_inventory = 0 //can we access the hidden inventory?
var/panel_open = 0 //Hacking that vending machine. Gonna get a free candy bar.
var/wires = 15
diff --git a/code/defines/procs/gamehelpers.dm b/code/defines/procs/gamehelpers.dm
index b511c7982f..2d84f38a96 100644
--- a/code/defines/procs/gamehelpers.dm
+++ b/code/defines/procs/gamehelpers.dm
@@ -257,4 +257,9 @@ proc/isInSight(var/atom/A, var/atom/B)
return 1
else
- return 0
+ return 0
+
+proc/check_can_reach(atom/user, atom/target)
+ if(!in_range(user,target))
+ return 0
+ return CanReachThrough(get_turf(user), get_turf(target), target)
\ No newline at end of file
diff --git a/code/game/atom_procs.dm b/code/game/atom_procs.dm
index 3b8a6207db..1ae5f9bcf0 100644
--- a/code/game/atom_procs.dm
+++ b/code/game/atom_procs.dm
@@ -810,7 +810,6 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl
// ------- CLICKED OBJECT EXISTS IN GAME WORLD, DISTANCE FROM PERSON TO OBJECT IS 1 SQUARE OR THEY'RE ON THE SAME SQUARE -------
var/direct = get_dir(usr, src)
- var/obj/item/weapon/dummy/D = new /obj/item/weapon/dummy( usr.loc )
var/ok = 0
if ( (direct - 1) & direct)
@@ -842,35 +841,12 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl
var/check_1 = 0
var/check_2 = 0
- if(step_to(D, Step_1))
- check_1 = 1
- for(var/obj/border_obstacle in Step_1)
- if(border_obstacle.flags & ON_BORDER)
- if(!border_obstacle.CheckExit(D, src))
- check_1 = 0
- // ------- YOU TRIED TO CLICK ON AN ITEM THROUGH A WINDOW (OR SIMILAR THING THAT LIMITS ON BORDERS) ON ONE OF THE DIRECITON TILES -------
- for(var/obj/border_obstacle in get_turf(src))
- if((border_obstacle.flags & ON_BORDER) && (src != border_obstacle))
- if(!border_obstacle.CanPass(D, D.loc, 1, 0))
- // ------- YOU TRIED TO CLICK ON AN ITEM THROUGH A WINDOW (OR SIMILAR THING THAT LIMITS ON BORDERS) ON THE TILE YOU'RE ON -------
- check_1 = 0
+ check_1 = CanReachThrough(get_turf(usr), Step_1, src) && CanReachThrough(Step_1, get_turf(src), src)
- D.loc = usr.loc
- if(step_to(D, Step_2))
- check_2 = 1
+ check_2 = CanReachThrough(get_turf(usr), Step_2, src) && CanReachThrough(Step_2, get_turf(src), src)
- for(var/obj/border_obstacle in Step_2)
- if(border_obstacle.flags & ON_BORDER)
- if(!border_obstacle.CheckExit(D, src))
- check_2 = 0
- for(var/obj/border_obstacle in get_turf(src))
- if((border_obstacle.flags & ON_BORDER) && (src != border_obstacle))
- if(!border_obstacle.CanPass(D, D.loc, 1, 0))
- check_2 = 0
+ ok = (check_1 || check_2)
-
- if(check_1 || check_2)
- ok = 1
// ------- YOU CAN REACH THE ITEM THROUGH AT LEAST ONE OF THE TWO DIRECTIONS. GOOD. -------
/*
@@ -883,29 +859,11 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl
*/
else
// ------- OBJECT IS ON A CARDINAL TILE (NORTH, SOUTH, EAST OR WEST OR THE TILE YOU'RE ON) -------
- if(loc == usr.loc)
- ok = 1
- // ------- OBJECT IS ON THE SAME TILE AS YOU -------
- else
- ok = 1
-
- //Now, check objects to block exit that are on the border
- for(var/obj/border_obstacle in usr.loc)
- if(border_obstacle.flags & ON_BORDER)
- if(!border_obstacle.CheckExit(D, src))
- ok = 0
-
- //Next, check objects to block entry that are on the border
- for(var/obj/border_obstacle in get_turf(src))
- if((border_obstacle.flags & ON_BORDER) && (src != border_obstacle))
- if(!border_obstacle.CanPass(D, D.loc, 1, 0))
- ok = 0
+ ok = CanReachThrough(get_turf(usr), get_turf(src), src)
/*
See the previous More info, for... more info...
*/
- del(D)
- // ------- DUMMY OBJECT'S SERVED IT'S PURPOSE, IT'S REWARDED WITH A SWIFT DELETE -------
if (!( ok ))
// ------- TESTS ABOVE DETERMINED YOU CANNOT REACH THE TILE -------
return 0
@@ -1020,6 +978,43 @@ var/using_new_click_proc = 0 //TODO ERRORAGE (This is temporary, while the DblCl
usr.next_move = world.time + 6
return
+////////////////////////////////////////
+///IMPORTANT: CACHE FOR DUMMY OBJECTS///
+//Used to cut down on stupid deletions//
+////////////////////////////////////////
+var/list/DummyCache = list()
+
+/proc/CanReachThrough(turf/srcturf, turf/targetturf, atom/target)
+
+ var/obj/item/weapon/dummy/D = locate() in DummyCache
+ if(!D)
+ D = new /obj/item/weapon/dummy( srcturf )
+ else
+ DummyCache.Remove(D)
+ D.loc = srcturf
+
+ if(targetturf.density && targetturf != get_turf(target))
+ return 0
+
+ //Now, check objects to block exit that are on the border
+ for(var/obj/border_obstacle in srcturf)
+ if(border_obstacle.flags & ON_BORDER)
+ if(!border_obstacle.CheckExit(D, targetturf))
+ D.loc = null
+ DummyCache.Add(D)
+ return 0
+
+ //Next, check objects to block entry that are on the border
+ for(var/obj/border_obstacle in targetturf)
+ if((border_obstacle.flags & ON_BORDER) && (target != border_obstacle))
+ if(!border_obstacle.CanPass(D, srcturf, 1, 0))
+ D.loc = null
+ DummyCache.Add(D)
+ return 0
+
+ D.loc = null
+ DummyCache.Add(D)
+ return 1
/atom/proc/ShiftClick(var/mob/M as mob)
diff --git a/code/game/jobs/whitelist.dm b/code/game/jobs/whitelist.dm
index 009a184c78..b47da0e77d 100644
--- a/code/game/jobs/whitelist.dm
+++ b/code/game/jobs/whitelist.dm
@@ -30,6 +30,8 @@ proc/load_alienwhitelist()
for (var/s in alien_whitelist)
if(findtext(s,"[M.ckey] - [species]"))
return 1
+ if(findtext(s,"[M.ckey] - All"))
+ return 1
return 0
#undef WHITELISTFILE
\ No newline at end of file
diff --git a/code/game/objects/items/item.dm b/code/game/objects/items/item.dm
index 280148e7d5..901c22dbeb 100755
--- a/code/game/objects/items/item.dm
+++ b/code/game/objects/items/item.dm
@@ -172,6 +172,9 @@
return
+mob/proc/flash_weak_pain()
+ flick("weak_pain",pain)
+
/obj/item/proc/attack(mob/living/M as mob, mob/living/user as mob, def_zone)
if (!istype(M)) // not sure if this is the right thing...
@@ -182,19 +185,41 @@
messagesource = M:container
if (src.hitsound)
playsound(src.loc, hitsound, 50, 1, -1)
+ M.flash_weak_pain()
/////////////////////////
user.lastattacked = M
M.lastattacker = user
+ var/power = src.force
+
+ // EXPERIMENTAL: scale power and time to the weight class
+ if(w_class >= 4.0 && !istype(src,/obj/item/weapon/melee/energy/blade)) // eswords are an exception, they only have a w_class of 4 to not fit into pockets
+ power = power * 2.5
+
+ user.visible_message("\red [user.name] swings at [M.name] with \the [src]!")
+ user.next_move = max(user.next_move, world.time + 30)
+
+ // if the mob didn't move, he has a 100% chance to hit(given the enemy also didn't move)
+ // otherwise, the chance to hit is lower
+ var/unmoved = 0
+ spawn
+ unmoved = do_after(user, 4)
+ sleep(4)
+ if( (!unmoved && !prob(70)) || (get_dist(user, M) != 1 && user != M))
+ user.visible_message("\red [user.name] misses with \the [src]!")
+ return
+
+
user.attack_log += "\[[time_stamp()]\] Attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(src.damtype)])"
M.attack_log += "\[[time_stamp()]\] Attacked by [user.name] ([user.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(src.damtype)])"
+ log_admin("ATTACK: [user] ([user.ckey]) attacked [M] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(src.damtype)]")
+ msg_admin_attack("ATTACK: [user] ([user.ckey]) attacked [M] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(src.damtype)]")
log_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)]) (DAMTYE: [uppertext(src.damtype)])" )
//spawn(1800) // this wont work right
// M.lastattacker = null
/////////////////////////
- var/power = src.force
if((HULK in user.mutations) || (SUPRSTR in user.augmentations))
power *= 2
diff --git a/code/game/objects/stool.dm b/code/game/objects/stool.dm
index 2ede6de660..448c4829ab 100644
--- a/code/game/objects/stool.dm
+++ b/code/game/objects/stool.dm
@@ -19,6 +19,13 @@
del(src)
/obj/structure/stool/attackby(obj/item/weapon/W as obj, mob/user as mob)
+ if(istype(W, /obj/item/weapon/screwdriver))
+ if (src.anchored)
+ src.anchored = 0
+ user << "\blue You unfasten [src] from the floor."
+ else
+ src.anchored = 1
+ user << "\blue You fasten [src] to the floor."
if(istype(W, /obj/item/weapon/wrench))
playsound(src.loc, 'sound/items/Ratchet.ogg', 50, 1)
new /obj/item/stack/sheet/metal(src.loc)
@@ -73,7 +80,7 @@
"You hear metal clanking")
else
buckled_mob.visible_message(\
- "\blue [buckled_mob.name] unbuckled himself!",\
+ "\blue [buckled_mob.name] unbuckles!",\
"You unbuckle yourself from [src].",\
"You hear metal clanking")
unbuckle()
@@ -108,6 +115,9 @@
/obj/structure/stool/bed/MouseDrop_T(mob/M as mob, mob/user as mob)
if(!istype(M)) return
+ if(issimpleanimal(user))
+ user << "\red You are unable to work the complex mechanisms of a buckle!"
+ return
buckle_mob(M, user)
return
@@ -164,6 +174,18 @@
icon_state = "down"
anchored = 0
+/obj/item/roller
+ name = "roller bed"
+ desc = "A collapsed roller bed that can be carried around."
+ icon = 'rollerbed.dmi'
+ icon_state = "folded"
+ w_class = 4.0 // Can't be put in backpacks. Oh well.
+
+ attack_self(mob/user)
+ var/obj/structure/stool/bed/roller/R = new /obj/structure/stool/bed/roller(user.loc)
+ R.add_fingerprint(user)
+ del(src)
+
/obj/structure/stool/bed/roller/Move()
..()
if(buckled_mob)
@@ -191,3 +213,15 @@
icon_state = "down"
..()
return
+
+/obj/structure/stool/bed/roller/MouseDrop(over_object, src_location, over_location)
+ ..()
+ if((over_object == usr && (in_range(src, usr) || usr.contents.Find(src))))
+ if(!ishuman(usr)) return
+ if(buckled_mob) return 0
+ visible_message("\The [usr] collapses \the [src.name]")
+ new/obj/item/roller(get_turf(src))
+ spawn(0)
+ del(src)
+ return
+
diff --git a/code/game/objects/storage/backpack.dm b/code/game/objects/storage/backpack.dm
index 94a9642ac9..dfd37287e6 100644
--- a/code/game/objects/storage/backpack.dm
+++ b/code/game/objects/storage/backpack.dm
@@ -14,6 +14,8 @@
if("l_hand")
M.u_equip(src)
M.put_in_l_hand(src)
+ M.update_inv_l_hand()
+ M.update_inv_r_hand()
src.add_fingerprint(usr)
return
if(over_object == usr && in_range(src, usr) || usr.contents.Find(src))
diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm
index 296d80680d..b6b6598195 100644
--- a/code/modules/assembly/signaler.dm
+++ b/code/modules/assembly/signaler.dm
@@ -20,6 +20,7 @@
var/delay = 0
var/airlock_wire = null
var/datum/radio_frequency/radio_connection
+ var/deadman = 0
proc
signal()
@@ -126,6 +127,8 @@
A.pulse(src.airlock_wire)
else if(holder)
holder.process_activation(src, 1, 0)
+ else
+ ..()
return 1
@@ -149,3 +152,24 @@
frequency = new_frequency
radio_connection = radio_controller.add_object(src, frequency, RADIO_CHAT)
return
+
+ process()
+ if(!deadman)
+ processing_objects.Remove(src)
+ var/mob/M = src.loc
+ if(!M || !ismob(M))
+ if(prob(5))
+ signal()
+ deadman = 0
+ processing_objects.Remove(src)
+ else if(prob(5))
+ M.visible_message("[M]'s finger twitches a bit over [src]'s signal button!")
+ return
+
+ verb/deadman_it()
+ set src in usr
+ set name = "Threaten to push the button!"
+ set desc = "BOOOOM!"
+ deadman = 1
+ processing_objects.Add(src)
+ usr.visible_message("\red [usr] moves their finger over [src]'s signal button...")
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index 5bc421dee4..12cc5a26c8 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -3,14 +3,21 @@
//Returns the thing in our active hand
/mob/proc/get_active_hand()
- if(hand) return l_hand
- else return r_hand
+ if(issilicon(src))
+ if(isrobot(src))
+ if(src:module_active)
+ return src:module_active
+ else
+ if(hand) return l_hand
+ else return r_hand
//Returns the thing in our inactive hand
/mob/proc/get_inactive_hand()
if(hand) return r_hand
else return l_hand
+/mob/proc/equipped()
+ return get_active_hand()
//Puts the item into your l_hand if possible and calls all necessary triggers/updates. returns 1 on success.
/mob/proc/put_in_l_hand(var/obj/item/W)
@@ -57,8 +64,14 @@
//This is probably the main one you need to know :)
/mob/proc/put_in_hands(var/obj/item/W)
if(!W) return 0
- if(put_in_active_hand(W)) return 1
- else if(put_in_inactive_hand(W)) return 1
+ if(put_in_active_hand(W))
+ update_inv_l_hand()
+ update_inv_r_hand()
+ return 1
+ else if(put_in_inactive_hand(W))
+ update_inv_l_hand()
+ update_inv_r_hand()
+ return 1
else
W.loc = get_turf(src)
W.layer = initial(W.layer)
diff --git a/code/modules/mob/living/carbon/give.dm b/code/modules/mob/living/carbon/give.dm
index 0b8c061419..bdad53f2ca 100644
--- a/code/modules/mob/living/carbon/give.dm
+++ b/code/modules/mob/living/carbon/give.dm
@@ -47,7 +47,10 @@ mob/living/carbon/verb/give()
I.loc = src
I.layer = 20
I.add_fingerprint(src)
- src.update_clothing()
+ src.update_inv_l_hand()
+ src.update_inv_r_hand()
+ usr.update_inv_l_hand()
+ usr.update_inv_r_hand()
src.visible_message("[usr.name] handed \the [I.name] to [src.name].")
if("No")
src.visible_message("[usr.name] tried to hand [I.name] to [src.name] but [src.name] didn't want it.")
@@ -78,7 +81,10 @@ mob/living/carbon/verb/give()
I.loc = src
I.layer = 20
I.add_fingerprint(src)
- src.update_clothing()
+ src.update_inv_l_hand()
+ src.update_inv_r_hand()
+ usr.update_inv_l_hand()
+ usr.update_inv_r_hand()
src.visible_message("[usr.name] handed \the [I.name] to [src.name].")
if("No")
src.visible_message("[usr.name] tried to hand [I.name] to [src.name] but [src.name] didn't want it.")
diff --git a/code/modules/mob/living/carbon/human/hud.dm b/code/modules/mob/living/carbon/human/hud.dm
index 4d017d14d5..b8d01a4a20 100644
--- a/code/modules/mob/living/carbon/human/hud.dm
+++ b/code/modules/mob/living/carbon/human/hud.dm
@@ -587,6 +587,12 @@
mymob.flash.screen_loc = "1,1 to 15,15"
mymob.flash.layer = 17
+ mymob.pain = new /obj/screen( null )
+ mymob.pain.icon_state = "blank"
+ mymob.pain.name = "pain"
+ mymob.pain.screen_loc = "1,1 to 15,15"
+ mymob.pain.layer = 17
+
/*
mymob.hands = new /obj/screen( null )
mymob.hands.icon = ui_style
@@ -704,7 +710,7 @@
mymob.client.screen = null
//, mymob.i_select, mymob.m_select
- mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.pressure, mymob.toxin, mymob.bodytemp, mymob.internals, mymob.fire, mymob.healths, mymob.nutrition_icon, mymob.pullin, mymob.blind, mymob.flash, mymob.damageoverlay) //, mymob.hands, mymob.rest, mymob.sleep) //, mymob.mach )
+ mymob.client.screen += list( mymob.pain, mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.pressure, mymob.toxin, mymob.bodytemp, mymob.internals, mymob.fire, mymob.healths, mymob.nutrition_icon, mymob.pullin, mymob.blind, mymob.flash, mymob.damageoverlay) //, mymob.hands, mymob.rest, mymob.sleep) //, mymob.mach )
mymob.client.screen += src.adding + src.hotkeybuttons
inventory_shown = 0;
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 46c875a9f9..314922c5aa 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -182,7 +182,7 @@ Please contact me on #coderbus IRC. ~Carn x
/mob/living/carbon/human/proc/update_body(var/update_icons=1)
if(stand_icon) del(stand_icon)
if(lying_icon) del(lying_icon)
- if(dna && dna.mutantrace) return
+// if(dna && dna.mutantrace) return
var/husk = (HUSK in src.mutations)
var/fat = (FAT in src.mutations)
var/g = "m"
@@ -233,7 +233,8 @@ Please contact me on #coderbus IRC. ~Carn x
overlays_standing[HAIR_LAYER] = null
//mutants don't have hair. masks and helmets can obscure our hair too.
- if( (dna && dna.mutantrace) || (head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR)) )
+ //BS12 EDIT - Mutants can have hair too!
+ if( (head && (head.flags & BLOCKHAIR)) || (wear_mask && (wear_mask.flags & BLOCKHAIR)) )
if(update_icons) update_icons()
return
diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm
index c0af35f8ca..74ce8062ee 100644
--- a/code/modules/mob/living/living_defense.dm
+++ b/code/modules/mob/living/living_defense.dm
@@ -44,6 +44,14 @@
src << "\blue Your [C.name] was disrupted!"
Stun(2)
+ flash_weak_pain()
+
+ if(istype(equipped(),/obj/item/device/assembly/signaler))
+ var/obj/item/device/assembly/signaler/signaler = equipped()
+ if(signaler.deadman && prob(80))
+ src.visible_message("\red [src] triggers their deadman's switch!")
+ signaler.signal()
+
var/absorb = run_armor_check(def_zone, P.flag)
if(absorb >= 2)
P.on_hit(src,2)
diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm
index 7aebd6ef67..d66ac31363 100644
--- a/code/modules/mob/living/say.dm
+++ b/code/modules/mob/living/say.dm
@@ -141,6 +141,37 @@ var/list/department_radio_keys = list(
if (!message)
return
+ //work out if we're speaking skrell or not
+ var/is_speaking_skrell = 0
+
+ if(copytext(message, 1, 3) == ":k" || copytext(message, 1, 3) == ":K")
+ message = copytext(message, 3)
+ if(skrell_talk_understand || universal_speak)
+ is_speaking_skrell = 1
+
+ //work out if we're speaking soghun or not
+ var/is_speaking_soghun = 0
+ if(copytext(message, 1, 3) == ":o" || copytext(message, 1, 3) == ":O")
+ message = copytext(message, 3)
+ if(soghun_talk_understand || universal_speak)
+ is_speaking_soghun = 1
+
+ //work out if we're speaking tajaran or not
+ var/is_speaking_tajaran = 0
+ if(copytext(message, 1, 3) == ":j" || copytext(message, 1, 3) == ":J")
+ message = copytext(message, 3)
+ if(tajaran_talk_understand || universal_speak)
+ is_speaking_soghun = 1
+
+// if( !message_mode && (disease_symptoms & DISEASE_WHISPER))
+// message_mode = "whisper"
+
+ if(src.stunned > 2 /*|| (traumatic_shock > 61 && prob(50))*/)
+ message_mode = "" //Stunned people shouldn't be able to physically turn on their radio/hold down the button to speak into it
+
+
+ message = capitalize(message) //capitalize the first letter of what they actually say
+
// :downs:
if (getBrainLoss() >= 60)
message = dd_replacetext(message, " am ", " ")
@@ -156,10 +187,12 @@ var/list/department_radio_keys = list(
message = uppertext(message)
message += "[stutter(pick("!", "!!", "!!!"))]"
if(!stuttering && prob(15))
- message = stutter(message)
+ message = NewStutter(message,stunned)
if (stuttering)
- message = stutter(message)
+ message = NewStutter(message,stunned)
+ if (slurring)
+ message = slur(message)
/* //qw do not have beesease atm.
if(virus)
@@ -283,6 +316,13 @@ var/list/department_radio_keys = list(
var/list/V = view(message_range, T)
var/list/W = V
+ var/list/eavesdroppers = get_mobs_in_view(7, src)
+ for(var/mob/M in listening)
+ eavesdroppers.Remove(M)
+ for(var/mob/M in eavesdroppers)
+ if(M.stat || !M.client || istype(M, /mob/living/silicon/pai) || M == src)
+ eavesdroppers.Remove(M)
+
for (var/obj/O in ((W | contents)-used_radios))
W |= O
@@ -312,17 +352,24 @@ var/list/department_radio_keys = list(
var/list/heard_a = list() // understood us
var/list/heard_b = list() // didn't understand us
- for (var/M in listening)
+ for (var/mob/M in listening) //My god this is to terrible and hacky - Erthilo
if(hascall(M,"say_understands"))
- if (M:say_understands(src))
+ if (M:say_understands(src) && !is_speaking_skrell && !is_speaking_soghun && !is_speaking_tajaran) //This could probably be merged into say_understands(), but I'm too lazy
+ heard_a += M
+ else if(is_speaking_skrell && (M.skrell_talk_understand || M.universal_speak))
+ heard_a += M
+ else if(is_speaking_soghun && (M.soghun_talk_understand || M.universal_speak))
+ heard_a += M
+ else if(is_speaking_tajaran && (M.tajaran_talk_understand || M.universal_speak))
heard_a += M
else
heard_b += M
+ var/speech_bubble_test = say_test(message)
+ var/image/speech_bubble = image('icons/mob/talk.dmi',src,"h[speech_bubble_test]")
var/rendered = null
if (length(heard_a))
- var/message_a = say_quote(message)
-
+ var/message_a = say_quote(message,is_speaking_soghun,is_speaking_skrell,is_speaking_tajaran)
if (italics)
message_a = "[message_a]"
if (!istype(src, /mob/living/carbon/human))
@@ -335,10 +382,17 @@ var/list/department_radio_keys = list(
else
rendered = "[real_name][alt_name] [message_a]"
- for (var/M in heard_a)
+ for (var/mob/M in heard_a)
+
+ M.show_message(rendered, 2)
+ M << speech_bubble
+ spawn(30) del(speech_bubble)
+ //spawn(30) del(speech_bubble)
+
+/* for (var/M in heard_a)
if(hascall(M,"show_message"))
M:show_message(rendered, 2)
-
+*/
if (length(heard_b))
var/message_b
@@ -346,13 +400,17 @@ var/list/department_radio_keys = list(
message_b = voice_message
else
message_b = stars(message)
- message_b = say_quote(message_b)
+ message_b = say_quote(message_b,is_speaking_soghun,is_speaking_skrell,is_speaking_tajaran)
if (italics)
message_b = "[message_b]"
rendered = "[voice_name] [message_b]"
+ for (var/mob/M in heard_b)
+ M.show_message(rendered, 2)
+ M << speech_bubble
+ spawn(30) del(speech_bubble)
for (var/M in heard_b)
if(hascall(M,"show_message"))
@@ -379,7 +437,16 @@ var/list/department_radio_keys = list(
del(B)
*/
+ if (length(eavesdroppers))
+
+ for (var/mob/M in eavesdroppers)
+ M << "\blue [src] speaks into their radio..."
+ M << speech_bubble
+ spawn(30) del(speech_bubble)
log_say("[name]/[key] : [message]")
+
+/obj/effect/speech_bubble
+ var/mob/parent
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/cat.dm b/code/modules/mob/living/simple_animal/cat.dm
index db4d6f96f7..d858a200e1 100644
--- a/code/modules/mob/living/simple_animal/cat.dm
+++ b/code/modules/mob/living/simple_animal/cat.dm
@@ -1,7 +1,7 @@
//Cat
/mob/living/simple_animal/cat
name = "cat"
- desc = "Kitty!!"
+ desc = "A domesticated, feline pet. Has a tendency to adopt crewmembers."
icon_state = "cat"
icon_living = "cat"
icon_dead = "cat_dead"
@@ -16,31 +16,31 @@
response_help = "pets the"
response_disarm = "gently pushes aside the"
response_harm = "kicks the"
-
-//RUNTIME IS ALIVE! SQUEEEEEEEE~
-/mob/living/simple_animal/cat/Runtime
- name = "Runtime"
- desc = ""
- response_help = "pets"
- response_disarm = "gently pushes aside"
- response_harm = "kicks"
var/turns_since_scan = 0
var/mob/living/simple_animal/mouse/movement_target
+ min_oxy = 16 //Require atleast 16kPA oxygen
+ minbodytemp = 223 //Below -50 Degrees Celcius
+ maxbodytemp = 323 //Above 50 Degrees Celcius
-/mob/living/simple_animal/cat/Runtime/Life()
+/mob/living/simple_animal/cat/Life()
//MICE!
if((src.loc) && isturf(src.loc))
if(!stat && !resting && !buckled)
for(var/mob/living/simple_animal/mouse/M in view(1,src))
if(!M.stat)
M.splat()
- emote("splats \the [M]")
+ emote(pick("\red splats the [M]!","\red toys with the [M]","worries the [M]"))
movement_target = null
stop_automated_movement = 0
break
..()
+ for(var/mob/living/simple_animal/mouse/snack in oview(src, 3))
+ if(prob(15))
+ emote(pick("hisses and spits!","mrowls fiercely!","eyes [snack] hungrily."))
+ break
+
if(!stat && !resting && !buckled)
turns_since_scan++
if(turns_since_scan > 5)
@@ -58,4 +58,11 @@
break
if(movement_target)
stop_automated_movement = 1
- walk_to(src,movement_target,0,3)
\ No newline at end of file
+ walk_to(src,movement_target,0,3)
+
+//RUNTIME IS ALIVE! SQUEEEEEEEE~
+/mob/living/simple_animal/cat/Runtime
+ name = "Runtime"
+ desc = "Its fur has the look and feel of velvet, and it's tail quivers occasionally."
+
+
diff --git a/code/modules/mob/living/simple_animal/corgi.dm b/code/modules/mob/living/simple_animal/corgi.dm
index c073a5f5ec..2edd2a8a52 100644
--- a/code/modules/mob/living/simple_animal/corgi.dm
+++ b/code/modules/mob/living/simple_animal/corgi.dm
@@ -26,6 +26,7 @@
regenerate_icons()
/mob/living/simple_animal/corgi/show_inv(mob/user as mob)
+ /*
user.machine = src
if(user.stat) return
@@ -41,6 +42,7 @@
user << browse(dat, text("window=mob[];size=325x500", name))
onclose(user, "mob[real_name]")
+ */
return
/mob/living/simple_animal/corgi/attackby(var/obj/item/O as obj, var/mob/user as mob)
@@ -313,6 +315,10 @@
dir = i
sleep(1)
+/obj/item/weapon/reagent_containers/food/snacks/meat/corgi
+ name = "Corgi meat"
+ desc = "Tastes like... well you know..."
+
/mob/living/simple_animal/corgi/Ian/Bump(atom/movable/AM as mob|obj, yes)
spawn( 0 )
diff --git a/code/modules/mob/living/simple_animal/crab.dm b/code/modules/mob/living/simple_animal/crab.dm
index c242ca03f0..418e4b6858 100644
--- a/code/modules/mob/living/simple_animal/crab.dm
+++ b/code/modules/mob/living/simple_animal/crab.dm
@@ -1,7 +1,7 @@
//Look Sir, free crabs!
/mob/living/simple_animal/crab
name = "crab"
- desc = "Free crabs!"
+ desc = "A hard-shelled crustacean. Seems quite content to lounge around all the time."
icon_state = "crab"
icon_living = "crab"
icon_dead = "crab_dead"
diff --git a/code/modules/mob/living/simple_animal/life.dm b/code/modules/mob/living/simple_animal/life.dm
index 5e9d549691..d4694514fe 100644
--- a/code/modules/mob/living/simple_animal/life.dm
+++ b/code/modules/mob/living/simple_animal/life.dm
@@ -389,4 +389,7 @@
health -= 30
/mob/living/simple_animal/adjustBruteLoss(damage)
- health -= damage
\ No newline at end of file
+ health -= damage
+
+/proc/issimpleanimal(var/mob/AM)
+ return istype(AM,/mob/living/simple_animal)
\ No newline at end of file
diff --git a/code/modules/mob/living/simple_animal/mouse.dm b/code/modules/mob/living/simple_animal/mouse.dm
index 8d00fe8ca3..cf13f9138f 100644
--- a/code/modules/mob/living/simple_animal/mouse.dm
+++ b/code/modules/mob/living/simple_animal/mouse.dm
@@ -1,13 +1,14 @@
/mob/living/simple_animal/mouse
name = "mouse"
- desc = "It's a nasty, ugly, evil, disease-ridden rodent."
+ real_name = "mouse"
+ desc = "It's a small, disease-ridden rodent."
icon_state = "mouse_gray"
icon_living = "mouse_gray"
icon_dead = "mouse_gray_dead"
speak = list("Squeek!","SQUEEK!","Squeek?")
- speak_emote = list("squeeks")
- emote_hear = list("squeeks")
- emote_see = list("runs in a circle", "shakes")
+ speak_emote = list("squeeks","squeeks","squiks")
+ emote_hear = list("squeeks","squeaks","squiks")
+ emote_see = list("runs in a circle", "shakes", "scritches at something")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
@@ -19,6 +20,16 @@
response_harm = "splats the"
density = 0
var/color //brown, gray and white, leave blank for random
+ layer = 2.5 //so they can hide under objects
+ min_oxy = 16 //Require atleast 16kPA oxygen
+ minbodytemp = 223 //Below -50 Degrees Celcius
+ maxbodytemp = 323 //Above 50 Degrees Celcius
+
+/mob/living/simple_animal/mouse/Life()
+ ..()
+ if(!stat && prob(speak_chance))
+ for(var/mob/M in view())
+ M << 'sound/effects/mousesqueek.ogg'
/mob/living/simple_animal/mouse/white
color = "white"
@@ -38,6 +49,7 @@
icon_state = "mouse_[color]"
icon_living = "mouse_[color]"
icon_dead = "mouse_[color]_dead"
+ desc = "It's a small [color] rodent, often seen hiding in maintenance areas and making a nuisance of itself."
//TOM IS ALIVE! SQUEEEEEEEE~K :)
/mob/living/simple_animal/mouse/brown/Tom
@@ -54,6 +66,96 @@
src.icon_dead = "mouse_[color]_splat"
src.icon_state = "mouse_[color]_splat"
+//copy paste from alien/larva, if that func is updated please update this one also
+/mob/living/simple_animal/mouse/verb/ventcrawl()
+ set name = "Crawl through Vent"
+ set desc = "Enter an air vent and crawl through the pipe system."
+ set category = "Mouse"
+
+// if(!istype(V,/obj/machinery/atmoalter/siphs/fullairsiphon/air_vent))
+// return
+ var/obj/machinery/atmospherics/unary/vent_pump/vent_found
+ var/welded = 0
+ for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src))
+ if(!v.welded)
+ vent_found = v
+ break
+ else
+ welded = 1
+ if(vent_found)
+ if(vent_found.network&&vent_found.network.normal_members.len)
+ var/list/vents = list()
+ for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members)
+ if(temp_vent.loc == loc)
+ continue
+ vents.Add(temp_vent)
+ var/list/choices = list()
+ for(var/obj/machinery/atmospherics/unary/vent_pump/vent in vents)
+ if(vent.loc.z != loc.z)
+ continue
+ var/atom/a = get_turf(vent)
+ choices.Add(a.loc)
+ var/turf/startloc = loc
+ var/obj/selection = input("Select a destination.", "Duct System") in choices
+ var/selection_position = choices.Find(selection)
+ if(loc==startloc)
+ var/obj/target_vent = vents[selection_position]
+ if(target_vent)
+ for(var/mob/O in oviewers(src, null))
+ if ((O.client && !( O.blinded )))
+ O.show_message(text("[src] scrambles into the ventillation ducts!"), 1)
+ loc = target_vent.loc
+ else
+ src << "\blue You need to remain still while entering a vent."
+ else
+ src << "\blue This vent is not connected to anything."
+ else if(welded)
+ src << "\red That vent is welded."
+ else
+ src << "\blue You must be standing on or beside an air vent to enter it."
+ return
+
+//copy paste from alien/larva, if that func is updated please update this one alsoghost
+/mob/living/simple_animal/mouse/verb/hide()
+ set name = "Hide"
+ set desc = "Allows to hide beneath tables or certain items. Toggled on or off."
+ set category = "Mouse"
+
+ if (layer != TURF_LAYER+0.2)
+ layer = TURF_LAYER+0.2
+ src << text("\blue You are now hiding.")
+ for(var/mob/O in oviewers(src, null))
+ if ((O.client && !( O.blinded )))
+ O << text("[] scurries to the ground!", src)
+ else
+ layer = MOB_LAYER
+ src << text("\blue You have stopped hiding.")
+ for(var/mob/O in oviewers(src, null))
+ if ((O.client && !( O.blinded )))
+ O << text("[] slowly peaks up from the ground...", src)
+
+//make mice fit under tables etc? this was hacky, and not working
+/*
+/mob/living/simple_animal/mouse/Move(var/dir)
+
+ var/turf/target_turf = get_step(src,dir)
+ //CanReachThrough(src.loc, target_turf, src)
+ var/can_fit_under = 0
+ if(target_turf.ZCanPass(get_turf(src),1))
+ can_fit_under = 1
+
+ ..(dir)
+ if(can_fit_under)
+ src.loc = target_turf
+ for(var/d in cardinal)
+ var/turf/O = get_step(T,d)
+ //Simple pass check.
+ if(O.ZCanPass(T, 1) && !(O in open) && !(O in closed) && O in possibles)
+ open += O
+ */
+
+mob/living/simple_animal/mouse/restrained() //Hotfix to stop mice from doing things with MouseDrop
+ return 1
/mob/living/simple_animal/mouse/HasEntered(AM as mob|obj)
if( ishuman(AM) )
diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm
index 2a8e6d2209..872d0071ba 100644
--- a/code/modules/mob/living/simple_animal/parrot.dm
+++ b/code/modules/mob/living/simple_animal/parrot.dm
@@ -2,9 +2,9 @@
name = "\improper Parrot"
desc = "It's a parrot! No dirty words!"
icon = 'icons/mob/mob.dmi'
- icon_state = "cat"
- icon_living = "cat"
- icon_dead = "cat_dead"
+ icon_state = "parrot"
+ icon_living = "parrot"
+ icon_dead = "parrot_dead"
speak = list("Hi","Hello!","Cracker?","BAWWWWK george mellons griffing me")
speak_emote = list("squawks","says","yells")
emote_hear = list("squawks","bawks")
@@ -15,15 +15,22 @@
response_help = "pets the"
response_disarm = "gently moves aside the"
response_harm = "swats the"
+ min_oxy = 16 //Require atleast 16kPA oxygen
+ minbodytemp = 223 //Below -50 Degrees Celcius
+ maxbodytemp = 323 //Above 50 Degrees Celcius
ears = new /obj/item/device/radio/headset/heads/ce()
/mob/living/simple_animal/parrot/DrProfessor
name = "Doctor Professor Parrot, PhD"
desc = "That's the Doctor Professor. He has more degrees than all of the engineering team put together, and has several published papers on quantum cracker theory."
- speak = list(":e Check the singlo, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN RIG SUIT?",":e OH GOD ITS FREE CALL THE SHUTTLE")
+ speak = list(":e Check the singlo, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN RIG SUIT?",":e OH GOD ITS FREE CALL THE SHUTTLE",":e Open secure storage please.",":e I think something happened to the containment field...")
response_harm = "is attacked in the face by"
+/obj/item/weapon/reagent_containers/food/snacks/cracker/
+ name = "Cracker"
+ desc = "It's a salted cracker."
+
/mob/living/simple_animal/parrot/show_inv(mob/user as mob)
user.machine = src
if(user.stat) return
diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm
index a22f570c25..b4980bddd7 100644
--- a/code/modules/mob/mob_defines.dm
+++ b/code/modules/mob/mob_defines.dm
@@ -11,6 +11,7 @@
var/obj/effect/organstructure/organStructure = null
// var/uses_hud = 0
+ var/obj/screen/pain = null
var/obj/screen/flash = null
var/obj/screen/blind = null
var/obj/screen/hands = null
@@ -65,6 +66,7 @@
var/ear_deaf = null //Carbon
var/ear_damage = null //Carbon
var/stuttering = null //Carbon
+ var/slurring = null //Carbon
var/real_name = null
// var/original_name = null //Original name is only used in ghost chat! Depracated, now used bb
var/blinded = null
@@ -226,3 +228,6 @@
var/universal_speak = 0 // Set to 1 to enable the mob to speak to everyone -- TLE
var/robot_talk_understand = 0
var/alien_talk_understand = 0
+ var/skrell_talk_understand = 0
+ var/tajaran_talk_understand = 0
+ var/soghun_talk_understand = 0
diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm
index d5905d608c..5a96d1b10b 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -114,26 +114,37 @@ proc/isorgan(A)
return
/proc/istajaran(A)
- return istype(A, /mob/living/carbon/human/tajaran)
+ if(istype(A, /mob/living/carbon/human))
+ var/mob/living/carbon/human/M = A
+ if(M.dna.mutantrace == "tajaran")
+ return 1
+ return 0
+
+/proc/issoghun(A)
+ if(istype(A, /mob/living/carbon/human))
+ var/mob/living/carbon/human/M = A
+ if(M.dna.mutantrace == "lizard")
+ return 1
+ return 0
+
+/proc/isskrell(A)
+ if(istype(A, /mob/living/carbon/human))
+ var/mob/living/carbon/human/M = A
+ if(M.dna.mutantrace == "skrell")
+ return 1
+ return 0
/proc/check_zone(zone)
- if(!zone) return "chest"
+ if(!zone)
+ return "chest"
switch(zone)
if("eyes")
zone = "head"
if("mouth")
zone = "head"
- if("l_hand")
- zone = "l_arm"
- if("r_hand")
- zone = "r_arm"
- if("l_foot")
- zone = "l_leg"
- if("r_foot")
- zone = "r_leg"
- if("groin")
- zone = "chest"
+// if("groin")
+// zone = "chest"
return zone
@@ -162,7 +173,7 @@ proc/isorgan(A)
else
if (pr >= 100)
return n
- var/te = n
+ var/te = html_decode(n)
var/t = ""
n = length(n)
var/p = null
@@ -173,8 +184,67 @@ proc/isorgan(A)
else
t = text("[]*", t)
p++
- return t
+ return html_encode(t)
+/*proc/NewStutter(phrase,stunned)
+ phrase = html_decode(phrase)
+
+ var/list/split_phrase = dd_text2list(phrase," ") //Split it up into words.
+
+ var/list/unstuttered_words = split_phrase.Copy()
+ var/i = rand(1,3)
+ if(stunned) i = split_phrase.len
+ for(,i > 0,i--) //Pick a few words to stutter on.
+
+ if (!unstuttered_words.len)
+ break
+ var/word = pick(unstuttered_words)
+ unstuttered_words -= word //Remove from unstuttered words so we don't stutter it again.
+ var/index = split_phrase.Find(word) //Find the word in the split phrase so we can replace it.
+
+ //Search for dipthongs (two letters that make one sound.)
+ var/first_sound = copytext(word,1,3)
+ var/first_letter = copytext(word,1,2)
+ if(lowertext(first_sound) in list("ch","th","sh"))
+ first_letter = first_sound
+
+ //Repeat the first letter to create a stutter.
+ var/rnum = rand(1,3)
+ switch(rnum)
+ if(1)
+ word = "[first_letter]-[word]"
+ if(2)
+ word = "[first_letter]-[first_letter]-[word]"
+ if(3)
+ word = "[first_letter]-[word]"
+
+ split_phrase[index] = word
+
+ return sanitize(dd_list2text(split_phrase," "))*/
+
+
+proc/slur(phrase)
+ phrase = html_decode(phrase)
+ var/leng=lentext(phrase)
+ var/counter=lentext(phrase)
+ var/newphrase=""
+ var/newletter=""
+ while(counter>=1)
+ newletter=copytext(phrase,(leng-counter)+1,(leng-counter)+2)
+ if(rand(1,3)==3)
+ if(lowertext(newletter)=="o") newletter="u"
+ if(lowertext(newletter)=="s") newletter="ch"
+ if(lowertext(newletter)=="a") newletter="ah"
+ if(lowertext(newletter)=="c") newletter="k"
+ switch(rand(1,15))
+ if(1,3,5,8) newletter="[lowertext(newletter)]"
+ if(2,4,6,15) newletter="[uppertext(newletter)]"
+ if(7) newletter+="'"
+ if(9,10) newletter="[newletter]"
+ if(11,12) newletter="[newletter]"
+ if(13) newletter="[newletter]"
+ newphrase+="[newletter]";counter-=1
+ return newphrase
/proc/stutter(n)
var/te = html_decode(n)
@@ -277,6 +347,15 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
return 0
+/mob/proc/abiotic2(var/full_body2 = 0)
+ if(full_body2 && ((l_hand && !( l_hand.abstract )) || (r_hand && !( r_hand.abstract )) || (back || wear_mask)))
+ return 1
+
+ if((l_hand && !( l_hand.abstract )) || (r_hand && !( r_hand.abstract )))
+ return 1
+
+ return 0
+
//Triggered when F12 is pressed (Unless someone changed something in the DMF)
/mob/verb/button_pressed_F12()
set name = "F12"
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 2e9d3734df..81b6c7564b 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -287,6 +287,13 @@
if(Process_Grab()) return
if(!mob.canmove) return
+//Making mob movememnt changes instant.
+ if(mob.paralysis || mob.stunned || mob.resting || mob.weakened || mob.buckled /*|| (mob.changeling && mob.changeling.changeling_fakedeath)*/)
+ mob.canmove = 0
+ return
+ else
+ mob.canmove = 1
+
//if(istype(mob.loc, /turf/space) || (mob.flags & NOGRAV))
// if(!mob.Process_Spacemove(0)) return 0
@@ -306,7 +313,7 @@
if(mob.restrained())//Why being pulled while cuffed prevents you from moving
for(var/mob/M in range(mob, 1))
- if(M.pulling == mob && !M.restrained() && M.stat == 0 && M.canmove)
+ if(((M.pulling == mob && (!( M.restrained() ) && M.stat == 0)) || locate(/obj/item/weapon/grab, mob.grabbed_by.len)))
src << "\blue You're restrained! You can't move!"
return 0
@@ -315,14 +322,14 @@
switch(mob.m_intent)
if("run")
if(mob.drowsyness > 0)
- move_delay += 6
+ move_delay += 5
// if(mob.organStructure && mob.organStructure.legs)
// move_delay += mob.organStructure.legs.moveRunDelay
- move_delay += 1
+ move_delay += 2
if("walk")
// if(mob.organStructure && mob.organStructure.legs)
// move_delay += mob.organStructure.legs.moveWalkDelay
- move_delay += 7
+ move_delay += 5
move_delay += mob.movement_delay()
if(config.Tickcomp)
@@ -368,10 +375,13 @@
M.animate_movement = 2
return
- else if(mob.confused)
+ else if(mob.confused && prob(30))
step(mob, pick(cardinal))
else
. = ..()
+ for(var/obj/effect/speech_bubble/S in range(1, mob))
+ if(S.parent == mob)
+ S.loc = mob.loc
moving = 0
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 2904c92293..f4ceed41a3 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -298,6 +298,11 @@
src << alert("[rank] is not available. Please try another.")
return 0
+ if(preferences.species != "Human")
+ if(!is_alien_whitelisted(src, preferences.species) && config.usealienwhitelist)
+ src << alert("You are currently not whitelisted to play [preferences.species].")
+ return 0
+
job_master.AssignRole(src, rank, 1)
var/mob/living/carbon/human/character = create_character() //creates the human and transfers vars and mind
@@ -377,6 +382,19 @@
new_character.dna.ready_dna(new_character)
new_character.dna.b_type = preferences.b_type
+ if(preferences.species == "Tajaran") //This is like the worst, but it works, so meh. - Erthilo
+ if(is_alien_whitelisted(src, "Tajaran") || !config.usealienwhitelist)
+ new_character.dna.mutantrace = "tajaran"
+ new_character.tajaran_talk_understand = 1
+ if(preferences.species == "Soghun")
+ if(is_alien_whitelisted(src, "Soghun") || !config.usealienwhitelist)
+ new_character.dna.mutantrace = "lizard"
+ new_character.soghun_talk_understand = 1
+ if(preferences.species == "Skrell")
+ if(is_alien_whitelisted(src, "Skrell") || !config.usealienwhitelist)
+ new_character.dna.mutantrace = "skrell"
+ new_character.skrell_talk_understand = 1
+
new_character.key = key //Manually transfer the key to log them in
return new_character
diff --git a/code/modules/mob/new_player/preferences.dm b/code/modules/mob/new_player/preferences.dm
index 3e74740112..447f38b46b 100644
--- a/code/modules/mob/new_player/preferences.dm
+++ b/code/modules/mob/new_player/preferences.dm
@@ -702,12 +702,11 @@ datum/preferences
b_type = new_b_type
if("hair")
- if(species == "Human")
- var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference") as color|null
- if(new_hair)
- r_hair = hex2num(copytext(new_hair, 2, 4))
- g_hair = hex2num(copytext(new_hair, 4, 6))
- b_hair = hex2num(copytext(new_hair, 6, 8))
+ var/new_hair = input(user, "Choose your character's hair colour:", "Character Preference") as color|null
+ if(new_hair)
+ r_hair = hex2num(copytext(new_hair, 2, 4))
+ g_hair = hex2num(copytext(new_hair, 4, 6))
+ b_hair = hex2num(copytext(new_hair, 6, 8))
if("h_style")
var/list/valid_hairstyles = list()
diff --git a/code/modules/mob/new_player/savefile.dm b/code/modules/mob/new_player/savefile.dm
index 3cd62beaec..7750c67d68 100644
--- a/code/modules/mob/new_player/savefile.dm
+++ b/code/modules/mob/new_player/savefile.dm
@@ -91,7 +91,7 @@ datum/preferences/proc/savefile_save(mob/user)
F["blood_type"] << src.b_type
F["underwear"] << src.underwear
F["backbag"] << src.backbag
- F["backbag"] << src.backbag
+ F["species"] << src.species
@@ -173,6 +173,8 @@ datum/preferences/proc/savefile_load(mob/user)
if(underwear == 0) underwear = 12 //For old players who have 0 in their savefile
F["backbag"] >> src.backbag
if(isnull(backbag)) backbag = 2
+ F["species"] >> src.species
+ if(isnull(species)) species = "human"
F["name_is_always_random"] >> src.be_random_name
F["midis"] >> src.midis
F["ghost_ears"] >> src.ghost_ears
diff --git a/code/modules/mob/say.dm b/code/modules/mob/say.dm
index bef4e6a45a..20917514f4 100644
--- a/code/modules/mob/say.dm
+++ b/code/modules/mob/say.dm
@@ -47,20 +47,35 @@
return
/mob/proc/say_understands(var/mob/other)
+ if(!other)
+ return 1
if (src.stat == 2)
return 1
else if (istype(other, src.type))
return 1
else if(other.universal_speak || src.universal_speak)
return 1
+ else if(isAI(src) && ispAI(other))
+ return 1
return 0
-/mob/proc/say_quote(var/text)
+/mob/proc/say_quote(var/text,var/is_speaking_soghun,var/is_speaking_skrell,var/is_speaking_tajaran)
if(!text)
return "says, \"...\""; //not the best solution, but it will stop a large number of runtimes. The cause is somewhere in the Tcomms code
var/ending = copytext(text, length(text))
+ if (is_speaking_soghun)
+ return "hisses, \"[text]\"";
+ if (is_speaking_skrell)
+ return "warbles, \"[text]\"";
+ if (is_speaking_tajaran)
+ return "purrs, \"[text]\"";
+//Needs Virus2
+// if (src.disease_symptoms & DISEASE_HOARSE)
+// return "rasps, \"[text]\"";
if (src.stuttering)
return "stammers, \"[text]\"";
+ if (src.slurring)
+ return "slurrs, \"[text]\"";
if(isliving(src))
var/mob/living/L = src
if (L.getBrainLoss() >= 60)
@@ -81,4 +96,12 @@
// should be overloaded for all mobs whose "ear" is separate from their "mob"
- return get_turf(src)
\ No newline at end of file
+ return get_turf(src)
+
+/mob/proc/say_test(var/text)
+ var/ending = copytext(text, length(text))
+ if (ending == "?")
+ return "1"
+ else if (ending == "!")
+ return "2"
+ return "0"
\ No newline at end of file
diff --git a/code/modules/mob/simple_animal/kobold.dm b/code/modules/mob/simple_animal/kobold.dm
deleted file mode 100644
index 3a8aace7ca..0000000000
--- a/code/modules/mob/simple_animal/kobold.dm
+++ /dev/null
@@ -1,33 +0,0 @@
-//kobold
-/mob/living/simple_animal/kobold
- name = "kobold"
- desc = "A small, rat-like creature."
- icon = 'mob.dmi'
- icon_state = "kobold_idle"
- icon_living = "kobold_idle"
- icon_dead = "kobold_dead"
- //speak = list("You no take candle!","Ooh, pretty shiny.","Me take?","Where gold here...","Me likey.")
- speak_emote = list("mutters","hisses","grumbles")
- emote_hear = list("mutters under it's breath.","grumbles.", "yips!")
- emote_see = list("looks around suspiciously.", "scratches it's arm.","putters around a bit.")
- speak_chance = 15
- turns_per_move = 5
- see_in_dark = 6
- meat_type = /obj/item/weapon/reagent_containers/food/snacks/sliceable/meat
- response_help = "pets the"
- response_disarm = "gently pushes aside the"
- response_harm = "kicks the"
- minbodytemp = 250
- min_oxy = 16 //Require atleast 16kPA oxygen
- minbodytemp = 223 //Below -50 Degrees Celcius
- maxbodytemp = 323 //Above 50 Degrees Celcius
-
-/mob/living/simple_animal/kobold/Life()
- ..()
- if(prob(15) && turns_since_move && !stat)
- flick("kobold_act",src)
-
-/mob/living/simple_animal/kobold/Move(var/dir)
- ..()
- if(!stat)
- flick("kobold_walk",src)
diff --git a/code/modules/projectiles/guns/projectile/revolver.dm b/code/modules/projectiles/guns/projectile/revolver.dm
index 1fd264d4c6..fd59d6cda7 100644
--- a/code/modules/projectiles/guns/projectile/revolver.dm
+++ b/code/modules/projectiles/guns/projectile/revolver.dm
@@ -6,7 +6,7 @@
origin_tech = "combat=2;materials=2"
ammo_type = "/obj/item/ammo_casing/c38"
-
+/*
special_check(var/mob/living/carbon/human/M)
if(ishuman(M))
if(istype(M.w_uniform, /obj/item/clothing/under/det) && istype(M.head, /obj/item/clothing/head/det_hat) && \
@@ -14,7 +14,7 @@
return 1
M << "\red You just don't feel cool enough to use this gun looking like that."
return 0
-
+*/
verb/rename_gun()
set name = "Name Gun"
diff --git a/code/stylesheet.dm b/code/stylesheet.dm
index 2e7ebd3ea9..e9480c3310 100644
--- a/code/stylesheet.dm
+++ b/code/stylesheet.dm
@@ -24,6 +24,7 @@ em {font-style: normal; font-weight: bold;}
.say {}
.deadsay {color: #5c00e6;}
+.species {color: #803B56;}
.radio {color: #008000;}
.deptradio {color: #993399;}
.comradio {color: #ACA82D;}
diff --git a/interface/skin.dmf b/interface/skin.dmf
index 34a360d160..1420a8292c 100644
--- a/interface/skin.dmf
+++ b/interface/skin.dmf
@@ -67,6 +67,14 @@ macro "macro"
name = "CTRL+D"
command = "drop-item"
is-disabled = false
+ elem
+ name = "CTRL+E"
+ command = "_changeintent 1"
+ is-disabled = false
+ elem
+ name = "CTRL+Q"
+ command = "_changeintent -1"
+ is-disabled = false
elem
name = "CTRL+S"
command = "swap-hand"
@@ -75,6 +83,42 @@ macro "macro"
name = "CTRL+W"
command = "attack-self"
is-disabled = false
+ elem
+ name = "NUMPAD2+REP"
+ command = ".south"
+ is-disabled = false
+ elem
+ name = "NUMPAD4+REP"
+ command = ".west"
+ is-disabled = false
+ elem
+ name = "NUMPAD5+REP"
+ command = ".center"
+ is-disabled = false
+ elem
+ name = "NUMPAD6+REP"
+ command = ".east"
+ is-disabled = false
+ elem
+ name = "NUMPAD8+REP"
+ command = ".north"
+ is-disabled = false
+ elem
+ name = "MULTIPLY"
+ command = "swap-hand"
+ is-disabled = false
+ elem
+ name = "ADD"
+ command = "attack-self"
+ is-disabled = false
+ elem
+ name = "SUBTRACT"
+ command = "drop-item"
+ is-disabled = false
+ elem
+ name = "DIVIDE"
+ command = "toggle-throw-mode"
+ is-disabled = false
elem
name = "F1"
command = "adminhelp"
@@ -83,6 +127,10 @@ macro "macro"
name = "CTRL+SHIFT+F1+REP"
command = ".options"
is-disabled = false
+ elem
+ name = "F2"
+ command = "ooc"
+ is-disabled = false
elem
name = "F2+REP"
command = ".screenshot auto"
@@ -91,6 +139,22 @@ macro "macro"
name = "SHIFT+F2+REP"
command = ".screenshot"
is-disabled = false
+ elem
+ name = "F3"
+ command = "say"
+ is-disabled = false
+ elem
+ name = "F4"
+ command = "me"
+ is-disabled = false
+ elem
+ name = "F5"
+ command = "asay"
+ is-disabled = false
+ elem
+ name = "F6"
+ command = "ToggleGunMode"
+ is-disabled = false
elem
name = "F12"
command = "F12"
@@ -251,6 +315,98 @@ menu "menu"
group = ""
is-disabled = false
saved-params = "is-checked"
+ elem
+ name = ""
+ command = ""
+ category = "&Help"
+ is-checked = false
+ can-check = false
+ group = ""
+ is-disabled = false
+ saved-params = "is-checked"
+ elem
+ name = "&Rules"
+ command = "Rules"
+ category = "&Help"
+ is-checked = false
+ can-check = false
+ group = ""
+ is-disabled = false
+ saved-params = "is-checked"
+ elem
+ name = "&News"
+ command = "Read-News"
+ category = "&Help"
+ is-checked = false
+ can-check = false
+ group = ""
+ is-disabled = false
+ saved-params = "is-checked"
+
+menu "minimap_menu"
+ elem
+ name = "Size"
+ command = ""
+ category = ""
+ is-checked = false
+ can-check = false
+ group = ""
+ is-disabled = false
+ saved-params = "is-checked"
+ elem
+ name = "50%"
+ command = ".winset \"minimap.icon-size=16\""
+ category = "Size"
+ is-checked = false
+ can-check = true
+ group = "minimap_size"
+ is-disabled = false
+ saved-params = "is-checked"
+ elem
+ name = "100%"
+ command = ".winset \"minimap.icon-size=32\""
+ category = "Size"
+ is-checked = true
+ can-check = true
+ group = "minimap_size"
+ is-disabled = false
+ saved-params = "is-checked"
+ elem
+ name = "200%"
+ command = ".winset \"minimap.icon-size=64\""
+ category = "Size"
+ is-checked = false
+ can-check = true
+ group = "minimap_size"
+ is-disabled = false
+ saved-params = "is-checked"
+ elem
+ name = "stretch"
+ command = ".winset \"minimap.icon-size=0\""
+ category = "Size"
+ is-checked = false
+ can-check = true
+ group = "minimap_size"
+ is-disabled = false
+ saved-params = "is-checked"
+ elem
+ name = "View"
+ command = ""
+ category = ""
+ is-checked = false
+ can-check = false
+ group = ""
+ is-disabled = false
+ saved-params = "is-checked"
+ elem
+ name = "Change Z level"
+ command = "Open-Minimap-Z"
+ category = "View"
+ is-checked = false
+ can-check = false
+ group = ""
+ is-disabled = false
+ saved-params = "is-checked"
window "Telecomms IDE"
@@ -496,6 +652,116 @@ window "chemdispenser"
macro = ""
menu = ""
on-close = ""
+ elem "charging"
+ type = BUTTON
+ pos = 72,24
+ size = 88x20
+ anchor1 = none
+ anchor2 = none
+ font-family = ""
+ font-size = 0
+ font-style = ""
+ text-color = #000000
+ background-color = none
+ is-visible = true
+ is-disabled = false
+ is-transparent = false
+ is-default = false
+ border = none
+ drop-zone = false
+ right-click = false
+ saved-params = "is-checked"
+ on-size = ""
+ text = "[Not charging]"
+ image = ""
+ command = "skincmd \"chemdispenser;tcharge\""
+ is-flat = false
+ stretch = false
+ is-checked = false
+ group = ""
+ button-type = pushbutton
+ elem "button4"
+ type = BUTTON
+ pos = 208,4
+ size = 48x20
+ anchor1 = none
+ anchor2 = none
+ font-family = ""
+ font-size = 0
+ font-style = ""
+ text-color = #000000
+ background-color = none
+ is-visible = true
+ is-disabled = false
+ is-transparent = false
+ is-default = false
+ border = none
+ drop-zone = false
+ right-click = false
+ saved-params = "is-checked"
+ on-size = ""
+ text = "[Other]"
+ image = ""
+ command = "skincmd \"chemdispenser;amountc\""
+ is-flat = false
+ stretch = false
+ is-checked = false
+ group = ""
+ button-type = pushbutton
+ elem "child2"
+ type = CHILD
+ pos = 0,48
+ size = 340x432
+ anchor1 = none
+ anchor2 = none
+ font-family = ""
+ font-size = 0
+ font-style = ""
+ text-color = #000000
+ background-color = none
+ is-visible = true
+ is-disabled = false
+ is-transparent = false
+ is-default = false
+ border = none
+ drop-zone = false
+ right-click = false
+ saved-params = "splitter"
+ on-size = ""
+ left = "chemdispenser_reagents"
+ right = ""
+ is-vert = false
+ splitter = 50
+ show-splitter = true
+ lock = none
+ elem "button3"
+ type = BUTTON
+ pos = 208,4
+ size = 48x20
+ anchor1 = none
+ anchor2 = none
+ font-family = ""
+ font-size = 0
+ font-style = ""
+ text-color = #000000
+ background-color = none
+ is-visible = true
+ is-disabled = false
+ is-transparent = false
+ is-default = false
+ border = none
+ drop-zone = false
+ right-click = false
+ saved-params = "is-checked"
+ on-size = ""
+ text = "[Other]"
+ image = ""
+ command = "skincmd \"chemdispenser;amountc\""
+ is-flat = false
+ stretch = false
+ is-checked = false
+ group = ""
+ button-type = pushbutton
elem "energy"
type = LABEL
pos = 8,24
@@ -879,7 +1145,7 @@ window "mainwindow"
elem "input"
type = INPUT
pos = 3,420
- size = 517x20
+ size = 554x20
anchor1 = 0,100
anchor2 = 100,100
font-family = ""
@@ -902,7 +1168,7 @@ window "mainwindow"
no-command = false
elem "saybutton"
type = BUTTON
- pos = 520,420
+ pos = 557,420
size = 40x20
anchor1 = 100,100
anchor2 = none
@@ -922,16 +1188,16 @@ window "mainwindow"
on-size = ""
text = "Chat"
image = ""
- command = ".winset \"saybutton.is-checked=true?input.command=\"!say \\\"\" macrobutton.is-checked=false:input.command=\""
+ command = ".winset \"saybutton.is-checked=true?input.command=\"!say \\\"\" oocbutton.is-checked=false:input.command=\""
is-flat = false
stretch = false
is-checked = false
group = ""
button-type = pushbox
- elem "macrobutton"
+ elem "oocbutton"
type = BUTTON
- pos = 560,420
- size = 30x20
+ pos = 597,420
+ size = 40x20
anchor1 = 100,100
anchor2 = none
font-family = ""
@@ -940,7 +1206,7 @@ window "mainwindow"
text-color = #000000
background-color = none
is-visible = true
- is-disabled = true
+ is-disabled = false
is-transparent = false
is-default = false
border = none
@@ -948,42 +1214,14 @@ window "mainwindow"
right-click = false
saved-params = "is-checked"
on-size = ""
- text = "Alt"
+ text = "OOC"
image = ""
- command = ".winset \"macrobutton.is-checked=true?input.command=\"!.alt \" saybutton.is-checked=false:input.command=\""
+ command = ".winset \"oocbutton.is-checked=true?input.command=\"!ooc \\\"\" saybutton.is-checked=false:input.command=\""
is-flat = false
stretch = false
is-checked = false
group = ""
button-type = pushbox
- elem "hostb"
- type = BUTTON
- pos = 590,420
- size = 47x20
- anchor1 = 100,100
- anchor2 = none
- font-family = ""
- font-size = 0
- font-style = ""
- text-color = #000000
- background-color = none
- is-visible = true
- is-disabled = true
- is-transparent = false
- is-default = false
- border = none
- drop-zone = false
- right-click = false
- saved-params = "is-checked"
- on-size = ""
- text = "Host..."
- image = ""
- command = ".host"
- is-flat = false
- stretch = false
- is-checked = false
- group = ""
- button-type = pushbutton
window "mapwindow"
elem "mapwindow"
@@ -1049,7 +1287,71 @@ window "mapwindow"
text-mode = false
on-show = ".winset\"mainwindow.mainvsplit.left=mapwindow\""
on-hide = ".winset\"mainwindow.mainvsplit.left=\""
- style = ""
+
+window "minimapwindow"
+ elem "minimapwindow"
+ type = MAIN
+ pos = 281,0
+ size = 640x480
+ anchor1 = none
+ anchor2 = none
+ font-family = ""
+ font-size = 0
+ font-style = ""
+ text-color = #000000
+ background-color = none
+ is-visible = false
+ is-disabled = false
+ is-transparent = false
+ is-default = false
+ border = none
+ drop-zone = false
+ right-click = false
+ saved-params = "pos;size;is-minimized;is-maximized"
+ on-size = ""
+ title = ""
+ titlebar = true
+ statusbar = true
+ can-close = true
+ can-minimize = true
+ can-resize = true
+ is-pane = false
+ is-minimized = false
+ is-maximized = false
+ can-scroll = none
+ icon = ""
+ image = ""
+ image-mode = stretch
+ keep-aspect = false
+ transparent-color = none
+ alpha = 255
+ macro = ""
+ menu = "minimap_menu"
+ on-close = ""
+ elem "minimap"
+ type = MAP
+ pos = 0,0
+ size = 640x480
+ anchor1 = 0,0
+ anchor2 = 100,100
+ font-family = ""
+ font-size = 0
+ font-style = ""
+ text-color = #000000
+ background-color = none
+ is-visible = true
+ is-disabled = false
+ is-transparent = false
+ is-default = false
+ border = none
+ drop-zone = true
+ right-click = false
+ saved-params = "icon-size"
+ on-size = ""
+ icon-size = 32
+ text-mode = false
+ on-show = ""
+ on-hide = ""
window "outputwindow"
elem "outputwindow"
@@ -1653,6 +1955,32 @@ window "vendingwindow_n"
macro = "vending"
menu = ""
on-close = ""
+ elem "label2"
+ type = LABEL
+ pos = 0,0
+ size = 80x16
+ anchor1 = none
+ anchor2 = none
+ font-family = ""
+ font-size = 0
+ font-style = ""
+ text-color = #0000a0
+ background-color = #ff8000
+ is-visible = true
+ is-disabled = false
+ is-transparent = false
+ is-default = false
+ border = sunken
+ drop-zone = false
+ right-click = false
+ saved-params = ""
+ on-size = ""
+ text = ""
+ image = ""
+ image-mode = center
+ keep-aspect = false
+ align = center
+ text-wrap = false
elem "page"
type = LABEL
pos = 64,416