mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-30 08:37:43 +01:00
Merge branch 'master' of https://github.com/tgstation/-tg-station into ayygentb
Conflicts: _maps/map_files/MetaStation/MetaStation.dmm
This commit is contained in:
@@ -594,3 +594,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
if(check_rights(R_ADMIN, 0))
|
||||
return 1
|
||||
return
|
||||
|
||||
/mob/dead/observer/is_literate()
|
||||
return 1
|
||||
|
||||
@@ -1038,3 +1038,6 @@
|
||||
. = ..()
|
||||
if (dna && dna.species)
|
||||
. += dna.species.check_weakness(weapon, attacker)
|
||||
|
||||
/mob/living/carbon/human/is_literate()
|
||||
return 1
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
var/hair_color = null // this allows races to have specific hair colors... if null, it uses the H's hair/facial hair colors. if "mutcolor", it uses the H's mutant_color
|
||||
var/hair_alpha = 255 // the alpha used by the hair. 255 is completely solid, 0 is transparent.
|
||||
var/use_skintones = 0 // does it use skintones or not? (spoiler alert this is only used by humans)
|
||||
var/need_nutrition = 1 //Does it need to eat food on a regular basis?
|
||||
var/exotic_blood = "" // If your race wants to bleed something other than bog standard blood, change this to reagent id.
|
||||
var/meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human //What the species drops on gibbing
|
||||
var/skinned_type = /obj/item/stack/sheet/animalhide/generic
|
||||
@@ -702,7 +701,9 @@
|
||||
H.update_inv_wear_suit()
|
||||
|
||||
// nutrition decrease and satiety
|
||||
if (H.nutrition > 0 && H.stat != DEAD && H.dna.species.need_nutrition)
|
||||
if (H.nutrition > 0 && H.stat != DEAD && \
|
||||
H.dna && H.dna.species && (!(NOHUNGER in H.dna.species.specflags)))
|
||||
// THEY HUNGER
|
||||
var/hunger_rate = HUNGER_FACTOR
|
||||
if(H.satiety > 0)
|
||||
H.satiety--
|
||||
|
||||
@@ -217,7 +217,7 @@
|
||||
id = "slime"
|
||||
default_color = "00FFFF"
|
||||
darksight = 3
|
||||
specflags = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD,VIRUSIMMUNE)
|
||||
specflags = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD,VIRUSIMMUNE,NODISMEMBER)
|
||||
say_mod = "says"
|
||||
eyes = "eyes"
|
||||
hair_color = "mutcolor"
|
||||
@@ -406,11 +406,10 @@
|
||||
name = "Spooky Scary Skeleton"
|
||||
id = "skeleton"
|
||||
say_mod = "rattles"
|
||||
need_nutrition = 0
|
||||
blacklisted = 1
|
||||
sexes = 0
|
||||
meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
|
||||
specflags = list(NOBREATH,RESISTTEMP,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE)
|
||||
specflags = list(NOBREATH,RESISTTEMP,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NOHUNGER)
|
||||
mutant_organs = list(/obj/item/organ/tongue/bone)
|
||||
|
||||
/*
|
||||
@@ -455,13 +454,12 @@ var/global/image/plasmaman_on_fire = image("icon"='icons/mob/OnFire.dmi', "icon_
|
||||
say_mod = "rattles"
|
||||
sexes = 0
|
||||
meat = /obj/item/stack/sheet/mineral/plasma
|
||||
specflags = list(NOBLOOD,RADIMMUNE,NOTRANSSTING,VIRUSIMMUNE)
|
||||
specflags = list(NOBLOOD,RADIMMUNE,NOTRANSSTING,VIRUSIMMUNE,NOHUNGER)
|
||||
safe_oxygen_min = 0 //We don't breath this
|
||||
safe_toxins_min = 16 //We breath THIS!
|
||||
safe_toxins_max = 0
|
||||
dangerous_existence = 1 //So so much
|
||||
blacklisted = 1 //See above
|
||||
need_nutrition = 0 //Hard to eat through a helmet
|
||||
burnmod = 2
|
||||
heatmod = 2
|
||||
speedmod = 1
|
||||
@@ -509,7 +507,7 @@ var/global/list/synth_flesh_disguises = list()
|
||||
id = "synth"
|
||||
say_mod = "beep boops" //inherited from a user's real species
|
||||
sexes = 0
|
||||
specflags = list(NOTRANSSTING,NOBREATH,VIRUSIMMUNE,NODISMEMBER) //all of these + whatever we inherit from the real species
|
||||
specflags = list(NOTRANSSTING,NOBREATH,VIRUSIMMUNE,NODISMEMBER,NOHUNGER) //all of these + whatever we inherit from the real species
|
||||
safe_oxygen_min = 0
|
||||
safe_toxins_min = 0
|
||||
safe_toxins_max = 0
|
||||
@@ -518,9 +516,8 @@ var/global/list/synth_flesh_disguises = list()
|
||||
SA_sleep_min = 0
|
||||
dangerous_existence = 1
|
||||
blacklisted = 1
|
||||
need_nutrition = 0 //beep boop robots do not need sustinance
|
||||
meat = null
|
||||
var/list/initial_specflags = list(NOTRANSSTING,NOBREATH,VIRUSIMMUNE) //for getting these values back for assume_disguise()
|
||||
var/list/initial_specflags = list(NOTRANSSTING,NOBREATH,VIRUSIMMUNE,NOHUNGER) //for getting these values back for assume_disguise()
|
||||
var/disguise_fail_health = 75 //When their health gets to this level their synthflesh partially falls off
|
||||
var/image/damaged_synth_flesh = null //an image to display when we're below disguise_fail_health
|
||||
var/datum/species/fake_species = null //a species to do most of our work for us, unless we're damaged
|
||||
@@ -705,7 +702,6 @@ SYNDICATE BLACK OPS
|
||||
name = "Corporate Agent"
|
||||
id = "agent"
|
||||
hair_alpha = 0
|
||||
need_nutrition = 0//They don't need to eat
|
||||
say_mod = "declares"
|
||||
speedmod = -2//Fast
|
||||
brutemod = 0.7//Tough against firearms
|
||||
@@ -719,5 +715,5 @@ SYNDICATE BLACK OPS
|
||||
attack_sound = "sound/weapons/resonator_blast.ogg"
|
||||
blacklisted = 1
|
||||
use_skintones = 0
|
||||
specflags = list(RADIMMUNE,VIRUSIMMUNE,NOBLOOD,PIERCEIMMUNE,EYECOLOR,NODISMEMBER)
|
||||
specflags = list(RADIMMUNE,VIRUSIMMUNE,NOBLOOD,PIERCEIMMUNE,EYECOLOR,NODISMEMBER,NOHUNGER)
|
||||
sexes = 0
|
||||
|
||||
@@ -39,21 +39,21 @@ var/list/department_radio_keys = list(
|
||||
|
||||
//kinda localization -- rastaf0
|
||||
//same keys as above, but on russian keyboard layout. This file uses cp1251 as encoding.
|
||||
":ê" = "right hand", "#ê" = "right hand", ".ê" = "right hand",
|
||||
":ä" = "left hand", "#ä" = "left hand", ".ä" = "left hand",
|
||||
":ø" = "intercom", "#ø" = "intercom", ".ø" = "intercom",
|
||||
":ð" = "department", "#ð" = "department", ".ð" = "department",
|
||||
":ñ" = "Command", "#ñ" = "Command", ".ñ" = "Command",
|
||||
":ò" = "Science", "#ò" = "Science", ".ò" = "Science",
|
||||
":ü" = "Medical", "#ü" = "Medical", ".ü" = "Medical",
|
||||
":ó" = "Engineering", "#ó" = "Engineering", ".ó" = "Engineering",
|
||||
":û" = "Security", "#û" = "Security", ".û" = "Security",
|
||||
":ö" = "whisper", "#ö" = "whisper", ".ö" = "whisper",
|
||||
":è" = "binary", "#è" = "binary", ".è" = "binary",
|
||||
":ô" = "alientalk", "#ô" = "alientalk", ".ô" = "alientalk",
|
||||
":å" = "Syndicate", "#å" = "Syndicate", ".å" = "Syndicate",
|
||||
":é" = "Supply", "#é" = "Supply", ".é" = "Supply",
|
||||
":ï" = "changeling", "#ï" = "changeling", ".ï" = "changeling"
|
||||
":ê" = "right hand", "#ê" = "right hand", ".ê" = "right hand",
|
||||
":ä" = "left hand", "#ä" = "left hand", ".ä" = "left hand",
|
||||
":ø" = "intercom", "#ø" = "intercom", ".ø" = "intercom",
|
||||
":ð" = "department", "#ð" = "department", ".ð" = "department",
|
||||
":ñ" = "Command", "#ñ" = "Command", ".ñ" = "Command",
|
||||
":ò" = "Science", "#ò" = "Science", ".ò" = "Science",
|
||||
":ü" = "Medical", "#ü" = "Medical", ".ü" = "Medical",
|
||||
":ó" = "Engineering", "#ó" = "Engineering", ".ó" = "Engineering",
|
||||
":û" = "Security", "#û" = "Security", ".û" = "Security",
|
||||
":ö" = "whisper", "#ö" = "whisper", ".ö" = "whisper",
|
||||
":è" = "binary", "#è" = "binary", ".è" = "binary",
|
||||
":ô" = "alientalk", "#ô" = "alientalk", ".ô" = "alientalk",
|
||||
":å" = "Syndicate", "#å" = "Syndicate", ".å" = "Syndicate",
|
||||
":é" = "Supply", "#é" = "Supply", ".é" = "Supply",
|
||||
":ï" = "changeling", "#ï" = "changeling", ".ï" = "changeling"
|
||||
)
|
||||
|
||||
var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
@@ -205,6 +205,21 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
/mob/living/proc/handle_inherent_channels(message, message_mode)
|
||||
if(message_mode == MODE_CHANGELING)
|
||||
switch(lingcheck())
|
||||
if(3)
|
||||
var/msg = "<i><font color=#800040><b>[src.mind]:</b> [message]</font></i>"
|
||||
for(var/mob/M in mob_list)
|
||||
if(M in dead_mob_list)
|
||||
M << "<a href='?src=\ref[M];follow=\ref[src]'>(F)</a> [msg]"
|
||||
else
|
||||
switch(M.lingcheck())
|
||||
if(3)
|
||||
M << msg
|
||||
if(2)
|
||||
M << msg
|
||||
if(1)
|
||||
if(prob(40))
|
||||
M << "<i><font color=#800080>We can faintly sense an outsider trying to communicate through the hivemind...</font></i>"
|
||||
return 1
|
||||
if(2)
|
||||
var/msg = "<i><font color=#800080><b>[mind.changeling.changelingID]:</b> [message]</font></i>"
|
||||
log_say("[mind.changeling.changelingID]/[src.key] : [message]")
|
||||
@@ -213,6 +228,8 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
M << "<a href='?src=\ref[M];follow=\ref[src]'>(F)</a> [msg]"
|
||||
else
|
||||
switch(M.lingcheck())
|
||||
if(3)
|
||||
M << msg
|
||||
if(2)
|
||||
M << msg
|
||||
if(1)
|
||||
@@ -272,11 +289,13 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
return NOPASS
|
||||
return 0
|
||||
|
||||
/mob/living/lingcheck() //Returns 1 if they are a changeling. Returns 2 if they are a changeling that can communicate through the hivemind
|
||||
/mob/living/lingcheck() //1 is ling w/ no hivemind. 2 is ling w/hivemind. 3 is ling victim being linked into hivemind.
|
||||
if(mind && mind.changeling)
|
||||
if(mind.changeling.changeling_speak)
|
||||
return 2
|
||||
return 1
|
||||
if(mind && mind.linglink)
|
||||
return 3
|
||||
return 0
|
||||
|
||||
/mob/living/say_quote(input, list/spans)
|
||||
@@ -285,4 +304,4 @@ var/list/crit_allowed_modes = list(MODE_WHISPER,MODE_CHANGELING,MODE_ALIEN)
|
||||
return "stammers, \"[tempinput]\""
|
||||
if (getBrainLoss() >= 60)
|
||||
return "gibbers, \"[tempinput]\""
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
@@ -555,7 +555,10 @@
|
||||
if(emagged || (connected_ai && lawupdate)) //Can't be sure which, metagamers
|
||||
emote("buzz-[user.name]")
|
||||
return
|
||||
MOD.install(src, user) //Proc includes a success mesage so we don't need another one
|
||||
if(!mind) //A player mind is required for law procs to run antag checks.
|
||||
user << "<span class='warning'>[src] is entirely unresponsive!</span>"
|
||||
return
|
||||
MOD.install(laws, user) //Proc includes a success mesage so we don't need another one
|
||||
return
|
||||
|
||||
else if(istype(W, /obj/item/device/encryptionkey/) && opened)
|
||||
|
||||
@@ -489,3 +489,5 @@
|
||||
animate(src, transform = ntransform, time = 2,easing = EASE_IN|EASE_OUT)
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/is_literate()
|
||||
return 1
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
var/new_destination // pending new destination (waiting for beacon response)
|
||||
var/destination // destination description tag
|
||||
var/next_destination // the next destination in the patrol route
|
||||
var/shuffle = FALSE // If we should shuffle our adjacency checking
|
||||
|
||||
var/blockcount = 0 //number of times retried a blocked path
|
||||
var/awaiting_beacon = 0 // count of pticks awaiting a beacon response
|
||||
@@ -375,11 +376,22 @@ Pass the desired type path itself, declaring a temporary var beforehand is not r
|
||||
if(!T)
|
||||
return
|
||||
var/list/adjacent = T.GetAtmosAdjacentTurfs(1)
|
||||
if(shuffle) //If we were on the same tile as another bot, let's randomize our choices so we dont both go the same way
|
||||
adjacent = shuffle(adjacent)
|
||||
shuffle = FALSE
|
||||
for(var/scan in adjacent)//Let's see if there's something right next to us first!
|
||||
var/final_result = checkscan(scan,scan_type,old_target)
|
||||
if(final_result)
|
||||
return final_result
|
||||
|
||||
if(check_bot(scan)) //Is there another bot there? Then let's just skip it
|
||||
continue
|
||||
if(isturf(scan_type)) //If we're lookeing for a turf we can just run the checks directly!
|
||||
var/final_result = checkscan(scan,scan_type,old_target)
|
||||
if(final_result)
|
||||
return final_result
|
||||
else
|
||||
var/turf/turfy = scan
|
||||
for(var/deepscan in turfy.contents)//Check the contents since adjacent is turfs
|
||||
var/final_result = checkscan(deepscan,scan_type,old_target)
|
||||
if(final_result)
|
||||
return final_result
|
||||
for (var/scan in shuffle(view(scan_range, src))-adjacent) //Search for something in range!
|
||||
var/final_result = checkscan(scan,scan_type,old_target)
|
||||
if(final_result)
|
||||
@@ -390,11 +402,7 @@ Pass the desired type path itself, declaring a temporary var beforehand is not r
|
||||
return 0 //If not, keep searching!
|
||||
if( (scan in ignore_list) || (scan == old_target) ) //Filter for blacklisted elements, usually unreachable or previously processed oness
|
||||
return 0
|
||||
var/turf/T = get_turf(scan)
|
||||
if(T)
|
||||
for(var/C in T.contents)
|
||||
if(istype(C,src.type) && (C != src)) //Is there another bot there already? If so, let's skip it so we dont all atack on top of eachother.
|
||||
return 0
|
||||
|
||||
var/scan_result = process_scan(scan) //Some bots may require additional processing when a result is selected.
|
||||
if(scan_result)
|
||||
return scan_result
|
||||
@@ -402,6 +410,12 @@ Pass the desired type path itself, declaring a temporary var beforehand is not r
|
||||
return 0 //The current element failed assessment, move on to the next.
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/proc/check_bot(targ)
|
||||
var/turf/T = get_turf(targ)
|
||||
if(T)
|
||||
for(var/C in T.contents)
|
||||
if(istype(C,type) && (C != src)) //Is there another bot there already? If so, let's skip it so we dont all atack on top of eachother.
|
||||
return 1 //Let's abort if we find a bot so we dont have to keep rechecking
|
||||
|
||||
//When the scan finds a target, run bot specific processing to select it for the next step. Empty by default.
|
||||
/mob/living/simple_animal/bot/proc/process_scan(scan_target)
|
||||
|
||||
@@ -140,7 +140,10 @@
|
||||
return
|
||||
|
||||
if(target && loc == target.loc)
|
||||
clean(target)
|
||||
if(!(check_bot(target) && prob(50))) //Target is not defined at the parent. 50% chance to still try and clean so we dont get stuck on the last blood drop.
|
||||
clean(target) //Rather than check at every step of the way, let's check before we do an action, so we can rescan before the other bot.
|
||||
else
|
||||
shuffle = TRUE //Shuffle the list the next time we scan so we dont both go the same way.
|
||||
path = list()
|
||||
target = null
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
dat += "<A href='?src=\ref[src];operation=eject'>Loaded \[[specialtiles]/[maxtiles]\]</a><BR>"
|
||||
else
|
||||
dat += "None Loaded<BR>"
|
||||
|
||||
|
||||
dat += "Behaviour controls are [locked ? "locked" : "unlocked"]<BR>"
|
||||
if(!locked || issilicon(user) || IsAdminGhost(user))
|
||||
dat += "Add tiles to new hull plating: <A href='?src=\ref[src];operation=autotile'>[autotile ? "Yes" : "No"]</A><BR>"
|
||||
@@ -162,7 +162,7 @@
|
||||
if("disable")
|
||||
targetdirection = null
|
||||
update_controls()
|
||||
|
||||
|
||||
/mob/living/simple_animal/bot/floorbot/proc/empty_tiles()
|
||||
var/turf/Tsec = get_turf(src)
|
||||
|
||||
@@ -204,7 +204,7 @@
|
||||
if(!target && fixfloors) //Repairs damaged floors and tiles.
|
||||
process_type = FIX_TILE
|
||||
target = scan(/turf/open/floor)
|
||||
|
||||
|
||||
if(!target && replacetiles && specialtiles > 0) //Replace a floor tile with custom tile
|
||||
process_type = REPLACE_TILE //The target must be a tile. The floor must already have a floortile.
|
||||
target = scan(/turf/open/floor)
|
||||
@@ -242,6 +242,12 @@
|
||||
return
|
||||
|
||||
if(loc == target || loc == target.loc)
|
||||
if(check_bot(target)) //Target is not defined at the parent
|
||||
shuffle = TRUE
|
||||
if(prob(50)) //50% chance to still try to repair so we dont end up with 2 floorbots failing to fix the last breach
|
||||
target = null
|
||||
path = list()
|
||||
return
|
||||
if(istype(target, /turf/) && emagged < 2)
|
||||
repair(target)
|
||||
else if(emagged == 2 && istype(target,/turf/open/floor))
|
||||
|
||||
@@ -148,6 +148,7 @@
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/proc/swoop_attack(fire_rain = 0, atom/movable/manual_target)
|
||||
if(stat)
|
||||
return
|
||||
swoop_cooldown = world.time + 200
|
||||
var/swoop_target
|
||||
if(manual_target)
|
||||
swoop_target = manual_target
|
||||
@@ -194,10 +195,6 @@
|
||||
stop_automated_movement = FALSE
|
||||
swooping = 0
|
||||
density = 1
|
||||
swoop_cooldown = world.time + 200
|
||||
|
||||
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/AltClickOn(atom/movable/A)
|
||||
if(!istype(A))
|
||||
|
||||
@@ -35,17 +35,19 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/zombie/darkholme //BOY♂NEXT♂RUIN
|
||||
desc = "This guy seems to have gotten lost on his way to the leather club."
|
||||
|
||||
gold_core_spawnable = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/zombie/darkholme/New()
|
||||
..()
|
||||
name = pick("Leatherman","Leatherhead")
|
||||
|
||||
|
||||
mob/living/simple_animal/hostile/zombie/gymboss
|
||||
name = "boss of this gym"
|
||||
desc = "There seems to be something shiny embedded in his waist."
|
||||
butcher_results = list(/obj/item/weapon/storage/belt/champion/wrestling = 1)
|
||||
attacktext = "spanks"
|
||||
|
||||
gold_core_spawnable = 0
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/zombie/AttackingTarget()
|
||||
..()
|
||||
|
||||
@@ -933,3 +933,6 @@ var/next_mob_id = 0
|
||||
if("resize")
|
||||
update_transform()
|
||||
..()
|
||||
|
||||
/mob/proc/is_literate()
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user