From 9387dd2366dca201013f3bd44180dc1692582609 Mon Sep 17 00:00:00 2001 From: Erthilo Date: Thu, 23 Aug 2012 22:43:38 +0100 Subject: [PATCH] * Merged diagonal reaching. * Merged speech bubbles and pain flashing * Merged Signaler Dead man switch. * Merged give verb. * Merged alien languages * Merged stuttering, slurring. * Merged Git Revision Info. * Fixed mutantraces not having hair/eyes * Fixed Soghun's not being able to change hair colour. * Fixed savefiles not saving species. * Shut up vending machines. * Added colour to species talk. --- code/datums/helper_datums/getrev.dm | 12 +-- code/defines/obj/vending.dm | 2 +- code/defines/procs/gamehelpers.dm | 7 +- code/game/atom_procs.dm | 87 +++++++++---------- code/game/jobs/whitelist.dm | 2 + code/game/objects/items/item.dm | 27 +++++- code/game/objects/storage/backpack.dm | 2 + code/modules/assembly/signaler.dm | 24 +++++ code/modules/mob/inventory.dm | 21 ++++- code/modules/mob/living/carbon/give.dm | 10 ++- code/modules/mob/living/carbon/human/hud.dm | 8 +- .../mob/living/carbon/human/update_icons.dm | 5 +- code/modules/mob/living/living_defense.dm | 8 ++ code/modules/mob/living/say.dm | 85 ++++++++++++++++-- code/modules/mob/mob_defines.dm | 5 ++ code/modules/mob/mob_helpers.dm | 87 ++++++++++++++++--- code/modules/mob/mob_movement.dm | 20 +++-- code/modules/mob/new_player/new_player.dm | 18 ++++ code/modules/mob/new_player/preferences.dm | 11 ++- code/modules/mob/new_player/savefile.dm | 4 +- code/modules/mob/say.dm | 27 +++++- code/stylesheet.dm | 1 + 22 files changed, 371 insertions(+), 102 deletions(-) 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;}