diff --git a/code/datums/helper_datums/getrev.dm b/code/datums/helper_datums/getrev.dm
index 03732d6873b..434ba91c4fa 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 ccbdde555cb..6b0043bc42b 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 b511c7982f4..2d84f38a967 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 3b8a6207dbb..1ae5f9bcf09 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 009a184c78a..b47da0e77d7 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 280148e7d58..901c22dbeb2 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/storage/backpack.dm b/code/game/objects/storage/backpack.dm
index 94a9642ac99..dfd37287e69 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 296d80680d1..b6b65981952 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 5bc421dee4d..12cc5a26c8e 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 0b8c0614190..bdad53f2ca2 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 4d017d14d59..b8d01a4a202 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 46c875a9f93..314922c5aaf 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 c0af35f8ca7..74ce8062ee8 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 7aebd6ef676..d66ac313630 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/mob_defines.dm b/code/modules/mob/mob_defines.dm
index a22f570c251..b4980bddd7e 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 a4372902996..5a96d1b10b7 100644
--- a/code/modules/mob/mob_helpers.dm
+++ b/code/modules/mob/mob_helpers.dm
@@ -136,22 +136,15 @@ proc/isorgan(A)
/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
@@ -180,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
@@ -191,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)
@@ -295,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 2e9d3734df0..81b6c7564be 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 2904c92293b..f4ceed41a3c 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 3e747401123..447f38b46b8 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 3cd62beaecb..7750c67d680 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 bef4e6a45a0..20917514f43 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/stylesheet.dm b/code/stylesheet.dm
index 2e7ebd3ea9e..e9480c33104 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;}