diff --git a/code/__DEFINES/flags.dm b/code/__DEFINES/flags.dm index d2aa1b8d78e..15a8ed20949 100644 --- a/code/__DEFINES/flags.dm +++ b/code/__DEFINES/flags.dm @@ -53,21 +53,21 @@ #define MUTCOLORS 1 #define HAIR 2 -#define FACEHAIR 4 -#define EYECOLOR 8 -#define LIPS 16 -#define RESISTCOLD 32 -#define RESISTHEAT 64 -#define RADIMMUNE 128 -#define NOBREATH 256 -#define NOGUNS 512 -#define NOBLOOD 1024 -#define NOFIRE 2048 -#define VIRUSIMMUNE 4096 -#define PIERCEIMMUNE 8192 -#define NOTRANSSTING 16384 - -#define MUTCOLORS_PARTSONLY 32768 //Used if we want the mutant colour to be only used by mutant bodyparts. Don't combine this with MUTCOLORS, or it will be useless. +#define FACEHAIR 3 +#define EYECOLOR 4 +#define LIPS 5 +#define RESISTTEMP 6 +#define RADIMMUNE 7 +#define NOBREATH 8 +#define NOGUNS 9 +#define NOBLOOD 10 +#define NOFIRE 11 +#define VIRUSIMMUNE 12 +#define PIERCEIMMUNE 13 +#define NOTRANSSTING 14 +#define MUTCOLORS_PARTSONLY 15 //Used if we want the mutant colour to be only used by mutant bodyparts. Don't combine this with MUTCOLORS, or it will be useless. +#define NODISMEMBER 16 +#define NOHUNGER 17 /* These defines are used specifically with the atom/movable/languages bitmask. diff --git a/code/game/gamemodes/blob/blob_finish.dm b/code/game/gamemodes/blob/blob_finish.dm index f5a415985fe..e1ade57fe22 100644 --- a/code/game/gamemodes/blob/blob_finish.dm +++ b/code/game/gamemodes/blob/blob_finish.dm @@ -1,9 +1,9 @@ /datum/game_mode/blob/check_finished() - if(blob_overminds.len > cores_to_spawn && cores_to_spawn > blob_cores.len)//Some blobs have yet to burst + if(overminds.len) return 0 if(blobwincount <= blobs_legit.len)//Blob took over return 1 - if(!overminds.len && !blob_cores.len) //blob is dead + if(!blob_cores.len) //blob is dead if(config.continuous["blob"]) continuous_sanity_checked = 1 //Nonstandard definition of "alive" gets past the check otherwise SSshuttle.emergencyNoEscape = 0 diff --git a/code/game/gamemodes/blob/theblob.dm b/code/game/gamemodes/blob/theblob.dm index 72112430613..5647c202066 100644 --- a/code/game/gamemodes/blob/theblob.dm +++ b/code/game/gamemodes/blob/theblob.dm @@ -45,6 +45,20 @@ return ..() +/obj/effect/blob/Adjacent(var/atom/neighbour) + . = ..() + if(.) + var/result = 0 + var/direction = get_dir(src, neighbour) + var/list/dirs = list("[NORTHWEST]" = list(NORTH, WEST), "[NORTHEAST]" = list(NORTH, EAST), "[SOUTHEAST]" = list(SOUTH, EAST), "[SOUTHWEST]" = list(SOUTH, WEST)) + for(var/A in dirs) + if(direction == text2num(A)) + for(var/B in dirs[A]) + var/C = locate(/obj/effect/blob) in get_step(src, B) + if(C) + result++ + . -= result - 1 + /obj/effect/blob/CanAtmosPass(turf/T) return !atmosblock diff --git a/code/game/gamemodes/changeling/powers/fleshmend.dm b/code/game/gamemodes/changeling/powers/fleshmend.dm index e4c68a8537c..1331788dc4e 100644 --- a/code/game/gamemodes/changeling/powers/fleshmend.dm +++ b/code/game/gamemodes/changeling/powers/fleshmend.dm @@ -1,13 +1,17 @@ /obj/effect/proc_holder/changeling/fleshmend name = "Fleshmend" - desc = "Our flesh rapidly regenerates, healing our wounds. Effectiveness decreases with quick, repeated use." - helptext = "Heals a moderate amount of damage over a short period of time. Can be used while unconscious, and will alert nearby crew." + desc = "Our flesh rapidly regenerates, healing our wounds, and growing \ + back missing limbs. Effectiveness decreases with quick, repeated use." + helptext = "Heals a moderate amount of damage over a short period of \ + time. Can be used while unconscious. Will alert nearby crew if \ + any limbs are regenerated." chemical_cost = 25 dna_cost = 2 req_stat = UNCONSCIOUS var/recent_uses = 1 //The factor of which the healing should be divided by var/healing_ticks = 10 - // The ideal total healing amount, divided by healing_ticks to get heal/tick + // The ideal total healing amount, + // divided by healing_ticks to get heal/tick var/total_healing = 100 /obj/effect/proc_holder/changeling/fleshmend/New() @@ -22,25 +26,29 @@ if(recent_uses > 1) recent_uses = max(1, recent_uses - (1 / healing_ticks)) -//Starts healing you every second for 10 seconds. Can be used whilst unconscious. +//Starts healing you every second for 10 seconds. +//Can be used whilst unconscious. /obj/effect/proc_holder/changeling/fleshmend/sting_action(mob/living/user) user << "We begin to heal rapidly." if(recent_uses > 1) - user << "Our healing's effectiveness is reduced by quickly repeated use!" + user << "Our healing's effectiveness is reduced \ + by quick repeated use!" spawn(0) recent_uses++ if(ishuman(user)) var/mob/living/carbon/human/H = user H.restore_blood() H.remove_all_embedded_objects() - if(H.get_missing_limbs()) + var/list/missing = H.get_missing_limbs() + if(missing.len) playsound(user, 'sound/magic/Demon_consume.ogg', 50, 1) H.visible_message("[user]'s missing limbs reform, making a loud, grotesque sound!", "Your limbs regrow, making a loud, crunchy sound and giving you great pain!", "You hear organic matter ripping and tearing!") H.emote("scream") H.regenerate_limbs(1) - // The healing itself - doesn't heal toxin damage (that's anatomic panacea) and - // effectiveness decreases with each use in a short timespan + // The healing itself - doesn't heal toxin damage + // (that's anatomic panacea) and the effectiveness decreases with + // each use in a short timespan for(var/i in 1 to healing_ticks) if(user) var/healpertick = -(total_healing / healing_ticks) diff --git a/code/game/gamemodes/cult/cult.dm b/code/game/gamemodes/cult/cult.dm index e5cc534da09..2b35c5df6b7 100644 --- a/code/game/gamemodes/cult/cult.dm +++ b/code/game/gamemodes/cult/cult.dm @@ -68,7 +68,7 @@ restricted_jobs += "Assistant" //cult scaling goes here - recommended_enemies = 3 + round(num_players()/20) + recommended_enemies = 3 + round(num_players()/15) for(var/cultists_number = 1 to recommended_enemies) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index fd97b4f73a8..64b6e1c6517 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -759,7 +759,7 @@ var/list/teleport_runes = list() var/mob/living/user = invokers[1] var/list/cultists = list() for(var/datum/mind/M in ticker.mode.cult) - if(!(M.current in invokers)) + if(!(M.current in invokers) && M.current.stat != DEAD) cultists |= M.current var/mob/living/cultist_to_summon = input(user, "Who do you wish to call to [src]?", "Followers of the Geometer") as null|anything in cultists if(!Adjacent(user) || !src || qdeleted(src) || user.incapacitated()) @@ -769,10 +769,15 @@ var/list/teleport_runes = list() fail_invoke() log_game("Summon Cultist rune failed - no target") return + if(cultist_to_summon.stat == DEAD) + user << "[cultist_to_summon] has died!" + fail_invoke() + log_game("Summon Cultist rune failed - target died") + return if(!iscultist(cultist_to_summon)) user << "[cultist_to_summon] is not a follower of the Geometer!" fail_invoke() - log_game("Summon Cultist rune failed - no target") + log_game("Summon Cultist rune failed - target was deconverted") return if(cultist_to_summon.z > ZLEVEL_SPACEMAX) user << "[cultist_to_summon] is not in our dimension!" diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm index 9ea427013e0..5ef9970bb3c 100644 --- a/code/game/gamemodes/shadowling/shadowling.dm +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -254,10 +254,10 @@ Made by Xhuis name = "Shadowling" id = "shadowling" say_mod = "chitters" - specflags = list(NOBREATH,NOBLOOD,RADIMMUNE,NOGUNS) //Can't use guns due to muzzle flash + specflags = list(NOBREATH,NOBLOOD,RADIMMUNE,NOGUNS,NODISMEMBER) //Can't use guns due to muzzle flash burnmod = 1.5 //1.5x burn damage, 2x is excessive heatmod = 1.5 - has_dismemberment = 0 + /datum/species/shadow/ling/spec_life(mob/living/carbon/human/H) if(!H.weakeyes) H.weakeyes = 1 //Makes them more vulnerable to flashes and flashbangs diff --git a/code/game/objects/items/devices/traitordevices.dm b/code/game/objects/items/devices/traitordevices.dm index b722c70fb6d..688a5ebc37a 100644 --- a/code/game/objects/items/devices/traitordevices.dm +++ b/code/game/objects/items/devices/traitordevices.dm @@ -72,7 +72,7 @@ effective or pretty fucking useless. name = "health analyzer" icon_state = "health" item_state = "analyzer" - desc = "A hand-held body scanner able to distinguish vital signs of the subject. A strange microlaser is hooked on to the scanning end." + desc = "A hand-held body scanner able to distinguish vital signs of the subject." flags = CONDUCT slot_flags = SLOT_BELT throwforce = 3 diff --git a/code/game/objects/items/toys.dm b/code/game/objects/items/toys.dm index 95d0254b564..24f20ce70c5 100755 --- a/code/game/objects/items/toys.dm +++ b/code/game/objects/items/toys.dm @@ -626,7 +626,7 @@ return OXYLOSS /obj/item/toy/talking/skeleton/generate_messages() - return list(regular_messages) + return list(pick(regular_messages)) /obj/item/toy/talking/skeleton/toy_talk(user, message) phomeme = pick("sans", "papyrus") diff --git a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm index 4a3e5bdfec0..968f230be28 100644 --- a/code/modules/cargo/console.dm +++ b/code/modules/cargo/console.dm @@ -5,6 +5,9 @@ circuit = /obj/item/weapon/circuitboard/computer/cargo var/requestonly = FALSE var/contraband = FALSE + var/safety_warning = "For safety reasons the automated supply shuttle \ + cannot transport live organisms, classified nuclear weaponry or \ + homing beacons." /obj/machinery/computer/cargo/request name = "supply request console" @@ -94,7 +97,7 @@ switch(action) if("send") if(SSshuttle.supply.canMove()) - say("For safety reasons the automated supply shuttle cannot transport live organisms, classified nuclear weaponry or homing beacons.") + say(safety_warning) return if(SSshuttle.supply.getDockedId() == "supply_home") SSshuttle.supply.emagged = emagged @@ -110,6 +113,9 @@ if("loan") if(!SSshuttle.shuttle_loan) return + if(SSshuttle.supply.canMove()) + say(safety_warning) + return else if(SSshuttle.supply.mode == SHUTTLE_IDLE) SSshuttle.shuttle_loan.loan_shuttle() say("The supply shuttle has been loaned to Centcom.") diff --git a/code/modules/chatter/chatter.dm b/code/modules/chatter/chatter.dm index 25226c07c12..4d1048e3ca9 100644 --- a/code/modules/chatter/chatter.dm +++ b/code/modules/chatter/chatter.dm @@ -10,8 +10,7 @@ var/list/punctuation = list(",",":",";",".","?","!","\'","-") var/regex/R = regex("(\[\\l\\d]*)(\[^\\l\\d\\s])?", "g") var/list/letter_count = list() - while(R.next <= length(message)) - R.Find(message) + while(R.Find(message) != 0) if(R.group[1]) letter_count += length(R.group[1]) if(R.group[2]) diff --git a/code/modules/events/abductor.dm b/code/modules/events/abductor.dm index 7f16410482b..19ccda1472b 100644 --- a/code/modules/events/abductor.dm +++ b/code/modules/events/abductor.dm @@ -16,7 +16,7 @@ /datum/round_event/ghost_role/abductor/spawn_role() var/list/mob/dead/observer/candidates = get_candidates("abductor", null, ROLE_ABDUCTOR) - if(!candidates.len < 2) + if(candidates.len < 2) return NOT_ENOUGH_PLAYERS //Oh god why we can't have static functions // I feel your pain, bro diff --git a/code/modules/events/portal_storm.dm b/code/modules/events/portal_storm.dm index fb4f68e7fba..7d4f144938b 100644 --- a/code/modules/events/portal_storm.dm +++ b/code/modules/events/portal_storm.dm @@ -11,15 +11,15 @@ /mob/living/simple_animal/hostile/syndicate/ranged/space/noloot = 2) /datum/round_event_control/portal_storm_narsie - name = "Portal Storm: Nar-sie" + name = "Portal Storm: Constructs" typepath = /datum/round_event/portal_storm/portal_storm_narsie weight = 0 max_occurrences = 0 /datum/round_event/portal_storm/portal_storm_narsie - boss_types = list(/obj/singularity/narsie/large = 1) - hostile_types = list(/mob/living/simple_animal/hostile/construct/armored/hostile = 10,\ - /mob/living/simple_animal/hostile/construct/wraith/hostile = 10) + boss_types = list(/mob/living/simple_animal/hostile/construct/builder = 6) + hostile_types = list(/mob/living/simple_animal/hostile/construct/armored/hostile = 8,\ + /mob/living/simple_animal/hostile/construct/wraith/hostile = 6) /datum/round_event/portal_storm startWhen = 7 diff --git a/code/modules/mob/living/carbon/human/blood.dm b/code/modules/mob/living/carbon/human/blood.dm index f67b3a4008f..4b18297b92c 100644 --- a/code/modules/mob/living/carbon/human/blood.dm +++ b/code/modules/mob/living/carbon/human/blood.dm @@ -227,7 +227,7 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 if (!injected || !our || !dna) return - if(blood_incompatible(injected.data["blood_type"], dna.blood_type,injected.data["species"], dna.species.id) ) + if (!(injected.data["blood_type"] in get_safe_blood(dna.blood_type)) || injected.data["species"] != dna.species.id) reagents.add_reagent("toxin",amount * 0.5) our.on_merge(injected.data) //still transfer viruses and such, even if incompatibles bloods reagents.update_total() @@ -246,28 +246,28 @@ var/const/BLOOD_VOLUME_SURVIVE = 122 return D return res -/proc/blood_incompatible(donor,receiver,donor_species,receiver_species) - if(!donor || !receiver) return 0 - - if(donor_species && receiver_species) - if(donor_species != receiver_species) - return 1 - - var/donor_antigen = copytext(donor,1,lentext(donor)) - var/receiver_antigen = copytext(receiver,1,lentext(receiver)) - var/donor_rh = (findtext(donor,"+")>0) - var/receiver_rh = (findtext(receiver,"+")>0) - - if(donor_rh && !receiver_rh) return 1 - switch(receiver_antigen) - if("A") - if(donor_antigen != "A" && donor_antigen != "O") return 1 - if("B") - if(donor_antigen != "B" && donor_antigen != "O") return 1 - if("O") - if(donor_antigen != "O") return 1 - //AB is a universal receiver. - return 0 +// This is has more potential uses, and is probably faster than the old proc. +/proc/get_safe_blood(bloodtype) + . = list() + if(!bloodtype) + return + switch(bloodtype) + if("A-") + return list("A-", "O-") + if("A+") + return list("A", "A+", "O-", "O+") + if("B-") + return list("B-", "O-") + if("B+") + return list("B-", "B+", "O-", "O+") + if("AB-") + return list("A-", "B-", "O-", "AB-") + if("AB+") + return list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+") + if("O-") + return list("O-") + if("O+") + return list("O-", "O+") /proc/blood_splatter(target,datum/reagent/blood/source,large) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index 10b12f5425b..99d99f6b6d6 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -214,7 +214,7 @@ if(dna.check_mutation(COLDRES)) return 1 //Fully protected from the cold. - if(dna && (RESISTCOLD in dna.species.specflags)) + if(dna && (RESISTTEMP in dna.species.specflags)) return 1 temperature = max(temperature, 2.7) //There is an occasional bug where the temperature is miscalculated in ares with a small amount of gas on them, so this is necessary to ensure that that bug does not affect this calculation. Space's temperature is 2.7K and most suits that are intended to protect against any cold, protect down to 2.0K. diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index ec8ae177cfa..83f46d70577 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -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 @@ -83,8 +82,6 @@ var/tox_breath_dam_min = MIN_PLASMA_DAMAGE var/tox_breath_dam_max = MAX_PLASMA_DAMAGE - var/has_dismemberment = 1 //Whether or not this species uses dismemberment for its limbs - /////////// // PROCS // /////////// @@ -127,7 +124,7 @@ var/obj/item/thing = C.get_item_by_slot(slot_id) if(thing) C.unEquip(thing) - if(!has_dismemberment) + if(NODISMEMBER in specflags) C.regenerate_limbs() //if we don't handle dismemberment, we grow our missing limbs back if(exotic_blood) C.reagents.add_reagent(exotic_blood, 80) @@ -152,7 +149,7 @@ return "[id]" /datum/species/proc/update_color(mob/living/carbon/human/H, forced_colour) - if(has_dismemberment) //only species without dismemberment still use base icon states. + if(!(NODISMEMBER in specflags)) //only species without dismemberment still use base icon states. return H.remove_overlay(SPECIES_LAYER) @@ -276,7 +273,7 @@ var/list/standing = list() - if(!has_dismemberment) //Legacy support + if(NODISMEMBER in specflags) //Legacy support H.update_base_icon_state() if(!(H.disabilities & HUSK)) update_color(H) @@ -703,7 +700,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-- @@ -1337,7 +1336,7 @@ if(200 to 260) H.apply_damage(COLD_GAS_DAMAGE_LEVEL_1, BURN, "head") - if(!(RESISTHEAT in specflags)) // HEAT DAMAGE + if(!(RESISTTEMP in specflags)) // HEAT DAMAGE switch(breath.temperature) if(360 to 400) H.apply_damage(HEAT_GAS_DAMAGE_LEVEL_1, BURN, "head") @@ -1372,7 +1371,7 @@ H.bodytemperature += min((1-thermal_protection) * ((loc_temp - H.bodytemperature) / BODYTEMP_HEAT_DIVISOR), BODYTEMP_HEATING_MAX) // +/- 50 degrees from 310.15K is the 'safe' zone, where no damage is dealt. - if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !(RESISTHEAT in specflags)) + if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !(RESISTTEMP in specflags)) //Body temperature is too hot. switch(H.bodytemperature) if(360 to 400) @@ -1411,7 +1410,7 @@ var/adjusted_pressure = H.calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob. switch(adjusted_pressure) if(HAZARD_HIGH_PRESSURE to INFINITY) - if(!(RESISTHEAT in specflags)) + if(!(RESISTTEMP in specflags)) H.adjustBruteLoss( min( ( (adjusted_pressure / HAZARD_HIGH_PRESSURE) -1 )*PRESSURE_DAMAGE_COEFFICIENT , MAX_HIGH_PRESSURE_DAMAGE) ) H.throw_alert("pressure", /obj/screen/alert/highpressure, 2) else @@ -1423,7 +1422,7 @@ if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE) H.throw_alert("pressure", /obj/screen/alert/lowpressure, 1) else - if(H.dna.check_mutation(COLDRES) || (RESISTCOLD in specflags)) + if(H.dna.check_mutation(COLDRES) || (RESISTTEMP in specflags)) H.clear_alert("pressure") else H.adjustBruteLoss( LOW_PRESSURE_DAMAGE ) @@ -1434,11 +1433,11 @@ ////////// /datum/species/proc/handle_fire(mob/living/carbon/human/H) - if((RESISTHEAT in specflags) || (NOFIRE in specflags)) + if((RESISTTEMP in specflags) || (NOFIRE in specflags)) return 1 /datum/species/proc/IgniteMob(mob/living/carbon/human/H) - if((RESISTHEAT in specflags) || (NOFIRE in specflags)) + if((RESISTTEMP in specflags) || (NOFIRE in specflags)) return 1 /datum/species/proc/ExtinguishMob(mob/living/carbon/human/H) diff --git a/code/modules/mob/living/carbon/human/species_types.dm b/code/modules/mob/living/carbon/human/species_types.dm index 886e0abc115..a2a3cdd16e0 100644 --- a/code/modules/mob/living/carbon/human/species_types.dm +++ b/code/modules/mob/living/carbon/human/species_types.dm @@ -179,10 +179,9 @@ default_color = "00FF90" say_mod = "chirps" eyes = "jelleyes" - specflags = list(MUTCOLORS,EYECOLOR,NOBLOOD,VIRUSIMMUNE) + specflags = list(MUTCOLORS,EYECOLOR,NOBLOOD,VIRUSIMMUNE,NODISMEMBER) meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/slime exotic_blood = "slimejelly" - has_dismemberment = 0 /datum/species/jelly/spec_life(mob/living/carbon/human/H) if(H.stat == DEAD) //can't farm slime jelly from a dead slime/jelly person indefinitely @@ -320,7 +319,7 @@ // Animated beings of stone. They have increased defenses, and do not need to breathe. They're also slow as fuuuck. name = "Golem" id = "golem" - specflags = list(NOBREATH,RESISTHEAT,RESISTCOLD,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE) + specflags = list(NOBREATH,RESISTTEMP,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER) speedmod = 2 armor = 55 siemens_coeff = 0 @@ -331,7 +330,6 @@ nojumpsuit = 1 sexes = 0 meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/golem - has_dismemberment = 0 /datum/species/golem/adamantine name = "Adamantine Golem" @@ -408,12 +406,11 @@ 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,NOHUNGER) mutant_organs = list(/obj/item/organ/tongue/bone) - specflags = list(NOBREATH,RESISTHEAT,RESISTCOLD,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE) /* ZOMBIES @@ -427,7 +424,7 @@ sexes = 0 blacklisted = 1 meat = /obj/item/weapon/reagent_containers/food/snacks/meat/slab/human/mutant/zombie - specflags = list(NOBREATH,RESISTHEAT,RESISTCOLD,NOBLOOD,RADIMMUNE) + specflags = list(NOBREATH,RESISTTEMP,NOBLOOD,RADIMMUNE) mutant_organs = list(/obj/item/organ/tongue/zombie) /datum/species/cosmetic_zombie @@ -457,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 @@ -511,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) //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 @@ -520,13 +516,11 @@ 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 - has_dismemberment = 0 /datum/species/synth/military name = "Military Synth" @@ -645,7 +639,7 @@ var/global/list/synth_flesh_disguises = list() H.updatehealth() if(H.health > disguise_fail_health) if(fake_species) - if(fake_species.has_dismemberment) + if(!(NODISMEMBER in fake_species.specflags)) return fake_species.handle_body(H) else return fake_species.update_base_icon_state(H) @@ -657,7 +651,7 @@ var/global/list/synth_flesh_disguises = list() /datum/species/synth/update_color(mob/living/carbon/human/H, forced_colour) H.updatehealth() if(H.health > disguise_fail_health) - if(fake_species && fake_species.has_dismemberment) + if(fake_species && !(NODISMEMBER in fake_species.specflags)) fake_species.update_color(H, forced_colour) @@ -708,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 @@ -722,6 +715,5 @@ SYNDICATE BLACK OPS attack_sound = "sound/weapons/resonator_blast.ogg" blacklisted = 1 use_skintones = 0 - specflags = list(RADIMMUNE,VIRUSIMMUNE,NOBLOOD,PIERCEIMMUNE,EYECOLOR) + specflags = list(RADIMMUNE,VIRUSIMMUNE,NOBLOOD,PIERCEIMMUNE,EYECOLOR,NODISMEMBER,NOHUNGER) sexes = 0 - has_dismemberment = 0 diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index e4dc7968ec3..d0650f6ae05 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -94,7 +94,7 @@ Please contact me on #coderbus IRC. ~Carnie x ..("Standing") /mob/living/carbon/human/proc/update_body_parts() - if(!dna.species.has_dismemberment) //Species don't have no dismemberment going for 'em! + if(NODISMEMBER in dna.species.specflags) //Species don't have no dismemberment going for 'em! remove_overlay(BODYPARTS_LAYER) return diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 6f1359ebeb5..9a65712b692 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -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 << "[src] is entirely unresponsive!" + 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) diff --git a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm index 652bea72c7c..1fd2754ae85 100644 --- a/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm +++ b/code/modules/mob/living/simple_animal/hostile/megafauna/dragon.dm @@ -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)) diff --git a/code/modules/projectiles/projectile/reusable.dm b/code/modules/projectiles/projectile/reusable.dm index 216b24e570a..f253655e3f6 100644 --- a/code/modules/projectiles/projectile/reusable.dm +++ b/code/modules/projectiles/projectile/reusable.dm @@ -54,8 +54,7 @@ newdart.update_icon() /obj/item/projectile/bullet/reusable/foam_dart/Destroy() - if(pen) - qdel(pen) + pen = null return ..() /obj/item/projectile/bullet/reusable/foam_dart/riot diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index c2000c95634..d3b604ae120 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -737,7 +737,7 @@ M.adjustToxLoss(rand(5,10)) /datum/reagent/space_cleaner/reaction_mob(mob/M, method=TOUCH, reac_volume) - if(method == TOUCH || VAPOR) + if(method == TOUCH || method == VAPOR) if(iscarbon(M)) var/mob/living/carbon/C = M if(istype(M,/mob/living/carbon/human)) diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm index 0a19f15eed6..0316b3899ff 100644 --- a/code/modules/surgery/bodyparts/dismemberment.dm +++ b/code/modules/surgery/bodyparts/dismemberment.dm @@ -5,7 +5,7 @@ //Dismember a limb /obj/item/bodypart/proc/dismember(dam_type = BRUTE) var/mob/living/carbon/human/H = owner - if(!istype(H) || !H.dna.species.has_dismemberment) // species don't allow dismemberment + if(!istype(H) || (NODISMEMBER in H.dna.species.specflags)) // species don't allow dismemberment return 0 var/obj/item/bodypart/affecting = H.get_bodypart("chest") @@ -35,7 +35,7 @@ /obj/item/bodypart/chest/dismember() var/mob/living/carbon/human/H = owner - if(!istype(H) || !H.dna.species.has_dismemberment) //human's species don't allow dismemberment + if(!istype(H) || (NODISMEMBER in H.dna.species.specflags)) //human's species don't allow dismemberment return 0 var/organ_spilled = 0 diff --git a/code/modules/surgery/bodyparts/helpers.dm b/code/modules/surgery/bodyparts/helpers.dm index 1dd5b807a62..c1980400a45 100644 --- a/code/modules/surgery/bodyparts/helpers.dm +++ b/code/modules/surgery/bodyparts/helpers.dm @@ -70,7 +70,7 @@ .++ /mob/living/proc/get_missing_limbs() - return + return list() /mob/living/carbon/human/get_missing_limbs() var/list/full = list("head", "chest", "r_arm", "l_arm", "r_leg", "l_leg") @@ -153,4 +153,4 @@ if("african2") . = "471c18" if("albino") - . = "fff4e6" \ No newline at end of file + . = "fff4e6" diff --git a/code/world.dm b/code/world.dm index 478b3790af7..9f2eefed96d 100644 --- a/code/world.dm +++ b/code/world.dm @@ -178,6 +178,14 @@ var/last_irc_status = 0 if(ticker.delay_end) world << "Reboot was cancelled by an admin." return + if(mapchanging) + world << "Map change operation detected, delaying reboot." + rebootingpendingmapchange = 1 + spawn(1200) + if(mapchanging) + mapchanging = 0 //map rotation can in some cases be finished but never exit, this is a failsafe + Reboot("Map change timed out", time = 10) + return feedback_set_details("[feedback_c]","[feedback_r]") log_game("Rebooting World. [reason]") kick_clients_in_lobby("The round came to an end with you in the lobby.", 1) //second parameter ensures only afk clients are kicked @@ -386,17 +394,19 @@ var/failed_db_connections = 0 world << "Map rotation has chosen [VM.friendlyname] for next round!" var/datum/votablemap/nextmap - +var/mapchanging = 0 +var/rebootingpendingmapchange = 0 /proc/changemap(var/datum/votablemap/VM) if (!SERVERTOOLS) return if (!istype(VM)) return - + mapchanging = 1 log_game("Changing map to [VM.name]([VM.friendlyname])") var/file = file("setnewmap.bat") file << "\nset MAPROTATE=[VM.name]\n" . = shell("..\\bin\\maprotate.bat") + mapchanging = 0 switch (.) if (null) message_admins("Failed to change map: Could not run map rotator") @@ -426,3 +436,5 @@ var/datum/votablemap/nextmap else message_admins("Failed to change map: Unknown error: Error code #[.]") log_game("Failed to change map: Unknown error: Error code #[.]") + if(rebootingpendingmapchange) + world.Reboot("Map change finished", time = 10) diff --git a/html/changelog.html b/html/changelog.html index 380533e46cc..0e03fcba626 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -593,38 +593,6 @@