merge conflicts fixed finally

This commit is contained in:
Seris02
2020-02-05 18:42:16 +08:00
1239 changed files with 52279 additions and 12808 deletions
@@ -159,6 +159,11 @@
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
/datum/sprite_accessory/ears/bunny
name = "Bunny"
icon_state = "bunny"
color_src = MATRIXED
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
/******************************************
*************** Furry Ears ****************
@@ -301,3 +306,7 @@
/datum/sprite_accessory/mam_ears/wolf
name = "Wolf"
icon_state = "wolf"
/datum/sprite_accessory/mam_ears/bunny
name = "Bunny"
icon_state = "bunny"
@@ -7,6 +7,26 @@
// please make sure they're sorted alphabetically and categorized
/datum/sprite_accessory/facial_hair/threeoclock
name = "Beard (3 o\'Clock)"
icon_state = "facial_3oclock"
/datum/sprite_accessory/facial_hair/fiveoclock
name = "Beard (5 o\'Clock)"
icon_state = "facial_5oclock"
/datum/sprite_accessory/facial_hair/fiveoclockm
name = "Beard (5 o\'Clock with Moustache)"
icon_state = "facial_5oclockmoustache"
/datum/sprite_accessory/facial_hair/sevenoclock
name = "Beard (7 o\'Clock)"
icon_state = "facial_7oclock"
/datum/sprite_accessory/facial_hair/sevenoclockm
name = "Beard (7 o\'Clock with Moustache)"
icon_state = "facial_7oclockmoustache"
/datum/sprite_accessory/facial_hair/abe
name = "Beard (Abraham Lincoln)"
icon_state = "facial_abe"
@@ -23,10 +43,6 @@
name = "Beard (Dwarf)"
icon_state = "facial_dwarf"
/datum/sprite_accessory/facial_hair/fiveoclock
name = "Beard (Five o Clock Shadow)"
icon_state = "facial_fiveoclock"
/datum/sprite_accessory/facial_hair/fullbeard
name = "Beard (Full)"
icon_state = "facial_fullbeard"
@@ -35,6 +51,10 @@
name = "Beard (Goatee)"
icon_state = "facial_gt"
/datum/sprite_accessory/facial_hair/goatee
name = "Beard (Goatee 2)"
icon_state = "facial_goatee"
/datum/sprite_accessory/facial_hair/hip
name = "Beard (Hipster)"
icon_state = "facial_hip"
@@ -43,18 +63,38 @@
name = "Beard (Jensen)"
icon_state = "facial_jensen"
/datum/sprite_accessory/facial_hair/martialartist
name = "Beard (Martial Artist)"
icon_state = "facial_martialartist"
/datum/sprite_accessory/facial_hair/moonshiner
name = "Beard (Moonshiner)"
icon_state = "facial_moonshiner"
/datum/sprite_accessory/facial_hair/neckbeard
name = "Beard (Neckbeard)"
icon_state = "facial_neckbeard"
/datum/sprite_accessory/facial_hair/tribeard
name = "Beard (Tribeard)"
icon_state = "facial_tribeard"
/datum/sprite_accessory/facial_hair/vlongbeard
name = "Beard (Very Long)"
icon_state = "facial_wise"
/datum/sprite_accessory/facial_hair/volaju
name = "Beard (Volaju)"
icon_state = "facial_volaju"
/datum/sprite_accessory/facial_hair/longbeard
name = "Beard (Long)"
icon_state = "facial_longbeard"
/datum/sprite_accessory/facial_hair/moustache
name = "Moustache"
icon_state = "facial_moustache"
/datum/sprite_accessory/facial_hair/fu
name = "Moustache (Fu Manchu)"
icon_state = "facial_fumanchu"
@@ -63,6 +103,10 @@
name = "Moustache (Hulk Hogan)"
icon_state = "facial_hogan" //-Neek
/datum/sprite_accessory/facial_hair/pencil
name = "Moustache (Pencil)"
icon_state = "facial_pencilstache"
/datum/sprite_accessory/facial_hair/selleck
name = "Moustache (Selleck)"
icon_state = "facial_selleck"
@@ -75,56 +119,31 @@
name = "Moustache (Van Dyke)"
icon_state = "facial_vandyke"
/datum/sprite_accessory/facial_hair/walrus
name = "Moustache (Walrus)"
icon_state = "facial_walrus"
/datum/sprite_accessory/facial_hair/watson
name = "Moustache (Watson)"
icon_state = "facial_watson"
/datum/sprite_accessory/facial_hair/mutton
name = "Mutton Chops"
icon_state = "facial_mutton"
/datum/sprite_accessory/facial_hair/muttonmus
name = "Mutton Chops with Moustache"
icon_state = "facial_muttonmus"
/datum/sprite_accessory/facial_hair/shaved
name = "Shaved"
icon_state = null
gender = NEUTER
/datum/sprite_accessory/facial_hair/sideburn
name = "Sideburns"
icon_state = "facial_sideburns"
/datum/sprite_accessory/facial_hair/elvis
name = "Sideburns (Elvis)"
icon_state = "facial_elvis"
#define VFACE(_name, new_state) /datum/sprite_accessory/facial_hair/##new_state/icon_state=#new_state;;/datum/sprite_accessory/facial_hair/##new_state/name= #_name + " (Virgo)"
VFACE("Watson", facial_watson_s)
VFACE("Chaplin", facial_chaplin_s)
VFACE("Fullbeard", facial_fullbeard_s)
VFACE("Vandyke", facial_vandyke_s)
VFACE("Elvis", facial_elvis_s)
VFACE("Abe", facial_abe_s)
VFACE("Chin", facial_chin_s)
VFACE("GT", facial_gt_s)
VFACE("Hip", facial_hip_s)
VFACE("Hogan", facial_hogan_s)
VFACE("Selleck", facial_selleck_s)
VFACE("Neckbeard", facial_neckbeard_s)
VFACE("Longbeard", facial_longbeard_s)
VFACE("Dwarf", facial_dwarf_s)
VFACE("Sideburn", facial_sideburn_s)
VFACE("Mutton", facial_mutton_s)
VFACE("Moustache", facial_moustache_s)
VFACE("Pencilstache", facial_pencilstache_s)
VFACE("Goatee", facial_goatee_s)
VFACE("Smallstache", facial_smallstache_s)
VFACE("Volaju", facial_volaju_s)
VFACE("3 O\'clock", facial_3oclock_s)
VFACE("5 O\'clock", facial_5oclock_s)
VFACE("7 O\'clock", facial_7oclock_s)
VFACE("5 O\'clock Moustache", facial_5oclockmoustache_s)
VFACE("7 O\'clock", facial_7oclockmoustache_s)
VFACE("Walrus", facial_walrus_s)
VFACE("Muttonmus", facial_muttonmus_s)
VFACE("Wise", facial_wise_s)
VFACE("Martial Artist", facial_martialartist_s)
VFACE("Dorsalfnil", facial_dorsalfnil_s)
VFACE("Hornadorns", facial_hornadorns_s)
VFACE("Spike", facial_spike_s)
VFACE("Chinhorns", facial_chinhorns_s)
VFACE("Cropped Fullbeard", facial_croppedfullbeard_s)
VFACE("Chinless Beard", facial_chinlessbeard_s)
VFACE("Moonshiner", facial_moonshiner_s)
VFACE("Tribearder", facial_tribearder_s)
#undef VFACE
icon_state = "facial_elvis"
@@ -27,7 +27,7 @@
/datum/sprite_accessory/hair/bald
name = "Bald"
icon_state = null
icon_state = "bald"
/datum/sprite_accessory/hair/balding
name = "Balding Hair"
@@ -37,6 +37,14 @@
name = "Bedhead"
icon_state = "hair_bedhead"
/datum/sprite_accessory/hair/bedhead_long
name = "Bedhead (Long)"
icon_state = "hair_long_bedhead"
/datum/sprite_accessory/hair/bedhead_longer
name = "Bedhead (Longer)"
icon_state = "hair_longer_bedhead"
/datum/sprite_accessory/hair/bedhead2
name = "Bedhead 2"
icon_state = "hair_bedheadv2"
@@ -51,7 +59,7 @@
/datum/sprite_accessory/hair/beehive2
name = "Beehive 2"
icon_state = "hair_beehivev2"
icon_state = "hair_beehive2"
/datum/sprite_accessory/hair/bob
name = "Bob Hair"
@@ -69,6 +77,14 @@
name = "Bobcurl"
icon_state = "hair_bobcurl"
/datum/sprite_accessory/hair/bobcut
name = "Bobcut"
icon_state = "hair_bobcut"
/datum/sprite_accessory/hair/bobcutalt
name = "Bobcut (Alt)"
icon_state = "hair_bobcutalt"
/datum/sprite_accessory/hair/boddicker
name = "Boddicker"
icon_state = "hair_boddicker"
@@ -77,6 +93,10 @@
name = "Bowl"
icon_state = "hair_bowlcut"
/datum/sprite_accessory/hair/bowl2
name = "Bowl 2"
icon_state = "hair_bowlcut2"
/datum/sprite_accessory/hair/braid
name = "Braid (Floorlength)"
icon_state = "hair_braid"
@@ -89,6 +109,10 @@
name = "Braided Front"
icon_state = "hair_braidfront"
/datum/sprite_accessory/hair/grandebraid
name = "Braid (Grande)"
icon_state = "hair_grande"
/datum/sprite_accessory/hair/not_floorlength_braid
name = "Braid (High)"
icon_state = "hair_braid2"
@@ -113,10 +137,26 @@
name = "Bun Head 2"
icon_state = "hair_bunhead2"
/datum/sprite_accessory/hair/bun3
name = "Bun Head 3"
icon_state = "hair_bunhead3"
/datum/sprite_accessory/hair/bun4
name = "Bun Head 4"
icon_state = "hair_bunhead4"
/datum/sprite_accessory/hair/doublebun
name = "Bun Head (Double)"
icon_state = "hair_doublebun"
/datum/sprite_accessory/hair/largebun
name = "Bun (Large)"
name = "Bun Head (Large)"
icon_state = "hair_largebun"
/datum/sprite_accessory/hair/tightbun
name = "Bun Head (Tight)"
icon_state = "hair_tightbun"
/datum/sprite_accessory/hair/business
name = "Business Hair"
icon_state = "hair_business"
@@ -137,10 +177,22 @@
name = "Buzzcut"
icon_state = "hair_buzzcut"
/datum/sprite_accessory/hair/cia
name = "CIA"
icon_state = "hair_cia"
/datum/sprite_accessory/hair/combover
name = "Combover"
icon_state = "hair_combover"
/datum/sprite_accessory/hair/coffeehouse
name = "Coffee House"
icon_state = "hair_coffeehouse"
/datum/sprite_accessory/hair/country
name = "Country"
icon_state = "hair_country"
/datum/sprite_accessory/hair/crew
name = "Crewcut"
icon_state = "hair_crewcut"
@@ -149,13 +201,21 @@
name = "Curls"
icon_state = "hair_curls"
/datum/sprite_accessory/hair/curly
name = "Curly"
icon_state = "hair_curly"
/datum/sprite_accessory/hair/cut
name = "Cut Hair"
icon_state = "hair_c"
/datum/sprite_accessory/hair/dave
name = "Dave"
icon_state = "hair_dave"
/datum/sprite_accessory/hair/devillock
name = "Devil Lock"
icon_state = "hair_devilock"
icon_state = "hair_devillock"
/datum/sprite_accessory/hair/dreadlocks
name = "Dreadlocks"
@@ -173,22 +233,66 @@
name = "Emo"
icon_state = "hair_emo"
/datum/sprite_accessory/hair/emo2
name = "Emo 2"
icon_state = "hair_emo2"
/datum/sprite_accessory/hair/emo_fringe
name = "Emo (Fringe)"
icon_state = "hair_emofringe"
/datum/sprite_accessory/hair/emo_long
name = "Emo (Long)"
icon_state = "hair_emolong"
/datum/sprite_accessory/hair/lowfade
name = "Fade (Low)"
icon_state = "hair_lowfade"
/datum/sprite_accessory/hair/medfade
name = "Fade (Medium)"
icon_state = "hair_medfade"
/datum/sprite_accessory/hair/highfade
name = "Fade (High)"
icon_state = "hair_highfade"
/datum/sprite_accessory/hair/baldfade
name = "Fade (Bald)"
icon_state = "hair_baldfade"
/datum/sprite_accessory/hair/nofade
name = "Fade (None)"
icon_state = "hair_nofade"
/datum/sprite_accessory/hair/father
name = "Father"
icon_state = "hair_father"
/datum/sprite_accessory/hair/feather
name = "Feather"
icon_state = "hair_feather"
/datum/sprite_accessory/hair/flair
name = "Flair"
icon_state = "hair_flair"
/datum/sprite_accessory/hair/sargeant
name = "Flat Top"
icon_state = "hair_sargeant"
icon_state = "hair_sergeant"
/datum/sprite_accessory/hair/bigflattop
name = "Flat Top (Big)"
icon_state = "hair_bigflattop"
/datum/sprite_accessory/hair/fag
/datum/sprite_accessory/hair/fag //grimacing emoji
name = "Flow Hair"
icon_state = "hair_f"
/datum/sprite_accessory/hair/fringetail
name = "Fringe Tail"
icon_state = "hair_fringetail"
/datum/sprite_accessory/hair/gelled
name = "Gelled Back"
icon_state = "hair_gelled"
@@ -205,10 +309,22 @@
name = "Half-banged Hair 2"
icon_state = "hair_halfbang2"
/datum/sprite_accessory/hair/halfbangalt
name = "Half-banged Hair (Alt)"
icon_state = "hair_halfbang_alt"
/datum/sprite_accessory/hair/halfshaved
name = "Half-shaved Hair"
icon_state = "hair_halfshaved"
/datum/sprite_accessory/hair/hedgehog
name = "Hedgehog Hair"
icon_state = "hair_hedgehog"
/datum/sprite_accessory/hair/hightight
name = "High and Tight"
icon_state = "hair_hightight"
/datum/sprite_accessory/hair/himecut
name = "Hime Cut"
icon_state = "hair_himecut"
@@ -217,6 +333,10 @@
name = "Hime Cut 2"
icon_state = "hair_himecut2"
/datum/sprite_accessory/hair/shorthime
name = "Hime Cut (Short)"
icon_state = "hair_shorthime"
/datum/sprite_accessory/hair/himeup
name = "Hime Updo"
icon_state = "hair_himeup"
@@ -225,16 +345,28 @@
name = "Hitop"
icon_state = "hair_hitop"
/datum/sprite_accessory/hair/jade
name = "Jade"
icon_state = "hair_jade"
/datum/sprite_accessory/hair/jensen
name = "Jensen Hair"
name = "Jensen"
icon_state = "hair_jensen"
/datum/sprite_accessory/hair/joestar
name = "Joestar"
icon_state = "hair_joestar"
/datum/sprite_accessory/hair/kagami
name = "Kagami"
icon_state = "hair_kagami"
/datum/sprite_accessory/hair/keanu
name = "Keanu Hair"
name = "Keanu"
icon_state = "hair_keanu"
/datum/sprite_accessory/hair/kusangi
name = "Kusanagi Hair"
name = "Kusanagi"
icon_state = "hair_kusanagi"
/datum/sprite_accessory/hair/long
@@ -249,6 +381,10 @@
name = "Long Hair 3"
icon_state = "hair_long3"
/datum/sprite_accessory/hair/longalt
name = "Long Hair (Alt)"
icon_state = "hair_longeralt"
/datum/sprite_accessory/hair/long_over_eye
name = "Long Over Eye"
icon_state = "hair_longovereye"
@@ -269,6 +405,10 @@
name = "Long Side Part"
icon_state = "hair_longsidepart"
/datum/sprite_accessory/hair/manbun
name = "Manbun"
icon_state = "hair_manbun"
/datum/sprite_accessory/hair/megaeyebrows
name = "Mega Eyebrows"
icon_state = "hair_megaeyebrows"
@@ -277,6 +417,10 @@
name = "Messy"
icon_state = "hair_messy"
/datum/sprite_accessory/hair/modern
name = "Modern"
icon_state = "hair_modern"
/datum/sprite_accessory/hair/mohawk
name = "Mohawk"
icon_state = "hair_d"
@@ -285,6 +429,26 @@
name = "Mohawk (Reverse)"
icon_state = "hair_reversemohawk"
/datum/sprite_accessory/hair/shavedmohawk
name = "Mohawk (Shaved)"
icon_state = "hair_shavedmohawk"
/datum/sprite_accessory/hair/mohawk_unshaven
name = "Mohawk (Unshaven)"
icon_state = "hair_unshaven_mohawk"
/datum/sprite_accessory/hair/mulder
name = "Mulder"
icon_state = "hair_mulder"
/datum/sprite_accessory/hair/nia
name = "Nia"
icon_state = "hair_nia"
/datum/sprite_accessory/hair/nitori
name = "Nitori"
icon_state = "hair_nitori"
/datum/sprite_accessory/hair/odango
name = "Odango"
icon_state = "hair_odango"
@@ -301,6 +465,10 @@
name = "Over Eye"
icon_state = "hair_shortovereye"
/datum/sprite_accessory/hair/oxton
name = "Oxton"
icon_state = "hair_oxton"
//Donator item - fractious
/datum/sprite_accessory/hair/over_eye_fr
name = "Over Eye (fract)"
@@ -331,6 +499,10 @@
name = "Pixie Cut"
icon_state = "hair_pixie"
/datum/sprite_accessory/hair/plait
name = "Plait"
icon_state = "hair_plait"
/datum/sprite_accessory/hair/pompadour
name = "Pompadour"
icon_state = "hair_pompadour"
@@ -383,10 +555,66 @@
name = "Ponytail (Side) 4"
icon_state = "hair_sidetail4"
/datum/sprite_accessory/hair/spikytail
name = "Ponytail (Spiky)"
icon_state = "hair_spikyponytail"
/datum/sprite_accessory/hair/poofy
name = "Poofy"
icon_state = "hair_poofy"
/datum/sprite_accessory/hair/poofy2
name = "Poofy 2"
icon_state = "hair_poofy2"
/datum/sprite_accessory/hair/quiff
name = "Quiff"
icon_state = "hair_quiff"
/datum/sprite_accessory/hair/ronin
name = "Ronin"
icon_state = "hair_ronin"
/datum/sprite_accessory/hair/row
name = "Rows"
icon_state = "hair_rows1"
/datum/sprite_accessory/hair/row2
name = "Rows 2"
icon_state = "hair_rows2"
/datum/sprite_accessory/hair/rowbun
name = "Rows (Bun)"
icon_state = "hair_rowbun"
/datum/sprite_accessory/hair/rowdualtail
name = "Rows (Pigtails)"
icon_state = "hair_rowdualtail"
/datum/sprite_accessory/hair/rowbraid
name = "Rows (Braid)"
icon_state = "hair_rowbraid"
/datum/sprite_accessory/hair/scully
name = "Scully"
icon_state = "hair_scully"
/datum/sprite_accessory/hair/shaggy
name = "Shaggy"
icon_state = "hair_shaggy"
/datum/sprite_accessory/hair/shaved
name = "Shaved"
icon_state = "hair_shaved"
/datum/sprite_accessory/hair/shavedpart
name = "Shaved (Part)"
icon_state = "hair_shavedpart"
/datum/sprite_accessory/hair/bangs_short
name = "Short Bangs"
icon_state = "hair_shortbangs"
/datum/sprite_accessory/hair/short
name = "Short Hair"
icon_state = "hair_a"
@@ -399,10 +627,30 @@
name = "Short Hair 3"
icon_state = "hair_shorthair3"
/datum/sprite_accessory/hair/shorthair4
name = "Short Hair 4"
icon_state = "hair_shorthair4"
/datum/sprite_accessory/hair/shorthair80s
name = "Short Hair 80s"
icon_state = "hair_80s"
/datum/sprite_accessory/hair/shorthairrosa
name = "Short Hair Rosa"
icon_state = "hair_rosa"
/datum/sprite_accessory/hair/stail
name = "Short Tail"
icon_state = "hair_stail"
/datum/sprite_accessory/hair/shoulderlength
name = "Shoulder-length Hair"
icon_state = "hair_b"
/datum/sprite_accessory/hair/shy
name = "Shy"
icon_state = "hair_shy"
/datum/sprite_accessory/hair/sidecut
name = "Sidecut"
icon_state = "hair_sidecut"
@@ -411,6 +659,10 @@
name = "Skinhead"
icon_state = "hair_skinhead"
/datum/sprite_accessory/hair/sleaze
name = "Sleaze"
icon_state = "hair_sleaze"
/datum/sprite_accessory/hair/protagonist
name = "Slightly Long Hair"
icon_state = "hair_protagonist"
@@ -435,14 +687,58 @@
name = "Swept Back Hair 2"
icon_state = "hair_swept2"
/datum/sprite_accessory/hair/thinning
name = "Thinning"
icon_state = "hair_thinning"
/datum/sprite_accessory/hair/thinningfront
name = "Thinning (Front)"
icon_state = "hair_thinningfront"
/datum/sprite_accessory/hair/thinningrear
name = "Thinning (Rear)"
icon_state = "hair_thinningrear"
/datum/sprite_accessory/hair/topknot
name = "Topknot"
icon_state = "hair_topknot"
/datum/sprite_accessory/hair/toriyama
name = "Toriyama"
icon_state = "hair_toriyama"
/datum/sprite_accessory/hair/toriyama2
name = "Toriyama 2"
icon_state = "hair_toriyama2"
/datum/sprite_accessory/hair/tressshoulder
name = "Tress Shoulder"
icon_state = "hair_tressshoulder"
/datum/sprite_accessory/hair/trimmed
name = "Trimmed"
icon_state = "hair_trimmed"
/datum/sprite_accessory/hair/trimflat
name = "Trimmed (Flat)"
icon_state = "hair_trimflat"
/datum/sprite_accessory/hair/twintails
name = "Twintails"
icon_state = "hair_twintail"
/datum/sprite_accessory/hair/longtwintails
name = "Twintails (Long)"
icon_state = "hair_longstraighttwintails"
/datum/sprite_accessory/hair/undercut
name = "Undercut"
icon_state = "hair_undercut"
/datum/sprite_accessory/hair/unkempt
name = "Unkempt"
icon_state = "hair_unkempt"
/datum/sprite_accessory/hair/updo
name = "Updo"
icon_state = "hair_updo"
@@ -463,161 +759,22 @@
name = "Very Long with Fringe"
icon_state = "hair_vlongfringe"
/*************** VIRGO PORTED HAIRS ****************************/
#define VHAIR(_name, new_state) /datum/sprite_accessory/hair/##new_state/icon_state=#new_state;/datum/sprite_accessory/hair/##new_state/name = #_name + " (Virgo)"
//VIRGO PORTED HAIRS
VHAIR("Short Hair Rosa", hair_rosa_s)
VHAIR("Short Hair 80s", hair_80s_s)
VHAIR("Long Bedhead", hair_long_bedhead_s)
VHAIR("Dave", hair_dave_s)
VHAIR("Country", hair_country_s)
VHAIR("Shy", hair_shy_s)
VHAIR("Unshaven Mohawk", hair_unshaven_mohawk_s)
VHAIR("Manbun", hair_manbun_s)
VHAIR("Longer Bedhead", hair_longer_bedhead_s)
VHAIR("Ponytail", hair_ponytail_s)
VHAIR("Ziegler", hair_ziegler_s)
VHAIR("Emo Fringe", hair_emofringe_s)
VHAIR("Very Short Over Eye Alt", hair_veryshortovereyealternate_s)
VHAIR("Shorthime", hair_shorthime_s)
VHAIR("High Tight", hair_hightight_s)
VHAIR("Thinning Front", hair_thinningfront_s)
VHAIR("Big Afro", hair_bigafro_s)
VHAIR("Afro", hair_afro_s)
VHAIR("High Braid", hair_hbraid_s)
VHAIR("Braid", hair_braid_s)
VHAIR("Sargeant", hair_sargeant_s)
VHAIR("Gelled", hair_gelled_s)
VHAIR("Kagami", hair_kagami_s)
VHAIR("ShortTail", hair_stail_s)
VHAIR("Gentle", hair_gentle_s)
VHAIR("Grande", hair_grande_s)
VHAIR("Bobcurl", hair_bobcurl_s)
VHAIR("Pompadeur", hair_pompadour_s)
VHAIR("Plait", hair_plait_s)
VHAIR("Long", hair_long_s)
VHAIR("Rattail", hair_rattail_s)
VHAIR("Tajspiky", hair_tajspiky_s)
VHAIR("Messy", hair_messy_s)
VHAIR("Bangs", hair_bangs_s)
VHAIR("TBraid", hair_tbraid_s)
VHAIR("Toriyama2", hair_toriyama2_s)
VHAIR("CIA", hair_cia_s)
VHAIR("Mulder", hair_mulder_s)
VHAIR("Scully", hair_scully_s)
VHAIR("Nitori", hair_nitori_s)
VHAIR("Joestar", hair_joestar_s)
VHAIR("Ponytail4", hair_ponytail4_s)
VHAIR("Ponytail5", hair_ponytail5_s)
VHAIR("Beehive2", hair_beehive2_s)
VHAIR("Short Braid", hair_shortbraid_s)
VHAIR("Reverse Mohawk", hair_reversemohawk_s)
VHAIR("SHort Bangs", hair_shortbangs_s)
VHAIR("Half Shaved", hair_halfshaved_s)
VHAIR("Longer Alt 2", hair_longeralt2_s)
VHAIR("Bun", hair_bun_s)
VHAIR("Curly", hair_curly_s)
VHAIR("Victory", hair_victory_s)
VHAIR("Ponytail6", hair_ponytail6_s)
VHAIR("Undercut3", hair_undercut3_s)
VHAIR("Bobcut Alt", hair_bobcultalt_s)
VHAIR("Fingerwave", hair_fingerwave_s)
VHAIR("Oxton", hair_oxton_s)
VHAIR("Poofy2", hair_poofy2_s)
VHAIR("Fringe Tail", hair_fringetail_s)
VHAIR("Bun3", hair_bun3_s)
VHAIR("Wisp", hair_wisp_s)
VHAIR("Undercut2", hair_undercut2_s)
VHAIR("TBob", hair_tbob_s)
VHAIR("Spiky Ponytail", hair_spikyponytail_s)
VHAIR("Rowbun", hair_rowbun_s)
VHAIR("Rowdualtail", hair_rowdualtail_s)
VHAIR("Rowbraid", hair_rowbraid_s)
VHAIR("Shaved Mohawk", hair_shavedmohawk_s)
VHAIR("Topknot", hair_topknot_s)
VHAIR("Ronin", hair_ronin_s)
VHAIR("Bowlcut2", hair_bowlcut2_s)
VHAIR("Thinning Rear", hair_thinningrear_s)
VHAIR("Thinning", hair_thinning_s)
VHAIR("Jade", hair_jade_s)
VHAIR("Bedhead", hair_bedhead_s)
VHAIR("Dreadlocks", hair_dreads_s)
VHAIR("Very Long", hair_vlong_s)
VHAIR("Jensen", hair_jensen_s)
VHAIR("Halfbang", hair_halfbang_s)
VHAIR("Kusangi", hair_kusangi_s)
VHAIR("Ponytail", hair_ponytail_s)
VHAIR("Ponytail3", hair_ponytail3_s)
VHAIR("Halfbang Alt", hair_halfbang_alt_s)
VHAIR("Bedhead V2", hair_bedheadv2_s)
VHAIR("Long Fringe", hair_longfringe_s)
VHAIR("Flair", hair_flair_s)
VHAIR("Bedhead V3", hair_bedheadv3_s)
VHAIR("Himecut", hair_himecut_s)
VHAIR("Curls", hair_curls_s)
VHAIR("Very Long Fringe", hair_vlongfringe_s)
VHAIR("Longest", hair_longest_s)
VHAIR("Father", hair_father_s)
VHAIR("Emo Long", hair_emolong_s)
VHAIR("Short Hair 3", hair_shorthair3_s)
VHAIR("Double Bun", hair_doublebun_s)
VHAIR("Sleeze", hair_sleeze_s)
VHAIR("Twintail", hair_twintail_s)
VHAIR("Emo 2", hair_emo2_s)
VHAIR("Low Fade", hair_lowfade_s)
VHAIR("Med Fade", hair_medfade_s)
VHAIR("High Fade", hair_highfade_s)
VHAIR("Bald Fade", hair_baldfade_s)
VHAIR("No Fade", hair_nofade_s)
VHAIR("Trim Flat", hair_trimflat_s)
VHAIR("Shaved", hair_shaved_s)
VHAIR("Trimmed", hair_trimmed_s)
VHAIR("Tight Bun", hair_tightbun_s)
VHAIR("Short Hair 4", hair_d_s)
VHAIR("Short Hair 5", hair_e_s)
VHAIR("Short Hair 6", hair_f_s)
VHAIR("Skinhead", hair_skinhead_s)
VHAIR("Afro2", hair_afro2_s)
VHAIR("Bobcut", hair_bobcut_s)
VHAIR("Emo", hair_emo_s)
VHAIR("Long Over Eye", hair_longovereye_s)
VHAIR("Feather", hair_feather_s)
VHAIR("Hitop", hair_hitop_s)
VHAIR("Short Over Eye", hair_shortoverye_s)
VHAIR("Straight", hair_straight_s)
VHAIR("Buzzcut", hair_buzzcut_s)
VHAIR("Combover", hair_combover_s)
VHAIR("Crewcut", hair_crewcut_s)
VHAIR("Devillock", hair_devilock_s)
VHAIR("Clean", hair_clean_s)
VHAIR("Shaggy", hair_shaggy_s)
VHAIR("Updo", hair_updo_s)
VHAIR("Mohawk", hair_mohawk_s)
VHAIR("Odango", hair_odango_s)
VHAIR("Ombre", hair_ombre_s)
VHAIR("Parted", hair_parted_s)
VHAIR("Quiff", hair_quiff_s)
VHAIR("Volaju", hair_volaju_s)
VHAIR("Bun2", hair_bun2_s)
VHAIR("Rows1", hair_rows1_s)
VHAIR("Rows2", hair_rows2_s)
VHAIR("Dandy Pompadour", hair_dandypompadour_s)
VHAIR("Poofy", hair_poofy_s)
VHAIR("Toriyama", hair_toriyama_s)
VHAIR("Drillruru", hair_drillruru_s)
VHAIR("Bowlcut", hair_bowlcut_s)
VHAIR("Coffee House", hair_coffeehouse_s)
VHAIR("Family Man", hair_thefamilyman_s)
VHAIR("Shaved Part", hair_shavedpart_s)
VHAIR("Modern", hair_modern_s)
VHAIR("One Shoulder", hair_oneshoulder_s)
VHAIR("Very Short Over Eye", hair_veryshortovereye_s)
VHAIR("Unkept", hair_unkept_s)
VHAIR("Wife", hair_wife_s)
VHAIR("Nia", hair_nia_s)
VHAIR("Undercut", hair_undercut_s)
VHAIR("Bobcut Alt", hair_bobcutalt_s)
VHAIR("Short Hair 4 alt", hair_shorthair4_s)
VHAIR("Tressshoulder", hair_tressshoulder_s)
//END
#undef VHAIR
/datum/sprite_accessory/hair/short_oe
name = "Very Short Over Eye"
icon_state = "hair_veryshortovereye"
/datum/sprite_accessory/hair/short_oe_alt
name = "Very Short Over Eye (Alt)"
icon_state = "hair_veryshortovereyealternate"
/datum/sprite_accessory/hair/volaju
name = "Volaju"
icon_state = "hair_volaju"
/datum/sprite_accessory/hair/wisp
name = "Wisp"
icon_state = "hair_wisp"
/datum/sprite_accessory/hair/ziegler
name = "Ziegler"
icon_state = "hair_ziegler"
@@ -24,7 +24,7 @@
/datum/notificationpanel/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.observer_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "notificationpanel", "Notification Preferences", 700, 700, master_ui, state)
ui = new(user, src, ui_key, "notificationpanel", "Notification Preferences", 270, 360, master_ui, state)
ui.open()
/datum/notificationpanel/ui_data(mob/user)
+9 -7
View File
@@ -232,14 +232,16 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
var/b_val
var/g_val
var/color_format = length(input_color)
if(color_format != length_char(input_color))
return 0
if(color_format == 3)
r_val = hex2num(copytext(input_color, 1, 2))*16
g_val = hex2num(copytext(input_color, 2, 3))*16
b_val = hex2num(copytext(input_color, 3, 0))*16
r_val = hex2num(copytext(input_color, 1, 2)) * 16
g_val = hex2num(copytext(input_color, 2, 3)) * 16
b_val = hex2num(copytext(input_color, 3, 0)) * 16
else if(color_format == 6)
r_val = hex2num(copytext(input_color, 1, 3))
g_val = hex2num(copytext(input_color, 3, 5))
b_val = hex2num(copytext(input_color, 5, 0))
b_val = hex2num(copytext(input_color, 5, 7))
else
return 0 //If the color format is not 3 or 6, you're using an unexpected way to represent a color.
@@ -253,7 +255,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
if(b_val > 255)
b_val = 255
return num2hex(r_val, 2) + num2hex(g_val, 2) + num2hex(b_val, 2)
return copytext(rgb(r_val, g_val, b_val), 2)
/*
Transfer_mind is there to check if mob is being deleted/not going to have a body.
@@ -263,7 +265,7 @@ Works together with spawning an observer, noted above.
/mob/proc/ghostize(can_reenter_corpse = TRUE, special = FALSE, penalize = FALSE, voluntary = FALSE)
penalize = suiciding || penalize // suicide squad.
voluntary_ghosted = voluntary
if(!key || cmptext(copytext(key,1,2),"@") || (SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special, penalize) & COMPONENT_BLOCK_GHOSTING))
if(!key || key[1] == "@" || (SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special, penalize) & COMPONENT_BLOCK_GHOSTING))
return //mob has no key, is an aghost or some component hijacked.
stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now
var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc.
@@ -365,7 +367,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(!can_reenter_corpse)
to_chat(src, "<span class='warning'>You cannot re-enter your body.</span>")
return
if(mind.current.key && copytext(mind.current.key,1,2)!="@") //makes sure we don't accidentally kick any clients
if(mind.current.key && mind.current.key[1] != "@") //makes sure we don't accidentally kick any clients
to_chat(usr, "<span class='warning'>Another consciousness is in your body...It is resisting you.</span>")
return
client.change_view(CONFIG_GET(string/default_view))
+3 -4
View File
@@ -1,13 +1,12 @@
/mob/dead/observer/say(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN))
if (!message)
return
var/message_mode = get_message_mode(message)
if(client && (message_mode == MODE_ADMIN || message_mode == MODE_DEADMIN))
message = copytext(message, 3)
if(findtext(message, " ", 1, 2))
message = copytext(message, 2)
message = copytext_char(message, 3)
message = trim_left(message)
if(message_mode == MODE_ADMIN)
client.cmd_admin_say(message)
+1 -1
View File
@@ -4,7 +4,7 @@
var/param = message
var/custom_param = findchar(act, " ")
if(custom_param)
param = copytext(act, custom_param + 1, length(act) + 1)
param = copytext(act, custom_param + length(act[custom_param]))
act = copytext(act, 1, custom_param)
var/datum/emote/E
+6 -7
View File
@@ -33,7 +33,7 @@
bleed_rate = 0
return
if(bleed_rate <= 0)
if(bleed_rate < 0)
bleed_rate = 0
if(HAS_TRAIT(src, TRAIT_NOMARROW)) //Bloodsuckers don't need to be here.
@@ -94,12 +94,12 @@
//We want an accurate reading of .len
listclearnulls(BP.embedded_objects)
temp_bleed += 0.5*BP.embedded_objects.len
temp_bleed += 0.5 * BP.embedded_objects.len
if(brutedamage >= 20)
temp_bleed += (brutedamage * 0.013)
bleed_rate = max(bleed_rate - 0.50, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases
bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases
if(bleed_rate && !bleedsuppress && !(HAS_TRAIT(src, TRAIT_FAKEDEATH)))
bleed(bleed_rate)
@@ -185,7 +185,7 @@
var/datum/disease/D = thing
blood_data["viruses"] += D.Copy()
blood_data["blood_DNA"] = copytext(dna.unique_enzymes,1,0)
blood_data["blood_DNA"] = dna.unique_enzymes
blood_data["bloodcolor"] = bloodtype_to_color(dna.blood_type)
if(disease_resistances && disease_resistances.len)
blood_data["resistances"] = disease_resistances.Copy()
@@ -204,7 +204,7 @@
if(!suiciding)
blood_data["cloneable"] = 1
blood_data["blood_type"] = copytext(dna.blood_type,1,0)
blood_data["blood_type"] = dna.blood_type
blood_data["gender"] = gender
blood_data["real_name"] = real_name
blood_data["features"] = dna.features
@@ -289,8 +289,7 @@
drop.update_icon()
return
else
temp_blood_DNA = list()
temp_blood_DNA |= drop.blood_DNA.Copy() //we transfer the dna from the drip to the splatter
temp_blood_DNA = drop.blood_DNA.Copy() //transfer dna from drip to splatter.
qdel(drop)//the drip is replaced by a bigger splatter
else
drop = new(T, get_static_viruses())
+7 -4
View File
@@ -55,16 +55,18 @@
//Update the body's icon so it doesnt appear debrained anymore
C.update_hair()
/obj/item/organ/brain/Remove(mob/living/carbon/C, special = 0, no_id_transfer = FALSE)
..()
/obj/item/organ/brain/Remove(special = FALSE, no_id_transfer = FALSE)
. = ..()
var/mob/living/carbon/C = .
for(var/X in traumas)
var/datum/brain_trauma/BT = X
BT.on_lose(TRUE)
BT.owner = null
if((!gc_destroyed || (owner && !owner.gc_destroyed)) && !no_id_transfer)
if((!QDELETED(src) || C) && !no_id_transfer)
transfer_identity(C)
C.update_hair()
if(C)
C.update_hair()
/obj/item/organ/brain/prepare_eat()
return // Too important to eat.
@@ -389,6 +391,7 @@
if(resilience)
actual_trauma.resilience = resilience
SSblackbox.record_feedback("tally", "traumas", 1, actual_trauma.type)
return actual_trauma
//Add a random trauma of a certain subtype
/obj/item/organ/brain/proc/gain_trauma_type(brain_trauma_type = /datum/brain_trauma, resilience)
@@ -120,7 +120,8 @@ Des: Removes all infected images from the alien.
/mob/living/carbon/alien/proc/RemoveInfectionImages()
if (client)
for(var/image/I in client.images)
if(dd_hasprefix_case(I.icon_state, "infected"))
var/searchfor = "infected"
if(findtext(I.icon_state, searchfor, 1, length(searchfor) + 1))
qdel(I)
return
@@ -13,7 +13,7 @@
var/alt_inhands_file = 'icons/mob/alienqueen.dmi'
/mob/living/carbon/alien/humanoid/royal/can_inject()
/mob/living/carbon/alien/humanoid/royal/can_inject(mob/user, error_msg, target_zone, penetrate_thick = FALSE, bypass_immunity = FALSE)
return 0
/mob/living/carbon/alien/humanoid/royal/queen
+12 -10
View File
@@ -20,9 +20,10 @@
M.AddAbility(P)
/obj/item/organ/alien/Remove(mob/living/carbon/M, special = 0)
for(var/obj/effect/proc_holder/alien/P in alien_powers)
M.RemoveAbility(P)
/obj/item/organ/alien/Remove(special = FALSE)
if(owner)
for(var/obj/effect/proc_holder/alien/P in alien_powers)
owner.RemoveAbility(P)
..()
/obj/item/organ/alien/prepare_eat()
@@ -100,11 +101,11 @@
var/mob/living/carbon/alien/A = M
A.updatePlasmaDisplay()
/obj/item/organ/alien/plasmavessel/Remove(mob/living/carbon/M, special = 0)
..()
if(isalien(M))
var/mob/living/carbon/alien/A = M
/obj/item/organ/alien/plasmavessel/Remove(special = FALSE)
if(owner && isalien(owner))
var/mob/living/carbon/alien/A = owner
A.updatePlasmaDisplay()
return ..()
#define QUEEN_DEATH_DEBUFF_DURATION 2400
@@ -121,9 +122,10 @@
..()
M.faction |= ROLE_ALIEN
/obj/item/organ/alien/hivenode/Remove(mob/living/carbon/M, special = 0)
M.faction -= ROLE_ALIEN
..()
/obj/item/organ/alien/hivenode/Remove(special = FALSE)
if(owner)
owner.faction -= ROLE_ALIEN
return ..()
//When the alien queen dies, all aliens suffer a penalty as punishment for failing to protect her.
/obj/item/organ/alien/hivenode/proc/queen_death()
@@ -135,5 +135,6 @@ Des: Removes all images from the mob infected by this embryo
for(var/mob/living/carbon/alien/alien in GLOB.player_list)
if(alien.client)
for(var/image/I in alien.client.images)
if(dd_hasprefix_case(I.icon_state, "infected") && I.loc == C)
var/searchfor = "infected"
if(I.loc == owner && findtext(I.icon_state, searchfor, 1, length(searchfor) + 1))
qdel(I)
@@ -252,7 +252,9 @@
return 0
if(M.getorgan(/obj/item/organ/alien/hivenode))
return 0
if(isvamp(M))
return 0
if(ismonkey(M))
return 1
+4 -4
View File
@@ -230,7 +230,7 @@
dat += "<BR><B>Back:</B> <A href='?src=[REF(src)];item=[SLOT_BACK]'>[back ? back : "Nothing"]</A>"
if(istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/tank))
if(!HAS_TRAIT(src, TRAIT_NO_INTERNALS) && istype(wear_mask, /obj/item/clothing/mask) && istype(back, /obj/item/tank))
dat += "<BR><A href='?src=[REF(src)];internal=1'>[internal ? "Disable Internals" : "Set Internals"]</A>"
if(handcuffed)
@@ -249,7 +249,7 @@
..()
//strip panel
if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY))
if(href_list["internal"])
if(href_list["internal"] && !HAS_TRAIT(src, TRAIT_NO_INTERNALS))
var/slot = text2num(href_list["internal"])
var/obj/item/ITEM = get_item_by_slot(slot)
if(ITEM && istype(ITEM, /obj/item/tank) && wear_mask && (wear_mask.clothing_flags & ALLOWINTERNALS))
@@ -533,7 +533,7 @@
break //Guess we're out of organs!
var/obj/item/organ/guts = pick(internal_organs)
var/turf/T = get_turf(src)
guts.Remove(src)
guts.Remove()
guts.forceMove(T)
var/atom/throw_target = get_edge_target_turf(guts, dir)
guts.throw_at(throw_target, power, 4, src)
@@ -879,7 +879,7 @@
var/obj/item/organ/O = X
if(prob(50))
organs_amt++
O.Remove(src)
O.Remove()
O.forceMove(drop_location())
if(organs_amt)
to_chat(user, "<span class='notice'>You retrieve some of [src]\'s internal organs!</span>")
@@ -49,7 +49,6 @@
//Gets filled up in create_bodyparts()
var/list/hand_bodyparts = list() //a collection of arms (or actually whatever the fug /bodyparts you monsters use to wreck my systems)
var/list/leg_bodyparts = list()
var/icon_render_key = ""
var/static/list/limb_icon_cache = list()
@@ -13,8 +13,8 @@
. += SOFTCRIT_ADD_SLOWDOWN
/mob/living/carbon/slip(knockdown_amount, obj/O, lube)
if(movement_type & FLYING)
return 0
if(movement_type & FLYING && !(lube & FLYING_DOESNT_HELP))
return FALSE
if(!(lube&SLIDE_ICE))
log_combat(src, (O ? O : get_turf(src)), "slipped on the", null, ((lube & SLIDE) ? "(LUBE)" : null))
return loc.handle_slip(src, knockdown_amount, O, lube)
@@ -87,7 +87,7 @@
if(!forced && HAS_TRAIT(src, TRAIT_TOXINLOVER)) //damage becomes healing and healing becomes damage
amount = -amount
if(amount > 0)
blood_volume -= 3*amount // x5 is too much, x3 should be still penalizing enough.
blood_volume -= 3 * amount //5x was too much, this is punishing enough.
else
blood_volume -= amount
return ..()
+2 -2
View File
@@ -43,7 +43,7 @@
continue
var/org_zone = check_zone(O.zone) //both groin and chest organs.
if(org_zone == BODY_ZONE_CHEST)
O.Remove(src)
O.Remove()
O.forceMove(Tsec)
O.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
else
@@ -55,7 +55,7 @@
if(no_organs && !istype(I, /obj/item/organ/brain))
qdel(I)
continue
I.Remove(src)
I.Remove()
I.forceMove(Tsec)
I.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
@@ -44,7 +44,8 @@
if(M.occupant == src)
M.go_out()
dna.species.spec_death(gibbed, src)
if(!QDELETED(dna)) //The gibbed param is bit redundant here since dna won't exist at this point if they got deleted.
dna.species.spec_death(gibbed, src)
if(SSticker.HasRoundStarted())
SSblackbox.ReportDeath(src)
+11 -14
View File
@@ -385,20 +385,17 @@
else if(isobserver(user) && traitstring)
. += "<span class='info'><b>Traits:</b> [traitstring]</span>"
if(print_flavor_text())
if(get_visible_name() == "Unknown") //Are we sure we know who this is? Don't show flavor text unless we can recognize them. Prevents certain metagaming with impersonation.
. += "...?"
else if(skipface) //Sometimes we're not unknown, but impersonating someone in a hardsuit, let's not reveal our flavor text then either.
. += "...?"
else
. += "[print_flavor_text()]"
if(print_flavor_text_2())
if(get_visible_name() == "Unknown") //Are we sure we know who this is? Don't show flavor text unless we can recognize them. Prevents certain metagaming with impersonation.
. += "...?"
else if(skipface) //Sometimes we're not unknown, but impersonating someone in a hardsuit, let's not reveal our flavor text then either.
. += "...?"
else
. += "[print_flavor_text_2()]"
//No flavor text unless the face can be seen. Prevents certain metagaming with impersonation.
var/invisible_man = skipface || get_visible_name() == "Unknown"
if(invisible_man)
. += "...?"
else
var/flavor = print_flavor_text()
if(flavor)
. += flavor
var/temp_flavor = print_flavor_text_2()
if(temp_flavor)
. += temp_flavor
. += "*---------*</span>"
/mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects!
+5 -10
View File
@@ -25,8 +25,7 @@
create_internal_organs() //most of it is done in set_species now, this is only for parent call
physiology = new()
handcrafting = new()
AddComponent(/datum/component/personal_crafting)
. = ..()
if(CONFIG_GET(flag/disable_stambuffer))
@@ -45,10 +44,6 @@
QDEL_NULL_LIST(vore_organs) // CITADEL EDIT belly stuff
return ..()
/mob/living/carbon/human/OpenCraftingMenu()
handcrafting.ui_interact(src)
/mob/living/carbon/human/prepare_data_huds()
//Update med hud images...
..()
@@ -85,7 +80,7 @@
var/obj/item/clothing/suit/space/space_ninja/SN = wear_suit
if(statpanel("SpiderOS"))
stat("SpiderOS Status:","[SN.s_initialized ? "Initialized" : "Disabled"]")
stat("Current Time:", "[STATION_TIME_TIMESTAMP("hh:mm:ss")]")
stat("Current Time:", "[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]")
if(SN.s_initialized)
//Suit gear
stat("Energy Charge:", "[round(SN.cell.charge/100)]%")
@@ -439,7 +434,7 @@
return
else if(!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security))
return
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, STATION_TIME_TIMESTAMP("hh:mm:ss"))
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, STATION_TIME_TIMESTAMP("hh:mm:ss", world.time))
GLOB.data_core.addMinorCrime(R.fields["id"], crime)
investigate_log("New Minor Crime: <strong>[t1]</strong>: [t2] | Added to [R.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS)
to_chat(usr, "<span class='notice'>Successfully added a minor crime.</span>")
@@ -455,7 +450,7 @@
return
else if (!istype(H.glasses, /obj/item/clothing/glasses/hud/security) && !istype(H.getorganslot(ORGAN_SLOT_HUD), /obj/item/organ/cyberimp/eyes/hud/security))
return
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, STATION_TIME_TIMESTAMP("hh:mm:ss"))
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, allowed_access, STATION_TIME_TIMESTAMP("hh:mm:ss", world.time))
GLOB.data_core.addMajorCrime(R.fields["id"], crime)
investigate_log("New Major Crime: <strong>[t1]</strong>: [t2] | Added to [R.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS)
to_chat(usr, "<span class='notice'>Successfully added a major crime.</span>")
@@ -488,7 +483,7 @@
var/counter = 1
while(R.fields[text("com_[]", counter)])
counter++
R.fields[text("com_[]", counter)] = text("Made by [] on [] [], []<BR>[]", allowed_access, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1)
R.fields["com_[counter]"] = "Made by [allowed_access] on [STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)] [time2text(world.realtime, "MMM DD")], [GLOB.year_integer]<BR>[t1]"
to_chat(usr, "<span class='notice'>Successfully added comment.</span>")
return
to_chat(usr, "<span class='warning'>Unable to locate a data core entry for this person.</span>")
@@ -336,7 +336,8 @@
if(bomb_armor < EXPLODE_GIB_THRESHOLD) //gibs the mob if their bomb armor is lower than EXPLODE_GIB_THRESHOLD
for(var/I in contents)
var/atom/A = I
A.ex_act(severity)
if(!QDELETED(A))
A.ex_act(severity)
gib()
return
else
@@ -59,7 +59,6 @@
var/custom_species = null
var/datum/personal_crafting/handcrafting
var/datum/physiology/physiology
var/list/datum/bioware = list()
@@ -59,7 +59,7 @@
var/obj/effect/decal/cleanable/blood/footprints/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints) in T
if(oldFP && (oldFP.blood_state == S.blood_state && oldFP.color == bloodtype_to_color(S.last_bloodtype)))
return
S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state]-BLOOD_LOSS_PER_STEP)
S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state] - BLOOD_LOSS_PER_STEP)
var/obj/effect/decal/cleanable/blood/footprints/FP = new /obj/effect/decal/cleanable/blood/footprints(T)
FP.blood_state = S.blood_state
FP.entered_dirs |= dir
+9 -17
View File
@@ -87,30 +87,22 @@
/mob/living/carbon/human/proc/forcesay(list/append) //this proc is at the bottom of the file because quote fuckery makes notepad++ cri
if(stat == CONSCIOUS)
if(client)
var/virgin = 1 //has the text been modified yet?
var/temp = winget(client, "input", "text")
if(findtextEx(temp, "Say \"", 1, 7) && length(temp) > 5) //"case sensitive means
var/say_starter = "Say \"" //"
if(findtextEx(temp, say_starter, 1, length(say_starter) + 1) && length(temp) > length(say_starter)) //case sensitive means
temp = replacetext(temp, ";", "") //general radio
temp = trim_left(copytext(temp, length(say_starter + 1)))
temp = replacetext(temp, ";", "", 1, 2) //general radio
while(trim_left(temp)[1] == ":") //dept radio again (necessary)
temp = copytext_char(trim_left(temp), 3)
if(findtext(trim_left(temp), ":", 6, 7)) //dept radio
temp = copytext(trim_left(temp), 8)
virgin = 0
if(virgin)
temp = copytext(trim_left(temp), 6) //normal speech
virgin = 0
while(findtext(trim_left(temp), ":", 1, 2)) //dept radio again (necessary)
temp = copytext(trim_left(temp), 3)
if(findtext(temp, "*", 1, 2)) //emotes
if(temp[1] == "*") //emotes
return
var/trimmed = trim_left(temp)
if(length(trimmed))
if(append)
temp += pick(append)
trimmed += pick(append)
say(temp)
say(trimmed)
winset(client, "input", "text=[null]")
+30 -32
View File
@@ -190,21 +190,21 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(brain && (replace_current || !should_have_brain))
if(!brain.decoy_override)//Just keep it if it's fake
brain.Remove(C,TRUE,TRUE)
brain.Remove(TRUE,TRUE)
QDEL_NULL(brain)
if(should_have_brain && !brain)
brain = new mutant_brain()
brain.Insert(C, TRUE, TRUE)
if(heart && (!should_have_heart || replace_current))
heart.Remove(C,1)
heart.Remove(TRUE)
QDEL_NULL(heart)
if(should_have_heart && !heart)
heart = new mutant_heart()
heart.Insert(C)
if(lungs && (!should_have_lungs || replace_current))
lungs.Remove(C,1)
lungs.Remove(TRUE)
QDEL_NULL(lungs)
if(should_have_lungs && !lungs)
if(mutantlungs)
@@ -214,7 +214,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
lungs.Insert(C)
if(liver && (!should_have_liver || replace_current))
liver.Remove(C,1)
liver.Remove(TRUE)
QDEL_NULL(liver)
if(should_have_liver && !liver)
if(mutantliver)
@@ -224,7 +224,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
liver.Insert(C)
if(stomach && (!should_have_stomach || replace_current))
stomach.Remove(C,1)
stomach.Remove(TRUE)
QDEL_NULL(stomach)
if(should_have_stomach && !stomach)
if(mutantstomach)
@@ -234,14 +234,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
stomach.Insert(C)
if(appendix && (!should_have_appendix || replace_current))
appendix.Remove(C,1)
appendix.Remove(TRUE)
QDEL_NULL(appendix)
if(should_have_appendix && !appendix)
appendix = new()
appendix.Insert(C)
if(tail && (!should_have_tail || replace_current))
tail.Remove(C,1)
tail.Remove(TRUE)
QDEL_NULL(tail)
if(should_have_tail && !tail)
tail = new mutanttail()
@@ -249,21 +249,21 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(C.get_bodypart(BODY_ZONE_HEAD))
if(eyes && (replace_current || !should_have_eyes))
eyes.Remove(C,1)
eyes.Remove(TRUE)
QDEL_NULL(eyes)
if(should_have_eyes && !eyes)
eyes = new mutanteyes
eyes.Insert(C, TRUE)
if(ears && (replace_current || !should_have_ears))
ears.Remove(C,1)
ears.Remove(TRUE)
QDEL_NULL(ears)
if(should_have_ears && !ears)
ears = new mutantears
ears.Insert(C)
if(tongue && (replace_current || !should_have_tongue))
tongue.Remove(C,1)
tongue.Remove(TRUE)
QDEL_NULL(tongue)
if(should_have_tongue && !tongue)
tongue = new mutanttongue
@@ -273,7 +273,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
for(var/mutantorgan in old_species.mutant_organs)
var/obj/item/organ/I = C.getorgan(mutantorgan)
if(I)
I.Remove(C)
I.Remove()
QDEL_NULL(I)
for(var/path in mutant_organs)
@@ -1594,7 +1594,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if (!HAS_TRAIT(target, TRAIT_PERMABONER))
stop_wagging_tail(target)
return FALSE
else if(aim_for_groin && (target == user || target.lying || same_dir) && (target_on_help || target_restrained || target_aiming_for_groin))
else if(!(user.client?.prefs.cit_toggles & NO_ASS_SLAP) && aim_for_groin && (target == user || target.lying || same_dir) && (target_on_help || target_restrained || target_aiming_for_groin))
if(target.client?.prefs.cit_toggles & NO_ASS_SLAP)
to_chat(user,"A force stays your hand, preventing you from slapping \the [target]'s ass!")
return FALSE
@@ -1610,7 +1610,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
"<span class='danger'>\The [user] slaps \the [target]'s ass!</span>",\
"<span class='notice'>You slap [user == target ? "your" : "\the [target]'s"] ass!</span>",\
"You hear a slap."
)
)
return FALSE
else if(attacker_style && attacker_style.disarm_act(user,target))
return 1
@@ -1893,6 +1893,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
if(get_turf(target) == target_oldturf)
shove_blocked = TRUE
var/append_message = ""
if(shove_blocked && !target.buckled)
var/directional_blocked = !target.Adjacent(target_shove_turf)
var/targetatrest = target.resting
@@ -1906,33 +1907,30 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
target_collateral_human.Knockdown(SHOVE_KNOCKDOWN_COLLATERAL)
user.visible_message("<span class='danger'>[user.name] shoves [target.name] into [target_collateral_human.name]!</span>",
"<span class='danger'>You shove [target.name] into [target_collateral_human.name]!</span>", null, COMBAT_MESSAGE_RANGE)
log_combat(user, target, "shoved", "into [target_collateral_human.name]")
append_message += ", into [target_collateral_human.name]"
else
user.visible_message("<span class='danger'>[user.name] shoves [target.name]!</span>",
"<span class='danger'>You shove [target.name]!</span>", null, COMBAT_MESSAGE_RANGE)
var/target_held_item = target.get_active_held_item()
var/knocked_item = FALSE
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
target_held_item = null
if(!target.has_movespeed_modifier(MOVESPEED_ID_SHOVE))
target.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH)
if(target_held_item)
var/obj/item/target_held_item = target.get_active_held_item()
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
target_held_item = null
if(!target.has_movespeed_modifier(MOVESPEED_ID_SHOVE))
target.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH)
if(target_held_item)
if(!HAS_TRAIT(target_held_item, TRAIT_NODROP))
target.visible_message("<span class='danger'>[target.name]'s grip on \the [target_held_item] loosens!</span>",
"<span class='danger'>Your grip on \the [target_held_item] loosens!</span>", null, COMBAT_MESSAGE_RANGE)
addtimer(CALLBACK(target, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH)
else if(target_held_item)
target.dropItemToGround(target_held_item)
knocked_item = TRUE
append_message += ", loosening their grip on [target_held_item]"
else
append_message += ", but couldn't loose their grip on [target_held_item]"
addtimer(CALLBACK(target, /mob/living/carbon/human/proc/clear_shove_slowdown), SHOVE_SLOWDOWN_LENGTH)
else if(target_held_item)
if(target.dropItemToGround(target_held_item))
target.visible_message("<span class='danger'>[target.name] drops \the [target_held_item]!!</span>",
"<span class='danger'>You drop \the [target_held_item]!!</span>", null, COMBAT_MESSAGE_RANGE)
var/append_message = ""
if(target_held_item)
if(knocked_item)
append_message = "causing them to drop [target_held_item]"
else
append_message = "loosening their grip on [target_held_item]"
log_combat(user, target, "shoved", append_message)
append_message += ", causing them to drop [target_held_item]"
log_combat(user, target, "shoved", append_message)
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE)
var/hit_percent = (100-(blocked+armor))/100
@@ -31,6 +31,7 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
. = ..()
var/dwarf_hair = pick("Beard (Dwarf)", "Beard (Very Long)", "Beard (Long)") //beard roullette
var/mob/living/carbon/human/H = C
H.grant_language(/datum/language/dwarf)
H.facial_hair_style = dwarf_hair
H.update_hair()
H.transform = H.transform.Scale(1, 0.8) //We use scale, and yeah. Dwarves can become gnomes with DWARFISM.
@@ -41,6 +42,7 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
. = ..()
H.transform = H.transform.Scale(1, 1.25) //And we undo it.
UnregisterSignal(H, COMSIG_MOB_SAY) //We register handle_speech is not being used.
H.remove_language(/datum/language/dwarf)
//Dwarf Name stuff
/proc/dwarf_name() //hello caller: my name is urist mcuristurister
@@ -88,7 +88,7 @@
if(NT)
NT.Insert(H, drop_if_replaced = FALSE)
else
tail.Remove(H)
tail.Remove()
/proc/mass_purrbation()
for(var/M in GLOB.mob_list)
@@ -849,6 +849,8 @@
linked_mobs.Add(M)
if(!selflink)
to_chat(M, "<span class='notice'>You are now connected to [slimelink_owner.real_name]'s Slime Link.</span>")
RegisterSignal(M, COMSIG_MOB_DEATH , .proc/unlink_mob)
RegisterSignal(M, COMSIG_PARENT_QDELETING, .proc/unlink_mob)
var/datum/action/innate/linked_speech/action = new(src)
linked_actions.Add(action)
action.Grant(M)
@@ -858,6 +860,7 @@
var/link_id = linked_mobs.Find(M)
if(!(link_id))
return
UnregisterSignal(M, list(COMSIG_MOB_DEATH, COMSIG_PARENT_QDELETING))
var/datum/action/innate/linked_speech/action = linked_actions[link_id]
action.Remove(M)
to_chat(M, "<span class='notice'>You are no longer connected to [slimelink_owner.real_name]'s Slime Link.</span>")
@@ -890,18 +893,11 @@
Remove(H)
return
if(QDELETED(H) || H.stat == DEAD)
species.unlink_mob(H)
return
if(message)
var/msg = "<i><font color=#008CA2>\[[species.slimelink_owner.real_name]'s Slime Link\] <b>[H]:</b> [message]</font></i>"
log_directed_talk(H, species.slimelink_owner, msg, LOG_SAY, "slime link")
for(var/X in species.linked_mobs)
var/mob/living/M = X
if(QDELETED(M) || M.stat == DEAD)
species.unlink_mob(M)
continue
to_chat(M, msg)
for(var/X in GLOB.dead_mob_list)
@@ -31,14 +31,15 @@
/datum/species/mush/on_species_gain(mob/living/carbon/C, datum/species/old_species)
. = ..()
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(!H.dna.features["caps"])
H.dna.features["caps"] = "Round"
handle_mutant_bodyparts(H)
H.faction |= "mushroom"
mush = new()
mush.teach(H, TRUE)
if(!ishuman(C))
return
var/mob/living/carbon/human/H = C
if(!H.dna.features["caps"])
H.dna.features["caps"] = "Round"
handle_mutant_bodyparts(H)
H.faction |= "mushroom"
mush = new()
mush.teach(H, TRUE)
RegisterSignal(C, COMSIG_MOB_ON_NEW_MIND, .proc/on_new_mind)
/datum/species/mush/proc/on_new_mind(mob/owner)
@@ -54,7 +54,7 @@
..()
/datum/species/plasmaman/before_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE)
var/current_job = J.title
var/current_job = J?.title
var/datum/outfit/plasmaman/O = new /datum/outfit/plasmaman
switch(current_job)
if("Chaplain")
@@ -84,10 +84,10 @@
shadowwalk = SW
/obj/item/organ/brain/nightmare/Remove(mob/living/carbon/M, special = 0)
if(shadowwalk)
M.RemoveSpell(shadowwalk)
..()
/obj/item/organ/brain/nightmare/Remove(special = FALSE)
if(shadowwalk && owner)
owner.RemoveSpell(shadowwalk)
return ..()
/obj/item/organ/heart/nightmare
@@ -120,12 +120,12 @@
blade = new/obj/item/light_eater
M.put_in_hands(blade)
/obj/item/organ/heart/nightmare/Remove(mob/living/carbon/M, special = 0)
/obj/item/organ/heart/nightmare/Remove(special = FALSE)
respawn_progress = 0
if(blade && special != HEART_SPECIAL_SHADOWIFY)
M.visible_message("<span class='warning'>\The [blade] disintegrates!</span>")
if(!QDELETED(owner) && blade && special != HEART_SPECIAL_SHADOWIFY)
owner.visible_message("<span class='warning'>\The [blade] disintegrates!</span>")
QDEL_NULL(blade)
..()
return ..()
/obj/item/organ/heart/nightmare/Stop()
return 0
@@ -146,7 +146,7 @@
owner.revive(full_heal = TRUE)
if(!(owner.dna.species.id == "shadow" || owner.dna.species.id == "nightmare"))
var/mob/living/carbon/old_owner = owner
Remove(owner, HEART_SPECIAL_SHADOWIFY)
Remove(HEART_SPECIAL_SHADOWIFY)
old_owner.set_species(/datum/species/shadow)
Insert(old_owner, HEART_SPECIAL_SHADOWIFY)
to_chat(owner, "<span class='userdanger'>You feel the shadows invade your skin, leaping into the center of your chest! You're alive!</span>")
@@ -382,9 +382,6 @@ There are several things that need to be remembered:
if(wear_suit)
var/obj/item/clothing/suit/S = wear_suit
var/item_level_support = FALSE // LISTEN! If you must degrade the code with further snowflake checks, at least keep it compatible with worn non-clothing items!
if(!istype(S))
item_level_support = TRUE
wear_suit.screen_loc = ui_oclothing
if(client && hud_used && hud_used.hud_shown)
if(hud_used.inventory_shown)
@@ -400,7 +397,7 @@ There are several things that need to be remembered:
if("taur" in dna.species.mutant_bodyparts)
T = GLOB.taur_list[dna.features["taur"]]
if(!item_level_support && S.mutantrace_variation)
if(S.mutantrace_variation)
if(T?.taur_mode)
var/init_worn_icon = worn_icon
variation_flag |= S.mutantrace_variation & T.taur_mode || S.mutantrace_variation & T.alt_taur_mode
@@ -464,6 +461,8 @@ There are several things that need to be remembered:
var/alt_icon = M.alternate_worn_icon || 'icons/mob/mask.dmi'
var/muzzled = FALSE
var/variation_flag = NONE
if(head && (head.flags_inv & HIDEMASK))
return
if(("mam_snouts" in dna.species.default_features) && dna.features["mam_snouts"] != "None")
muzzled = TRUE
if(!muzzled && ("snout" in dna.species.default_features) && dna.features["snout"] != "None")
+4 -3
View File
@@ -334,9 +334,10 @@
var/obj/item/clothing/check
var/internals = FALSE
for(check in GET_INTERNAL_SLOTS(src))
if(CHECK_BITFIELD(check.clothing_flags, ALLOWINTERNALS))
internals = TRUE
if(!HAS_TRAIT(src, TRAIT_NO_INTERNALS))
for(check in GET_INTERNAL_SLOTS(src))
if(CHECK_BITFIELD(check.clothing_flags, ALLOWINTERNALS))
internals = TRUE
if(internal)
if(internal.loc != src)
internal = null
@@ -30,6 +30,9 @@
/mob/living/carbon/monkey/handle_mutations_and_radiation()
if(radiation)
if(radiation > RAD_MOB_MUTATE && prob((radiation - RAD_MOB_MUTATE) / 25))
gorillize()
return
if(radiation > RAD_MOB_KNOCKDOWN && prob(RAD_MOB_KNOCKDOWN_PROB))
if(!IsKnockdown())
emote("collapse")
@@ -41,10 +44,6 @@
easy_randmut(NEGATIVE+MINOR_NEGATIVE)
emote("gasp")
domutcheck()
if(radiation > RAD_MOB_MUTATE * 2 && prob(50))
gorillize()
return
if(radiation > RAD_MOB_VOMIT && prob(RAD_MOB_VOMIT_PROB))
vomit(10, TRUE)
return ..()
+1 -1
View File
@@ -61,7 +61,7 @@
stat = DEAD
unset_machine()
timeofdeath = world.time
tod = STATION_TIME_TIMESTAMP("hh:mm:ss")
tod = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)
for(var/obj/item/I in contents)
I.on_mob_death(src, gibbed)
if(mind)
+31 -23
View File
@@ -200,25 +200,25 @@
message_param = "blows a kiss to %t."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/laugh
/datum/emote/living/audio_emote
emote_type = EMOTE_AUDIBLE
/datum/emote/living/audio_emote/can_run_emote(mob/living/user, status_check = TRUE)
. = ..()
if(. && iscarbon(user))
var/mob/living/carbon/C = user
return !C.silent && (!C.mind || !C.mind.miming)
/datum/emote/living/audio_emote/laugh
key = "laugh"
key_third_person = "laughs"
message = "laughs."
message_mime = "laughs silently!"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/laugh/can_run_emote(mob/living/user, status_check = TRUE)
. = ..()
if(. && iscarbon(user))
var/mob/living/carbon/C = user
return !C.silent
/datum/emote/living/laugh/run_emote(mob/user, params)
/datum/emote/living/audio_emote/laugh/run_emote(mob/user, params)
. = ..()
if(. && iscarbon(user)) //Citadel Edit because this is hilarious
var/mob/living/carbon/C = user
if(!C.mind || C.mind.miming)
return
if(iscatperson(C)) //we ask for is cat first because they're a subtype that tests true for ishumanbasic because HERESY
playsound(C, pick('sound/voice/catpeople/nyahaha1.ogg',
'sound/voice/catpeople/nyahaha2.ogg',
@@ -226,12 +226,27 @@
'sound/voice/catpeople/nyahehe.ogg'),
50, 1)
return
if(ishumanbasic(C))
else if(ismoth(C))
playsound(C, 'sound/voice/moth/mothlaugh.ogg', 50, 1)
else if(ishumanbasic(C))
if(user.gender == FEMALE)
playsound(C, 'sound/voice/human/womanlaugh.ogg', 50, 1)
else
playsound(C, pick('sound/voice/human/manlaugh1.ogg', 'sound/voice/human/manlaugh2.ogg'), 50, 1)
/datum/emote/living/audio_emote/chitter
key = "chitter"
key_third_person = "chitters"
message = "chitters."
message_mime = "chitters silently!"
/datum/emote/living/audio_emote/chitter/run_emote(mob/user, params)
. = ..()
if(. && iscarbon(user)) //Citadel Edit because this is hilarious
var/mob/living/carbon/C = user
if(ismoth(C))
playsound(C, 'sound/voice/moth/mothchitter.ogg', 50, 1)
/datum/emote/living/look
key = "look"
key_third_person = "looks"
@@ -411,17 +426,10 @@
message = null
/datum/emote/living/custom/proc/check_invalid(mob/user, input)
. = TRUE
if(copytext(input,1,5) == "says")
if(stop_bad_mime.Find(input, 1, 1))
to_chat(user, "<span class='danger'>Invalid emote.</span>")
else if(copytext(input,1,9) == "exclaims")
to_chat(user, "<span class='danger'>Invalid emote.</span>")
else if(copytext(input,1,6) == "yells")
to_chat(user, "<span class='danger'>Invalid emote.</span>")
else if(copytext(input,1,5) == "asks")
to_chat(user, "<span class='danger'>Invalid emote.</span>")
else
. = FALSE
return TRUE
return FALSE
/datum/emote/living/custom/run_emote(mob/user, params, type_override = null)
if(jobban_isbanned(user, "emote"))
@@ -433,7 +441,7 @@
to_chat(user, "You cannot send IC messages (muted).")
return FALSE
else if(!params)
var/custom_emote = copytext(sanitize(input("Choose an emote to display.") as message|null), 1, MAX_MESSAGE_LEN) //CIT CHANGE - expands emote textbox
var/custom_emote = stripped_multiline_input("Choose an emote to display.", "Custom Emote", null, MAX_MESSAGE_LEN)
if(custom_emote && !check_invalid(user, custom_emote))
var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable")
switch(type)
+14 -8
View File
@@ -90,8 +90,10 @@
if(now_pushing)
return TRUE
var/they_can_move = TRUE
if(isliving(M))
var/mob/living/L = M
they_can_move = L.canmove //L.mobility_flags & MOBILITY_MOVE
//Also spread diseases
for(var/thing in diseases)
var/datum/disease/D = thing
@@ -144,13 +146,17 @@
return 1
if(!M.buckled && !M.has_buckled_mobs())
var/mob_swap
//the puller can always swap with its victim if on grab intent
if(M.pulledby == src && a_intent == INTENT_GRAB)
mob_swap = 1
//restrained people act if they were on 'help' intent to prevent a person being pulled from being separated from their puller
else if((M.restrained() || M.a_intent == INTENT_HELP) && (restrained() || a_intent == INTENT_HELP))
mob_swap = 1
var/mob_swap = FALSE
var/too_strong = (M.move_resist > move_force) //can't swap with immovable objects unless they help us
if(!they_can_move) //we have to physically move them
if(!too_strong)
mob_swap = TRUE
else
if(M.pulledby == src && a_intent == INTENT_GRAB)
mob_swap = TRUE
//restrained people act if they were on 'help' intent to prevent a person being pulled from being separated from their puller
else if((M.restrained() || M.a_intent == INTENT_HELP) && (restrained() || a_intent == INTENT_HELP))
mob_swap = TRUE
if(mob_swap)
//switch our position with M
if(loc && !loc.Adjacent(M.loc))
@@ -453,7 +459,7 @@
return ret
// Living mobs use can_inject() to make sure that the mob is not syringe-proof in general.
/mob/living/proc/can_inject()
/mob/living/proc/can_inject(mob/user, error_msg, target_zone, penetrate_thick = FALSE, bypass_immunity = FALSE)
return TRUE
/mob/living/is_injectable(allowmobs = TRUE)
+12 -14
View File
@@ -89,7 +89,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
var/static/list/one_character_prefix = list(MODE_HEADSET = TRUE, MODE_ROBOT = TRUE, MODE_WHISPER = TRUE)
if(sanitize)
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN))
if(!message || message == "")
return
@@ -99,11 +99,10 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
var/in_critical = InCritical()
if(one_character_prefix[message_mode])
message = copytext(message, 2)
message = copytext_char(message, 2)
else if(message_mode || saymode)
message = copytext(message, 3)
if(findtext(message, " ", 1, 2))
message = copytext(message, 2)
message = copytext_char(message, 3)
message = trim_left(message)
if(message_mode == MODE_ADMIN)
if(client)
@@ -135,11 +134,10 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
// No, you cannot speak in xenocommon just because you know the key
if(can_speak_in_language(message_language))
language = message_language
message = copytext(message, 3)
message = copytext_char(message, 3)
// Trim the space if they said ",0 I LOVE LANGUAGES"
if(findtext(message, " ", 1, 2))
message = copytext(message, 2)
message = trim_left(message)
if(!language)
language = get_default_language()
@@ -167,8 +165,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
if(fullcrit)
var/health_diff = round(-HEALTH_THRESHOLD_DEAD + health)
// If we cut our message short, abruptly end it with a-..
var/message_len = length(message)
message = copytext(message, 1, health_diff) + "[message_len > health_diff ? "-.." : "..."]"
var/message_len = length_char(message)
message = copytext_char(message, 1, health_diff) + "[message_len > health_diff ? "-.." : "..."]"
message = Ellipsis(message, 10, 1)
message_mode = MODE_WHISPER_CRIT
succumbed = TRUE
@@ -326,13 +324,13 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
return 1
/mob/living/proc/get_key(message)
var/key = copytext(message, 1, 2)
var/key = message[1]
if(key in GLOB.department_radio_prefixes)
return lowertext(copytext(message, 2, 3))
return lowertext(message[1 + length(key)])
/mob/living/proc/get_message_language(message)
if(copytext(message, 1, 2) == ",")
var/key = copytext(message, 2, 3)
if(message[1] == ",")
var/key = message[1 + length(message[1])]
for(var/ld in GLOB.all_languages)
var/datum/language/LD = ld
if(initial(LD.key) == key)
+5 -5
View File
@@ -53,11 +53,11 @@
if(NONE)
return FALSE
if(POWER_REQ_ALL)
return !T || !A || ((!A.power_equip || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha)))
return !T || !A || ((!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha)))
if(POWER_REQ_CLOCKCULT)
for(var/obj/effect/clockwork/sigil/transmission/ST in range(src, SIGIL_ACCESS_RANGE))
return FALSE
return !T || !A || (!istype(T, /turf/open/floor/clockwork) && (!A.power_equip || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha)))
return !T || !A || (!istype(T, /turf/open/floor/clockwork) && (!A.powered(EQUIP) || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha)))
/mob/living/silicon/ai/updatehealth()
if(status_flags & GODMODE)
@@ -100,7 +100,7 @@
sleep(50)
var/turf/T = get_turf(src)
var/area/AIarea = get_area(src)
if(AIarea && AIarea.power_equip)
if(AIarea && AIarea.powered(EQUIP))
if(!isspaceturf(T))
ai_restore_power()
return
@@ -120,7 +120,7 @@
var/PRP //like ERP with the code, at least this stuff is no more 4x sametext
for (PRP=1, PRP<=4, PRP++)
T = get_turf(src)
AIarea = get_area(src)
AIarea = get_base_area(src)
if(AIarea)
for (var/obj/machinery/power/apc/APC in AIarea)
if (!(APC.stat & BROKEN))
@@ -134,7 +134,7 @@
to_chat(src, "Lost connection with the APC!")
aiRestorePowerRoutine = POWER_RESTORATION_SEARCH_APC
return
if(AIarea.power_equip)
if(AIarea.powered(EQUIP))
if(!isspaceturf(T))
ai_restore_power()
return
+2 -1
View File
@@ -26,7 +26,8 @@
..()
/mob/living/silicon/ai/get_message_mode(message)
if(copytext(message, 1, 3) in list(":h", ":H", ".h", ".H", "#h", "#H"))
var/static/regex/holopad_finder = regex(@"[:.#][hH]")
if(holopad_finder.Find(message, 1, 1))
return MODE_HOLOPAD
else
return ..()
@@ -8,7 +8,7 @@
*/
/datum/paiCandidate/proc/savefile_path(mob/user)
return "data/player_saves/[copytext(user.ckey, 1, 2)]/[user.ckey]/pai.sav"
return "data/player_saves/[user.ckey[1]]/[user.ckey]/pai.sav"
/datum/paiCandidate/proc/savefile_save(mob/user)
if(IsGuestKey(user.key))
@@ -438,7 +438,7 @@
if(1)
. += "<CENTER><B>Medical Record</B></CENTER><BR>"
if(medicalActive1 in GLOB.data_core.general)
. += "Name: [medicalActive1.fields["name"]] ID: [medicalActive1.fields["id"]]<BR>\nSex: [medicalActive1.fields["sex"]]<BR>\nAge: [medicalActive1.fields["age"]]<BR>\nFingerprint: [medicalActive1.fields["fingerprint"]]<BR>\nPhysical Status: [medicalActive1.fields["p_stat"]]<BR>\nMental Status: [medicalActive1.fields["m_stat"]]<BR>"
. += "Name: [medicalActive1.fields["name"]] ID: [medicalActive1.fields["id"]]<BR>\nGender: [medicalActive1.fields["gender"]]<BR>\nAge: [medicalActive1.fields["age"]]<BR>\nFingerprint: [medicalActive1.fields["fingerprint"]]<BR>\nPhysical Status: [medicalActive1.fields["p_stat"]]<BR>\nMental Status: [medicalActive1.fields["m_stat"]]<BR>"
else
. += "<pre>Requested medical record not found.</pre><BR>"
if(medicalActive2 in GLOB.data_core.medical)
@@ -460,7 +460,7 @@
if(1)
. += "<h3>Security Record</h3>"
if(securityActive1 in GLOB.data_core.general)
. += "Name: <A href='?src=[REF(src)];field=name'>[securityActive1.fields["name"]]</A> ID: <A href='?src=[REF(src)];field=id'>[securityActive1.fields["id"]]</A><BR>\nSex: <A href='?src=[REF(src)];field=sex'>[securityActive1.fields["sex"]]</A><BR>\nAge: <A href='?src=[REF(src)];field=age'>[securityActive1.fields["age"]]</A><BR>\nRank: <A href='?src=[REF(src)];field=rank'>[securityActive1.fields["rank"]]</A><BR>\nFingerprint: <A href='?src=[REF(src)];field=fingerprint'>[securityActive1.fields["fingerprint"]]</A><BR>\nPhysical Status: [securityActive1.fields["p_stat"]]<BR>\nMental Status: [securityActive1.fields["m_stat"]]<BR>"
. += "Name: <A href='?src=[REF(src)];field=name'>[securityActive1.fields["name"]]</A> ID: <A href='?src=[REF(src)];field=id'>[securityActive1.fields["id"]]</A><BR>\nGender: <A href='?src=[REF(src)];field=sex'>[securityActive1.fields["gender"]]</A><BR>\nAge: <A href='?src=[REF(src)];field=age'>[securityActive1.fields["age"]]</A><BR>\nRank: <A href='?src=[REF(src)];field=rank'>[securityActive1.fields["rank"]]</A><BR>\nFingerprint: <A href='?src=[REF(src)];field=fingerprint'>[securityActive1.fields["fingerprint"]]</A><BR>\nPhysical Status: [securityActive1.fields["p_stat"]]<BR>\nMental Status: [securityActive1.fields["m_stat"]]<BR>"
else
. += "<pre>Requested security record not found,</pre><BR>"
if(securityActive2 in GLOB.data_core.security)
+1 -1
View File
@@ -151,7 +151,7 @@
for(var/key in alarm_types_clear)
alarm_types_clear[key] = 0
/mob/living/silicon/can_inject(mob/user, error_msg)
/mob/living/silicon/can_inject(mob/user, error_msg, target_zone, penetrate_thick = FALSE, bypass_immunity = FALSE)
if(error_msg)
to_chat(user, "<span class='alert'>[p_their(TRUE)] outer shell is too tough.</span>")
return FALSE
@@ -14,7 +14,7 @@
icon_state = "mulebot0"
density = TRUE
move_resist = MOVE_FORCE_STRONG
animate_movement = 1
animate_movement = FORWARD_STEPS
health = 50
maxHealth = 50
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
@@ -29,10 +29,14 @@
model = "MULE"
bot_core_type = /obj/machinery/bot_core/mulebot
var/ui_x = 350
var/ui_y = 425
var/id
path_image_color = "#7F5200"
var/base_icon = "mulebot"
var/atom/movable/load = null
var/mob/living/passenger = null
var/turf/target // this is turf to navigate to (location of beacon)
@@ -74,16 +78,16 @@
/mob/living/simple_animal/bot/mulebot/proc/set_id(new_id)
id = new_id
if(paicard)
bot_name = "\improper MULEbot ([new_id])"
bot_name = "[initial(name)] ([new_id])"
else
name = "\improper MULEbot ([new_id])"
name = "[initial(name)] ([new_id])"
/mob/living/simple_animal/bot/mulebot/bot_reset()
..()
reached_target = 0
/mob/living/simple_animal/bot/mulebot/attackby(obj/item/I, mob/user, params)
if(istype(I, /obj/item/screwdriver))
if(I.tool_behaviour == TOOL_SCREWDRIVER)
..()
if(open)
on = FALSE
@@ -91,13 +95,13 @@
if(!user.transferItemToLoc(I, src))
return
cell = I
visible_message("[user] inserts a cell into [src].",
visible_message("<span class='notice'>[user] inserts a cell into [src].</span>",
"<span class='notice'>You insert the new cell into [src].</span>")
else if(istype(I, /obj/item/crowbar) && open && cell)
else if(I.tool_behaviour == TOOL_CROWBAR && open && cell)
cell.add_fingerprint(usr)
cell.forceMove(loc)
cell = null
visible_message("[user] crowbars out the power cell from [src].",
visible_message("<span class='notice'>[user] crowbars out the power cell from [src].</span>",
"<span class='notice'>You pry the powercell out of [src].</span>")
else if(is_wire_tool(I) && open)
return attack_hand(user)
@@ -115,21 +119,19 @@
return
/mob/living/simple_animal/bot/mulebot/emag_act(mob/user)
. = SEND_SIGNAL(src, COMSIG_ATOM_EMAG_ACT)
if(emagged < 1)
emagged = TRUE
if(!open)
locked = !locked
to_chat(user, "<span class='notice'>You [locked ? "lock" : "unlock"] [src]'s controls!</span>")
flick("mulebot-emagged", src)
playsound(src, "sparks", 100, 0)
return TRUE
playsound(src, "sparks", 100, FALSE)
/mob/living/simple_animal/bot/mulebot/update_icon()
if(open)
icon_state="mulebot-hatch"
icon_state="[base_icon]-hatch"
else
icon_state = "mulebot[wires.is_cut(WIRE_AVOIDANCE)]"
icon_state = "[base_icon][wires.is_cut(WIRE_AVOIDANCE)]"
cut_overlays()
if(load && !ismob(load))//buckling handles the mob offsets
load.pixel_y = initial(load.pixel_y) + 9
@@ -152,7 +154,7 @@
/mob/living/simple_animal/bot/mulebot/bullet_act(obj/item/projectile/Proj)
. = ..()
if(. == BULLET_ACT_HIT && !QDELETED(src)) //Got hit and not blown up yet.)
if(. && !QDELETED(src)) //Got hit and not blown up yet.
if(prob(50) && !isnull(load))
unload(0)
if(prob(25))
@@ -171,7 +173,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "mulebot", name, 600, 375, master_ui, state)
ui = new(user, src, ui_key, "mulebot", name, ui_x, ui_y, master_ui, state)
ui.open()
/mob/living/simple_animal/bot/mulebot/ui_data(mob/user)
@@ -191,12 +193,15 @@
else
data["load"] = load ? load.name : null
data["destination"] = destination ? destination : null
data["home"] = home_destination
data["destinations"] = GLOB.deliverybeacontags
data["cell"] = cell ? TRUE : FALSE
data["cellPercent"] = cell ? cell.percent() : null
data["autoReturn"] = auto_return
data["autoPickup"] = auto_pickup
data["reportDelivery"] = report_delivery
data["haspai"] = paicard ? TRUE : FALSE
data["id"] = id
return data
/mob/living/simple_animal/bot/mulebot/ui_act(action, params)
@@ -216,10 +221,10 @@
return
. = TRUE
else
bot_control(action, usr) // Kill this later.
bot_control(action, usr, params) // Kill this later.
. = TRUE
/mob/living/simple_animal/bot/mulebot/bot_control(command, mob/user, pda = FALSE)
/mob/living/simple_animal/bot/mulebot/bot_control(command, mob/user, list/params = list(), pda = FALSE)
if(pda && wires.is_cut(WIRE_RX)) // MULE wireless is controlled by wires.
return
@@ -234,15 +239,27 @@
if(mode == BOT_IDLE || mode == BOT_DELIVER)
start_home()
if("destination")
var/new_dest = input(user, "Enter Destination:", name, destination) as null|anything in GLOB.deliverybeacontags
var/new_dest
if(pda)
new_dest = input(user, "Enter Destination:", name, destination) as null|anything in GLOB.deliverybeacontags
else
new_dest = params["value"]
if(new_dest)
set_destination(new_dest)
if("setid")
var/new_id = stripped_input(user, "Enter ID:", name, id, MAX_NAME_LEN)
var/new_id
if(pda)
new_id = stripped_input(user, "Enter ID:", name, id, MAX_NAME_LEN)
else
new_id = params["value"]
if(new_id)
set_id(new_id)
if("sethome")
var/new_home = input(user, "Enter Home:", name, home_destination) as null|anything in GLOB.deliverybeacontags
var/new_home
if(pda)
new_home = input(user, "Enter Home:", name, home_destination) as null|anything in GLOB.deliverybeacontags
else
new_home = params["value"]
if(new_home)
home_destination = new_home
if("unload")
@@ -317,26 +334,28 @@
/mob/living/simple_animal/bot/mulebot/proc/buzz(type)
switch(type)
if(SIGH)
audible_message("[src] makes a sighing buzz.", "<span class='italics'>You hear an electronic buzzing sound.</span>")
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, 0)
audible_message("<span class='hear'>[src] makes a sighing buzz.</span>")
playsound(loc, 'sound/machines/buzz-sigh.ogg', 50, FALSE)
if(ANNOYED)
audible_message("[src] makes an annoyed buzzing sound.", "<span class='italics'>You hear an electronic buzzing sound.</span>")
playsound(loc, 'sound/machines/buzz-two.ogg', 50, 0)
audible_message("<span class='hear'>[src] makes an annoyed buzzing sound.</span>")
playsound(loc, 'sound/machines/buzz-two.ogg', 50, FALSE)
if(DELIGHT)
audible_message("[src] makes a delighted ping!", "<span class='italics'>You hear a ping.</span>")
playsound(loc, 'sound/machines/ping.ogg', 50, 0)
audible_message("<span class='hear'>[src] makes a delighted ping!</span>")
playsound(loc, 'sound/machines/ping.ogg', 50, FALSE)
// mousedrop a crate to load the bot
// can load anything if hacked
/mob/living/simple_animal/bot/mulebot/MouseDrop_T(atom/movable/AM, mob/user)
if(user.incapacitated() || user.lying)
return
if(!istype(AM))
return
if(!istype(AM) || isdead(AM) || iscameramob(AM) || istype(AM, /obj/effect/dummy/phased_mob))
return
load(AM)
// called to load a crate
@@ -449,10 +468,8 @@
process_bot()
num_steps--
if(mode != BOT_IDLE)
spawn(0)
for(var/i=num_steps,i>0,i--)
sleep(2)
process_bot()
var/process_timer = addtimer(CALLBACK(src, .proc/process_bot), 2, TIMER_LOOP|TIMER_STOPPABLE)
addtimer(CALLBACK(GLOBAL_PROC, /proc/deltimer, process_timer), (num_steps*2) + 1)
/mob/living/simple_animal/bot/mulebot/proc/process_bot()
if(!on || client)
@@ -477,7 +494,7 @@
if(isturf(next))
if(bloodiness)
var/obj/effect/decal/cleanable/blood/tracks/B = new(loc)
if(blood_DNA && blood_DNA.len)
if(length(blood_DNA))
B.blood_DNA |= blood_DNA.Copy()
var/newdir = get_dir(next, loc)
if(newdir == dir)
@@ -491,6 +508,7 @@
B.setDir(newdir)
bloodiness--
var/oldloc = loc
var/moved = step_towards(src, next) // attempt to move
if(cell)
@@ -516,11 +534,7 @@
buzz(SIGH)
mode = BOT_WAIT_FOR_NAV
blockcount = 0
spawn(20)
calc_path(avoid=next)
if(path.len > 0)
buzz(DELIGHT)
mode = BOT_BLOCKED
addtimer(CALLBACK(src, .proc/process_blocked, next), 2 SECONDS)
return
return
else
@@ -533,18 +547,26 @@
if(BOT_NAV) // calculate new path
mode = BOT_WAIT_FOR_NAV
spawn(0)
calc_path()
INVOKE_ASYNC(src, .proc/process_nav)
if(path.len > 0)
blockcount = 0
mode = BOT_BLOCKED
buzz(DELIGHT)
/mob/living/simple_animal/bot/mulebot/proc/process_blocked(turf/next)
calc_path(avoid=next)
if(path.len > 0)
buzz(DELIGHT)
mode = BOT_BLOCKED
else
buzz(SIGH)
/mob/living/simple_animal/bot/mulebot/proc/process_nav()
calc_path()
mode = BOT_NO_ROUTE
if(path.len > 0)
blockcount = 0
mode = BOT_BLOCKED
buzz(DELIGHT)
else
buzz(SIGH)
mode = BOT_NO_ROUTE
// calculates a path to the current destination
// given an optional turf to avoid
@@ -574,26 +596,28 @@
/mob/living/simple_animal/bot/mulebot/proc/start_home()
if(!on)
return
spawn(0)
set_destination(home_destination)
mode = BOT_BLOCKED
INVOKE_ASYNC(src, .proc/do_start_home)
update_icon()
/mob/living/simple_animal/bot/mulebot/proc/do_start_home()
set_destination(home_destination)
mode = BOT_BLOCKED
// called when bot reaches current target
/mob/living/simple_animal/bot/mulebot/proc/at_target()
if(!reached_target)
radio_channel = "Supply" //Supply channel
audible_message("[src] makes a chiming sound!", "<span class='italics'>You hear a chime.</span>")
playsound(loc, 'sound/machines/chime.ogg', 50, 0)
radio_channel = RADIO_CHANNEL_SUPPLY //Supply channel
audible_message("<span class='hear'>[src] makes a chiming sound!</span>")
playsound(loc, 'sound/machines/chime.ogg', 50, FALSE)
reached_target = 1
if(pathset) //The AI called us here, so notify it of our arrival.
loaddir = dir //The MULE will attempt to load a crate in whatever direction the MULE is "facing".
if(calling_ai)
to_chat(calling_ai, "<span class='notice'>[icon2html(src, calling_ai)] [src] wirelessly plays a chiming sound!</span>")
playsound(calling_ai, 'sound/machines/chime.ogg',40, 0)
playsound(calling_ai, 'sound/machines/chime.ogg',40, FALSE)
calling_ai = null
radio_channel = "AI Private" //Report on AI Private instead if the AI is controlling us.
radio_channel = RADIO_CHANNEL_AI_PRIVATE //Report on AI Private instead if the AI is controlling us.
if(load) // if loaded, unload at target
if(report_delivery)
@@ -645,7 +669,7 @@
log_combat(src, H, "run over", null, "(DAMTYPE: [uppertext(BRUTE)])")
H.visible_message("<span class='danger'>[src] drives over [H]!</span>", \
"<span class='userdanger'>[src] drives over you!</span>")
playsound(loc, 'sound/effects/splat.ogg', 50, 1)
playsound(loc, 'sound/effects/splat.ogg', 50, TRUE)
var/damage = rand(5,15)
H.apply_damage(2*damage, BRUTE, BODY_ZONE_HEAD, run_armor_check(BODY_ZONE_HEAD, "melee"))
@@ -734,7 +758,7 @@
/mob/living/simple_animal/bot/mulebot/insertpai(mob/user, obj/item/paicard/card)
if(..())
visible_message("[src] safeties are locked on.")
visible_message("<span class='notice'>[src] safeties are locked on.</span>")
#undef SIGH
#undef ANNOYED
@@ -742,3 +766,4 @@
/obj/machinery/bot_core/mulebot
req_access = list(ACCESS_CARGO)
@@ -207,7 +207,11 @@
switch(add_to)
if("collar")
add_collar(usr.get_active_held_item(), usr)
var/obj/item/clothing/neck/petcollar/P = usr.get_active_held_item()
if(!istype(P))
to_chat(usr,"<span class='warning'>That's not a collar.</span>")
return
add_collar(P, usr)
update_corgi_fluff()
if(BODY_ZONE_HEAD)
@@ -130,10 +130,6 @@
hacked = TRUE
visualAppearence = CLOCKDRONE
can_be_held = FALSE
mouse_opacity = MOUSE_OPACITY_OPAQUE
flavortext = "<b><span class='nezbere'>You are a cogscarab,</span> a tiny building construct of Ratvar. While you're weak and can't recite scripture, \
you have a set of quick tools, as well as a replica fabricator that can create brass and convert objects.<br><br>Work with the servants of Ratvar \
to construct and maintain defenses at the City of Cogs. If there are no servants, use this time to experiment with base designs!"
/mob/living/simple_animal/drone/cogscarab/ratvar //a subtype for spawning when ratvar is alive, has a slab that it can use and a normal fabricator
default_storage = /obj/item/storage/toolbox/brass/prefilled/ratvar
@@ -38,7 +38,7 @@
var/obj/item/organ/tail/cat/tail = L.getorgan(/obj/item/organ/tail/cat)
if(!QDELETED(tail))
visible_message("[src] severs [L]'s tail in one swift swipe!", "<span class='notice'>You sever [L]'s tail in one swift swipe.</span>")
tail.Remove(L)
tail.Remove()
var/obj/item/organ/tail/cat/dropped_tail = new(target.drop_location())
dropped_tail.color = L.hair_color
return 1
@@ -61,7 +61,7 @@
time++
if(time >= EGG_INCUBATION_TIME)
Pop()
Remove(owner)
Remove()
qdel(src)
/obj/item/organ/body_egg/changeling_egg/proc/Pop()
@@ -479,31 +479,33 @@ Difficulty: Very Hard
NewTerrainTables = /obj/structure/table/abductor
/obj/machinery/anomalous_crystal/theme_warp/ActivationReaction(mob/user, method)
if(..())
var/area/A = get_area(src)
if(!A.outdoors && !(A in affected_targets))
for(var/atom/Stuff in A)
if(isturf(Stuff))
var/turf/T = Stuff
if((isspaceturf(T) || isfloorturf(T)) && NewTerrainFloors)
var/turf/open/O = T.ChangeTurf(NewTerrainFloors, flags = CHANGETURF_INHERIT_AIR)
if(prob(florachance) && NewFlora.len && !is_blocked_turf(O, TRUE))
var/atom/Picked = pick(NewFlora)
new Picked(O)
continue
if(iswallturf(T) && NewTerrainWalls)
T.ChangeTurf(NewTerrainWalls)
continue
if(istype(Stuff, /obj/structure/chair) && NewTerrainChairs)
var/obj/structure/chair/Original = Stuff
var/obj/structure/chair/C = new NewTerrainChairs(Original.loc)
C.setDir(Original.dir)
qdel(Stuff)
continue
if(istype(Stuff, /obj/structure/table) && NewTerrainTables)
new NewTerrainTables(Stuff.loc)
continue
affected_targets += A
. = ..()
if(!.)
return
for(var/i in get_sub_areas(src))
var/area/A = i
if(A.outdoors || (A in affected_targets))
continue
affected_targets += A
for(var/stuff in A)
var/atom/target = stuff
if(isturf(target))
var/turf/T = target
if((isspaceturf(T) || isfloorturf(T)) && NewTerrainFloors)
var/turf/open/O = T.ChangeTurf(NewTerrainFloors, flags = CHANGETURF_INHERIT_AIR)
if(NewFlora.len && prob(florachance) && !is_blocked_turf(O, TRUE))
var/atom/Picked = pick(NewFlora)
new Picked(O)
else if(iswallturf(T) && NewTerrainWalls)
T.ChangeTurf(NewTerrainWalls)
else if(NewTerrainChairs && istype(target, /obj/structure/chair))
var/obj/structure/chair/Original = target
var/obj/structure/chair/C = new NewTerrainChairs(Original.loc)
C.setDir(Original.dir)
qdel(target)
else if(NewTerrainTables && istype(target, /obj/structure/table))
new NewTerrainTables(target.loc)
qdel(target)
/obj/machinery/anomalous_crystal/emitter //Generates a projectile when interacted with
observer_desc = "This crystal generates a projectile when activated."
@@ -170,7 +170,7 @@ Difficulty: Medium
to_chat(user, "<span class='warning'>The staff is still recharging!</span>")
return
var/area/user_area = get_area(user)
var/area/user_area = get_base_area(user)
var/turf/user_turf = get_turf(user)
if(!user_area || !user_turf || (user_area.type in excluded_areas))
to_chat(user, "<span class='warning'>Something is preventing you from using the staff here.</span>")
@@ -208,8 +208,8 @@
ears.forceMove(drop_location())
ears = null
for(var/possible_phrase in speak)
if(copytext(possible_phrase,1,3) in GLOB.department_radio_keys)
possible_phrase = copytext(possible_phrase,3)
if(copytext_char(possible_phrase, 2, 3) in GLOB.department_radio_keys)
possible_phrase = copytext_char(possible_phrase, 3)
//Adding things to inventory
else if(href_list["add_inv"])
@@ -332,8 +332,8 @@
speak_chance *= 1.27 // 20 crackers to go from 1% to 100%
speech_shuffle_rate += 10
to_chat(user, "<span class='notice'>[src] eagerly devours the cracker.</span>")
..()
return
return // the cracker was deleted
return ..()
//Bullets
/mob/living/simple_animal/parrot/bullet_act(obj/item/projectile/Proj)
@@ -419,8 +419,8 @@
if(prob(50))
useradio = 1
if((copytext(possible_phrase,1,2) in GLOB.department_radio_prefixes) && (copytext(possible_phrase,2,3) in GLOB.department_radio_keys))
possible_phrase = "[useradio?pick(available_channels):""][copytext(possible_phrase,3)]" //crop out the channel prefix
if((possible_phrase[1] in GLOB.department_radio_prefixes) && (copytext_char(possible_phrase, 2, 3) in GLOB.department_radio_keys))
possible_phrase = "[useradio?pick(available_channels):""][copytext_char(possible_phrase, 3)]" //crop out the channel prefix
else
possible_phrase = "[useradio?pick(available_channels):""][possible_phrase]"
@@ -428,8 +428,8 @@
else //If we have no headset or channels to use, dont try to use any!
for(var/possible_phrase in speak)
if((copytext(possible_phrase,1,2) in GLOB.department_radio_prefixes) && (copytext(possible_phrase,2,3) in GLOB.department_radio_keys))
possible_phrase = copytext(possible_phrase,3) //crop out the channel prefix
if((possible_phrase[1] in GLOB.department_radio_prefixes) && (copytext_char(possible_phrase, 2, 3) in GLOB.department_radio_keys))
possible_phrase = copytext_char(possible_phrase, 3) //crop out the channel prefix
newspeak.Add(possible_phrase)
speak = newspeak
@@ -81,9 +81,9 @@
var/dextrous = FALSE //If the creature has, and can use, hands
var/dextrous_hud_type = /datum/hud/dextrous
var/datum/personal_crafting/handcrafting
var/AIStatus = AI_ON //The Status of our AI, can be set to AI_ON (On, usual processing), AI_IDLE (Will not process, but will return to AI_ON if an enemy comes near), AI_OFF (Off, Not processing ever), AI_Z_OFF (Temporarily off due to nonpresence of players)
var/can_have_ai = TRUE //once we have become sentient, we can never go back
var/shouldwakeup = FALSE //convenience var for forcibly waking up an idling AI on next check.
@@ -97,7 +97,6 @@
/mob/living/simple_animal/Initialize()
. = ..()
GLOB.simple_animals[AIStatus] += src
handcrafting = new()
if(gender == PLURAL)
gender = pick(MALE,FEMALE)
if(!real_name)
@@ -105,6 +104,8 @@
if(!loc)
stack_trace("Simple animal being instantiated in nullspace")
update_simplemob_varspeed()
if(dextrous)
AddComponent(/datum/component/personal_crafting)
/mob/living/simple_animal/Destroy()
GLOB.simple_animals[AIStatus] -= src
@@ -425,6 +426,9 @@
canmove = FALSE
else
canmove = value_otherwise
if(!canmove) // !(mobility_flags & MOBILITY_MOVE)
walk(src, 0) //stop mid walk
update_transform()
update_action_buttons_icon()
return canmove
@@ -443,6 +447,7 @@
/mob/living/simple_animal/proc/sentience_act() //Called when a simple animal gains sentience via gold slime potion
toggle_ai(AI_OFF) // To prevent any weirdness.
can_have_ai = FALSE
/mob/living/simple_animal/update_sight()
if(!client)
@@ -466,10 +471,6 @@
/mob/living/simple_animal/get_idcard(hand_first = TRUE)
return ..() || access_card
/mob/living/simple_animal/OpenCraftingMenu()
if(dextrous)
handcrafting.ui_interact(src)
/mob/living/simple_animal/can_hold_items()
return dextrous
@@ -557,6 +558,8 @@
LoadComponent(/datum/component/riding)
/mob/living/simple_animal/proc/toggle_ai(togglestatus)
if(!can_have_ai && (togglestatus != AI_OFF))
return
if (AIStatus != togglestatus)
if (togglestatus > 0 && togglestatus < 5)
if (togglestatus == AI_Z_OFF || AIStatus == AI_Z_OFF)
@@ -41,7 +41,7 @@
AIproc = 1
while(AIproc && stat != DEAD && (attacked || hungry || rabid || buckled))
if(buckled) // can't eat AND have this little process at the same time
if(!canmove) // !(mobility_flags & MOBILITY_MOVE) //also covers buckling. Not sure why buckled is in the while condition if we're going to immediately break, honestly
break
if(!Target || client)
+1 -1
View File
@@ -212,7 +212,7 @@
emote("deathgasp")
ADD_TRAIT(src, TRAIT_FAKEDEATH, source)
ADD_TRAIT(src, TRAIT_DEATHCOMA, source)
tod = STATION_TIME_TIMESTAMP("hh:mm:ss")
tod = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)
update_stat()
/mob/living/proc/unignore_slowdown(list/sources)
+2
View File
@@ -53,3 +53,5 @@
CB.Invoke()
log_message("Client [key_name(src)] has taken ownership of mob [src]([src.type])", LOG_OWNERSHIP)
SEND_SIGNAL(src, COMSIG_MOB_CLIENT_LOGIN, client)
+20 -26
View File
@@ -82,7 +82,7 @@
if(!client)
return
msg = copytext(msg, 1, MAX_MESSAGE_LEN)
msg = copytext_char(msg, 1, MAX_MESSAGE_LEN)
if(type)
if(type & MSG_VISUAL && eye_blind )//Vision related
@@ -414,7 +414,7 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
set name = "Add Note"
set category = "IC"
msg = copytext(msg, 1, MAX_MESSAGE_LEN)
msg = copytext_char(msg, 1, MAX_MESSAGE_LEN)
msg = sanitize(msg)
if(mind)
@@ -456,8 +456,10 @@ mob/visible_message(message, self_message, blind_message, vision_distance = DEFA
return
/mob/proc/transfer_ckey(mob/new_mob, send_signal = TRUE)
if(!ckey || !new_mob)
CRASH("transfer_ckey() called [ckey ? "" : "on a ckey-less mob[new_mob ? "" : " and "]"][new_mob ? "" : "without a valid mob target"]!")
if(!new_mob || (!ckey && new_mob.ckey))
CRASH("transfer_ckey() called [new_mob ? "on ckey-less mob with a player mob as target" : "without a valid mob target"]!")
if(!ckey)
return
SEND_SIGNAL(new_mob, COMSIG_MOB_PRE_PLAYER_CHANGE, new_mob, src)
if (client && client.prefs && client.prefs.auto_ooc)
if (client.prefs.chat_toggles & CHAT_OOC && isliving(new_mob))
@@ -511,7 +513,7 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
if(href_list["flavor2_more"])
usr << browse(text("<HTML><HEAD><TITLE>[]</TITLE></HEAD><BODY><TT>[]</TT></BODY></HTML>", name, replacetext(flavor_text_2, "\n", "<BR>")), text("window=[];size=500x200", name))
onclose(usr, "[name]")
if(href_list["flavor_change"])
update_flavor_text()
@@ -569,29 +571,23 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
M.show_inv(user)
/mob/proc/is_muzzled()
return 0
return FALSE
/mob/Stat()
..()
if(statpanel("Status"))
if (client)
stat(null, "Ping: [round(client.lastping, 1)]ms (Average: [round(client.avgping, 1)]ms)")
stat(null, "Map: [SSmapping.config?.map_name || "Loading..."]")
var/datum/map_config/cached = SSmapping.next_map_config
if(cached)
stat(null, "Next Map: [cached.map_name]")
stat(null, "Round ID: [GLOB.round_id ? GLOB.round_id : "NULL"]")
stat(null, "Server Time: [time2text(world.timeofday, "YYYY-MM-DD hh:mm:ss")]")
stat(null, "Round Time: [WORLDTIME2TEXT("hh:mm:ss")]")
stat(null, "Station Time: [STATION_TIME_TIMESTAMP("hh:mm:ss")]")
stat(null, "Time Dilation: [round(SStime_track.time_dilation_current,1)]% AVG:([round(SStime_track.time_dilation_avg_fast,1)]%, [round(SStime_track.time_dilation_avg,1)]%, [round(SStime_track.time_dilation_avg_slow,1)]%)")
if(SSshuttle.emergency)
var/ETA = SSshuttle.emergency.getModeStr()
if(ETA)
stat(null, "[ETA] [SSshuttle.emergency.getTimerStr()]")
//This is only called from client/Stat(), let's assume client exists.
if(client && client.holder)
if(statpanel("Status"))
var/list/L = list()
L += "Ping: [round(client.lastping,1)]ms (Avg: [round(client.avgping,1)]ms)"
L += SSmapping.stat_map_name
L += "Round ID: [GLOB.round_id || "NULL"]"
L += SStime_track.stat_time_text
L += SSshuttle.emergency_shuttle_stat_text
stat(null, "[L.Join("\n\n")]")
if(client.holder)
if(statpanel("MC"))
var/turf/T = get_turf(client.eye)
stat("Location:", COORD(T))
@@ -641,8 +637,6 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
if(A.IsObscured())
continue
statpanel(listed_turf.name, null, A)
if(mind)
add_spells_to_statpanel(mind.spell_list)
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
@@ -964,4 +958,4 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
/mob/setMovetype(newval)
. = ..()
update_movespeed(FALSE)
update_movespeed(FALSE)
+1 -1
View File
@@ -26,7 +26,7 @@
var/computer_id = null
var/list/logging = list()
var/obj/machinery/machine = null
var/atom/machine = null
var/next_move = null
var/create_area_cooldown
+141 -148
View File
@@ -42,128 +42,131 @@
else
return 0
/proc/stars(n, pr)
n = html_encode(n)
if (pr == null)
pr = 25
if (pr <= 0)
return null
else
if (pr >= 100)
return n
var/te = n
var/t = ""
n = length(n)
var/p = null
p = 1
while(p <= n)
if ((copytext(te, p, p + 1) == " " || prob(pr)))
t = text("[][]", t, copytext(te, p, p + 1))
/**
* Convert random parts of a passed in message to stars
*
* * phrase - the string to convert
* * probability - probability any character gets changed
*
* This proc is dangerously laggy, avoid it or die
*/
/proc/stars(phrase, probability = 25)
if(probability <= 0)
return phrase
phrase = html_decode(phrase)
var/leng = length(phrase)
. = ""
var/char = ""
for(var/i = 1, i <= leng, i += length(char))
char = phrase[i]
if(char == " " || !prob(probability))
. += char
else
t = text("[]*", t)
p++
return sanitize(t)
. += "*"
return sanitize(.)
/proc/slur(n,var/strength=50)
strength = min(strength,50)
var/phrase = html_decode(n)
/**
* Makes you speak like you're drunk
*/
/proc/slur(phrase, strength = 50)
strength = min(50, strength)
phrase = html_decode(phrase)
var/leng = length(phrase)
var/counter=length(phrase)
var/newphrase=""
var/newletter=""
while(counter>=1)
newletter=copytext(phrase,(leng-counter)+1,(leng-counter)+2)
if(rand(1,100)<=strength*0.5)
if(lowertext(newletter)=="o")
newletter="u"
if(lowertext(newletter)=="s")
newletter="ch"
if(lowertext(newletter)=="a")
newletter="ah"
if(lowertext(newletter)=="u")
newletter="oo"
if(lowertext(newletter)=="c")
newletter="k"
if(rand(1,100) <= strength*0.25)
if(newletter==" ")
newletter="...huuuhhh..."
if(newletter==".")
newletter=" BURP!"
if(rand(1,100) <= strength*0.5)
if(rand(1,5) == 1)
newletter+="'"
if(rand(1,5) == 1)
newletter+="[newletter]"
if(rand(1,5) == 1)
newletter+="[newletter][newletter]"
newphrase+="[newletter]";counter-=1
return newphrase
/proc/cultslur(n) // Inflicted on victims of a stun talisman
var/phrase = html_decode(n)
var/leng = length(phrase)
var/counter=length(phrase)
var/newphrase=""
var/newletter=""
while(counter>=1)
newletter=copytext(phrase,(leng-counter)+1,(leng-counter)+2)
if(rand(1,2)==2)
if(lowertext(newletter)=="o")
newletter="u"
if(lowertext(newletter)=="t")
newletter="ch"
if(lowertext(newletter)=="a")
newletter="ah"
if(lowertext(newletter)=="u")
newletter="oo"
if(lowertext(newletter)=="c")
newletter=" NAR "
if(lowertext(newletter)=="s")
newletter=" SIE "
if(rand(1,4)==4)
if(newletter==" ")
newletter=" no hope... "
if(newletter=="H")
newletter=" IT COMES... "
switch(rand(1,15))
. = ""
var/newletter = ""
var/rawchar = ""
for(var/i = 1, i <= leng, i += length(rawchar))
rawchar = newletter = phrase[i]
if(rand(1,100)<=strength * 0.5)
var/lowerletter = lowertext(newletter)
if(lowerletter == "o")
newletter = "u"
else if(lowerletter == "s")
newletter = "ch"
else if(lowerletter == "a")
newletter = "ah"
else if(lowerletter == "u")
newletter = "oo"
else if(lowerletter == "c")
newletter = "k"
if(rand(1,100) <= strength * 0.25)
if(newletter == " ")
newletter = "...huuuhhh..."
else if(newletter == ".")
newletter = " *BURP*."
switch(rand(1,100) <= strength * 0.5)
if(1)
newletter="'"
newletter += "'"
if(10)
newletter += "[newletter]"
if(20)
newletter += "[newletter][newletter]"
. += "[newletter]"
return sanitize(.)
/// Makes you talk like you got cult stunned, which is slurring but with some dark messages
/proc/cultslur(phrase) // Inflicted on victims of a stun talisman
phrase = html_decode(phrase)
var/leng = length(phrase)
. = ""
var/newletter = ""
var/rawchar = ""
for(var/i = 1, i <= leng, i += length(rawchar))
rawchar = newletter = phrase[i]
if(rand(1, 2) == 2)
var/lowerletter = lowertext(newletter)
if(lowerletter == "o")
newletter = "u"
else if(lowerletter == "t")
newletter = "ch"
else if(lowerletter == "a")
newletter = "ah"
else if(lowerletter == "u")
newletter = "oo"
else if(lowerletter == "c")
newletter = " NAR "
else if(lowerletter == "s")
newletter = " SIE "
if(rand(1, 4) == 4)
if(newletter == " ")
newletter = " no hope... "
else if(newletter == "H")
newletter = " IT COMES... "
switch(rand(1, 15))
if(1)
newletter = "'"
if(2)
newletter+="agn"
newletter += "agn"
if(3)
newletter="fth"
newletter = "fth"
if(4)
newletter="nglu"
newletter = "nglu"
if(5)
newletter="glor"
newphrase+="[newletter]";counter-=1
return newphrase
newletter = "glor"
. += newletter
return sanitize(.)
/proc/stutter(n)
var/te = html_decode(n)
var/t = ""//placed before the message. Not really sure what it's for.
n = length(n)//length of the entire word
var/p = null
p = 1//1 is the start of any word
while(p <= n)//while P, which starts at 1 is less or equal to N which is the length.
var/n_letter = copytext(te, p, p + 1)//copies text from a certain distance. In this case, only one letter at a time.
if (prob(80) && (ckey(n_letter) in list("b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z")))
if (prob(10))
n_letter = text("[n_letter]-[n_letter]-[n_letter]-[n_letter]")//replaces the current letter with this instead.
///Adds stuttering to the message passed in
/proc/stutter(phrase)
phrase = html_decode(phrase)
var/leng = length(phrase)
. = ""
var/newletter = ""
var/rawchar
for(var/i = 1, i <= leng, i += length(rawchar))
rawchar = newletter = phrase[i]
if(prob(80) && !(lowertext(newletter) in list("a", "e", "i", "o", "u", " ")))
if(prob(10))
newletter = "[newletter]-[newletter]-[newletter]-[newletter]"
else if(prob(20))
newletter = "[newletter]-[newletter]-[newletter]"
else if (prob(5))
newletter = ""
else
if (prob(20))
n_letter = text("[n_letter]-[n_letter]-[n_letter]")
else
if (prob(5))
n_letter = null
else
n_letter = text("[n_letter]-[n_letter]")
t = text("[t][n_letter]")//since the above is ran through for each letter, the text just adds up back to the original word.
p++//for each letter p is increased to find where the next letter will be.
return copytext(sanitize(t),1,MAX_MESSAGE_LEN)
newletter = "[newletter]-[newletter]"
. += newletter
return sanitize(.)
/proc/derpspeech(message, stuttering)
message = replacetext(message, " am ", " ")
@@ -183,52 +186,42 @@
return message
/proc/Gibberish(t, p)//t is the inputted message, and any value higher than 70 for p will cause letters to be replaced instead of added
/* Turn text into complete gibberish! */
var/returntext = ""
for(var/i = 1, i <= length(t), i++)
var/letter = copytext(t, i, i+1)
if(prob(50))
if(p >= 70)
/proc/Gibberish(text, replace_characters = FALSE, chance = 50)
text = html_decode(text)
. = ""
var/rawchar = ""
var/letter = ""
var/lentext = length(text)
for(var/i = 1, i <= lentext, i += length(rawchar))
rawchar = letter = text[i]
if(prob(chance))
if(replace_characters)
letter = ""
for(var/j in 1 to rand(0, 2))
letter += pick("#", "@", "*", "&", "%", "$", "/", "<", ">", ";", "*", "*", "*", "*", "*", "*", "*")
. += letter
return sanitize(.)
for(var/j = 1, j <= rand(0, 2), j++)
letter += pick("#","@","*","&","%","$","/", "<", ">", ";","*","*","*","*","*","*","*")
returntext += letter
return returntext
/proc/ninjaspeak(n) //NINJACODE
/*
The difference with stutter is that this proc can stutter more than 1 letter
The issue here is that anything that does not have a space is treated as one word (in many instances). For instance, "LOOKING," is a word, including the comma.
It's fairly easy to fix if dealing with single letters but not so much with compounds of letters./N
*/
var/te = html_decode(n)
var/t = ""
n = length(n)
var/p = 1
while(p <= n)
var/n_letter
var/n_mod = rand(1,4)
if(p+n_mod>n+1)
n_letter = copytext(te, p, n+1)
else
n_letter = copytext(te, p, p+n_mod)
/proc/ninjaspeak(phrase) //NINJACODE
. = ""
var/lentext = length_char(phrase)
var/rawchars = ""
var/letter = ""
for(var/i = 1, i <= lentext, i += length_char(rawchars))
var/end = i + rand(1,4)
letter = rawchars = copytext_char(phrase, i, end > lentext ? 0 : end)
if (prob(50))
if (prob(30))
n_letter = text("[n_letter]-[n_letter]-[n_letter]")
letter = "[letter]-[letter]-[letter]"
else
n_letter = text("[n_letter]-[n_letter]")
else
n_letter = text("[n_letter]")
t = text("[t][n_letter]")
p=p+n_mod
return copytext(sanitize(t),1,MAX_MESSAGE_LEN)
letter = "[letter]-[letter]"
. += letter
return copytext_char(sanitize(.),1,MAX_MESSAGE_LEN)
/proc/shake_camera(mob/M, duration, strength=1)
if(!M || !M.client || duration < 1)
+32 -33
View File
@@ -9,37 +9,36 @@
mob.dropItemToGround(mob.get_active_held_item())
return
/client/proc/Move_object(direct)
/client/proc/Move_object(direction)
if(mob && mob.control_object)
if(mob.control_object.density)
step(mob.control_object,direct)
step(mob.control_object,direction)
if(!mob.control_object)
return
mob.control_object.setDir(direct)
mob.control_object.setDir(direction)
else
mob.control_object.forceMove(get_step(mob.control_object,direct))
mob.control_object.forceMove(get_step(mob.control_object,direction))
#define MOVEMENT_DELAY_BUFFER 0.75
#define MOVEMENT_DELAY_BUFFER_DELTA 1.25
/client/Move(n, direct)
/client/Move(n, direction)
if(world.time < move_delay) //do not move anything ahead of this check please
return FALSE
else
next_move_dir_add = 0
next_move_dir_sub = 0
next_move_dir_add = next_move_dir_sub = NONE
var/old_move_delay = move_delay
move_delay = world.time + world.tick_lag //this is here because Move() can now be called mutiple times per tick
if(!mob || !mob.loc)
return FALSE
if(!n || !direct)
if(!n || !direction || !mob?.loc)
return FALSE
//GET RID OF THIS SOON AS MOBILITY FLAGS IS DONE
if(mob.notransform)
return FALSE //This is sota the goto stop mobs from moving var
return FALSE
if(mob.control_object)
return Move_object(direct)
return Move_object(direction)
if(!isliving(mob))
return mob.Move(n, direct)
return mob.Move(n, direction)
if(mob.stat == DEAD)
mob.ghostize()
return FALSE
@@ -48,29 +47,29 @@
var/mob/living/L = mob //Already checked for isliving earlier
if(L.incorporeal_move) //Move though walls
Process_Incorpmove(direct)
Process_Incorpmove(direction)
return FALSE
if(mob.remote_control) //we're controlling something, our movement is relayed to it
return mob.remote_control.relaymove(mob, direct)
return mob.remote_control.relaymove(mob, direction)
if(isAI(mob))
return AIMove(n,direct,mob)
return AIMove(n,direction,mob)
if(Process_Grab()) //are we restrained by someone's grip?
return
if(mob.buckled) //if we're buckled to something, tell it we moved.
return mob.buckled.relaymove(mob, direct)
return mob.buckled.relaymove(mob, direction)
if(!mob.canmove)
return FALSE
if(isobj(mob.loc) || ismob(mob.loc)) //Inside an object, tell it we moved
var/atom/O = mob.loc
return O.relaymove(mob, direct)
return O.relaymove(mob, direction)
if(!mob.Process_Spacemove(direct))
if(!mob.Process_Spacemove(direction))
return FALSE
//We are now going to move
var/add_delay = mob.movement_delay()
@@ -85,16 +84,16 @@
if(L.confused > 40)
newdir = pick(GLOB.alldirs)
else if(prob(L.confused * 1.5))
newdir = angle2dir(dir2angle(direct) + pick(90, -90))
newdir = angle2dir(dir2angle(direction) + pick(90, -90))
else if(prob(L.confused * 3))
newdir = angle2dir(dir2angle(direct) + pick(45, -45))
newdir = angle2dir(dir2angle(direction) + pick(45, -45))
if(newdir)
direct = newdir
n = get_step(L, direct)
direction = newdir
n = get_step(L, direction)
. = ..()
if((direct & (direct - 1)) && mob.loc == n) //moved diagonally successfully
if((direction & (direction - 1)) && mob.loc == n) //moved diagonally successfully
add_delay *= 2
move_delay += add_delay
if(.) // If mob is null here, we deserve the runtime
@@ -102,7 +101,7 @@
mob.throwing.finalize(FALSE)
for(var/obj/O in mob.user_movement_hooks)
O.intercept_user_move(direct, mob, n, oldloc)
O.intercept_user_move(direction, mob, n, oldloc)
var/atom/movable/P = mob.pulling
if(P && !ismob(P) && P.density)
@@ -126,22 +125,22 @@
///Process_Incorpmove
///Called by client/Move()
///Allows mobs to run though walls
/client/proc/Process_Incorpmove(direct)
/client/proc/Process_Incorpmove(direction)
var/turf/mobloc = get_turf(mob)
if(!isliving(mob))
return
var/mob/living/L = mob
switch(L.incorporeal_move)
if(INCORPOREAL_MOVE_BASIC)
var/T = get_step(L,direct)
var/T = get_step(L,direction)
if(T)
L.forceMove(T)
L.setDir(direct)
L.setDir(direction)
if(INCORPOREAL_MOVE_SHADOW)
if(prob(50))
var/locx
var/locy
switch(direct)
switch(direction)
if(NORTH)
locx = mobloc.x
locy = (mobloc.y+2)
@@ -175,12 +174,12 @@
break
else
new /obj/effect/temp_visual/dir_setting/ninja/shadow(mobloc, L.dir)
var/T = get_step(L,direct)
var/T = get_step(L,direction)
if(T)
L.forceMove(T)
L.setDir(direct)
L.setDir(direction)
if(INCORPOREAL_MOVE_JAUNT) //Incorporeal move, but blocked by holy-watered tiles and salt piles.
var/turf/open/floor/stepTurf = get_step(L, direct)
var/turf/open/floor/stepTurf = get_step(L, direction)
if(stepTurf)
for(var/obj/effect/decal/cleanable/salt/S in stepTurf)
to_chat(L, "<span class='warning'>[S] bars your passage!</span>")
@@ -197,7 +196,7 @@
return
L.forceMove(stepTurf)
L.setDir(direct)
L.setDir(direction)
return TRUE
+8 -8
View File
@@ -12,7 +12,7 @@
var/customsayverb = findtext(input, "*")
if(customsayverb && message_mode != MODE_WHISPER_CRIT)
message_mode = MODE_CUSTOM_SAY
return lowertext(copytext(input, 1, customsayverb))
return lowertext(copytext_char(input, 1, customsayverb))
else
return ..()
@@ -35,7 +35,7 @@
to_chat(usr, "<span class='danger'>Speech is currently admin-disabled.</span>")
return
message = trim(copytext(sanitize(message), 1, MAX_MESSAGE_LEN))
message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN))
usr.emote("me",1,message,TRUE)
@@ -83,9 +83,9 @@
deadchat_broadcast(rendered, follow_target = src, speaker_key = key)
/mob/proc/check_emote(message)
if(copytext(message, 1, 2) == "*")
emote(copytext(message, 2), intentional = TRUE)
return 1
if(message[1] == "*")
emote(copytext(message, length(message[1]) + 1), intentional = TRUE)
return TRUE
/mob/proc/hivecheck()
return 0
@@ -94,11 +94,11 @@
return LINGHIVE_NONE
/mob/proc/get_message_mode(message)
var/key = copytext(message, 1, 2)
var/key = message[1]
if(key == "#")
return MODE_WHISPER
else if(key == ";")
return MODE_HEADSET
else if(length(message) > 2 && (key in GLOB.department_radio_prefixes))
var/key_symbol = lowertext(copytext(message, 2, 3))
else if((length(message) > (length(key) + 1)) && (key in GLOB.department_radio_prefixes))
var/key_symbol = lowertext(message[length(key) + 1])
return GLOB.department_radio_keys[key_symbol]
+20 -46
View File
@@ -9,25 +9,19 @@
set src in usr
if(usr != src)
to_chat(usr, "No.")
var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", html_decode(flavor_text), MAX_MESSAGE_LEN*2, TRUE)
var/msg = stripped_multiline_input(usr, "Set the flavor text in your 'examine' verb. This can also be used for OOC notes and preferences!", "Flavor Text", html_decode(flavor_text), MAX_MESSAGE_LEN, TRUE)
if(!isnull(msg))
msg = copytext(msg, 1, MAX_MESSAGE_LEN)
msg = html_encode(msg)
flavor_text = msg
if(msg)
flavor_text = html_encode(msg)
/mob/proc/update_flavor_text_2()
set src in usr
if(usr != src)
to_chat(usr, "No.")
var/msg = stripped_multiline_input(usr, "Set the temporary flavor text in your 'examine' verb. This should be used only for things pertaining to the current round!", "Short-Term Flavor Text", html_decode(flavor_text_2), MAX_MESSAGE_LEN*2, TRUE)
var/msg = stripped_multiline_input(usr, "Set the temporary flavor text in your 'examine' verb. This should be used only for things pertaining to the current round!", "Short-Term Flavor Text", html_decode(flavor_text_2), MAX_MESSAGE_LEN, TRUE)
if(!isnull(msg))
msg = copytext(msg, 1, MAX_MESSAGE_LEN)
msg = html_encode(msg)
flavor_text_2 = msg
if(msg)
flavor_text_2 = html_encode(msg)
/mob/proc/warn_flavor_changed()
@@ -39,19 +33,19 @@
if(flavor_text && flavor_text != "")
// We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown.
var/msg = html_decode(replacetext(flavor_text, "\n", " "))
if(length(msg) <= 40)
if(length_char(msg) <= 40)
return "<span class='notice'>[html_encode(msg)]</span>"
else
return "<span class='notice'>[html_encode(copytext(msg, 1, 37))]... <a href='?src=[REF(src)];flavor_more=1'>More...</span></a>"
return "<span class='notice'>[html_encode(copytext_char(msg, 1, 37))]... <a href='?src=[REF(src)];flavor_more=1'>More...</span></a>"
/mob/proc/print_flavor_text_2()
if(flavor_text && flavor_text != "")
// We are decoding and then encoding to not only get correct amount of characters, but also to prevent partial escaping characters being shown.
var/msg = html_decode(replacetext(flavor_text_2, "\n", " "))
if(length(msg) <= 40)
if(length_char(msg) <= 40)
return "<span class='notice'>[html_encode(msg)]</span>"
else
return "<span class='notice'>[html_encode(copytext(msg, 1, 37))]... <a href='?src=[REF(src)];flavor2_more=1'>More...</span></a>"
return "<span class='notice'>[html_encode(copytext_char(msg, 1, 37))]... <a href='?src=[REF(src)];flavor2_more=1'>More...</span></a>"
/mob/proc/get_top_level_mob()
@@ -80,17 +74,10 @@ proc/get_top_level_mob(var/mob/S)
/datum/emote/living/subtle/proc/check_invalid(mob/user, input)
. = TRUE
if(copytext(input,1,5) == "says")
if(stop_bad_mime.Find(input, 1, 1))
to_chat(user, "<span class='danger'>Invalid emote.</span>")
else if(copytext(input,1,9) == "exclaims")
to_chat(user, "<span class='danger'>Invalid emote.</span>")
else if(copytext(input,1,6) == "yells")
to_chat(user, "<span class='danger'>Invalid emote.</span>")
else if(copytext(input,1,5) == "asks")
to_chat(user, "<span class='danger'>Invalid emote.</span>")
else
. = FALSE
return TRUE
return FALSE
/datum/emote/living/subtle/run_emote(mob/user, params, type_override = null)
if(jobban_isbanned(user, "emote"))
@@ -100,7 +87,7 @@ proc/get_top_level_mob(var/mob/S)
to_chat(user, "You cannot send IC messages (muted).")
return FALSE
else if(!params)
var/subtle_emote = copytext(sanitize(input("Choose an emote to display.") as message|null), 1, MAX_MESSAGE_LEN)
var/subtle_emote = stripped_multiline_input(user, "Choose an emote to display.", "Subtle", null, MAX_MESSAGE_LEN)
if(subtle_emote && !check_invalid(user, subtle_emote))
var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable")
switch(type)
@@ -122,7 +109,7 @@ proc/get_top_level_mob(var/mob/S)
if(!can_run_emote(user))
return FALSE
user.log_message(message, INDIVIDUAL_EMOTE_LOG)
user.log_message(message, LOG_EMOTE)
message = "<b>[user]</b> " + "<i>[message]</i>"
for(var/mob/M in GLOB.dead_mob_list)
@@ -136,10 +123,7 @@ proc/get_top_level_mob(var/mob/S)
user.audible_message(message=message,hearing_distance=1)
else
user.visible_message(message=message,self_message=message,vision_distance=1)
log_emote("[key_name(user)] : [message]")
message = null
emote_type = EMOTE_VISIBLE
///////////////// SUBTLE 2: NO GHOST BOOGALOO
@@ -151,17 +135,10 @@ proc/get_top_level_mob(var/mob/S)
/datum/emote/living/subtler/proc/check_invalid(mob/user, input)
. = TRUE
if(copytext(input,1,5) == "says")
if(stop_bad_mime.Find(input, 1, 1))
to_chat(user, "<span class='danger'>Invalid emote.</span>")
else if(copytext(input,1,9) == "exclaims")
to_chat(user, "<span class='danger'>Invalid emote.</span>")
else if(copytext(input,1,6) == "yells")
to_chat(user, "<span class='danger'>Invalid emote.</span>")
else if(copytext(input,1,5) == "asks")
to_chat(user, "<span class='danger'>Invalid emote.</span>")
else
. = FALSE
return TRUE
return FALSE
/datum/emote/living/subtler/run_emote(mob/user, params, type_override = null)
if(jobban_isbanned(user, "emote"))
@@ -171,7 +148,7 @@ proc/get_top_level_mob(var/mob/S)
to_chat(user, "You cannot send IC messages (muted).")
return FALSE
else if(!params)
var/subtle_emote = copytext(sanitize(input("Choose an emote to display.") as message|null), 1, MAX_MESSAGE_LEN)
var/subtle_emote = stripped_multiline_input(user, "Choose an emote to display.", "Subtler" , null, MAX_MESSAGE_LEN)
if(subtle_emote && !check_invalid(user, subtle_emote))
var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable")
switch(type)
@@ -193,16 +170,13 @@ proc/get_top_level_mob(var/mob/S)
if(!can_run_emote(user))
return FALSE
user.log_message(message, INDIVIDUAL_EMOTE_LOG)
user.log_message(message, LOG_SUBTLER)
message = "<b>[user]</b> " + "<i>[message]</i>"
if(emote_type == EMOTE_AUDIBLE)
user.audible_message(message=message,hearing_distance=1, ignored_mobs = GLOB.dead_mob_list)
else
user.visible_message(message=message,self_message=message,vision_distance=1, ignored_mobs = GLOB.dead_mob_list)
log_emote("[key_name(user)] : (SUBTLER) [message]")
message = null
///////////////// VERB CODE
/mob/living/verb/subtle()
+7 -7
View File
@@ -42,8 +42,8 @@
// hash the original name?
if(tr_flags & TR_HASHNAME)
O.name = "monkey ([copytext(md5(real_name), 2, 6)])"
O.real_name = "monkey ([copytext(md5(real_name), 2, 6)])"
O.name = "monkey ([copytext_char(md5(real_name), 2, 6)])"
O.real_name = "monkey ([copytext_char(md5(real_name), 2, 6)])"
//handle DNA and other attributes
dna.transfer_identity(O)
@@ -89,7 +89,7 @@
if(tr_flags & TR_KEEPORGANS)
for(var/X in O.internal_organs)
var/obj/item/organ/I = X
I.Remove(O, 1)
I.Remove(TRUE)
if(mind)
mind.transfer_to(O)
@@ -102,7 +102,7 @@
for(var/X in internal_organs)
var/obj/item/organ/I = X
int_organs += I
I.Remove(src, 1)
I.Remove(TRUE)
for(var/X in int_organs)
var/obj/item/organ/I = X
@@ -201,7 +201,7 @@
dna.transfer_identity(O)
O.updateappearance(mutcolor_update=1)
if(cmptext("monkey",copytext(O.dna.real_name,1,7)))
if(findtext(O.dna.real_name, "monkey", 1, 7)) //7 == length("monkey") + 1
O.real_name = random_unique_name(O.gender)
O.dna.generate_unique_enzymes(O)
else
@@ -248,7 +248,7 @@
if(tr_flags & TR_KEEPORGANS)
for(var/X in O.internal_organs)
var/obj/item/organ/I = X
I.Remove(O, 1)
I.Remove(TRUE)
if(mind)
mind.transfer_to(O)
@@ -260,7 +260,7 @@
for(var/X in internal_organs)
var/obj/item/organ/I = X
int_organs += I
I.Remove(src, 1)
I.Remove(TRUE)
for(var/X in int_organs)
var/obj/item/organ/I = X