From 94d8e5d9a4f8dd8c1e539b521e643eacff475bbf Mon Sep 17 00:00:00 2001 From: Ergovisavi Date: Thu, 16 Jul 2015 23:42:01 -0700 Subject: [PATCH 001/108] -First revision of the wumborian fugu mob -Nerfs collapse emote, causes stamina damage to yourself now -Minor fixes with aggro() for mobs --- code/modules/mob/living/emote.dm | 1 + .../living/simple_animal/hostile/hostile.dm | 6 +- .../simple_animal/hostile/mining_mobs.dm | 118 +++++++++++++++++- .../mob/living/simple_animal/simple_animal.dm | 2 + icons/mob/animal.dmi | Bin 192024 -> 195820 bytes 5 files changed, 124 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm index 08ffb07c7d9..6d2a5cca157 100644 --- a/code/modules/mob/living/emote.dm +++ b/code/modules/mob/living/emote.dm @@ -56,6 +56,7 @@ if ("collapse") Paralyse(2) + adjustStaminaLoss(100) // Hampers abuse against simple mobs, but still leaves it a viable option. message = "[src] collapses!" m_type = 2 diff --git a/code/modules/mob/living/simple_animal/hostile/hostile.dm b/code/modules/mob/living/simple_animal/hostile/hostile.dm index 26fe0a596c2..15ca694da5f 100644 --- a/code/modules/mob/living/simple_animal/hostile/hostile.dm +++ b/code/modules/mob/living/simple_animal/hostile/hostile.dm @@ -149,8 +149,9 @@ /mob/living/simple_animal/hostile/proc/GiveTarget(var/new_target)//Step 4, give us our selected target target = new_target if(target != null) - Aggro() - stance = HOSTILE_STANCE_ATTACK + if(stance != HOSTILE_STANCE_ATTACK) + Aggro() + stance = HOSTILE_STANCE_ATTACK return /mob/living/simple_animal/hostile/proc/MoveToTarget()//Step 5, handle movement between us and our target @@ -237,6 +238,7 @@ //////////////END HOSTILE MOB TARGETTING AND AGGRESSION//////////// /mob/living/simple_animal/hostile/death(gibbed) + target = null LoseAggro() ..(gibbed) walk(src, 0) diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm index 850f307f63b..d6d6e16a900 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm @@ -17,7 +17,8 @@ /mob/living/simple_animal/hostile/asteroid/Aggro() ..() - icon_state = icon_aggro + if(vision_range != aggro_vision_range) + icon_state = icon_aggro /mob/living/simple_animal/hostile/asteroid/LoseAggro() ..() @@ -497,3 +498,118 @@ adjustBruteLoss(2) else if(bodytemperature > maxbodytemp) adjustBruteLoss(20) + + +/mob/living/simple_animal/hostile/asteroid/fugu + name = "wumborian fugu" + desc = "The wumborian fugu rapidly increases its body mass in order to pulverize its prey. Great care should be taken to avoid it while it's in this state as it is nearly invincible, but it cannot maintain it forever." + icon = 'icons/mob/animal.dmi' + icon_state = "Fugu" + icon_living = "Fugu" + icon_aggro = "Fugu" + icon_dead = "Fugu_dead" + icon_gib = "syndicate_gib" + attack_sound = 'sound/weapons/punch4.ogg' + mouse_opacity = 2 + move_to_delay = 5 + friendly = "floats near" + speak_emote = list("puffs") + vision_range = 5 + speed = 3 + maxHealth = 50 + health = 50 + harm_intent_damage = 5 + melee_damage_lower = 0 + melee_damage_upper = 0 + attacktext = "chomps" + attack_sound = 'sound/weapons/punch1.ogg' + throw_message = "is avoided by the" + aggro_vision_range = 9 + idle_vision_range = 5 + mob_size = MOB_SIZE_SMALL + var/wumbo = 0 + var/inflate_cooldown = 0 + +/mob/living/simple_animal/hostile/asteroid/fugu/Life() + if(!wumbo) + inflate_cooldown = max((inflate_cooldown - 1), 0) + if(target) + Inflate() + ..() + +/mob/living/simple_animal/hostile/asteroid/fugu/adjustBruteLoss(var/damage) + if(wumbo) + return + ..() + +/mob/living/simple_animal/hostile/asteroid/fugu/Aggro() + ..() + Inflate() + +/mob/living/simple_animal/hostile/asteroid/fugu/proc/Inflate() + if(wumbo || inflate_cooldown || buffed) + return + wumbo = 1 + icon_state = "Fugu_big" + melee_damage_lower = 15 + melee_damage_upper = 20 + harm_intent_damage = 0 + throw_message = "is absorbed by the girth of the" + retreat_distance = null + minimum_distance = 1 + move_to_delay = 6 + transform *= 2 + environment_smash = 2 + mob_size = MOB_SIZE_LARGE + spawn(100) + Deflate() + +/mob/living/simple_animal/hostile/asteroid/fugu/proc/Deflate() + if(wumbo) + walk(src, 0) + wumbo = 0 + icon_state = "Fugu" + melee_damage_lower = 0 + melee_damage_upper = 0 + harm_intent_damage = 5 + throw_message = "is avoided by the" + retreat_distance = 9 + minimum_distance = 9 + move_to_delay = 2 + transform /= 2 + inflate_cooldown = 4 + environment_smash = 0 + mob_size = MOB_SIZE_SMALL + +/mob/living/simple_animal/hostile/asteroid/fugu/death(gibbed) + Deflate() + var/obj/item/asteroid/fugu_gland/F = new /obj/item/asteroid/fugu_gland(src.loc) + F.layer = 4.1 + ..(gibbed) + +/obj/item/asteroid/fugu_gland + name = "wumborian fugu gland" + desc = "The key to the wumborian fugu's ability to increase its mass arbitrarily, this disgusting remnant can apply the same effect to other creatures, giving them great strength." + icon = 'icons/obj/mining.dmi' + icon_state = "goliath_hide" + flags = NOBLUDGEON + w_class = 3 + layer = 4 + origin_tech = "biotech=6" + var/list/banned_mobs() + +/obj/item/asteroid/fugu_gland/afterattack(atom/target, mob/user, proximity_flag) + if(proximity_flag && istype(target, /mob/living/simple_animal)) + var/mob/living/simple_animal/A = target + if(A.buffed || A.type in banned_mobs || A.stat) + user << "Something's interfering with the [src]'s effects. It's no use." + return + A.buffed++ + A.maxHealth *= 2 + A.health = min(A.maxHealth,A.health*1.5) + A.melee_damage_lower *= 2 + A.melee_damage_upper *= 2 + A.transform *= 2 + A.environment_smash += 2 + user << "You increase the size of [A], giving it a surge of strength!" + qdel(src) \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index f20d4c04b8b..f63b9894637 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -57,6 +57,8 @@ var/obj/item/weapon/card/id/access_card = null //innate access uses an internal ID card var/flying = 0 //whether it's flying or touching the ground. + var/buffed = 0 //In the event that you want to have a buffing effect on the mob, but don't want it to stack with other effects, any outside force that applies a buff to a simple mob should at least set this to 1, so we have something to check against + /mob/living/simple_animal/New() ..() verbs -= /mob/verb/observe diff --git a/icons/mob/animal.dmi b/icons/mob/animal.dmi index e33396b70492839e59974366c881477fda97e118..eefdb1ad455d5d3848f932591580bd73ba02c726 100644 GIT binary patch delta 26780 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 Date: Sat, 1 Aug 2015 11:29:59 -0700 Subject: [PATCH 002/108] Changes Backpack Slotcount --- code/game/objects/items/weapons/storage/backpack.dm | 7 +++---- code/game/objects/items/weapons/storage/storage.dm | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 84b158e9e4b..9e74a5c2246 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -18,6 +18,7 @@ slot_flags = SLOT_BACK //ERROOOOO max_w_class = 3 max_combined_w_class = 21 + storage_slots = 21 burn_state = 0 //Burnable burntime = 20 @@ -109,7 +110,6 @@ icon_state = "giftbag0" item_state = "giftbag" w_class = 4.0 - storage_slots = 20 //Can store a lot. max_w_class = 3 max_combined_w_class = 60 @@ -292,12 +292,11 @@ /obj/item/weapon/storage/backpack/dufflebag name = "dufflebag" - desc = "A large dufflebag for holding extra things" + desc = "A large dufflebag for holding extra things." icon_state = "duffle" item_state = "duffle" - storage_slots = 9 slowdown = 1 - max_combined_w_class = 27 + max_combined_w_class = 30 /obj/item/weapon/storage/backpack/dufflebag/syndiemed name = "medical dufflebag" diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 82758639261..17abffa5386 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -266,7 +266,7 @@ if(sum_w_class > max_combined_w_class) if(!stop_messages) - usr << "[src] is full, make some space!" + usr << "[W] won't fit in [src], make some space!" return 0 if(W.w_class >= w_class && (istype(W, /obj/item/weapon/storage))) From c2e959200970b9c4aa01627cef32061c4038a914 Mon Sep 17 00:00:00 2001 From: bustygoku Date: Wed, 5 Aug 2015 13:10:57 -0700 Subject: [PATCH 003/108] Added Changelog And Fixed Smuggler Satchel And Duffelbag --- code/game/objects/items/weapons/storage/backpack.dm | 2 -- html/changelogs/bustygoku-10975.yml | 6 ++++++ 2 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 html/changelogs/bustygoku-10975.yml diff --git a/code/game/objects/items/weapons/storage/backpack.dm b/code/game/objects/items/weapons/storage/backpack.dm index 9e74a5c2246..70aa9c914c9 100644 --- a/code/game/objects/items/weapons/storage/backpack.dm +++ b/code/game/objects/items/weapons/storage/backpack.dm @@ -270,7 +270,6 @@ desc = "A very slim satchel that can easily fit into tight spaces." icon_state = "satchel-flat" w_class = 3 //Can fit in backpacks itself. - storage_slots = 5 max_combined_w_class = 15 level = 1 cant_hold = list(/obj/item/weapon/storage/backpack/satchel_flat) //muh recursive backpacks @@ -334,7 +333,6 @@ desc = "A menacingly looking dufflebag for holding surgery tools." icon_state = "duffle-syndiemed" item_state = "duffle-syndiemed" - storage_slots = 10 /obj/item/weapon/storage/backpack/dufflebag/syndiesurgery/New() ..() diff --git a/html/changelogs/bustygoku-10975.yml b/html/changelogs/bustygoku-10975.yml new file mode 100644 index 00000000000..f34e1e56ba6 --- /dev/null +++ b/html/changelogs/bustygoku-10975.yml @@ -0,0 +1,6 @@ +author: bustygoku + +delete-after: True + +changes: + - tweak: "Most backpacks now have 21 or more slots, but are still weight restricted. What this means is that you can have a lot of tiny weight items, but only 7 medium items just like before." From 109cbe72802105896b2052a2dcf14f8858ca41cf Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Wed, 5 Aug 2015 16:18:14 -0500 Subject: [PATCH 004/108] Survival Pod --- code/modules/mining/mine_items.dm | 101 ++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index ea0886af653..f8c70412112 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -153,3 +153,104 @@ name = "Mining car (not for rails)" icon_crate = "miningcar" icon_state = "miningcar" +/*****************************Survival Pod********************************/ + + +/area/survivalpod + name = "\improper Emergency Shelter" + icon_state = "away" + requires_power = 0 + has_gravity = 1 + +/obj/item/weapon/survivalcapsule + name = "bluespace shelter capsule" + desc = "An emergency shelter stored within a pocket of bluespace." + icon_state = "pill3" + icon = 'icons/obj/chemical.dmi' + w_class = 1.0 + var/used = FALSE + +/obj/item/weapon/survivalcapsule/attack_self() + if(used == FALSE) + src.loc.visible_message("The [src] begins to shake. Stand back!") + used = TRUE + sleep(50) + playsound(get_turf(src), 'sound/effects/phasein.ogg', 100, 1) + PoolOrNew(/obj/effect/effect/smoke, src.loc) + load() + qdel(src) + +/obj/item/weapon/survivalcapsule/proc/load() + var/turf/start_turf = src.loc + var/turf/cur_turf + var/x_size = 5 + var/y_size = 5 + var/list/walltypes = list(/turf/simulated/wall) + var/floor_type = /turf/simulated/floor/wood + var/room + + //Center the room/spawn it + start_turf = locate(start_turf.x -2, start_turf.y - 2, start_turf.z) + + room = spawn_room(start_turf, x_size, y_size, walltypes, floor_type, "Emergency Shelter") + + start_turf = src.loc + + + //Fill it + cur_turf = locate(start_turf.x, start_turf.y-2, start_turf.z) + new /obj/machinery/door/airlock/glass(cur_turf) + + cur_turf = locate(start_turf.x+1, start_turf.y, start_turf.z) + new /obj/structure/table/wood(cur_turf) + new /obj/item/weapon/storage/pill_bottle/dice(cur_turf) + + cur_turf = locate(start_turf.x+1, start_turf.y-1, start_turf.z) + var/obj/structure/stool/bed/chair/comfy/C = new /obj/structure/stool/bed/chair/comfy(cur_turf) + C.dir = 1 + + cur_turf = locate(start_turf.x+1, start_turf.y+1, start_turf.z) + new /obj/structure/stool/bed/chair/comfy(cur_turf) + + cur_turf = locate(start_turf.x-1, start_turf.y-1, start_turf.z) + var/obj/machinery/sleeper/S = new /obj/machinery/sleeper(cur_turf) + S.dir = 4 + + cur_turf = locate(start_turf.x-1, start_turf.y, start_turf.z) + new /obj/structure/table/wood(cur_turf) + new /obj/item/weapon/storage/box/donkpockets(cur_turf) + + cur_turf = locate(start_turf.x-1, start_turf.y+1, start_turf.z) + new /obj/structure/table/wood(cur_turf) + new /obj/machinery/microwave(cur_turf) + + var/area/survivalpod/L = new /area/survivalpod + + var/turf/threshhold = locate(start_turf.x, start_turf.y-2, start_turf.z) + threshhold.ChangeTurf(/turf/simulated/floor/wood) + threshhold.blocks_air = 1 //So the air doesn't leak out + threshhold.oxygen = 21 + threshhold.temperature = 293.15 + threshhold.nitrogen = 82 + threshhold.carbon_dioxide = 0 + threshhold.toxins = 0 + L.contents += threshhold + threshhold.overlays.Cut() + + var/list/turfs = room["floors"] + for(var/turf/simulated/floor/A in turfs) + SSair.remove_from_active(A) + A.oxygen = 21 + A.temperature = 293.15 + A.nitrogen = 82 + A.carbon_dioxide = 0 + A.toxins = 0 + A.air.oxygen = 21 + A.air.carbon_dioxide = 0 + A.air.nitrogen = 82 + A.air.toxins = 0 + A.air.temperature = 293.15 + SSair.add_to_active(A) + A.overlays.Cut() + + L.contents += A From 278a3369c5bf8b308b8e264989cdf1af78006e1c Mon Sep 17 00:00:00 2001 From: phil235 Date: Thu, 6 Aug 2015 16:53:11 +0200 Subject: [PATCH 005/108] Fixes reactionary explosion not acting correctly. Fixes indestructible turfs not blocking explosions. Replacing cheap_pythag by cheap_hypothenuse --- code/game/objects/explosion.dm | 13 ++++--------- code/game/turfs/turf.dm | 1 + 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index cf714ed52eb..5502ef807ee 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -1,11 +1,5 @@ //TODO: Flash range does nothing currently -//A very crude linear approximatiaon of pythagoras theorem. -/proc/cheap_pythag(dx, dy) - dx = abs(dx); dy = abs(dy); - if(dx>=dy) return dx + (0.5*dy) //The longest side add half the shortest side approximates the hypotenuse - else return dy + (0.5*dx) - /proc/trange(Dist=0,turf/Center=null)//alternative to range (ONLY processes turfs and thus less intensive) if(Center==null) return @@ -89,7 +83,7 @@ for(var/turf/T in trange(max_range, epicenter)) - var/dist = cheap_pythag(T.x - x0,T.y - y0) + var/dist = cheap_hypotenuse(T.x, T.y, x0, y0) if(config.reactionary_explosions) var/turf/Trajectory = T @@ -123,7 +117,8 @@ if(flame_dist && prob(40) && !istype(T, /turf/space) && !T.density) PoolOrNew(/obj/effect/hotspot, T) //Mostly for ambience! if(dist > 0) - T.ex_act(dist) + spawn(0) + T.ex_act(dist) //--- THROW ITEMS AROUND --- @@ -196,7 +191,7 @@ var/list/wipe_colours = list() for(var/turf/T in trange(max_range, epicenter)) wipe_colours += T - var/dist = cheap_pythag(T.x - x0, T.y - y0) + var/dist = cheap_hypotenuse(T.x, T.y, x0, y0) if(newmode == "Yes") var/turf/TT = T diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 2bcfe8d976f..a9ab0f0b0b1 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -280,6 +280,7 @@ density = 1 blocks_air = 1 opacity = 1 + explosion_block = 50 /turf/indestructible/splashscreen name = "Space Station 13" From 6a59afe2d58433996880a9b6046df1b936b766cc Mon Sep 17 00:00:00 2001 From: bgobandit Date: Sat, 8 Aug 2015 18:51:48 -0400 Subject: [PATCH 006/108] Adds forensics and toy crates to cargonia, by request. --- code/datums/supplypacks.dm | 32 +++++++++++++++++++++++ html/changelogs/bgobandit - newcrates.yml | 4 +++ 2 files changed, 36 insertions(+) create mode 100644 html/changelogs/bgobandit - newcrates.yml diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 5d0e6fb95a0..175ec10a0fd 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -233,6 +233,17 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine cost = 10 containername = "disabler crate" +/datum/supply_packs/security/forensics + name = "Forensics Crate" + contains = list(/obj/item/device/detective_scanner, + /obj/item/weapon/storage/box/evidence, + /obj/item/device/camera, + /obj/item/device/taperecorder, + /obj/item/toy/crayon/white, + /obj/item/clothing/head/det_hat) + cost = 20 + containername ="forensics crate" + ///// Armory stuff /datum/supply_packs/security/armory @@ -1219,6 +1230,26 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine containername = "crate" //let's keep it subtle, eh? contraband = 1 +/datum/supply_packs/misc/randomised/toys + name = "Toy Crate" + num_contained = 5 + contains = list(/obj/item/toy/spinningtoy, + /obj/item/toy/sword, + /obj/item/toy/foamblade, + /obj/item/toy/AI, + /obj/item/toy/owl, + /obj/item/toy/griffin, + /obj/item/toy/nuke, + /obj/item/toy/minimeteor, + /obj/item/toy/carpplushie, + /obj/item/weapon/coin/antagtoken, + /obj/item/stack/tile/fakespace, + /obj/item/weapon/gun/projectile/shotgun/toy/crossbow, + /obj/item/toy/redbutton) + + cost = 50 // or play the arcade machines ya lazy bum + containername ="toy crate" + /datum/supply_packs/misc/autodrobe name = "Autodrobe Supply Crate" contains = list(/obj/item/weapon/vending_refill/autodrobe, @@ -1280,3 +1311,4 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine cost = 40 containername = "foam force pistols crate" contraband = 1 + diff --git a/html/changelogs/bgobandit - newcrates.yml b/html/changelogs/bgobandit - newcrates.yml new file mode 100644 index 00000000000..8377c32b219 --- /dev/null +++ b/html/changelogs/bgobandit - newcrates.yml @@ -0,0 +1,4 @@ +author: bgobandit +delete-after: True +changes: + - rscadd: "CentComm now offers its cargo department toys, as well as detective gear so their boss can figure out which tech wasted all the points on them." From d2a4024e7f4095a48fc3f2973baa38a44eb7a658 Mon Sep 17 00:00:00 2001 From: phil235 Date: Sun, 9 Aug 2015 14:23:12 +0200 Subject: [PATCH 007/108] reagent reaction() now use more methods. Instead of just INGEST or TOUCH, we now have INGEST (for injection, ingestion), TOUCH (for splashing), PATCH (for patch application and blob attack), and VAPOR (for smoke, foam and spray application). - TOUCH no longer transfer reagent by default, it's now only used for touch based effect like being flammable when touched by fuel or you and your stuff being acided when touched by acid). - PATCH does no transfer of its own (but actual patches code do make a transfer) but is used for touch effect that ignore clothes and protection (blob attacks, patches effect going through hardsuits) - VAPOR does reagent transfer but it takes into account clothing protection Fixes a typo in humanoid/get_permeability_prot Fixes acid splashing on objects not destroying it. Fixes acid splashing on turf not destroying objects on the turf. Changed damp rag smothering code a bit. Blob Smoke now doesn't do anything. --- .../components/unary_devices/cryo.dm | 2 +- code/game/gamemodes/blob/powers.dm | 2 +- .../effects/effect_system/effects_foam.dm | 6 +- .../effects/effect_system/effects_smoke.dm | 6 +- code/game/objects/items.dm | 1 - .../detectivework/footprints_and_rag.dm | 17 +- .../living/carbon/alien/humanoid/humanoid.dm | 2 +- code/modules/reagents/Chemistry-Holder.dm | 8 +- code/modules/reagents/Chemistry-Readme.dm | 2 +- code/modules/reagents/Chemistry-Reagents.dm | 4 +- .../Chemistry-Reagents/Blob-Reagents.dm | 22 +-- .../Drink-Reagents/Alcohols.dm | 4 +- .../Consumable-Reagents/Food-Reagents.dm | 2 +- .../Chemistry-Reagents/Medicine-Reagents.dm | 20 +-- .../Chemistry-Reagents/Other-Reagents.dm | 159 +++++++++--------- .../Pyrotechnic-Reagents.dm | 14 +- .../Chemistry-Reagents/Toxin-Reagents.dm | 47 +++--- .../reagents/reagent_containers/patch.dm | 2 +- .../reagents/reagent_containers/spray.dm | 4 +- 19 files changed, 164 insertions(+), 160 deletions(-) diff --git a/code/ATMOSPHERICS/components/unary_devices/cryo.dm b/code/ATMOSPHERICS/components/unary_devices/cryo.dm index 87eb0e606e8..246716772aa 100644 --- a/code/ATMOSPHERICS/components/unary_devices/cryo.dm +++ b/code/ATMOSPHERICS/components/unary_devices/cryo.dm @@ -314,7 +314,7 @@ occupant.heal_organ_damage(heal_brute,heal_fire) if(beaker && next_trans == 0) beaker.reagents.trans_to(occupant, 1, 10) - beaker.reagents.reaction(occupant) + beaker.reagents.reaction(occupant, VAPOR) next_trans++ if(next_trans == 10) next_trans = 0 diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index 78c15e08e5e..774f8f181f1 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -276,7 +276,7 @@ last_attack = world.time OB.expand(T, 0, blob_reagent_datum.color) for(var/mob/living/L in T) - blob_reagent_datum.reaction_mob(L, TOUCH, 25) + blob_reagent_datum.reaction_mob(L, PATCH, 25) blob_reagent_datum.send_message(L) OB.color = blob_reagent_datum.color return diff --git a/code/game/objects/effects/effect_system/effects_foam.dm b/code/game/objects/effects/effect_system/effects_foam.dm index aa1abe7ae6c..a3a305541c7 100644 --- a/code/game/objects/effects/effect_system/effects_foam.dm +++ b/code/game/objects/effects/effect_system/effects_foam.dm @@ -58,14 +58,14 @@ for(var/obj/O in range(0,src)) if(O.type == src.type) continue - reagents.reaction(O, TOUCH, fraction) + reagents.reaction(O, VAPOR, fraction) var/hit = 0 for(var/mob/living/L in range(0,src)) hit += foam_mob(L) if(hit) lifetime++ //this is so the decrease from mobs hit and the natural decrease don't cumulate. var/T = get_turf(src) - reagents.reaction(T, TOUCH, fraction) + reagents.reaction(T, VAPOR, fraction) if(--amount < 0) return @@ -77,7 +77,7 @@ if(!istype(L)) return 0 var/fraction = 1/initial(lifetime) - reagents.reaction(L, TOUCH, fraction) + reagents.reaction(L, VAPOR, fraction) lifetime-- return 1 diff --git a/code/game/objects/effects/effect_system/effects_smoke.dm b/code/game/objects/effects/effect_system/effects_smoke.dm index b1e6b6dde79..db7b6be9b54 100644 --- a/code/game/objects/effects/effect_system/effects_smoke.dm +++ b/code/game/objects/effects/effect_system/effects_smoke.dm @@ -156,10 +156,10 @@ for(var/obj/O in range(1,src)) if(O.type == src.type) continue - reagents.reaction(O, TOUCH, fraction) + reagents.reaction(O, VAPOR, fraction) for(var/turf/T in range(1,src)) - reagents.reaction(T, TOUCH, fraction) + reagents.reaction(T, VAPOR, fraction) var/hit = 0 for(var/mob/living/L in range(1,src)) @@ -173,7 +173,7 @@ if(!istype(M)) return 0 var/fraction = 1/initial(lifetime) - reagents.reaction(M, TOUCH, fraction) + reagents.reaction(M, VAPOR, fraction) lifetime-- return 1 diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 6b4660a28f0..9afcca1dc6f 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -450,7 +450,6 @@ var/global/image/fire_overlay = image("icon" = 'icons/effects/fire.dmi', "icon_s var/melting_threshold = 100 if(meltingpwr <= melting_threshold) // so a single unit can't melt items. You need 5.1+ unit for fluoro and 10.1+ for sulphuric return - for(var/V in armor) if(armor[V] > 0) .-- //it survives the acid... diff --git a/code/modules/detectivework/footprints_and_rag.dm b/code/modules/detectivework/footprints_and_rag.dm index 7d7818fa3e2..6e770a21eda 100644 --- a/code/modules/detectivework/footprints_and_rag.dm +++ b/code/modules/detectivework/footprints_and_rag.dm @@ -22,14 +22,17 @@ /obj/item/weapon/reagent_containers/glass/rag/afterattack(atom/A as obj|turf|area, mob/user,proximity) if(!proximity) return - if(ismob(A) && A.reagents && reagents.total_volume) - var/mob/M = A - if(user.a_intent == "harm") - reagents.reaction(M, TOUCH) - reagents.clear_reagents() + if(iscarbon(A) && A.reagents && reagents.total_volume) + var/mob/living/carbon/C = A + if(user.a_intent == "harm" && !C.is_mouth_covered()) + reagents.reaction(C, INGEST) + reagents.trans_to(C, reagents.total_volume) + C.visible_message("[user] has smothered \the [C] with \the [src]!", "[user] has smothered you with \the [src]!", "You hear some struggling and muffled cries of surprise.") else - reagents.trans_to(M, reagents.total_volume) - M.visible_message("[user] has smothered \the [A] with \the [src]!", "[user] has smothered you with \the [src]!", "You hear some struggling and muffled cries of surprise.") + reagents.reaction(C, TOUCH) + reagents.clear_reagents() + C.visible_message("[user] has touched \the [C] with \the [src].") + else if(istype(A) && src in user) user.visible_message("[user] starts to wipe down [A] with [src]!", "You start to wipe down [A] with [src]...") if(do_after(user,30, target = A)) diff --git a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm index 4c27150e481..32871dd073c 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/humanoid.dm @@ -147,5 +147,5 @@ /mob/living/carbon/alien/humanoid/check_ear_prot() return 1 -/mob/living/carbon/alien/carbon/alien/humanoid/get_permeability_protection() +/mob/living/carbon/alien/humanoid/get_permeability_protection() return 0.8 \ No newline at end of file diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm index e83acf03014..734b4d6aebf 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/Chemistry-Holder.dm @@ -1,7 +1,9 @@ //This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 -var/const/TOUCH = 1 -var/const/INGEST = 2 +var/const/TOUCH = 1 //splashing +var/const/INGEST = 2 //injection, ingestion +var/const/VAPOR = 3 //smoke, foam, spray +var/const/PATCH = 4 //patches, blob attack /////////////////////////////////////////////////////////////////////////////////// @@ -429,7 +431,7 @@ var/const/INGEST = 2 if(isliving(A)) var/mob/living/L = A var/touch_protection = 0 - if(method == TOUCH) + if(method == VAPOR) touch_protection = L.get_permeability_protection() for(var/datum/reagent/R in reagent_list) R.reaction_mob(L, method, R.volume*volume_modifier, show_message, touch_protection) diff --git a/code/modules/reagents/Chemistry-Readme.dm b/code/modules/reagents/Chemistry-Readme.dm index 74e9fe0b093..e0b68c4a597 100644 --- a/code/modules/reagents/Chemistry-Readme.dm +++ b/code/modules/reagents/Chemistry-Readme.dm @@ -69,7 +69,7 @@ About the Holder: This proc calls the appropriate reaction procs of the reagents. I.e. if A is an object, it will call the reagents reaction_obj proc. The method var is used for reaction on mobs. It simply tells - us if the mob TOUCHed the reagent or if it INGESTed the reagent. + us if the mob TOUCHed the reagent, if it INGESTed the reagent or if the reagent was VAPORIZEd on them.. Since the volume can be checked in a reagents proc, you might want to use the volume_modifier var to modifiy the passed value without actually changing the volume of the reagents. diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index c89a5d434eb..61290e5d22f 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -40,9 +40,9 @@ var/datum/reagent/self = src src = null - if(method == TOUCH) + if(method == VAPOR) //smoke, foam, spray if(M.reagents) - var/modifier = Clamp((1 - touch_protection) + rand(-5,5)/100, 0, 1) + var/modifier = Clamp((1 - touch_protection), 0, 1) var/amount = round(volume*modifier, 0.1) if(amount >= 1) M.reagents.add_reagent(self.id, amount) diff --git a/code/modules/reagents/Chemistry-Reagents/Blob-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Blob-Reagents.dm index 5470a6f5db1..a47cc5e02e3 100644 --- a/code/modules/reagents/Chemistry-Reagents/Blob-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Blob-Reagents.dm @@ -12,7 +12,7 @@ message = "The blob splashes you with burning oil" /datum/reagent/blob/boiling_oil/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) + if(method == PATCH) var/ratio = volume/25 M.apply_damage(15*ratio, BURN) M.adjust_fire_stacks(2*ratio) @@ -28,7 +28,7 @@ message_living = ", and you feel sick and nauseated" /datum/reagent/blob/toxic_goop/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) + if(method == PATCH) var/ratio = volume/25 M.apply_damage(20*ratio, TOX) @@ -40,7 +40,7 @@ message_living = ", and you feel your skin ripping and tearing off" /datum/reagent/blob/skin_ripper/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) + if(method == PATCH) var/ratio = volume/25 M.apply_damage(20*ratio, BRUTE) if(iscarbon(M)) @@ -56,7 +56,7 @@ message_living = ", and you feel your skin char and melt" /datum/reagent/blob/skin_melter/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) + if(method == PATCH) var/ratio = volume/25 M.apply_damage(10*ratio, BRUTE) M.apply_damage(10*ratio, BURN) @@ -73,7 +73,7 @@ message_living = ", and your lungs feel heavy and weak" /datum/reagent/blob/lung_destroying_toxin/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) + if(method == PATCH) var/ratio = volume/25 M.apply_damage(20* ratio, OXY) M.losebreath += 15*ratio @@ -89,7 +89,7 @@ message_living = ", and your skin feels papery and everything hurts" /datum/reagent/blob/radioactive_liquid/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) + if(method == PATCH) var/ratio = volume/25 M.apply_damage(10*ratio, BRUTE) if(istype(M, /mob/living/carbon/human)) @@ -109,7 +109,7 @@ message = "You feel a thrum as the blob strikes you, and everything flies at you" /datum/reagent/blob/dark_matter/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) + if(method == PATCH) var/ratio = volume/25 M.apply_damage(15*ratio, BRUTE) reagent_vortex(M, 0) @@ -123,7 +123,7 @@ message = "The blob slams into you, and sends you flying" /datum/reagent/blob/b_sorium/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) + if(method == PATCH) var/ratio = volume/25 M.apply_damage(15*ratio, BRUTE) reagent_vortex(M, 1) @@ -137,7 +137,7 @@ message = "The blob strikes you, and its tendrils explode" /datum/reagent/blob/explosive/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) + if(method == PATCH) var/ratio = volume/25 if(prob(75*ratio)) explosion(M.loc, 0, 0, 1, 0, 0) @@ -151,7 +151,7 @@ message_living = ", and you feel great" /datum/reagent/blob/omnizine/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) + if(method == PATCH) var/ratio = volume/25 M.reagents.add_reagent("omnizine", 11*ratio) @@ -164,7 +164,7 @@ message_living = ", and you feel funny" /datum/reagent/blob/spacedrugs/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) + if(method == PATCH) var/ratio = volume/25 M.hallucination += 20*ratio M.reagents.add_reagent("space_drugs", 15*ratio) diff --git a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Alcohols.dm b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Alcohols.dm index df637f4eab8..c3d04b713e0 100644 --- a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Alcohols.dm +++ b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Alcohols.dm @@ -51,9 +51,9 @@ /datum/reagent/consumable/ethanol/reaction_mob(mob/living/M, method=TOUCH, volume)//Splashing people with ethanol isn't quite as good as fuel. if(!istype(M, /mob/living)) return - if(method == TOUCH) + if(method == TOUCH || method == VAPOR) M.adjust_fire_stacks(volume / 15) - return + ..() /datum/reagent/consumable/ethanol/beer name = "Beer" diff --git a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm index 6ca5afcf052..f16ed8685fc 100644 --- a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm @@ -168,7 +168,7 @@ return var/mob/living/carbon/victim = M - if(method == TOUCH) + if(method == TOUCH || method == VAPOR) //check for protection var/mouth_covered = 0 var/eyes_covered = 0 diff --git a/code/modules/reagents/Chemistry-Reagents/Medicine-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Medicine-Reagents.dm index 3f08110b756..611136589e6 100644 --- a/code/modules/reagents/Chemistry-Reagents/Medicine-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Medicine-Reagents.dm @@ -165,7 +165,7 @@ /datum/reagent/medicine/silver_sulfadiazine/reaction_mob(mob/living/M, method=TOUCH, volume, show_message = 1) if(iscarbon(M)) - if(method == TOUCH) + if(method == PATCH) M.adjustFireLoss(-volume) if(show_message) M << "You feel your burns healing!" @@ -175,12 +175,10 @@ if(show_message) M << "You probably shouldn't have eaten that. Maybe you should of splashed it on, or applied a patch?" ..() - return /datum/reagent/medicine/silver_sulfadiazine/on_mob_life(mob/living/M) M.adjustFireLoss(-2*REM) ..() - return /datum/reagent/medicine/styptic_powder name = "Styptic Powder" @@ -191,23 +189,21 @@ /datum/reagent/medicine/styptic_powder/reaction_mob(mob/living/M, method=TOUCH, volume, show_message = 1) if(iscarbon(M)) - if(method == TOUCH) + if(method == PATCH) M.adjustBruteLoss(-volume) if(show_message) M << "You feel your wounds knitting back together!" - if(M.stat) - M.emote("scream") + M.emote("scream") if(method == INGEST) M.adjustToxLoss(0.5*volume) if(show_message) M << "You feel kind of ill. Maybe you ate a medicine you shouldn't have?" ..() - return + /datum/reagent/medicine/styptic_powder/on_mob_life(mob/living/M) M.adjustBruteLoss(-2*REM) ..() - return /datum/reagent/medicine/salglu_solution name = "Saline-Glucose Solution" @@ -222,7 +218,6 @@ M.adjustBruteLoss(-0.5*REM) M.adjustFireLoss(-0.5*REM) ..() - return /datum/reagent/medicine/mine_salve name = "Miner's Salve" @@ -239,20 +234,19 @@ M.adjustBruteLoss(-0.25*REM) M.adjustFireLoss(-0.25*REM) ..() - return /datum/reagent/medicine/mine_salve/reaction_mob(mob/living/M, method=TOUCH, volume, show_message = 1) if(iscarbon(M)) if(method == TOUCH) if(show_message) M << "You feel your wounds knitting back together!" + method = VAPOR //so it's correctly absorbed in reagent/reaction_mob() if(method == INGEST) if(show_message) M << "That tasted horrible." M.AdjustStunned(2) M.AdjustWeakened(2) ..() - return /datum/reagent/medicine/mine_salve/on_mob_delete(mob/living/M) if(iscarbon(M)) @@ -269,13 +263,13 @@ /datum/reagent/medicine/synthflesh/reaction_mob(mob/living/M, method=TOUCH, volume,show_message = 1) if(iscarbon(M)) - if(method == TOUCH) + if(method == PATCH) M.adjustBruteLoss(-1.5*volume) M.adjustFireLoss(-1.5*volume) if(show_message) M << "You feel your burns healing and your flesh knitting together!" ..() - return + /datum/reagent/medicine/charcoal name = "Charcoal" diff --git a/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm index 8c4de4c0cd5..8b890157b4f 100644 --- a/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm @@ -14,9 +14,9 @@ if(D.spread_flags & SPECIAL || D.spread_flags & NON_CONTAGIOUS) continue - if(method == TOUCH) + if(method == TOUCH || method == VAPOR) M.ContractDisease(D) - else //injected + else //ingest or patch M.ForceContractDisease(D) /datum/reagent/blood/on_new(list/data) @@ -101,13 +101,11 @@ if(D.GetDiseaseID() in self.data) D.cure() M.resistances |= self.data - return /datum/reagent/vaccine/on_merge(list/data) if(istype(data)) src.data |= data.Copy() - /datum/reagent/water name = "Water" id = "water" @@ -171,6 +169,7 @@ return if(method == TOUCH) M.adjust_fire_stacks(-(volume / 10)) + ..() /datum/reagent/water/holywater name = "Holy Water" @@ -260,10 +259,10 @@ color = "#FFC080" // rgb: 255, 196, 128 Bright orange metabolization_rate = 10 * REAGENTS_METABOLISM // very fast, so it can be applied rapidly. But this changes on an overdose overdose_threshold = 11 //Slightly more than one un-nozzled spraybottle. - + /datum/reagent/spraytan/reaction_mob(mob/living/M, method=TOUCH, volume, show_message = 1) if(istype(M, /mob/living/carbon/human)) - if(method == TOUCH) + if(method == PATCH || method == VAPOR) var/mob/living/carbon/human/N = M if(N.dna.species.id == "human") switch(N.skin_tone) @@ -289,7 +288,7 @@ N.skin_tone = "caucasian2" if ("albino") N.skin_tone = "caucasian1" - + if(MUTCOLORS in N.dna.species.specflags) //take current alien color and darken it slightly var/newcolor = "" var/len = length(N.dna.features["mcolor"]) @@ -307,20 +306,20 @@ N.dna.features["mcolor"] = newcolor N.regenerate_icons() N.update_body() - - - + + + if(method == INGEST) if(show_message) M << "That tasted horrible." M.AdjustStunned(2) M.AdjustWeakened(2) ..() - - + + /datum/reagent/spraytan/overdose_process(mob/living/M) metabolization_rate = 1 * REAGENTS_METABOLISM - + if(istype(M, /mob/living/carbon/human)) var/mob/living/carbon/human/N = M if(N.dna.species.id == "human") // If they're human, turn em to the "orange" race, and give em spiky black hair @@ -329,7 +328,7 @@ N.hair_color = "000" N.update_hair() if(MUTCOLORS in N.dna.species.specflags) //Aliens with custom colors simply get turned orange - N.dna.features["mcolor"] = "f80" + N.dna.features["mcolor"] = "f80" N.regenerate_icons() N.update_body() if(prob(7)) @@ -382,9 +381,10 @@ description = "An advanced corruptive toxin produced by slimes." color = "#13BC5E" // rgb: 19, 188, 94 -/datum/reagent/aslimetoxin/reaction_mob(mob/M, volume) +/datum/reagent/aslimetoxin/reaction_mob(mob/M, method=TOUCH, volume) src = null - M.ForceContractDisease(new /datum/disease/transformation/slime(0)) + if(method != TOUCH) + M.ForceContractDisease(new /datum/disease/transformation/slime(0)) /datum/reagent/serotrotium name = "Serotrotium" @@ -583,8 +583,6 @@ /datum/reagent/uranium/on_mob_life(mob/living/M) M.apply_effect(1/M.metabolism_efficiency,IRRADIATE,0) ..() - return - /datum/reagent/uranium/reaction_turf(turf/T, volume) src = null @@ -616,14 +614,14 @@ /datum/reagent/fuel/reaction_mob(mob/living/M, method=TOUCH, volume)//Splashing people with welding fuel to make them easy to ignite! if(!istype(M, /mob/living)) return - if(method == TOUCH) + if(method == TOUCH || method == VAPOR) M.adjust_fire_stacks(volume / 10) return + ..() /datum/reagent/fuel/on_mob_life(mob/living/M) M.adjustToxLoss(1) ..() - return /datum/reagent/space_cleaner name = "Space cleaner" @@ -652,35 +650,36 @@ F.dirt = 0 /datum/reagent/space_cleaner/reaction_mob(mob/M, method=TOUCH, volume) - if(iscarbon(M)) - var/mob/living/carbon/C = M - if(istype(M,/mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - if(H.lip_style) - H.lip_style = null - H.update_body() - if(C.r_hand) - C.r_hand.clean_blood() - if(C.l_hand) - C.l_hand.clean_blood() - if(C.wear_mask) - if(C.wear_mask.clean_blood()) - C.update_inv_wear_mask() - if(ishuman(M)) - var/mob/living/carbon/human/H = C - if(H.head) - if(H.head.clean_blood()) - H.update_inv_head() - if(H.wear_suit) - if(H.wear_suit.clean_blood()) - H.update_inv_wear_suit() - else if(H.w_uniform) - if(H.w_uniform.clean_blood()) - H.update_inv_w_uniform() - if(H.shoes) - if(H.shoes.clean_blood()) - H.update_inv_shoes() - M.clean_blood() + if(method == TOUCH || VAPOR) + if(iscarbon(M)) + var/mob/living/carbon/C = M + if(istype(M,/mob/living/carbon/human)) + var/mob/living/carbon/human/H = M + if(H.lip_style) + H.lip_style = null + H.update_body() + if(C.r_hand) + C.r_hand.clean_blood() + if(C.l_hand) + C.l_hand.clean_blood() + if(C.wear_mask) + if(C.wear_mask.clean_blood()) + C.update_inv_wear_mask() + if(ishuman(M)) + var/mob/living/carbon/human/H = C + if(H.head) + if(H.head.clean_blood()) + H.update_inv_head() + if(H.wear_suit) + if(H.wear_suit.clean_blood()) + H.update_inv_wear_suit() + else if(H.w_uniform) + if(H.w_uniform.clean_blood()) + H.update_inv_w_uniform() + if(H.shoes) + if(H.shoes.clean_blood()) + H.update_inv_shoes() + M.clean_blood() /datum/reagent/cryptobiolin name = "Cryptobiolin" @@ -717,9 +716,9 @@ description = "Microscopic construction robots." color = "#535E66" // rgb: 83, 94, 102 -/datum/reagent/nanites/reaction_mob(mob/M, method=TOUCH, volume) +/datum/reagent/nanites/reaction_mob(mob/M, method=TOUCH, volume, show_message = 1, touch_protection = 0) src = null - if( (prob(min(10, volume)) && method==TOUCH) || method==INGEST) + if(method==PATCH || method==INGEST || (method == VAPOR && prob(min(volume,100)*(1 - touch_protection)))) M.ForceContractDisease(new /datum/disease/transformation/robot(0)) /datum/reagent/xenomicrobes @@ -728,9 +727,9 @@ description = "Microbes with an entirely alien cellular structure." color = "#535E66" // rgb: 83, 94, 102 -/datum/reagent/xenomicrobes/reaction_mob(mob/M, method=TOUCH, volume) +/datum/reagent/xenomicrobes/reaction_mob(mob/M, method=TOUCH, volume, show_message = 1, touch_protection = 0) src = null - if( (prob(min(10, volume)) && method==TOUCH) || method==INGEST) + if(method==PATCH || method==INGEST || (method == VAPOR && prob(min(volume,100)*(1 - touch_protection)))) M.ContractDisease(new /datum/disease/transformation/xeno(0)) /datum/reagent/fluorosurfactant//foam precursor @@ -956,17 +955,16 @@ if(M && isliving(M)) M.color = pick(random_color_list) ..() - return + /datum/reagent/colorful_reagent/reaction_obj(obj/O, volume) if(O) O.color = pick(random_color_list) ..() - return + /datum/reagent/colorful_reagent/reaction_turf(turf/T, volume) if(T) T.color = pick(random_color_list) ..() - return /datum/reagent/hair_dye name = "Quantum Hair Dye" @@ -976,14 +974,13 @@ color = "#C8A5DC" var/list/potential_colors = list("0ad","a0f","f73","d14","d14","0b5","0ad","f73","fc2","084","05e","d22","fa0") // fucking hair code -/datum/reagent/hair_dye/reaction_mob(mob/living/M, volume) - if(M && ishuman(M)) - var/mob/living/carbon/human/H = M - H.hair_color = pick(potential_colors) - H.facial_hair_color = pick(potential_colors) - H.update_hair() - ..() - return +/datum/reagent/hair_dye/reaction_mob(mob/living/M, method=TOUCH, volume) + if(method == TOUCH || method == VAPOR) + if(M && ishuman(M)) + var/mob/living/carbon/human/H = M + H.hair_color = pick(potential_colors) + H.facial_hair_color = pick(potential_colors) + H.update_hair() /datum/reagent/barbers_aid name = "Barber's Aid" @@ -992,16 +989,15 @@ reagent_state = LIQUID color = "#C8A5DC" -/datum/reagent/barbers_aid/reaction_mob(mob/living/M, volume) - if(M && ishuman(M)) - var/mob/living/carbon/human/H = M - var/datum/sprite_accessory/hair/picked_hair = pick(hair_styles_list) - var/datum/sprite_accessory/facial_hair/picked_beard = pick(facial_hair_styles_list) - H.hair_style = picked_hair - H.facial_hair_style = picked_beard - H.update_hair() - ..() - return +/datum/reagent/barbers_aid/reaction_mob(mob/living/M, method=TOUCH, volume) + if(method == TOUCH || method == VAPOR) + if(M && ishuman(M)) + var/mob/living/carbon/human/H = M + var/datum/sprite_accessory/hair/picked_hair = pick(hair_styles_list) + var/datum/sprite_accessory/facial_hair/picked_beard = pick(facial_hair_styles_list) + H.hair_style = picked_hair + H.facial_hair_style = picked_beard + H.update_hair() /datum/reagent/concentrated_barbers_aid name = "Concentrated Barber's Aid" @@ -1010,14 +1006,13 @@ reagent_state = LIQUID color = "#C8A5DC" -/datum/reagent/concentrated_barbers_aid/reaction_mob(mob/living/M, volume) - if(M && ishuman(M)) - var/mob/living/carbon/human/H = M - H.hair_style = "Very Long Hair" - H.facial_hair_style = "Very Long Beard" - H.update_hair() - ..() - return +/datum/reagent/concentrated_barbers_aid/reaction_mob(mob/living/M, method=TOUCH, volume) + if(method == TOUCH || method == VAPOR) + if(M && ishuman(M)) + var/mob/living/carbon/human/H = M + H.hair_style = "Very Long Hair" + H.facial_hair_style = "Very Long Beard" + H.update_hair() /datum/reagent/saltpetre name = "Saltpetre" diff --git a/code/modules/reagents/Chemistry-Reagents/Pyrotechnic-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Pyrotechnic-Reagents.dm index 56300fffd97..0303fe93a10 100644 --- a/code/modules/reagents/Chemistry-Reagents/Pyrotechnic-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Pyrotechnic-Reagents.dm @@ -67,10 +67,11 @@ W.ChangeTurf(/turf/simulated/floor/plating) /datum/reagent/clf3/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH && isliving(M)) - M.adjust_fire_stacks(min(volume/5, 10)) - M.IgniteMob() - PoolOrNew(/obj/effect/hotspot, M.loc) + if(istype(M)) + if(method != INGEST) + M.adjust_fire_stacks(min(volume/5, 10)) + M.IgniteMob() + PoolOrNew(/obj/effect/hotspot, M.loc) /datum/reagent/sorium name = "Sorium" @@ -148,8 +149,9 @@ ..() /datum/reagent/napalm/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH && isliving(M)) - M.adjust_fire_stacks(min(volume/4, 20)) + if(istype(M)) + if(method != INGEST) + M.adjust_fire_stacks(min(volume/4, 20)) /datum/reagent/cryostylane name = "Cryostylane" diff --git a/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm index c5416d0fe77..31ca9044802 100644 --- a/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm @@ -34,7 +34,7 @@ if(!istype(M) || !M.dna) return //No robots, AIs, aliens, Ians or other mobs should be affected by this. src = null - if((method==TOUCH && prob(min(33, volume))) || method==INGEST) + if((method==VAPOR && prob(min(33, volume))) || method==INGEST || method == PATCH) randmuti(M) if(prob(98)) randmutb(M) @@ -42,13 +42,12 @@ randmutg(M) domutcheck(M, null) updateappearance(M) - return + ..() /datum/reagent/toxin/mutagen/on_mob_life(mob/living/carbon/M) if(istype(M)) M.apply_effect(5,IRRADIATE,0) ..() - return /datum/reagent/toxin/plasma name = "Plasma" @@ -81,9 +80,10 @@ /datum/reagent/toxin/plasma/reaction_mob(mob/living/M, method=TOUCH, volume)//Splashing people with plasma is stronger than fuel! if(!istype(M, /mob/living)) return - if(method == TOUCH) + if(method == TOUCH || method == VAPOR) M.adjust_fire_stacks(volume / 5) return + ..() /datum/reagent/toxin/lexorin name = "Lexorin" @@ -191,11 +191,13 @@ /datum/reagent/toxin/plantbgone/reaction_mob(mob/living/M, method=TOUCH, volume) src = null - if(iscarbon(M)) - var/mob/living/carbon/C = M - if(!C.wear_mask) // If not wearing a mask - var/damage = min(round(0.4*volume, 0.1),10) - C.adjustToxLoss(damage) + if(method == VAPOR) + if(iscarbon(M)) + var/mob/living/carbon/C = M + if(!C.wear_mask) // If not wearing a mask + var/damage = min(round(0.4*volume, 0.1),10) + C.adjustToxLoss(damage) + /datum/reagent/toxin/plantbgone/weedkiller name = "Weed Killer" id = "weedkiller" @@ -212,11 +214,12 @@ /datum/reagent/toxin/pestkiller/reaction_mob(mob/living/M, method=TOUCH, volume) src = null - if(iscarbon(M)) - var/mob/living/carbon/C = M - if(!C.wear_mask) // If not wearing a mask - var/damage = min(round(0.4*volume, 0.1),10) - C.adjustToxLoss(damage) + if(method == VAPOR) + if(iscarbon(M)) + var/mob/living/carbon/C = M + if(!C.wear_mask) // If not wearing a mask + var/damage = min(round(0.4*volume, 0.1),10) + C.adjustToxLoss(damage) /datum/reagent/toxin/spore name = "Spore Toxin" @@ -454,9 +457,8 @@ toxpwr = 0 /datum/reagent/toxin/itching_powder/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == TOUCH) + if(method != INGEST) M.reagents.add_reagent("itching_powder", volume) - return /datum/reagent/toxin/itching_powder/on_mob_life(mob/living/M) if(prob(15)) @@ -624,17 +626,24 @@ if(!istype(C)) return volume = round(volume,0.1) - if(method != TOUCH) + if(method == INGEST) C.take_organ_damage(min(6*toxpwr, volume * toxpwr)) return - C.acid_act(acidpwr, toxpwr, volume) /datum/reagent/toxin/acid/reaction_obj(obj/O, volume) if(istype(O.loc, /mob)) //handled in human acid_act() return volume = round(volume,0.1) - O.acid_act(acidpwr, toxpwr, volume) + O.acid_act(acidpwr, volume) + +/datum/reagent/toxin/acid/reaction_turf(turf/T, volume) + if (!istype(T)) + return + src = null + volume = round(volume,0.1) + for(var/obj/O in T) + O.acid_act(acidpwr, volume) /datum/reagent/toxin/acid/fluacid name = "Fluorosulfuric acid" diff --git a/code/modules/reagents/reagent_containers/patch.dm b/code/modules/reagents/reagent_containers/patch.dm index f87d3682a7c..1b475da801e 100644 --- a/code/modules/reagents/reagent_containers/patch.dm +++ b/code/modules/reagents/reagent_containers/patch.dm @@ -6,7 +6,7 @@ item_state = "bandaid" possible_transfer_amounts = null volume = 50 - apply_type = TOUCH + apply_type = PATCH apply_method = "apply" /obj/item/weapon/reagent_containers/pill/patch/New() diff --git a/code/modules/reagents/reagent_containers/spray.dm b/code/modules/reagents/reagent_containers/spray.dm index 73923de0f62..46aef0834e4 100644 --- a/code/modules/reagents/reagent_containers/spray.dm +++ b/code/modules/reagents/reagent_containers/spray.dm @@ -79,12 +79,12 @@ continue if(puff_reagent_left <= 0) break - D.reagents.reaction(T) + D.reagents.reaction(T, VAPOR) if(ismob(T)) //mobs are obstacles that consume part of the puff, shortening its range. puff_reagent_left -= 1 if(puff_reagent_left > 0) - D.reagents.reaction(get_turf(D)) + D.reagents.reaction(get_turf(D), VAPOR) puff_reagent_left -= 1 if(puff_reagent_left <= 0) // we used all the puff so we delete it. From 3bf0063f972a44fab2cfd0db8285da0648a96129 Mon Sep 17 00:00:00 2001 From: Francis Devine Date: Tue, 11 Aug 2015 11:29:56 +1200 Subject: [PATCH 008/108] Check an item exists before trying to eject it --- code/game/machinery/suit_storage_unit.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 67b8c167772..e881e2f0a30 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -319,8 +319,9 @@ MASK = null /obj/machinery/suit_storage_unit/proc/eject_storage() - eject(STORAGE) - STORAGE = null + if(STORAGE) + eject(STORAGE) + STORAGE = null /obj/machinery/suit_storage_unit/proc/eject(atom/movable/ITEM) ITEM.loc = src.loc From 3216b07759becc373e833d38389bd2a486d090a6 Mon Sep 17 00:00:00 2001 From: NikNakFlak Date: Tue, 11 Aug 2015 21:05:30 -0700 Subject: [PATCH 009/108] Makes restarts not restart the server if admins are online --- code/controllers/subsystem/voting.dm | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/code/controllers/subsystem/voting.dm b/code/controllers/subsystem/voting.dm index 7988d4ab99e..90a9f38b568 100644 --- a/code/controllers/subsystem/voting.dm +++ b/code/controllers/subsystem/voting.dm @@ -116,7 +116,18 @@ var/datum/subsystem/vote/SSvote else master_mode = . if(restart) - world.Reboot("Restart vote successful.", "end_error", "restart vote") + if(!admins.len) + return + var/total_admins + var/afk_admins + for(var/client/C in admins) + total_admins++ + if(C.is_afk()) + afk_admins++ + var/active_admins + active_admins = total_admins - afk_admins + if(active_admins <= 0) + world.Reboot("Restart vote successful.", "end_error", "restart vote") return . From 65b6eae001131b8ef95eebf3e5924cbebc7547c7 Mon Sep 17 00:00:00 2001 From: Orange Borg Date: Wed, 12 Aug 2015 16:33:05 +1200 Subject: [PATCH 010/108] Improve the check for active admins --- code/controllers/subsystem/voting.dm | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/code/controllers/subsystem/voting.dm b/code/controllers/subsystem/voting.dm index 90a9f38b568..677757deeaa 100644 --- a/code/controllers/subsystem/voting.dm +++ b/code/controllers/subsystem/voting.dm @@ -116,16 +116,10 @@ var/datum/subsystem/vote/SSvote else master_mode = . if(restart) - if(!admins.len) - return - var/total_admins - var/afk_admins + var/active_admins = 0 for(var/client/C in admins) - total_admins++ - if(C.is_afk()) - afk_admins++ - var/active_admins - active_admins = total_admins - afk_admins + if(!C.is_afk()) + active_admins++ if(active_admins <= 0) world.Reboot("Restart vote successful.", "end_error", "restart vote") From f176789a0b40596069fd9dd4aed184ebfa39e128 Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Tue, 11 Aug 2015 22:03:21 -0700 Subject: [PATCH 011/108] improvements to vote restart when admins are on It will only count admins who can actually restart the server. It will stop searching for admins once it finds one. It will let the users and admins know that the restart vote will not automatically restart the server because of the active admins. --- code/controllers/subsystem/voting.dm | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/code/controllers/subsystem/voting.dm b/code/controllers/subsystem/voting.dm index 677757deeaa..d413809558e 100644 --- a/code/controllers/subsystem/voting.dm +++ b/code/controllers/subsystem/voting.dm @@ -118,10 +118,14 @@ var/datum/subsystem/vote/SSvote if(restart) var/active_admins = 0 for(var/client/C in admins) - if(!C.is_afk()) - active_admins++ - if(active_admins <= 0) + if(!C.is_afk() && check_rights_for(C, R_SERVER)) + active_admins = 1 + break + if(!active_admins) world.Reboot("Restart vote successful.", "end_error", "restart vote") + else + world << "Notice:Restart vote will not restart the server automatically because there are active admins on." + message_admins("A restart vote has passed, but there are active admins on with +server, so it has been canceled. If you wish, you may restart the server.") return . From df4d5cfe0d7eeed27f7123a068f694838d919d4f Mon Sep 17 00:00:00 2001 From: c0 Date: Wed, 12 Aug 2015 15:18:13 +0300 Subject: [PATCH 012/108] RnD update --- code/controllers/subsystem/shuttles.dm | 9 ++- code/controllers/subsystem/shuttles/supply.dm | 26 +++++++ .../items/weapons/implants/implantcase.dm | 8 ++ .../research/designs/medical_designs.dm | 73 ++++++++++++++++++- code/modules/research/rdconsole.dm | 22 ++++-- code/modules/research/research.dm | 25 +++++++ 6 files changed, 149 insertions(+), 14 deletions(-) diff --git a/code/controllers/subsystem/shuttles.dm b/code/controllers/subsystem/shuttles.dm index d578f1c501c..71ed49b0394 100644 --- a/code/controllers/subsystem/shuttles.dm +++ b/code/controllers/subsystem/shuttles.dm @@ -24,10 +24,13 @@ var/datum/subsystem/shuttle/SSshuttle var/points_per_decisecond = 0.005 //points gained every decisecond var/points_per_slip = 2 //points gained per slip returned var/points_per_crate = 5 //points gained per crate returned - var/points_per_intel = 100 //points gained per intel returned + var/points_per_intel = 250 //points gained per intel returned var/points_per_plasma = 5 //points gained per plasma returned + var/points_per_design = 25 //points gained per max reliability research design returned (only for initilally unreliable designs) var/centcom_message = "" //Remarks from Centcom on how well you checked the last order. - var/list/discoveredPlants = list() //Unique typepaths for unusual things we've already sent CentComm, associated with their potencies + var/list/discoveredPlants = list() //Typepaths for unusual plants we've already sent CentComm, associated with their potencies + var/list/techLevels = list() + var/list/researchDesigns = list() var/list/shoppinglist = list() var/list/requestlist = list() var/list/supply_packs = list() @@ -306,7 +309,7 @@ var/datum/subsystem/shuttle/SSshuttle var/obj/structure/largecrate/LC = Crate LC.manifest = slip LC.update_icon() - + return Crate /datum/subsystem/shuttle/proc/generateSupplyOrder(packId, _orderedby, _orderedbyRank, _comment) diff --git a/code/controllers/subsystem/shuttles/supply.dm b/code/controllers/subsystem/shuttles/supply.dm index 8d0ca50207f..71873c539da 100644 --- a/code/controllers/subsystem/shuttles/supply.dm +++ b/code/controllers/subsystem/shuttles/supply.dm @@ -143,6 +143,32 @@ if(istype(thing, /obj/item/documents/syndicate)) ++intel_count + // Sell tech levels + if(istype(thing, /obj/item/weapon/disk/tech_disk)) + var/obj/item/weapon/disk/tech_disk/disk = thing + if(!disk.stored) continue + var/datum/tech/tech = disk.stored + + var/cost = tech.getCost(SSshuttle.techLevels[tech.id]) + if(cost) + SSshuttle.techLevels[tech.id] = tech.level + SSshuttle.points += cost + msg += "+[cost]: [tech.name] - new data.
" + + // Sell max reliablity designs + if(istype(thing, /obj/item/weapon/disk/design_disk)) + var/obj/item/weapon/disk/design_disk/disk = thing + if(!disk.blueprint) continue + var/datum/design/design = disk.blueprint + if(design.id in SSshuttle.researchDesigns) continue + + if(initial(design.reliability) < 100 && design.reliability >= 100) + // Maxed out reliability designs only. + SSshuttle.points += SSshuttle.points_per_design + SSshuttle.researchDesigns += design.id + msg += "+[SSshuttle.points_per_design]: Reliable [design.name] design.
" + + // Sell exotic plants if(istype(thing, /obj/item/seeds)) var/obj/item/seeds/S = thing if(S.rarity == 0) // Mundane species diff --git a/code/game/objects/items/weapons/implants/implantcase.dm b/code/game/objects/items/weapons/implants/implantcase.dm index b38dbaea378..d6644f1c886 100644 --- a/code/game/objects/items/weapons/implants/implantcase.dm +++ b/code/game/objects/items/weapons/implants/implantcase.dm @@ -83,3 +83,11 @@ /obj/item/weapon/implantcase/weapons_auth/New() imp = new /obj/item/weapon/implant/weapons_auth(src) ..() + +/obj/item/weapon/implantcase/adrenaline + name = "implant case - 'Adrenaline'" + desc = "A glass case containing an adrenaline implant." + +/obj/item/weapon/implantcase/adrenaline/New() + imp = new /obj/item/weapon/implant/adrenalin(src) + ..() diff --git a/code/modules/research/designs/medical_designs.dm b/code/modules/research/designs/medical_designs.dm index 1501167a730..c01225e38e1 100644 --- a/code/modules/research/designs/medical_designs.dm +++ b/code/modules/research/designs/medical_designs.dm @@ -111,15 +111,27 @@ //////////Cybernetic Implants//////////// ///////////////////////////////////////// +/datum/design/cyberimp_welding + name = "Welding Shield implant" + desc = "These reactive micro-shields will protect you from welders and flashes without obscuring your vision." + id = "ci-welding" + req_tech = list("materials" = 4, "biotech" = 2) + build_type = PROTOLATHE | MECHFAB + construction_time = 40 + materials = list(MAT_METAL = 200, MAT_GLASS = 400) + build_path = /obj/item/organ/internal/cyberimp/eyes/shield + category = list("Misc", "Medical Designs") + /datum/design/cyberimp_medical_hud name = "Medical HUD implant" desc = "These cybernetic eyes will display a medical HUD over everything you see. Wiggle eyes to control." id = "ci-medhud" req_tech = list("materials" = 6, "programming" = 4, "biotech" = 4) build_type = PROTOLATHE | MECHFAB + construction_time = 50 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 500, MAT_GOLD = 500) build_path = /obj/item/organ/internal/cyberimp/eyes/hud/medical - category = list("Medical Designs") + category = list("Misc", "Medical Designs") /datum/design/cyberimp_security_hud name = "Security HUD implant" @@ -127,9 +139,10 @@ id = "ci-sechud" req_tech = list("materials" = 6, "programming" = 5, "biotech" = 4, "combat" = 2) build_type = PROTOLATHE | MECHFAB + construction_time = 50 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 750, MAT_GOLD = 750) build_path = /obj/item/organ/internal/cyberimp/eyes/hud/security - category = list("Medical Designs") + category = list("Misc", "Medical Designs") /datum/design/cyberimp_xray name = "X-Ray implant" @@ -137,9 +150,10 @@ id = "ci-xray" req_tech = list("materials" = 7, "programming" = 5, "biotech" = 6, "magnets" = 5) build_type = PROTOLATHE | MECHFAB + construction_time = 60 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 600, MAT_GOLD = 600, MAT_PLASMA = 1000, MAT_URANIUM = 1000, MAT_DIAMOND = 2000) build_path = /obj/item/organ/internal/cyberimp/eyes/xray - category = list("Medical Designs") + category = list("Misc", "Medical Designs") /datum/design/cyberimp_thermals name = "Thermals implant" @@ -147,9 +161,10 @@ id = "ci-thermals" req_tech = list("materials" = 7, "programming" = 5, "biotech" = 5, "magnets" = 5, "syndicate" = 5) build_type = PROTOLATHE | MECHFAB + construction_time = 60 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 600, MAT_GOLD = 600, MAT_PLASMA = 1000, MAT_DIAMOND = 2000) build_path = /obj/item/organ/internal/cyberimp/eyes/thermals - category = list("Medical Designs") + category = list("Misc", "Medical Designs") /datum/design/cyberimp_antidrop name = "Anti-Drop implant" @@ -157,6 +172,7 @@ id = "ci-antidrop" req_tech = list("materials" = 7, "programming" = 5, "biotech" = 5) build_type = PROTOLATHE | MECHFAB + construction_time = 60 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 400, MAT_GOLD = 400) build_path = /obj/item/organ/internal/cyberimp/brain/anti_drop category = list("Medical Designs") @@ -167,6 +183,7 @@ id = "ci-antistun" req_tech = list("materials" = 7, "programming" = 5, "biotech" = 6) build_type = PROTOLATHE | MECHFAB + construction_time = 60 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_SILVER = 500, MAT_GOLD = 1000) build_path = /obj/item/organ/internal/cyberimp/brain/anti_stun category = list("Medical Designs") @@ -177,6 +194,7 @@ id = "ci-nutriment" req_tech = list("materials" = 6, "programming" = 4, "biotech" = 5) build_type = PROTOLATHE | MECHFAB + construction_time = 40 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_GOLD = 500, MAT_URANIUM = 500) build_path = /obj/item/organ/internal/cyberimp/chest/nutriment category = list("Medical Designs") @@ -187,6 +205,7 @@ id = "ci-nutrimentplus" req_tech = list("materials" = 6, "programming" = 4, "biotech" = 6) build_type = PROTOLATHE | MECHFAB + construction_time = 50 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_GOLD = 500, MAT_URANIUM = 750) build_path = /obj/item/organ/internal/cyberimp/chest/nutriment/plus category = list("Medical Designs") @@ -197,6 +216,52 @@ id = "ci-reviver" req_tech = list("materials" = 6, "programming" = 4, "biotech" = 7, "syndicate" = 4) build_type = PROTOLATHE | MECHFAB + construction_time = 60 materials = list(MAT_METAL = 200, MAT_GLASS = 200, MAT_GOLD = 500, MAT_URANIUM = 1000, MAT_DIAMOND = 2000) build_path = /obj/item/organ/internal/cyberimp/chest/reviver + category = list("Misc", "Medical Designs") + + +///////////////////////////////////////// +////////////Regular Implants///////////// +///////////////////////////////////////// + +/datum/design/implanter + name = "Implanter" + desc = "A sterile automatic implant injector." + id = "implanter" + req_tech = list("materials" = 1, "programming" = 2, "biotech" = 3) + build_type = PROTOLATHE + materials = list(MAT_METAL = 600, MAT_GLASS = 200) + build_path = /obj/item/weapon/implanter + category = list("Medical Designs") + +/datum/design/implantcase + name = "Implant Case" + desc = "A glass case containing an implant." + id = "implantcase" + req_tech = list("materials" = 1, "biotech" = 2) + build_type = PROTOLATHE + materials = list(MAT_GLASS = 500) + build_path = /obj/item/weapon/implantcase + category = list("Medical Designs") + +/datum/design/implant_freedom + name = "Freedom Implant Case" + desc = "A glass case containing an implant." + id = "implant_freedom" + req_tech = list("materials" = 2, "biotech" = 3, "magnets" = 3, "syndicate" = 5) + build_type = PROTOLATHE + materials = list(MAT_METAL = 50, MAT_GLASS = 500, MAT_GOLD = 250) + build_path = /obj/item/weapon/implantcase/freedom + category = list("Medical Designs") + +/datum/design/implant_adrenalin + name = "Adrenalin Implant Case" + desc = "A glass case containing an implant." + id = "implant_adrenalin" + req_tech = list("materials" = 2, "biotech" = 5, "combat" = 3, "syndicate" = 6) + build_type = PROTOLATHE + materials = list(MAT_METAL = 50, MAT_GLASS = 500, MAT_GOLD = 500, MAT_URANIUM = 100, MAT_DIAMOND = 200) + build_path = /obj/item/weapon/implantcase/adrenaline category = list("Medical Designs") \ No newline at end of file diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index a3e8c47888d..8f6a1112c52 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -715,11 +715,14 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += "Load Design to Disk" else dat += "Name: [d_disk.blueprint.name]
" - dat += "Level: [Clamp((d_disk.blueprint.reliability + rand(-15,15)), 0, 100)]
" - switch(d_disk.blueprint.build_type) - if(IMPRINTER) dat += "Lathe Type: Circuit Imprinter
" - if(PROTOLATHE) dat += "Lathe Type: Proto-lathe
" - if(AUTOLATHE) dat += "Lathe Type: Auto-lathe
" + dat += "Level: [d_disk.blueprint.reliability]
" + var/b_type = d_disk.blueprint.build_type + if(b_type) + dat += "Lathe Types:
" + if(b_type & IMPRINTER) dat += "Circuit Imprinter
" + if(b_type & PROTOLATHE) dat += "Proto-lathe
" + if(b_type & AUTOLATHE) dat += "Auto-lathe
" + if(b_type & MECHFAB) dat += "Mech Fabricator
" dat += "Required Materials:
" for(var/M in d_disk.blueprint.materials) if(copytext(M, 1, 2) == "$") dat += "* [copytext(M, 2)] x [d_disk.blueprint.materials[M]]
" @@ -790,7 +793,12 @@ won't update every console in existence) but it's more of a hassle to do. Also, dat += "Origin Tech:
" var/list/temp_tech = linked_destroy.ConvertReqString2List(linked_destroy.loaded_item.origin_tech) for(var/T in temp_tech) - dat += "* [CallTechName(T)] [temp_tech[T]]
" + dat += "* [CallTechName(T)] [temp_tech[T]]" + for(var/datum/tech/F in files.known_tech) + if(F.name == CallTechName(T)) + dat += " (Current: [F.level])" + break + dat += "
" dat += "Options: " dat += "Deconstruct Item" dat += "Eject Item" @@ -1102,4 +1110,4 @@ won't update every console in existence) but it's more of a hassle to do. Also, /obj/machinery/computer/rdconsole/experiment name = "E.X.P.E.R.I-MENTOR R&D Console" desc = "A console used to interface with R&D tools." - id = 1 + id = 3 diff --git a/code/modules/research/research.dm b/code/modules/research/research.dm index ac43f99f99c..d164418c115 100644 --- a/code/modules/research/research.dm +++ b/code/modules/research/research.dm @@ -190,6 +190,7 @@ research holder datum. var/desc = "description" //General description of what it does and what it makes. var/id = "id" //An easily referenced ID. Must be alphanumeric, lower-case, and no symbols. var/level = 1 //A simple number scale of the research level. Level 0 = Secret tech. + var/rare = 1 //How much CentCom wants to get that tech. Used in supply shuttle tech cost calculation. var/list/req_tech = list() //List of ids associated values of techs required to research this tech. "id" = # @@ -209,6 +210,7 @@ research holder datum. name = "Plasma Research" desc = "Research into the mysterious substance colloqually known as 'plasma'." id = "plasmatech" + rare = 3 /datum/tech/powerstorage name = "Power Manipulation Technology" @@ -219,6 +221,7 @@ research holder datum. name = "'Blue-space' Research" desc = "Research into the sub-reality known as 'blue-space'" id = "bluespace" + rare = 2 /datum/tech/biotech name = "Biological Technology" @@ -244,6 +247,8 @@ research holder datum. name = "Illegal Technologies Research" desc = "The study of technologies that violate Nanotrassen regulations." id = "syndicate" + rare = 4 + /* /datum/tech/arcane @@ -273,6 +278,26 @@ research holder datum. */ +/datum/tech/proc/getCost(var/current_level = null) + // Calculates tech disk's supply points sell cost + if(!current_level) + current_level = initial(level) + + if(current_level >= level) + return 0 + + var/cost = 0 + var/i + for(i=current_level+1, i<=level, i++) + if(i == initial(level)) + continue + cost += i*5*rare + + return cost + + + + /obj/item/weapon/disk/tech_disk name = "Technology Disk" desc = "A disk for storing technology data for further research." From c62a203a4e5a8e8cb109f71368c3bd64bb2be728 Mon Sep 17 00:00:00 2001 From: Supermichael777 Date: Wed, 12 Aug 2015 08:42:47 -0400 Subject: [PATCH 013/108] Signed-off-by: Supermichael777 --- html/changelogs/Supermichael777-PR-#11158.yml | 8 ++++++++ interface/interface.dm | 3 +++ interface/skin.dmf | 20 +++++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 html/changelogs/Supermichael777-PR-#11158.yml diff --git a/html/changelogs/Supermichael777-PR-#11158.yml b/html/changelogs/Supermichael777-PR-#11158.yml new file mode 100644 index 00000000000..050195e831b --- /dev/null +++ b/html/changelogs/Supermichael777-PR-#11158.yml @@ -0,0 +1,8 @@ +author: Supermichael777 + +delete-after: True + +changes: + - bugfix: "Added an ooc hotkey for borgs = O. They simply didn't have one and it was a consistency issue" + - rscadd: "Also added Ctrl+O as an any mode keycombo so you dont have to backspace and type ooc. Added to hotkey mode to remain consistent with all other Ctrl combos" + \ No newline at end of file diff --git a/interface/interface.dm b/interface/interface.dm index a97aa48e385..578e0f084fd 100644 --- a/interface/interface.dm +++ b/interface/interface.dm @@ -112,6 +112,7 @@ Any-Mode: (hotkey doesn't need to be on) \tCtrl+e = equip \tCtrl+r = throw \tCtrl+b = resist +\tCtrl+O = OOC \tCtrl+x = swap-hand \tCtrl+z = activate held object (or Ctrl+y) \tCtrl+f = cycle-intents-left @@ -141,6 +142,7 @@ Hotkey-Mode: (hotkey-mode must be on) \tw = up \tq = unequip active module \tt = say +\to = OOC \tx = cycle active modules \tb = resist \tz = activate held object (or y) @@ -161,6 +163,7 @@ Any-Mode: (hotkey doesn't need to be on) \tCtrl+q = unequip active module \tCtrl+x = cycle active modules \tCtrl+b = resist +\tCtrl+o = OOC \tCtrl+z = activate held object (or Ctrl+y) \tCtrl+f = cycle-intents-left \tCtrl+g = cycle-intents-right diff --git a/interface/skin.dmf b/interface/skin.dmf index 7db57837c75..ef5ae3f9ebf 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -107,6 +107,14 @@ macro "borghotkeymode" name = "CTRL+B" command = "resist" is-disabled = false + elem + name = "O" + command = "ooc" + is-disabled = false + elem + name = "CTRL+O" + command = "ooc" + is-disabled = false elem name = "D+REP" command = ".east" @@ -373,6 +381,10 @@ macro "macro" name = "F5" command = "Aghost" is-disabled = false + elem + name = "CTRL+O" + command = "ooc" + is-disabled = false elem name = "F6" command = "Player-Panel" @@ -543,6 +555,10 @@ macro "hotkeymode" name = "O" command = "ooc" is-disabled = false + elem + name = "CTRL+O" + command = "ooc" + is-disabled = false elem name = "Q" command = ".northwest" @@ -725,6 +741,10 @@ macro "borgmacro" name = "CTRL+B" command = "resist" is-disabled = false + elem + name = "CTRL+O" + command = "ooc" + is-disabled = false elem name = "CTRL+D+REP" command = ".east" From 5b6861dd17c2cf4fef009acb0757f8b8e4d27804 Mon Sep 17 00:00:00 2001 From: Supermichael777 Date: Wed, 12 Aug 2015 08:54:00 -0400 Subject: [PATCH 014/108] Numbers are hard when you dont know what it will be. oops. --- ...ermichael777-PR-#11158.yml => Supermichael777-PR-#11163.yml} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename html/changelogs/{Supermichael777-PR-#11158.yml => Supermichael777-PR-#11163.yml} (99%) diff --git a/html/changelogs/Supermichael777-PR-#11158.yml b/html/changelogs/Supermichael777-PR-#11163.yml similarity index 99% rename from html/changelogs/Supermichael777-PR-#11158.yml rename to html/changelogs/Supermichael777-PR-#11163.yml index 050195e831b..79b90558790 100644 --- a/html/changelogs/Supermichael777-PR-#11158.yml +++ b/html/changelogs/Supermichael777-PR-#11163.yml @@ -5,4 +5,4 @@ delete-after: True changes: - bugfix: "Added an ooc hotkey for borgs = O. They simply didn't have one and it was a consistency issue" - rscadd: "Also added Ctrl+O as an any mode keycombo so you dont have to backspace and type ooc. Added to hotkey mode to remain consistent with all other Ctrl combos" - \ No newline at end of file + From 4a76033e4827fa8e02cfc98dbfa5e06d68aaa643 Mon Sep 17 00:00:00 2001 From: Oisin100 Date: Wed, 12 Aug 2015 20:07:58 +0200 Subject: [PATCH 015/108] Bugfix And Feature addition. Chameleon And Stealth Mutations Bug: Noticed this a while ago that the Chameleon And the Stealth(Cloak Of Darkness) Dont work together. As the stealth mutation will instantly change the players visibility to visible. So i have added a check to see if the player has the Chameleon mutation and if they dont THEN change their visibility to visible Feature: Due to the checks nature having both mutations will cause you to go invisible double speed in the dark --- code/datums/mutations.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm index b517e417d93..f9516df1068 100644 --- a/code/datums/mutations.dm +++ b/code/datums/mutations.dm @@ -364,7 +364,8 @@ if(T.lighting_lumcount <= 2) owner.alpha -= 25 else - owner.alpha = round(255 * 0.80) + if(!owner.dna.check_mutation("Chameleon")) + owner.alpha = round(255 * 0.80) /datum/mutation/human/stealth/on_losing(mob/living/carbon/human/owner) if(..()) From 5979ffdec7ee5a4083785f038b1ee33c3788c6af Mon Sep 17 00:00:00 2001 From: Cheridan Date: Thu, 13 Aug 2015 12:14:14 -0500 Subject: [PATCH 016/108] Logging Syntax Improvement --- code/modules/assembly/holder.dm | 2 +- code/modules/crafting/table.dm | 4 +- .../kitchen machinery/microwave.dm | 2 +- code/modules/mining/mine_turfs.dm | 12 +-- .../mob/living/carbon/human/human_defense.dm | 2 +- .../simple_animal/hostile/mining_mobs.dm | 2 +- code/modules/power/cell.dm | 2 +- code/modules/projectiles/gun.dm | 2 +- .../Chemistry-Recipes/Slime_extracts.dm | 88 ++++++++----------- code/modules/research/rdconsole.dm | 6 +- 10 files changed, 54 insertions(+), 68 deletions(-) diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index 4b6489290d2..fe02a86da7f 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -21,7 +21,7 @@ attach(A2,user) name = "[A.name]-[A2.name] assembly" update_icon() - feedback_add_details("assembly_made","[name]") + feedback_add_details("assembly_made","[type]") /obj/item/device/assembly_holder/proc/attach(obj/item/device/assembly/A, mob/user) if(!A.remove_item_from_storage(src)) diff --git a/code/modules/crafting/table.dm b/code/modules/crafting/table.dm index 3d0ed8b6d84..1999ed6edb8 100644 --- a/code/modules/crafting/table.dm +++ b/code/modules/crafting/table.dm @@ -78,7 +78,7 @@ if(istype(I, /obj/item/weapon/reagent_containers/food/snacks)) var/obj/item/weapon/reagent_containers/food/snacks/S = I S.create_reagents(S.volume) - feedback_add_details("food_made","[S.name]") + feedback_add_details("food_made","[S.type]") send_feedback = 0 var/list/parts = del_reqs(R, I) for(var/A in parts) @@ -93,7 +93,7 @@ I.reagents.reagent_list.Add(A) I.CheckParts() if(send_feedback) - feedback_add_details("object_crafted","[I.name]") + feedback_add_details("object_crafted","[I.type]") return 1 return 0 diff --git a/code/modules/food&drinks/kitchen machinery/microwave.dm b/code/modules/food&drinks/kitchen machinery/microwave.dm index 0221c4bdc07..400bbd075a9 100644 --- a/code/modules/food&drinks/kitchen machinery/microwave.dm +++ b/code/modules/food&drinks/kitchen machinery/microwave.dm @@ -244,7 +244,7 @@ if(F.cooked_type) var/obj/item/weapon/reagent_containers/food/snacks/S = new F.cooked_type (get_turf(src)) F.initialize_cooked_food(S, efficiency) - feedback_add_details("food_made","[F.name]") + feedback_add_details("food_made","[F.type]") else new /obj/item/weapon/reagent_containers/food/snacks/badrecipe(src) if(dirty < 100) diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index 894d29cbc5c..24a358a10b2 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -432,10 +432,10 @@ var/global/list/rockTurfEdgeCache P.playDigSound() if(do_after(user,P.digspeed, target = src)) - if(istype(src, /turf/simulated/mineral)) + if(istype(src, /turf/simulated/mineral)) user << "You finish cutting into the rock." gets_drilled(user) - feedback_add_details("pick_used_mining","[P.name]") + feedback_add_details("pick_used_mining","[P.type]") else return attack_hand(user) return @@ -565,13 +565,13 @@ var/global/list/rockTurfEdgeCache user << "You start digging..." playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1) //FUCK YO RUSTLE I GOT'S THE DIGS SOUND HERE - + if(do_after(user, digging_speed, target = src)) - if(istype(src, /turf/simulated/floor/plating/asteroid)) + if(istype(src, /turf/simulated/floor/plating/asteroid)) user << "You dig a hole." gets_dug() - feedback_add_details("pick_used_mining","[W.name]") - + feedback_add_details("pick_used_mining","[W.type]") + if(istype(W,/obj/item/weapon/storage/bag/ore)) var/obj/item/weapon/storage/bag/ore/S = W if(S.collection_mode == 1) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 86c3b23fd50..c5d6344961d 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -129,7 +129,7 @@ emp_act var/obj/item/organ/limb/affecting = get_organ(ran_zone(user.zone_sel.selecting)) var/hit_area = parse_zone(affecting.name) var/target_area = parse_zone(target_limb.name) - feedback_add_details("item_used_for_combat","[I.name]|[I.force]") + feedback_add_details("item_used_for_combat","[I.type]|[I.force]") feedback_add_details("zone_targeted","[def_zone]") if(dna) // allows your species to affect the attacked_by code diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm index 7e01e2942ef..777ecc44f92 100644 --- a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm +++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm @@ -42,7 +42,7 @@ ..() /mob/living/simple_animal/hostile/asteroid/death(gibbed) - feedback_add_details("mobs_killed_mining","[src.name]") + feedback_add_details("mobs_killed_mining","[src.type]") ..(gibbed) /mob/living/simple_animal/hostile/asteroid/basilisk diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index b99735503ee..152e160e7c9 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -43,7 +43,7 @@ if(charge < amount) return 0 charge = (charge - amount) if(!istype(loc, /obj/machinery/power/apc)) - feedback_add_details("cell_used","[src.name]") + feedback_add_details("cell_used","[src.type]") return 1 // recharge the cell diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index cc5bd988992..fe5ef91095c 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -232,7 +232,7 @@ user.update_inv_l_hand() else user.update_inv_r_hand() - feedback_add_details("gun_fired","[src.name]") + feedback_add_details("gun_fired","[src.type]") /obj/item/weapon/gun/attack(mob/M as mob, mob/user) if(user.a_intent == "harm") //Flogging diff --git a/code/modules/reagents/Chemistry-Recipes/Slime_extracts.dm b/code/modules/reagents/Chemistry-Recipes/Slime_extracts.dm index a0b76e0bad4..1caf7cf85b3 100644 --- a/code/modules/reagents/Chemistry-Recipes/Slime_extracts.dm +++ b/code/modules/reagents/Chemistry-Recipes/Slime_extracts.dm @@ -10,7 +10,7 @@ required_other = 1 /datum/chemical_reaction/slimespawn/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/mob/living/simple_animal/slime/S = new /mob/living/simple_animal/slime S.loc = get_turf(holder.my_atom) S.visible_message("Infused with plasma, the core begins to quiver and grow, and soon a new baby slime emerges from it!") @@ -25,7 +25,7 @@ required_container = /obj/item/slime_extract/grey /datum/chemical_reaction/slimeinaprov/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") /datum/chemical_reaction/slimemonkey name = "Slime Monkey" @@ -37,7 +37,7 @@ required_other = 1 /datum/chemical_reaction/slimemonkey/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") for(var/i = 1, i <= 3, i++) var /obj/item/weapon/reagent_containers/food/snacks/monkeycube/M = new /obj/item/weapon/reagent_containers/food/snacks/monkeycube M.loc = get_turf(holder.my_atom) @@ -53,7 +53,7 @@ required_container = /obj/item/slime_extract/green /datum/chemical_reaction/slimemutate/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") //Mutated Green /datum/chemical_reaction/slimemutate_unstable @@ -67,7 +67,7 @@ mix_message = "The mixture rapidly expands and contracts, its appearance shifting into a sickening green." /datum/chemical_reaction/slimemutate_unstable/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") //Metal /datum/chemical_reaction/slimemetal @@ -80,7 +80,7 @@ required_other = 1 /datum/chemical_reaction/slimemetal/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/obj/item/stack/sheet/metal/M = new /obj/item/stack/sheet/metal M.amount = 15 M.loc = get_turf(holder.my_atom) @@ -99,7 +99,7 @@ required_other = 1 /datum/chemical_reaction/slimecrit/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") for(var/mob/O in viewers(get_turf(holder.my_atom), null)) O.show_message(text("The slime extract begins to vibrate violently !"), 1) spawn(50) @@ -116,7 +116,7 @@ required_other = 1 /datum/chemical_reaction/slimecritlesser/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") for(var/mob/O in viewers(get_turf(holder.my_atom), null)) O.show_message(text("The slime extract begins to vibrate violently !"), 1) spawn(50) @@ -133,7 +133,7 @@ required_other = 1 /datum/chemical_reaction/slimecritfriendly/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") for(var/mob/O in viewers(get_turf(holder.my_atom), null)) O.show_message(text("The slime extract begins to vibrate adorably !"), 1) spawn(50) @@ -152,7 +152,7 @@ /datum/chemical_reaction/slimebork/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/list/blocked = list(/obj/item/weapon/reagent_containers/food/snacks, /obj/item/weapon/reagent_containers/food/snacks/store/bread, /obj/item/weapon/reagent_containers/food/snacks/breadslice, @@ -200,7 +200,7 @@ /datum/chemical_reaction/slimebork2/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/list/blocked = list(/obj/item/weapon/reagent_containers/food/drinks) var/list/borks = typesof(/obj/item/weapon/reagent_containers/food/drinks) - blocked @@ -232,7 +232,7 @@ required_other = 1 /datum/chemical_reaction/slimefrost/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") /datum/chemical_reaction/slimestabilizer @@ -245,7 +245,7 @@ required_other = 1 /datum/chemical_reaction/slimestabilizer/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/obj/item/weapon/slimestabilizer/P = new /obj/item/weapon/slimestabilizer P.loc = get_turf(holder.my_atom) @@ -262,7 +262,7 @@ required_other = 1 /datum/chemical_reaction/slimefreeze/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") for(var/mob/O in viewers(get_turf(holder.my_atom), null)) O.show_message(text("The slime extract begins to vibrate violently !"), 1) spawn(50) @@ -283,7 +283,7 @@ required_other = 1 /datum/chemical_reaction/slimecasp/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") /datum/chemical_reaction/slimefire name = "Slime fire" @@ -295,7 +295,7 @@ required_other = 1 /datum/chemical_reaction/slimefire/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") for(var/mob/O in viewers(get_turf(holder.my_atom), null)) O.show_message(text("The slime extract begins to vibrate violently !"), 1) spawn(50) @@ -316,7 +316,7 @@ required_other = 1 /datum/chemical_reaction/slimeoverload/on_reaction(datum/reagents/holder, created_volume) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") empulse(get_turf(holder.my_atom), 3, 7) @@ -330,7 +330,7 @@ required_other = 1 /datum/chemical_reaction/slimecell/on_reaction(datum/reagents/holder, created_volume) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/obj/item/weapon/stock_parts/cell/high/slime/P = new /obj/item/weapon/stock_parts/cell/high/slime P.loc = get_turf(holder.my_atom) @@ -344,7 +344,7 @@ required_other = 1 /datum/chemical_reaction/slimeglow/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") for(var/mob/O in viewers(get_turf(holder.my_atom), null)) O.show_message(text("The slime begins to emit a soft light. Squeezing it will cause it to grow brightly."), 1) var/obj/item/device/flashlight/slime/F = new /obj/item/device/flashlight/slime @@ -362,7 +362,7 @@ required_other = 1 /datum/chemical_reaction/slimepsteroid/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/obj/item/weapon/slimesteroid/P = new /obj/item/weapon/slimesteroid P.loc = get_turf(holder.my_atom) @@ -376,7 +376,7 @@ required_other = 1 /datum/chemical_reaction/slimejam/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") //Dark Purple @@ -390,25 +390,11 @@ required_other = 1 /datum/chemical_reaction/slimeplasma/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/obj/item/stack/sheet/mineral/plasma/P = new /obj/item/stack/sheet/mineral/plasma P.amount = 10 P.loc = get_turf(holder.my_atom) -//Red -/*/datum/chemical_reaction/slimeglycerol - name = "Slime Glycerol" - id = "m_glycerol" - result = "glycerol" - required_reagents = list("plasma" = 1) - result_amount = 8 - required_container = /obj/item/slime_extract/red - required_other = 1 - -/datum/chemical_reaction/slimeglycerol/on_reaction(var/datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") -*/ - /datum/chemical_reaction/slimemutator name = "Slime Mutator" id = "m_slimemutator" @@ -419,7 +405,7 @@ required_other = 1 /datum/chemical_reaction/slimemutator/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/obj/item/weapon/slimemutator/P = new /obj/item/weapon/slimemutator P.loc = get_turf(holder.my_atom) @@ -433,7 +419,7 @@ required_other = 1 /datum/chemical_reaction/slimebloodlust/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") for(var/mob/living/simple_animal/slime/slime in viewers(get_turf(holder.my_atom), null)) slime.rabid = 1 for(var/mob/O in viewers(get_turf(holder.my_atom), null)) @@ -450,7 +436,7 @@ required_other = 1 /datum/chemical_reaction/slimeppotion/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/obj/item/slimepotion/P = new /obj/item/slimepotion P.loc = get_turf(holder.my_atom) @@ -466,7 +452,7 @@ required_container = /obj/item/slime_extract/black /datum/chemical_reaction/slimemutate2/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") //Oil /datum/chemical_reaction/slimeexplosion @@ -479,7 +465,7 @@ required_other = 1 /datum/chemical_reaction/slimeexplosion/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") for(var/mob/O in viewers(get_turf(holder.my_atom), null)) O.show_message(text("The slime extract begins to vibrate violently !"), 1) spawn(50) @@ -497,7 +483,7 @@ required_other = 1 /datum/chemical_reaction/slimepotion2/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/obj/item/slimepotion2/P = new /obj/item/slimepotion2 P.loc = get_turf(holder.my_atom) @@ -512,7 +498,7 @@ required_other = 1 /datum/chemical_reaction/slimegolem/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/obj/effect/golemrune/Z = new /obj/effect/golemrune Z.loc = get_turf(holder.my_atom) notify_ghosts("Golem rune created in [get_area(Z)].", 'sound/effects/ghost2.ogg') @@ -528,7 +514,7 @@ required_other = 1 /datum/chemical_reaction/slimefloor2/on_reaction(datum/reagents/holder, created_volume) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/obj/item/stack/tile/bluespace/P = new /obj/item/stack/tile/bluespace P.amount = 25 P.loc = get_turf(holder.my_atom) @@ -544,7 +530,7 @@ required_other = 1 /datum/chemical_reaction/slimecrystal/on_reaction(datum/reagents/holder, created_volume) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") if(holder.my_atom) var/obj/item/bluespace_crystal/BC = new(get_turf(holder.my_atom)) BC.visible_message("The [BC.name] appears out of thin air!") @@ -560,7 +546,7 @@ required_other = 1 /datum/chemical_reaction/slimepsteroid2/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/obj/item/weapon/slimesteroid2/P = new /obj/item/weapon/slimesteroid2 P.loc = get_turf(holder.my_atom) @@ -575,7 +561,7 @@ required_other = 1 /datum/chemical_reaction/slimestop/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/mob/mob = get_mob_by_key(holder.my_atom.fingerprintslast) var/obj/effect/timestop/T = new /obj/effect/timestop T.loc = get_turf(holder.my_atom) @@ -593,7 +579,7 @@ required_other = 1 /datum/chemical_reaction/slimecamera/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/obj/item/device/camera/P = new /obj/item/device/camera P.loc = get_turf(holder.my_atom) var/obj/item/device/camera_film/Z = new /obj/item/device/camera_film @@ -609,7 +595,7 @@ required_other = 1 /datum/chemical_reaction/slimefloor/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/obj/item/stack/tile/sepia/P = new /obj/item/stack/tile/sepia P.amount = 25 P.loc = get_turf(holder.my_atom) @@ -628,7 +614,7 @@ required_other = 1 /datum/chemical_reaction/slimepaint/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/list/paints = typesof(/obj/item/weapon/paint) - /obj/item/weapon/paint var/chosen = pick(paints) var/obj/P = new chosen @@ -646,7 +632,7 @@ required_container = /obj/item/slime_extract/rainbow /datum/chemical_reaction/slimeRNG/on_reaction(datum/reagents/holder) - feedback_add_details("slime_cores_used","[replacetext(name," ","_")]") + feedback_add_details("slime_cores_used","[type]") var/mob/living/simple_animal/slime/S = new /mob/living/simple_animal/slime S.colour = pick("grey","orange", "metal", "blue", "purple", "dark purple", "dark blue", "green", "silver", "yellow", "gold", "yellow", "red", "silver", "pink", "cerulean", "sepia", "bluespace", "pyrite", "light pink", "oil", "adamantine", "black") S.loc = get_turf(holder.my_atom) diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index a3e8c47888d..028858dd0b9 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -278,7 +278,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, if(linked_lathe) //Also sends salvaged materials to a linked protolathe, if any. linked_lathe.m_amount += min((linked_lathe.max_material_storage - linked_lathe.TotalMaterials()), (linked_destroy.loaded_item.materials[MAT_METAL]*(linked_destroy.decon_mod/10))) linked_lathe.g_amount += min((linked_lathe.max_material_storage - linked_lathe.TotalMaterials()), (linked_destroy.loaded_item.materials[MAT_GLASS]*(linked_destroy.decon_mod/10))) - feedback_add_details("item_deconstructed","[linked_destroy.loaded_item.name]") + feedback_add_details("item_deconstructed","[linked_destroy.loaded_item.type]") linked_destroy.loaded_item = null else screen = 1.0 @@ -421,7 +421,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, R = max((new_item.reliability/2), 0) new_item.loc = linked_lathe.loc if(!already_logged) - feedback_add_details("item_printed","[new_item.name]|[amount]") + feedback_add_details("item_printed","[new_item.type]|[amount]") already_logged = 1 linked_lathe.busy = 0 screen = old_screen @@ -476,7 +476,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, var/obj/item/new_item = new P(src) new_item.reliability = R new_item.loc = linked_imprinter.loc - feedback_add_details("circuit_printed","[new_item.name]") + feedback_add_details("circuit_printed","[new_item.type]") linked_imprinter.busy = 0 screen = old_screen updateUsrDialog() From 4e82bc056e92170f9189e1326e29a65ce6851fef Mon Sep 17 00:00:00 2001 From: Cheridan Date: Thu, 13 Aug 2015 12:31:10 -0500 Subject: [PATCH 017/108] Fixes def_zone not being logged, maybe --- code/modules/mob/living/carbon/human/human_defense.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index c5d6344961d..7a39b9969fe 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -130,7 +130,7 @@ emp_act var/hit_area = parse_zone(affecting.name) var/target_area = parse_zone(target_limb.name) feedback_add_details("item_used_for_combat","[I.type]|[I.force]") - feedback_add_details("zone_targeted","[def_zone]") + feedback_add_details("zone_targeted","[target_area]") if(dna) // allows your species to affect the attacked_by code return dna.species.spec_attacked_by(I,user,def_zone,affecting,hit_area,src.a_intent,target_limb,target_area,src) From 1cee0d30147abb4cf6b6476f526e458ca0a3e773 Mon Sep 17 00:00:00 2001 From: phil235 Date: Thu, 13 Aug 2015 23:49:02 +0200 Subject: [PATCH 018/108] Fixes slipping on water while riding janicart. The handle_slip() now also handles cases where the mob is buckled. If you are buckled and slip on lube (or something that ignores galoshes) you get unbuckled and stunned and the buckle object moves one step (no slides unlike when unbuckled). You can thus slip on lube while buckled to a chair or a roller bed. Fixes getting hit by abstract held items when slipping. Fixes janicart rider getting hit twice by bullets. Removing the STEP constant var in slipping code, it's no more used. Fixes carbon/slip() not returning the correct value. Changed var/obj/structure/stool/bed/buckled to var/obj/buckled since buckled can now technically be any obj. Removes hacky unbuckling/buckling in bed/Move() --- code/game/objects/structures/janicart.dm | 13 ---- .../structures/stool_bed_chair_nest/bed.dm | 2 - code/game/turfs/simulated.dm | 7 +-- code/game/turfs/turf.dm | 59 ++++++++++--------- code/modules/mob/living/carbon/carbon.dm | 9 ++- code/modules/mob/mob_defines.dm | 2 +- html/changelogs/phil235 - JanicartFixes.yml | 7 +++ 7 files changed, 47 insertions(+), 52 deletions(-) create mode 100644 html/changelogs/phil235 - JanicartFixes.yml diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 22f4ae79d1b..7246ac3dbbd 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -238,14 +238,6 @@ step(src, direction) update_mob() handle_rotation() - if(istype(src.loc, /turf/simulated)) - var/turf/simulated/T = src.loc - if(T.wet == 2) //Lube! Fall off! - playsound(src, 'sound/misc/slip.ogg', 50, 1, -3) - buckled_mob.Stun(7) - buckled_mob.Weaken(7) - unbuckle_mob() - step(src, dir) move_delay = 1 spawn(2) move_delay = 0 @@ -300,11 +292,6 @@ buckled_mob.pixel_x = -12 buckled_mob.pixel_y = 7 - -/obj/structure/stool/bed/chair/janicart/bullet_act(obj/item/projectile/Proj) - if(buckled_mob) - buckled_mob.bullet_act(Proj) - /obj/item/key name = "key" desc = "A small grey key." diff --git a/code/game/objects/structures/stool_bed_chair_nest/bed.dm b/code/game/objects/structures/stool_bed_chair_nest/bed.dm index 7f7b7c0ae05..160c798e99c 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm @@ -24,14 +24,12 @@ /obj/structure/stool/bed/Move(atom/newloc, direct) //Some bed children move . = ..() if(buckled_mob) - buckled_mob.buckled = null if(!buckled_mob.Move(loc, direct)) loc = buckled_mob.loc //we gotta go back last_move = buckled_mob.last_move inertia_dir = last_move buckled_mob.inertia_dir = last_move . = 0 - buckled_mob.buckled = src /obj/structure/stool/bed/Process_Spacemove(movement_dir = 0) if(buckled_mob) diff --git a/code/game/turfs/simulated.dm b/code/game/turfs/simulated.dm index 58e7ae67fd2..5267ccbae9e 100644 --- a/code/game/turfs/simulated.dm +++ b/code/game/turfs/simulated.dm @@ -44,14 +44,13 @@ ..() if (istype(A,/mob/living/carbon)) var/mob/living/carbon/M = A - if(M.lying) return - switch (src.wet) + switch(wet) if(1) //wet floor - if(!M.slip(4, 2, null, (NO_SLIP_WHEN_WALKING|STEP))) + if(!M.slip(4, 2, null, NO_SLIP_WHEN_WALKING)) M.inertia_dir = 0 return if(2) //lube - M.slip(0, 7, null, (STEP|SLIDE|GALOSHES_DONT_HELP)) + M.slip(0, 7, null, (SLIDE|GALOSHES_DONT_HELP)) /turf/simulated/ChangeTurf(var/path) . = ..() diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index 2bcfe8d976f..69f8443f315 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -224,38 +224,43 @@ if(has_gravity(src)) playsound(src, "bodyfall", 50, 1) -/turf/handle_slip(mob/slipper, s_amount, w_amount, obj/O, lube) +/turf/handle_slip(mob/living/carbon/C, s_amount, w_amount, obj/O, lube) if(has_gravity(src)) - var/mob/living/carbon/M = slipper - if (M.m_intent=="walk" && (lube&NO_SLIP_WHEN_WALKING)) - return 0 - if(!M.lying && (M.status_flags & CANWEAKEN)) // we slip those who are standing and can fall. - if(O) - M << "You slipped on the [O.name]!" - else - M << "You slipped!" - M.attack_log += "\[[time_stamp()]\] Slipped[O ? " on the [O.name]" : ""][(lube&SLIDE)? " (LUBE)" : ""]!" - playsound(M.loc, 'sound/misc/slip.ogg', 50, 1, -3) + var/obj/buckled_obj + var/oldlying = C.lying + if(C.buckled) + buckled_obj = C.buckled + if(!(lube&GALOSHES_DONT_HELP)) //can't slip while buckled unless it's lube. + return 0 + else + if(C.lying || !(C.status_flags & CANWEAKEN)) // can't slip unbuckled mob if they're lying or can't fall. + return 0 + if(C.m_intent=="walk" && (lube&NO_SLIP_WHEN_WALKING)) + return 0 - M.accident(M.l_hand) - M.accident(M.r_hand) + C << "You slipped[ O ? " on the [O.name]" : ""]!" - var/olddir = M.dir - M.Stun(s_amount) - M.Weaken(w_amount) - M.stop_pulling() - if(lube&SLIDE) - for(var/i=1, i<5, i++) - spawn (i) - step(M, olddir) - M.spin(1,1) - if(M.lying) //did I fall over? - M.adjustBruteLoss(2) + C.attack_log += "\[[time_stamp()]\] Slipped[O ? " on the [O.name]" : ""][(lube&SLIDE)? " (LUBE)" : ""]!" + playsound(C.loc, 'sound/misc/slip.ogg', 50, 1, -3) + C.accident(C.l_hand) + C.accident(C.r_hand) - - return 1 - return 0 // no success. Used in clown pda and wet floors + var/olddir = C.dir + C.Stun(s_amount) + C.Weaken(w_amount) + C.stop_pulling() + if(buckled_obj) + buckled_obj.unbuckle_mob() + step(buckled_obj, olddir) + else if(lube&SLIDE) + for(var/i=1, i<5, i++) + spawn (i) + step(C, olddir) + C.spin(1,1) + if(C.lying != oldlying) //did we actually fall? + C.adjustBruteLoss(2) + return 1 /turf/singularity_act() if(intact) diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index c54c9e9f592..5ff8b7b26aa 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -335,11 +335,10 @@ return "trails_2" var/const/NO_SLIP_WHEN_WALKING = 1 -var/const/STEP = 2 -var/const/SLIDE = 4 -var/const/GALOSHES_DONT_HELP = 8 +var/const/SLIDE = 2 +var/const/GALOSHES_DONT_HELP = 4 /mob/living/carbon/slip(s_amount, w_amount, obj/O, lube) - loc.handle_slip(src, s_amount, w_amount, O, lube) + return loc.handle_slip(src, s_amount, w_amount, O, lube) /mob/living/carbon/fall(forced) loc.handle_fall(src, forced)//it's loc so it doesn't call the mob's handle_fall which does nothing @@ -505,7 +504,7 @@ var/const/GALOSHES_DONT_HELP = 8 return 1 /mob/living/carbon/proc/accident(obj/item/I) - if(!I || (I.flags & NODROP)) + if(!I || (I.flags & (NODROP|ABSTRACT))) return unEquip(I) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 265a428ba71..51fd9bece6f 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -83,7 +83,7 @@ var/a_intent = "help"//Living var/m_intent = "run"//Living var/lastKnownIP = null - var/obj/structure/stool/bed/buckled = null//Living + var/obj/buckled = null//Living var/obj/item/l_hand = null//Living var/obj/item/r_hand = null//Living var/obj/item/weapon/storage/s_active = null//Carbon diff --git a/html/changelogs/phil235 - JanicartFixes.yml b/html/changelogs/phil235 - JanicartFixes.yml new file mode 100644 index 00000000000..21617e26dce --- /dev/null +++ b/html/changelogs/phil235 - JanicartFixes.yml @@ -0,0 +1,7 @@ + +author: phil235 + +delete-after: True + +changes: + - tweak: "Janicart rider no longer slip on wet floor or bananas. Moving on a floor tile with lube while buckled (chair, roller bed, etc) will make you fall off." From afbcb506783fea087b71a7548ee33ac6b11425e9 Mon Sep 17 00:00:00 2001 From: GunHog Date: Fri, 14 Aug 2015 11:39:32 -0500 Subject: [PATCH 019/108] Malf AI Module List The modules purchased by a Malfunctioning AI are now listed at round end. --- code/game/gamemodes/malfunction/Malf_Modules.dm | 10 +++++----- code/game/gamemodes/malfunction/malfunction.dm | 6 +++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm index 8f90c400ae9..1909376ce74 100644 --- a/code/game/gamemodes/malfunction/Malf_Modules.dm +++ b/code/game/gamemodes/malfunction/Malf_Modules.dm @@ -19,7 +19,7 @@ /datum/AI_Module/large/fireproof_core - module_name = "Core upgrade" + module_name = "Core Upgrade" mod_pick_name = "coreup" description = "An upgrade to improve core resistance, making it immune to fire and heat. This effect is permanent." cost = 50 @@ -36,7 +36,7 @@ src << "Core fireproofed." /datum/AI_Module/large/upgrade_turrets - module_name = "AI Turret upgrade" + module_name = "AI Turret Upgrade" mod_pick_name = "turret" description = "Improves the power and health of all AI turrets. This effect is permanent." cost = 50 @@ -121,7 +121,7 @@ minor_announce("Automatic system reboot complete. Have a secure day.","Network reset:") /datum/AI_Module/large/disable_rcd - module_name = "RCD disable" + module_name = "RCD Disable" mod_pick_name = "rcd" description = "Send a specialised pulse to break all RCD devices on the station." cost = 50 @@ -217,7 +217,7 @@ /datum/AI_Module/small/overload_machine - module_name = "Machine overload" + module_name = "Machine Overload" mod_pick_name = "overload" description = "Overloads an electrical machine, causing a small explosion. 2 uses." uses = 2 @@ -246,7 +246,7 @@ else src << "That's not a machine." /datum/AI_Module/small/override_machine - module_name = "Machine override" + module_name = "Machine Override" mod_pick_name = "override" description = "Overrides a machine's programming, causing it to rise up and attack everyone except other machines. 4 uses." uses = 4 diff --git a/code/game/gamemodes/malfunction/malfunction.dm b/code/game/gamemodes/malfunction/malfunction.dm index 3b453e491cc..5a88c2e0525 100644 --- a/code/game/gamemodes/malfunction/malfunction.dm +++ b/code/game/gamemodes/malfunction/malfunction.dm @@ -285,6 +285,7 @@ /datum/game_mode/proc/auto_declare_completion_malfunction() if( malf_ai.len || istype(ticker.mode,/datum/game_mode/malfunction) ) var/text = "
The malfunctioning AIs were:" + var/module_text_temp = "
Purchased modules:
" //Added at the end for(var/datum/mind/malf in malf_ai) @@ -296,10 +297,13 @@ text += "operational" if(malf.current.real_name != malf.name) text += " as [malf.current.real_name]" + var/mob/living/silicon/ai/AI = malf.current + for(var/datum/AI_Module/mod in AI.current_modules) + module_text_temp += mod.module_name + "
" else text += "hardware destroyed" text += ")" - text += "
" + text += module_text_temp world << text return 1 From 138610b2a9bc90dc44515ea003898c1b3869d7da Mon Sep 17 00:00:00 2001 From: SconesC Date: Fri, 14 Aug 2015 15:23:30 -0700 Subject: [PATCH 020/108] Belts into the Uplink --- code/datums/uplink_item.dm | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index ebd3e3f3f4d..73cbcbac6ea 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -514,6 +514,13 @@ var/list/uplink_items = list() item = /obj/item/weapon/storage/backpack/dufflebag/syndie/surgery cost = 4 +/datum/uplink_item/device_tools/military_belt + name = "Military Belt" + desc = "A robust seven-slot red belt made for carrying a broad variety of weapons, ammunition and explosives" + item = /obj/item/weapon/storage/belt/military + cost = 5 + excludefrom = list(/datum/game_mode/nuclear) + /datum/uplink_item/device_tools/medkit name = "Syndicate Combat Medic Kit" desc = "The syndicate medkit is a suspicious black and red. Included is a combat stimulant injector for rapid healing, a medical hud for quick identification of injured comrades, \ From 024c71553a7c9aa0a26a3194775b64d257b7ab4e Mon Sep 17 00:00:00 2001 From: SconesC Date: Fri, 14 Aug 2015 15:32:07 -0700 Subject: [PATCH 021/108] Reduces price to 3 TC --- code/datums/uplink_item.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index 73cbcbac6ea..a90e8351418 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -518,7 +518,7 @@ var/list/uplink_items = list() name = "Military Belt" desc = "A robust seven-slot red belt made for carrying a broad variety of weapons, ammunition and explosives" item = /obj/item/weapon/storage/belt/military - cost = 5 + cost = 3 excludefrom = list(/datum/game_mode/nuclear) /datum/uplink_item/device_tools/medkit From 23011e09067a1cd7fc1aba0bf85f252dc74629f1 Mon Sep 17 00:00:00 2001 From: c0 Date: Sat, 15 Aug 2015 13:22:02 +0300 Subject: [PATCH 022/108] changelog --- code/modules/surgery/organs/augments_eyes.dm | 3 +- html/changelogs/c0-RnDupdate.yml | 40 ++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 html/changelogs/c0-RnDupdate.yml diff --git a/code/modules/surgery/organs/augments_eyes.dm b/code/modules/surgery/organs/augments_eyes.dm index ab814cbf9df..4ef193183b1 100644 --- a/code/modules/surgery/organs/augments_eyes.dm +++ b/code/modules/surgery/organs/augments_eyes.dm @@ -121,7 +121,8 @@ origin_tech = "materials=4;biotech=3" implant_color = "#101010" flash_protect = 2 - // Welding with thermals will still hurt your eyes a bit. + aug_message = null + eye_color = "fff" /obj/item/organ/internal/cyberimp/eyes/shield/emp_act(severity) return \ No newline at end of file diff --git a/html/changelogs/c0-RnDupdate.yml b/html/changelogs/c0-RnDupdate.yml new file mode 100644 index 00000000000..84812a8a855 --- /dev/null +++ b/html/changelogs/c0-RnDupdate.yml @@ -0,0 +1,40 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# spellcheck (typo fixes) +# experiment +# tgs (TG-ported fixes?) +################################# + +# Your name. +author: CoreOverload + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "Added a new low-tech eye cyberimplant in RnD - welding shield implant." + - rscadd: "Implanter and empty implant case added to protolathe." + - rscadd: "You can sell tech disks and maxed reliability design disks in cargo for supply points." + - tweak: "DA menu shows current research levels." + - tweak: "You can print cyberimplants in updated mech fab." \ No newline at end of file From 7e1bd3458348f7c7fee712e0593f4d989ba979ff Mon Sep 17 00:00:00 2001 From: c0 Date: Sat, 15 Aug 2015 13:34:15 +0300 Subject: [PATCH 023/108] Spawn panel improvements --- code/modules/admin/create_object.dm | 27 ++++++------- code/modules/admin/topic.dm | 62 ++++++++++++++++------------- html/create_object.html | 8 +--- 3 files changed, 48 insertions(+), 49 deletions(-) diff --git a/code/modules/admin/create_object.dm b/code/modules/admin/create_object.dm index bb58339dc4c..e7e787476ce 100644 --- a/code/modules/admin/create_object.dm +++ b/code/modules/admin/create_object.dm @@ -1,4 +1,8 @@ -/var/create_object_html = null +var/create_object_html = null +var/list/create_object_forms = list( + /obj, /obj/structure, /obj/machinery, /obj/effect, + /obj/item, /obj/item/clothing, /obj/item/stack, + /obj/item/weapon, /obj/item/weapon/reagent_containers, /obj/item/weapon/gun) /datum/admins/proc/create_object(mob/user) if (!create_object_html) @@ -11,18 +15,13 @@ /datum/admins/proc/quick_create_object(mob/user) + var/path = input("Select the path of the object you wish to create.", "Path", /obj) in create_object_forms + var/html_form = create_object_forms[path] - var/quick_create_object_html = null - var/pathtext = null + if (!html_form) + var/objectjs = list2text(typesof(path), ";") + html_form = file2text('html/create_object.html') + html_form = replacetext(html_form, "null /* object types */", "\"[objectjs]\"") + create_object_forms[path] = html_form - pathtext = input("Select the path of the object you wish to create.", "Path", "/obj") in list("/obj","/obj/structure","/obj/effect","/obj/item","/obj/item/clothing","/obj/item/weapon/reagent_containers/food","/obj/item/weapon","/obj/item/weapon/gun","/obj/machinery","/obj/item/stack") - - var path = text2path(pathtext) - - if (!quick_create_object_html) - var/objectjs = null - objectjs = list2text(typesof(path), ";") - quick_create_object_html = file2text('html/create_object.html') - quick_create_object_html = replacetext(quick_create_object_html, "null /* object types */", "\"[objectjs]\"") - - user << browse(replacetext(quick_create_object_html, "/* ref src */", "\ref[src]"), "window=quick_create_object;size=425x475") \ No newline at end of file + user << browse(replacetext(html_form, "/* ref src */", "\ref[src]"), "window=qco[path];size=425x475") \ No newline at end of file diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index b1ce38e14d7..b41dbcd4cf6 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1793,41 +1793,36 @@ if(!obj_dir || !(obj_dir in list(1,2,4,8,5,6,9,10))) obj_dir = 2 var/obj_name = sanitize(href_list["object_name"]) + + + var/atom/target //Where the object will be spawned var/where = href_list["object_where"] if (!( where in list("onfloor","inhand","inmarked") )) where = "onfloor" - if( where == "inhand" ) - usr << "Support for inhand not available yet. Will spawn on floor." - where = "onfloor" - if ( where == "inhand" ) //Can only give when human or monkey - if ( !( ishuman(usr) || ismonkey(usr) ) ) - usr << "Can only spawn in hand when you're a human or a monkey." - where = "onfloor" - else if ( usr.get_active_hand() ) - usr << "Your active hand is full. Spawning on floor." - where = "onfloor" + switch(where) + if("inhand") + if (!iscarbon(usr) && !isrobot(usr)) + usr << "Can only spawn in hand when you're a carbon mob or cyborg." + where = "onfloor" + target = usr - if ( where == "inmarked" ) - if ( !marked_datum ) - usr << "You don't have any object marked. Abandoning spawn." - return - else - if ( !istype(marked_datum,/atom) ) - usr << "The object you have marked cannot be used as a target. Target must be of type /atom. Abandoning spawn." - return - - var/atom/target //Where the object will be spawned - switch ( where ) - if ( "onfloor" ) - switch (href_list["offset_type"]) + if("onfloor") + switch(href_list["offset_type"]) if ("absolute") target = locate(0 + X,0 + Y,0 + Z) if ("relative") target = locate(loc.x + X,loc.y + Y,loc.z + Z) - if ( "inmarked" ) - target = marked_datum + if("inmarked") + if(!marked_datum) + usr << "You don't have any object marked. Abandoning spawn." + return + else if(!istype(marked_datum,/atom)) + usr << "The object you have marked cannot be used as a target. Target must be of type /atom. Abandoning spawn." + return + else + target = marked_datum if(target) for (var/path in paths) @@ -1835,9 +1830,8 @@ if(path in typesof(/turf)) var/turf/O = target var/turf/N = O.ChangeTurf(path) - if(N) - if(obj_name) - N.name = obj_name + if(N && obj_name) + N.name = obj_name else var/atom/O = new path(target) if(O) @@ -1847,6 +1841,18 @@ if(istype(O,/mob)) var/mob/M = O M.real_name = obj_name + if(where == "inhand" && isliving(usr) && istype(O, /obj/item)) + var/mob/living/L = usr + var/obj/item/I = O + L.put_in_hands(I) + if(isrobot(L)) + var/mob/living/silicon/robot/R = L + if(R.module) + R.module.modules += I + I.loc = R.module + R.module.rebuild() + R.activate_module(I) + if (number == 1) log_admin("[key_name(usr)] created a [english_list(paths)]") diff --git a/html/create_object.html b/html/create_object.html index f4e0aa8644c..ac47cc7769b 100644 --- a/html/create_object.html +++ b/html/create_object.html @@ -39,7 +39,7 @@ Where:

@@ -54,7 +54,6 @@ var objects = object_paths == null ? new Array() : object_paths.split(";"); document.spawner.filter.focus(); - populateList(objects); function populateList(from_list) { @@ -72,11 +71,6 @@ function updateSearch() { - if (old_search == document.spawner.filter.value) - { - return; - } - old_search = document.spawner.filter.value; From c16daab82319bceb0ce32470e5ae3dc3cc633033 Mon Sep 17 00:00:00 2001 From: c0 Date: Sat, 15 Aug 2015 13:52:45 +0300 Subject: [PATCH 024/108] Added /obj/item/device to spawn panel --- code/modules/admin/create_object.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/admin/create_object.dm b/code/modules/admin/create_object.dm index e7e787476ce..9c6e54335e9 100644 --- a/code/modules/admin/create_object.dm +++ b/code/modules/admin/create_object.dm @@ -1,7 +1,7 @@ var/create_object_html = null var/list/create_object_forms = list( /obj, /obj/structure, /obj/machinery, /obj/effect, - /obj/item, /obj/item/clothing, /obj/item/stack, + /obj/item, /obj/item/clothing, /obj/item/stack, /obj/item/device, /obj/item/weapon, /obj/item/weapon/reagent_containers, /obj/item/weapon/gun) /datum/admins/proc/create_object(mob/user) From e2d3488f7ffc7556a1cd528dfbc87b44b6f6f2be Mon Sep 17 00:00:00 2001 From: Jordie0608 Date: Sat, 15 Aug 2015 22:24:24 +1000 Subject: [PATCH 025/108] database notes --- SQL/database_changelog.txt | 12 ++ SQL/tgstation_schema.sql | 20 +++ SQL/tgstation_schema_prefixed.sql | 20 +++ code/game/verbs/ooc.dm | 2 +- code/modules/admin/NewBan.dm | 4 +- code/modules/admin/admin_investigate.dm | 2 +- code/modules/admin/player_panel.dm | 2 +- code/modules/admin/sql_notes.dm | 169 ++++++++++++++++++++++++ code/modules/admin/topic.dm | 62 ++++++--- tgstation.dme | 2 +- 10 files changed, 274 insertions(+), 21 deletions(-) create mode 100644 code/modules/admin/sql_notes.dm diff --git a/SQL/database_changelog.txt b/SQL/database_changelog.txt index bf305298ce2..dfd4b30dad3 100644 --- a/SQL/database_changelog.txt +++ b/SQL/database_changelog.txt @@ -1,3 +1,15 @@ +14 August 2015, by Jordie0608 + +Added new table 'notes' to replace BYOND's .sav note system. + +To create this new table run the following command: + +CREATE TABLE `notes` ( `id` int(11) NOT NULL AUTO_INCREMENT, `ckey` varchar(32) NOT NULL, `notetext` text NOT NULL, `timestamp` datetime NOT NULL, `adminckey` varchar(32) NOT NULL, `last_editor` varchar(32), `edits` text, `server` varchar(50) NOT NULL, PRIMARY KEY (`id`)) + +Remember to add prefix to the table name if you use them. + +---------------------------------------------------- + 28 July 2015, by Jordie0608 Modified table 'memo', removing 'id' column and making 'ckey' primary. diff --git a/SQL/tgstation_schema.sql b/SQL/tgstation_schema.sql index caeec1c432c..ae8bf1859d6 100644 --- a/SQL/tgstation_schema.sql +++ b/SQL/tgstation_schema.sql @@ -338,5 +338,25 @@ CREATE TABLE `memo` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `notes` +-- + +DROP TABLE IF EXISTS `notes`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `notes` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ckey` varchar(32) NOT NULL, + `notetext` text NOT NULL, + `timestamp` datetime NOT NULL, + `adminckey` varchar(32) NOT NULL, + `last_editor` varchar(32), + `edits` text, + `server` varchar(50) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + -- Dump completed on 2013-03-24 18:02:35 diff --git a/SQL/tgstation_schema_prefixed.sql b/SQL/tgstation_schema_prefixed.sql index 93ba765835d..b49032a7ee1 100644 --- a/SQL/tgstation_schema_prefixed.sql +++ b/SQL/tgstation_schema_prefixed.sql @@ -333,5 +333,25 @@ CREATE TABLE `SS13_memo` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1; /*!40101 SET character_set_client = @saved_cs_client */; +-- +-- Table structure for table `SS13_notes` +-- + +DROP TABLE IF EXISTS `SS13_notes`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `SS13_notes` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `ckey` varchar(32) NOT NULL, + `notetext` text NOT NULL, + `timestamp` datetime NOT NULL, + `adminckey` varchar(32) NOT NULL, + `last_editor` varchar(32), + `edits` text, + `server` varchar(50) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +/*!40101 SET character_set_client = @saved_cs_client */; + -- Dump completed on 2013-03-24 18:02:35 diff --git a/code/game/verbs/ooc.dm b/code/game/verbs/ooc.dm index eb9bbc56c0f..3a5b8178aae 100644 --- a/code/game/verbs/ooc.dm +++ b/code/game/verbs/ooc.dm @@ -137,4 +137,4 @@ var/global/normal_ooc_colour = "#002eb8" usr << "Sorry, that function is not enabled on this server." return - see_own_notes() + show_note(usr, null, 1) diff --git a/code/modules/admin/NewBan.dm b/code/modules/admin/NewBan.dm index c1716c470de..7fb18b8e55f 100644 --- a/code/modules/admin/NewBan.dm +++ b/code/modules/admin/NewBan.dm @@ -117,9 +117,9 @@ var/savefile/Banlist if (temp) Banlist["minutes"] << bantimestamp if(!temp) - notes_add(ckey, "Permanently banned - [reason]") + add_note(ckey, "Permanently banned - [reason]", null, bannedby, 0) else - notes_add(ckey, "Banned for [minutes] minutes - [reason]") + add_note(ckey, "Banned for [minutes] minutes - [reason]", null, bannedby, 0) return 1 /proc/RemoveBan(foldername) diff --git a/code/modules/admin/admin_investigate.dm b/code/modules/admin/admin_investigate.dm index b542204bd23..103d7eac30d 100644 --- a/code/modules/admin/admin_investigate.dm +++ b/code/modules/admin/admin_investigate.dm @@ -45,4 +45,4 @@ src << "Error: admin_investigate: Href Logging is not on." return if("notes") - holder.notes_show() + show_note() diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 7fdf3adb2d7..027541007f5 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -76,7 +76,7 @@ body += ""; body += "PP - " - body += "N - " + body += "N - " body += "VV - " body += "TP - " body += "PM - " diff --git a/code/modules/admin/sql_notes.dm b/code/modules/admin/sql_notes.dm new file mode 100644 index 00000000000..ab14a73e799 --- /dev/null +++ b/code/modules/admin/sql_notes.dm @@ -0,0 +1,169 @@ +proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1) + if(!dbcon.IsConnected()) + usr << "Failed to establish database connection." + return + if(!target_ckey) + var/new_ckey = ckey(input(usr,"Who would you like to add a note for?","Enter a ckey",null) as text|null) + if(!new_ckey) + return + var/DBQuery/query_find_ckey = dbcon.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey = '[new_ckey]'") + if(!query_find_ckey.Execute()) + var/err = query_find_ckey.ErrorMsg() + log_game("SQL ERROR obtaining ckey from notes table. Error : \[[err]\]\n") + return + if(!query_find_ckey.NextRow()) + usr << "[new_ckey] has not been seen before, you can only add notes to unknown players." + else + target_ckey = new_ckey + var/target_sql_ckey = sanitizeSQL(target_ckey) + if(!notetext) + notetext = input(usr,"Write your Note","Add Note") as message + if(!notetext) + return + notetext = sanitizeSQL(notetext) + if(!timestamp) + timestamp = SQLtime() + if(!adminckey) + adminckey = usr.ckey + if(!adminckey) + return + var/server + if (config && config.server_name) + server = config.server_name + var/admin_sql_ckey = sanitizeSQL(adminckey) + var/DBQuery/query_noteadd = dbcon.NewQuery("INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server) VALUES ('[target_sql_ckey]', '[timestamp]', '[notetext]', '[admin_sql_ckey]', '[server]')") + if(!query_noteadd.Execute()) + var/err = query_noteadd.ErrorMsg() + log_game("SQL ERROR adding new note to table. Error : \[[err]\]\n") + return + if(logged) + log_admin("[key_name(usr)] has added a note to [target_ckey]: [notetext]") + message_admins("[key_name_admin(usr)] has added a note to [target_ckey]:
[notetext]") + show_note(target_ckey) + +proc/remove_note(note_id) + var/ckey + var/notetext + var/adminckey + if(!dbcon.IsConnected()) + usr << "Failed to establish database connection." + return + if(!note_id) + return + var/DBQuery/query_find_note_del = dbcon.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id = '[note_id]'") + if(!query_find_note_del.Execute()) + var/err = query_find_note_del.ErrorMsg() + log_game("SQL ERROR obtaining ckey, notetext, adminckey from notes table. Error : \[[err]\]\n") + return + if(query_find_note_del.NextRow()) + ckey = query_find_note_del.item[1] + notetext = query_find_note_del.item[2] + adminckey = query_find_note_del.item[3] + var/DBQuery/query_del_note = dbcon.NewQuery("DELETE FROM [format_table_name("notes")] WHERE id = '[note_id]'") + if(!query_del_note.Execute()) + var/err = query_del_note.ErrorMsg() + log_game("SQL ERROR removing note from table. Error : \[[err]\]\n") + return + log_admin("[key_name(usr)] has removed a note made by [adminckey] from [ckey]: [notetext]") + message_admins("[key_name_admin(usr)] has removed a note made by [adminckey] from [ckey]:
[notetext]") + show_note(ckey) + +proc/edit_note(note_id) + if(!dbcon.IsConnected()) + usr << "Failed to establish database connection." + return + if(!note_id) + return + var/target_ckey + var/sql_ckey = sanitizeSQL(usr.ckey) + var/DBQuery/query_find_note_edit = dbcon.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id = '[note_id]'") + if(!query_find_note_edit.Execute()) + var/err = query_find_note_edit.ErrorMsg() + log_game("SQL ERROR obtaining notetext from notes table. Error : \[[err]\]\n") + return + if(query_find_note_edit.NextRow()) + target_ckey = query_find_note_edit.item[1] + var/old_note = query_find_note_edit.item[2] + var/adminckey = query_find_note_edit.item[3] + var/new_note = input("Input new note", "New Note", "[old_note]") as message + if(!new_note) + return + var/edit_text = "Edited by [sql_ckey] on [SQLtime()] from
[old_note]
to
[new_note]
" + edit_text = sanitizeSQL(edit_text) + var/DBQuery/query_update_note = dbcon.NewQuery("UPDATE [format_table_name("notes")] SET notetext = '[new_note]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE (id = '[note_id]')") + if(!query_update_note.Execute()) + var/err = query_update_note.ErrorMsg() + log_game("SQL ERROR editing note. Error : \[[err]\]\n") + return + log_admin("[key_name(usr)] has edited [target_ckey]'s note made by [adminckey] from [old_note] to [new_note]") + message_admins("[key_name_admin(usr)] has edited [target_ckey]'s note made by [adminckey] from
[old_note]
to
[new_note]") + show_note(target_ckey) + +proc/show_note(target_ckey, index, linkless = 0) + var/output + var/navbar + var/ruler + ruler = "
" + navbar = "\[All\]|\[#\]" + for(var/letter in alphabet) + navbar += "|\[[letter]\]" + navbar += "
\ + \ + \ +
" + if(!linkless) + output = navbar + if(target_ckey) + world << "target_ckey: [target_ckey]" + var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT id, timestamp, notetext, adminckey, last_editor, server FROM [format_table_name("notes")] WHERE ckey = '[target_ckey]'") + if(!query_get_notes.Execute()) + var/err = query_get_notes.ErrorMsg() + log_game("SQL ERROR obtaining ckey, notetext, adminckey, last_editor, server from notes table. Error : \[[err]\]\n") + return + output += "

Notes of [target_ckey]

" + if(!linkless) + output += "
\[Add Note\]
" + output += ruler + while(query_get_notes.NextRow()) + var/id = query_get_notes.item[1] + var/timestamp = query_get_notes.item[2] + var/notetext = query_get_notes.item[3] + var/adminckey = query_get_notes.item[4] + var/last_editor = query_get_notes.item[5] + var/server = query_get_notes.item[6] + output += "[timestamp] | [server] | [adminckey]" + if(!linkless) + output += " \[Remove Note\] \[Edit Note\]" + if(last_editor) + output += " Last edit by [last_editor] (Click here to see edit log)" + output += "
[notetext]
" + else if(index) + world << "index: [index]" + var/index_ckey + var/search + output += "
\[Add Note\]
" + output += ruler + switch(index) + if(1) + search = "^." + if(2) + search = "^\[^\[:alpha:\]\]" + else + search = "^[index]" + world << "search: [search]" + if(!search) + world << "null search" + return + var/DBQuery/query_list_notes = dbcon.NewQuery("SELECT DISTINCT ckey FROM [format_table_name("notes")] WHERE ckey REGEXP '[search]'") + if(!query_list_notes.Execute()) + var/err = query_list_notes.ErrorMsg() + log_game("SQL ERROR obtaining ckey from notes table. Error : \[[err]\]\n") + return + while(query_list_notes.NextRow()) + index_ckey = query_list_notes.item[1] + world << "index_ckey: [index_ckey]" + output += "[index_ckey]
" + else + output += "
\[Add Note\]
" + output += ruler + usr << browse(output, "window=show_notes;size=900x500") \ No newline at end of file diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index b1ce38e14d7..5bfd15f4c67 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -505,7 +505,7 @@ feedback_inc("ban_appearance",1) DB_ban_record(BANTYPE_APPEARANCE, M, -1, reason) appearance_fullban(M, "[reason]; By [usr.ckey] on [time2text(world.realtime)]") - notes_add(M.ckey, "Appearance banned - [reason]") + add_note(M.ckey, "Appearance banned - [reason]", null, usr, 0) message_admins("[key_name_admin(usr)] appearance banned [key_name_admin(M)]") M << "You have been appearance banned by [usr.client.ckey]." M << "The reason is: [reason]" @@ -921,7 +921,7 @@ msg = job else msg += ", [job]" - notes_add(M.ckey, "Banned from [msg] - [reason]") + add_note(M.ckey, "Banned from [msg] - [reason]", null, usr, 0) message_admins("[key_name_admin(usr)] banned [key_name_admin(M)] from [msg] for [mins] minutes") M << "You have been jobbanned by [usr.client.ckey] from: [msg]." M << "The reason is: [reason]" @@ -941,7 +941,7 @@ jobban_fullban(M, job, "[reason]; By [usr.ckey] on [time2text(world.realtime)]") if(!msg) msg = job else msg += ", [job]" - notes_add(M.ckey, "Banned from [msg] - [reason]") + add_note(M.ckey, "Banned from [msg] - [reason]", null, usr, 0) message_admins("[key_name_admin(usr)] banned [key_name_admin(M)] from [msg]") M << "You have been jobbanned by [usr.client.ckey] from: [msg]." M << "The reason is: [reason]" @@ -994,17 +994,49 @@ del(M.client) //Player Notes - else if(href_list["notes"]) - var/ckey = href_list["ckey"] - switch(href_list["notes"]) - if("show") - notes_show(ckey) - if("add") - notes_add(ckey,href_list["text"], 1) - notes_show(ckey) - if("remove") - notes_remove(ckey,text2num(href_list["from"]),text2num(href_list["to"])) - notes_show(ckey) + else if(href_list["addnote"]) + var/target_ckey = href_list["addnote"] + world << "addnote: [target_ckey]" + add_note(target_ckey) + + else if(href_list["addnoteempty"]) + add_note() + + else if(href_list["removenote"]) + var/note_id = href_list["removenote"] + remove_note(note_id) + + else if(href_list["editnote"]) + var/note_id = href_list["editnote"] + edit_note(note_id) + + else if(href_list["shownote"]) + var/target = href_list["shownote"] + show_note(index = target) + + else if(href_list["nonalpha"]) + var/target = href_list["nonalpha"] + target = text2num(target) + show_note(index = target) + + else if(href_list["shownoteckey"]) + var/target_ckey = href_list["shownoteckey"] + show_note(target_ckey) + + else if(href_list["notessearch"]) + var/target = href_list["notessearch"] + show_note(index = target) + + else if(href_list["noteedits"]) + var/note_id = sanitizeSQL("[href_list["noteedits"]]") + var/DBQuery/query_noteedits = dbcon.NewQuery("SELECT edits FROM [format_table_name("notes")] WHERE id = '[note_id]'") + if(!query_noteedits.Execute()) + var/err = query_noteedits.ErrorMsg() + log_game("SQL ERROR obtaining edits from notes table. Error : \[[err]\]\n") + return + if(query_noteedits.NextRow()) + var/edit_log = query_noteedits.item[1] + usr << browse(edit_log,"window=noteedits") else if(href_list["removejobban"]) if(!check_rights(R_BAN)) return @@ -2089,4 +2121,4 @@ message_admins("[key_name_admin(usr)] has kicked [afkonly ? "all AFK" : "all"] clients from the lobby. [length(listkicked)] clients kicked: [strkicked ? strkicked : "--"]") log_admin("[key_name(usr)] has kicked [afkonly ? "all AFK" : "all"] clients from the lobby. [length(listkicked)] clients kicked: [strkicked ? strkicked : "--"]") else - usr << "You may only use this when the game is running" + usr << "You may only use this when the game is running" \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index 75cb814a0aa..9b1ff3e38d6 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -815,9 +815,9 @@ #include "code\modules\admin\IsBanned.dm" #include "code\modules\admin\NewBan.dm" #include "code\modules\admin\newbanjob.dm" -#include "code\modules\admin\player_notes.dm" #include "code\modules\admin\player_panel.dm" #include "code\modules\admin\secrets.dm" +#include "code\modules\admin\sql_notes.dm" #include "code\modules\admin\topic.dm" #include "code\modules\admin\DB ban\functions.dm" #include "code\modules\admin\permissionverbs\permissionedit.dm" From 9e2c59ca243e18a4e8e2a9fbc36c3d89ec0b747e Mon Sep 17 00:00:00 2001 From: Jordie0608 Date: Sat, 15 Aug 2015 22:34:18 +1000 Subject: [PATCH 026/108] debug fix --- code/modules/admin/sql_notes.dm | 10 ++-------- code/modules/admin/topic.dm | 1 - 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/code/modules/admin/sql_notes.dm b/code/modules/admin/sql_notes.dm index ab14a73e799..fe9aeeeb2c5 100644 --- a/code/modules/admin/sql_notes.dm +++ b/code/modules/admin/sql_notes.dm @@ -12,7 +12,8 @@ proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1) log_game("SQL ERROR obtaining ckey from notes table. Error : \[[err]\]\n") return if(!query_find_ckey.NextRow()) - usr << "[new_ckey] has not been seen before, you can only add notes to unknown players." + usr << "[new_ckey] has not been seen before, you can only add notes to known players." + return else target_ckey = new_ckey var/target_sql_ckey = sanitizeSQL(target_ckey) @@ -114,7 +115,6 @@ proc/show_note(target_ckey, index, linkless = 0) if(!linkless) output = navbar if(target_ckey) - world << "target_ckey: [target_ckey]" var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT id, timestamp, notetext, adminckey, last_editor, server FROM [format_table_name("notes")] WHERE ckey = '[target_ckey]'") if(!query_get_notes.Execute()) var/err = query_get_notes.ErrorMsg() @@ -138,7 +138,6 @@ proc/show_note(target_ckey, index, linkless = 0) output += " Last edit by [last_editor] (Click here to see edit log)" output += "
[notetext]
" else if(index) - world << "index: [index]" var/index_ckey var/search output += "
\[Add Note\]
" @@ -150,10 +149,6 @@ proc/show_note(target_ckey, index, linkless = 0) search = "^\[^\[:alpha:\]\]" else search = "^[index]" - world << "search: [search]" - if(!search) - world << "null search" - return var/DBQuery/query_list_notes = dbcon.NewQuery("SELECT DISTINCT ckey FROM [format_table_name("notes")] WHERE ckey REGEXP '[search]'") if(!query_list_notes.Execute()) var/err = query_list_notes.ErrorMsg() @@ -161,7 +156,6 @@ proc/show_note(target_ckey, index, linkless = 0) return while(query_list_notes.NextRow()) index_ckey = query_list_notes.item[1] - world << "index_ckey: [index_ckey]" output += "[index_ckey]
" else output += "
\[Add Note\]
" diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index 5bfd15f4c67..6b5dfce04f7 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -996,7 +996,6 @@ //Player Notes else if(href_list["addnote"]) var/target_ckey = href_list["addnote"] - world << "addnote: [target_ckey]" add_note(target_ckey) else if(href_list["addnoteempty"]) From 7d9a9f132456a74119a2841d345fcfe513a14e20 Mon Sep 17 00:00:00 2001 From: phil235 Date: Sat, 15 Aug 2015 20:56:56 +0200 Subject: [PATCH 027/108] Readds blob smoke reagent effect. You can now partially (max is 50%) protect yourself again blob reagent effects (blob smoke and blob attack). Although some effects are unaffected (explosion probability, vortex power, adding fire_stacks). Changes the "volume" argument used in reaction_mob() to "reac_volume" to avoid confusion with the "volume" variable. Buffed blob smoke reagent amount from 5 to 10 to counterbalance the nerf from clothes protection. Blob direct attack now uses the VAPOR method. --- code/game/gamemodes/blob/blobs/blob_mobs.dm | 6 +- code/game/gamemodes/blob/powers.dm | 5 +- code/modules/reagents/Chemistry-Holder.dm | 4 +- code/modules/reagents/Chemistry-Readme.dm | 2 +- code/modules/reagents/Chemistry-Reagents.dm | 4 +- .../Chemistry-Reagents/Blob-Reagents.dm | 137 ++++++++---------- .../Drink-Reagents/Alcohols.dm | 8 +- .../Consumable-Reagents/Food-Reagents.dm | 14 +- .../Chemistry-Reagents/Medicine-Reagents.dm | 22 +-- .../Chemistry-Reagents/Other-Reagents.dm | 84 +++++------ .../Pyrotechnic-Reagents.dm | 32 ++-- .../Chemistry-Reagents/Toxin-Reagents.dm | 56 ++++--- .../phil235-VaporizeMethodReaction.yml | 8 + 13 files changed, 190 insertions(+), 192 deletions(-) create mode 100644 html/changelogs/phil235-VaporizeMethodReaction.yml diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index eeada126134..440967945ab 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -94,12 +94,12 @@ var/turf/location = get_turf(src) // Create the reagents to put into the air - create_reagents(5) + create_reagents(10) if(overmind && overmind.blob_reagent_datum) - reagents.add_reagent(overmind.blob_reagent_datum.id, 5) + reagents.add_reagent(overmind.blob_reagent_datum.id, 10) else - reagents.add_reagent("spore", 5) + reagents.add_reagent("spore", 10) // Attach the smoke spreader and setup/start it. S.attach(location) diff --git a/code/game/gamemodes/blob/powers.dm b/code/game/gamemodes/blob/powers.dm index 3f5c17c9649..a0c97c1da99 100644 --- a/code/game/gamemodes/blob/powers.dm +++ b/code/game/gamemodes/blob/powers.dm @@ -157,7 +157,10 @@ last_attack = world.time OB.expand(T, 0, blob_reagent_datum.color) for(var/mob/living/L in T) - blob_reagent_datum.reaction_mob(L, PATCH, 25) + if("blob" in L.faction) //no friendly fire + continue + var/mob_protection = L.get_permeability_protection() + blob_reagent_datum.reaction_mob(L, VAPOR, 25, 1, mob_protection) blob_reagent_datum.send_message(L) OB.color = blob_reagent_datum.color diff --git a/code/modules/reagents/Chemistry-Holder.dm b/code/modules/reagents/Chemistry-Holder.dm index 734b4d6aebf..56a077bbfa0 100644 --- a/code/modules/reagents/Chemistry-Holder.dm +++ b/code/modules/reagents/Chemistry-Holder.dm @@ -2,8 +2,8 @@ var/const/TOUCH = 1 //splashing var/const/INGEST = 2 //injection, ingestion -var/const/VAPOR = 3 //smoke, foam, spray -var/const/PATCH = 4 //patches, blob attack +var/const/VAPOR = 3 //smoke, foam, spray, blob attack +var/const/PATCH = 4 //patches /////////////////////////////////////////////////////////////////////////////////// diff --git a/code/modules/reagents/Chemistry-Readme.dm b/code/modules/reagents/Chemistry-Readme.dm index e0b68c4a597..bd28dcb79f1 100644 --- a/code/modules/reagents/Chemistry-Readme.dm +++ b/code/modules/reagents/Chemistry-Readme.dm @@ -69,7 +69,7 @@ About the Holder: This proc calls the appropriate reaction procs of the reagents. I.e. if A is an object, it will call the reagents reaction_obj proc. The method var is used for reaction on mobs. It simply tells - us if the mob TOUCHed the reagent, if it INGESTed the reagent or if the reagent was VAPORIZEd on them.. + us if the mob TOUCHed the reagent, if it INGESTed the reagent, if the reagent was VAPORIZEd on them, or transfered via a PATCH to them.. Since the volume can be checked in a reagents proc, you might want to use the volume_modifier var to modifiy the passed value without actually changing the volume of the reagents. diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 61290e5d22f..7a58c099077 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -28,13 +28,13 @@ var/overdose_threshold = 0 var/addiction_threshold = 0 var/addiction_stage = 0 - var/overdosed = 0 // You fucked up and this is now triggering it's overdose effects, purge that shit quick. + var/overdosed = 0 // You fucked up and this is now triggering its overdose effects, purge that shit quick. /datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references ..() holder = null -/datum/reagent/proc/reaction_mob(mob/living/M, method=TOUCH, volume, show_message = 1, touch_protection = 0) +/datum/reagent/proc/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0) if(!istype(M)) return 0 var/datum/reagent/self = src diff --git a/code/modules/reagents/Chemistry-Reagents/Blob-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Blob-Reagents.dm index a47cc5e02e3..6265d0cb858 100644 --- a/code/modules/reagents/Chemistry-Reagents/Blob-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Blob-Reagents.dm @@ -4,6 +4,9 @@ var/message = "The blob strikes you" //message sent to any mob hit by the blob var/message_living = null //extension to first mob sent to only living mobs i.e. silicons have no skin to be burnt +/datum/reagent/blob/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message, touch_protection) + return round(reac_volume * min(1.5 - touch_protection, 1), 0.1) //full touch protection means 50% volume, any prot below 0.5 means 100% volume. + /datum/reagent/blob/boiling_oil name = "Boiling Oil" id = "boiling_oil" @@ -11,14 +14,13 @@ color = "#B68D00" message = "The blob splashes you with burning oil" -/datum/reagent/blob/boiling_oil/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == PATCH) - var/ratio = volume/25 - M.apply_damage(15*ratio, BURN) - M.adjust_fire_stacks(2*ratio) - M.IgniteMob() - if(isliving(M)) - M.emote("scream") +/datum/reagent/blob/boiling_oil/reaction_mob(mob/living/M, method=TOUCH, reac_volume) + M.adjust_fire_stacks(round(reac_volume/12)) + reac_volume = ..() + M.apply_damage(0.6*reac_volume, BURN) + M.IgniteMob() + if(iscarbon(M)) + M.emote("scream") /datum/reagent/blob/toxic_goop name = "Toxic Goop" @@ -27,10 +29,9 @@ color = "#008000" message_living = ", and you feel sick and nauseated" -/datum/reagent/blob/toxic_goop/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == PATCH) - var/ratio = volume/25 - M.apply_damage(20*ratio, TOX) +/datum/reagent/blob/toxic_goop/reaction_mob(mob/living/M, method=TOUCH, reac_volume) + reac_volume = ..() + M.apply_damage(0.8*reac_volume, TOX) /datum/reagent/blob/skin_ripper name = "Skin Ripper" @@ -39,12 +40,11 @@ color = "#FF4C4C" message_living = ", and you feel your skin ripping and tearing off" -/datum/reagent/blob/skin_ripper/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == PATCH) - var/ratio = volume/25 - M.apply_damage(20*ratio, BRUTE) - if(iscarbon(M)) - M.emote("scream") +/datum/reagent/blob/skin_ripper/reaction_mob(mob/living/M, method=TOUCH, reac_volume) + reac_volume = ..() + M.apply_damage(0.8*reac_volume, BRUTE) + if(iscarbon(M)) + M.emote("scream") // Combo Reagents @@ -55,15 +55,14 @@ color = "#7F0000" message_living = ", and you feel your skin char and melt" -/datum/reagent/blob/skin_melter/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == PATCH) - var/ratio = volume/25 - M.apply_damage(10*ratio, BRUTE) - M.apply_damage(10*ratio, BURN) - M.adjust_fire_stacks(2*ratio) - M.IgniteMob() - if(iscarbon(M)) - M.emote("scream") +/datum/reagent/blob/skin_melter/reaction_mob(mob/living/M, method=TOUCH, reac_volume) + M.adjust_fire_stacks(round(reac_volume/12)) + reac_volume = ..() + M.apply_damage(0.4*reac_volume, BRUTE) + M.apply_damage(0.4*reac_volume, BURN) + M.IgniteMob() + if(iscarbon(M)) + M.emote("scream") /datum/reagent/blob/lung_destroying_toxin name = "Lung Destroying Toxin" @@ -72,12 +71,11 @@ color = "#00FFC5" message_living = ", and your lungs feel heavy and weak" -/datum/reagent/blob/lung_destroying_toxin/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == PATCH) - var/ratio = volume/25 - M.apply_damage(20* ratio, OXY) - M.losebreath += 15*ratio - M.apply_damage(20*ratio, TOX) +/datum/reagent/blob/lung_destroying_toxin/reaction_mob(mob/living/M, method=TOUCH, reac_volume) + reac_volume = ..() + M.apply_damage(0.8* reac_volume, OXY) + M.losebreath += round(0.6*reac_volume) + M.apply_damage(0.8*reac_volume, TOX) // Special Reagents @@ -88,18 +86,17 @@ color = "#00EE00" message_living = ", and your skin feels papery and everything hurts" -/datum/reagent/blob/radioactive_liquid/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == PATCH) - var/ratio = volume/25 - M.apply_damage(10*ratio, BRUTE) - if(istype(M, /mob/living/carbon/human)) - M.irradiate(40*ratio) - if(prob(33*ratio)) - randmuti(M) - if(prob(98)) - randmutb(M) - domutcheck(M, null) - updateappearance(M) +/datum/reagent/blob/radioactive_liquid/reaction_mob(mob/living/M, method=TOUCH, reac_volume) + reac_volume = ..() + M.apply_damage(0.4*reac_volume, BRUTE) + if(ishuman(M)) + M.irradiate(1.6*reac_volume) + if(prob(1.3*reac_volume)) + randmuti(M) + if(prob(98)) + randmutb(M) + domutcheck(M, null) + updateappearance(M) /datum/reagent/blob/dark_matter name = "Dark Matter" @@ -108,12 +105,10 @@ color = "#61407E" message = "You feel a thrum as the blob strikes you, and everything flies at you" -/datum/reagent/blob/dark_matter/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == PATCH) - var/ratio = volume/25 - M.apply_damage(15*ratio, BRUTE) - reagent_vortex(M, 0) - +/datum/reagent/blob/dark_matter/reaction_mob(mob/living/M, method=TOUCH, reac_volume) + reagent_vortex(M, 0, reac_volume) + reac_volume = ..() + M.apply_damage(0.6*reac_volume, BRUTE) /datum/reagent/blob/b_sorium name = "Sorium" @@ -122,12 +117,10 @@ color = "#808000" message = "The blob slams into you, and sends you flying" -/datum/reagent/blob/b_sorium/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == PATCH) - var/ratio = volume/25 - M.apply_damage(15*ratio, BRUTE) - reagent_vortex(M, 1) - +/datum/reagent/blob/b_sorium/reaction_mob(mob/living/M, method=TOUCH, reac_volume) + reagent_vortex(M, 1, reac_volume) + reac_volume = ..() + M.apply_damage(0.6*reac_volume, BRUTE) /datum/reagent/blob/explosive // I'm gonna burn in hell for this one name = "Explosive Gelatin" @@ -136,11 +129,9 @@ color = "#FFA500" message = "The blob strikes you, and its tendrils explode" -/datum/reagent/blob/explosive/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == PATCH) - var/ratio = volume/25 - if(prob(75*ratio)) - explosion(M.loc, 0, 0, 1, 0, 0) +/datum/reagent/blob/explosive/reaction_mob(mob/living/M, method=TOUCH, reac_volume) + if(prob(3*reac_volume)) + explosion(M.loc, 0, 0, 1, 0, 0) /datum/reagent/blob/omnizine name = "Omnizine" @@ -150,10 +141,9 @@ message = "The blob squirts something at you" message_living = ", and you feel great" -/datum/reagent/blob/omnizine/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == PATCH) - var/ratio = volume/25 - M.reagents.add_reagent("omnizine", 11*ratio) +/datum/reagent/blob/omnizine/reaction_mob(mob/living/M, method=TOUCH, reac_volume) + reac_volume = ..() + M.reagents.add_reagent("omnizine", 0.6*reac_volume) /datum/reagent/blob/spacedrugs name = "Space drugs" @@ -163,17 +153,16 @@ message = "The blob squirts something at you" message_living = ", and you feel funny" -/datum/reagent/blob/spacedrugs/reaction_mob(mob/living/M, method=TOUCH, volume) - if(method == PATCH) - var/ratio = volume/25 - M.hallucination += 20*ratio - M.reagents.add_reagent("space_drugs", 15*ratio) - M.apply_damage(10*ratio, TOX) +/datum/reagent/blob/spacedrugs/reaction_mob(mob/living/M, method=TOUCH, reac_volume) + reac_volume = ..() + M.hallucination += 0.8*reac_volume + M.reagents.add_reagent("space_drugs", 0.6*reac_volume) + M.apply_damage(0.4*reac_volume, TOX) -/datum/reagent/blob/proc/reagent_vortex(mob/living/M, setting_type) +/datum/reagent/blob/proc/reagent_vortex(mob/living/M, setting_type, reac_volume) var/turf/pull = get_turf(M) - var/range_power = Clamp(round(volume/5, 1), 1, 5) + var/range_power = Clamp(round(reac_volume/5, 1), 1, 5) for(var/atom/movable/X in range(range_power,pull)) if(istype(X, /obj/effect)) continue diff --git a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Alcohols.dm b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Alcohols.dm index c3d04b713e0..04eae9fb1b1 100644 --- a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Alcohols.dm +++ b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Drink-Reagents/Alcohols.dm @@ -34,13 +34,13 @@ M.adjustToxLoss(2) ..() return -/datum/reagent/consumable/ethanol/reaction_obj(obj/O, volume) +/datum/reagent/consumable/ethanol/reaction_obj(obj/O, reac_volume) if(istype(O,/obj/item/weapon/paper)) var/obj/item/weapon/paper/paperaffected = O paperaffected.clearpaper() usr << "The solution melts away the ink on the paper." if(istype(O,/obj/item/weapon/book)) - if(volume >= 5) + if(reac_volume >= 5) var/obj/item/weapon/book/affectedbook = O affectedbook.dat = null usr << "The solution melts away the ink on the book." @@ -48,11 +48,11 @@ usr << "It wasn't enough..." return -/datum/reagent/consumable/ethanol/reaction_mob(mob/living/M, method=TOUCH, volume)//Splashing people with ethanol isn't quite as good as fuel. +/datum/reagent/consumable/ethanol/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with ethanol isn't quite as good as fuel. if(!istype(M, /mob/living)) return if(method == TOUCH || method == VAPOR) - M.adjust_fire_stacks(volume / 15) + M.adjust_fire_stacks(reac_volume / 15) ..() /datum/reagent/consumable/ethanol/beer diff --git a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm index f16ed8685fc..2b4630b4416 100644 --- a/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Consumable-Reagents/Food-Reagents.dm @@ -150,8 +150,8 @@ ..() return -/datum/reagent/consumable/frostoil/reaction_turf(turf/simulated/T, volume) - if(volume >= 5) +/datum/reagent/consumable/frostoil/reaction_turf(turf/simulated/T, reac_volume) + if(reac_volume >= 5) for(var/mob/living/simple_animal/slime/M in T) M.adjustToxLoss(rand(15,30)) //if(istype(T)) @@ -163,7 +163,7 @@ description = "A chemical agent used for self-defense and in police work." color = "#B31008" // rgb: 179, 16, 8 -/datum/reagent/consumable/condensedcapsaicin/reaction_mob(mob/living/M, method=TOUCH, volume) +/datum/reagent/consumable/condensedcapsaicin/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(!istype(M, /mob/living/carbon/human) && !istype(M, /mob/living/carbon/monkey)) return @@ -321,11 +321,11 @@ nutriment_factor = 20 * REAGENTS_METABOLISM color = "#302000" // rgb: 48, 32, 0 -/datum/reagent/consumable/cornoil/reaction_turf(turf/simulated/T, volume) +/datum/reagent/consumable/cornoil/reaction_turf(turf/simulated/T, reac_volume) if (!istype(T)) return src = null - if(volume >= 3) + if(reac_volume >= 3) T.MakeSlippery() var/obj/effect/hotspot/hotspot = (locate(/obj/effect/hotspot) in T) if(hotspot) @@ -380,11 +380,11 @@ reagent_state = SOLID color = "#FFFFFF" // rgb: 0, 0, 0 -/datum/reagent/consumable/flour/reaction_turf(turf/T, volume) +/datum/reagent/consumable/flour/reaction_turf(turf/T, reac_volume) src = null if(!istype(T, /turf/space)) var/obj/effect/decal/cleanable/reagentdecal = new/obj/effect/decal/cleanable/flour(T) - reagentdecal.reagents.add_reagent("flour", volume) + reagentdecal.reagents.add_reagent("flour", reac_volume) /datum/reagent/consumable/cherryjelly name = "Cherry Jelly" diff --git a/code/modules/reagents/Chemistry-Reagents/Medicine-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Medicine-Reagents.dm index 46ffc611afc..a8999d8ddac 100644 --- a/code/modules/reagents/Chemistry-Reagents/Medicine-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Medicine-Reagents.dm @@ -163,15 +163,15 @@ reagent_state = LIQUID color = "#C8A5DC" -/datum/reagent/medicine/silver_sulfadiazine/reaction_mob(mob/living/M, method=TOUCH, volume, show_message = 1) +/datum/reagent/medicine/silver_sulfadiazine/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(iscarbon(M) && M.stat != DEAD) if(method == PATCH) - M.adjustFireLoss(-volume) + M.adjustFireLoss(-reac_volume) if(show_message) M << "You feel your burns healing!" M.emote("scream") if(method == INGEST) - M.adjustToxLoss(0.5*volume) + M.adjustToxLoss(0.5*reac_volume) if(show_message) M << "You probably shouldn't have eaten that. Maybe you should of splashed it on, or applied a patch?" ..() @@ -187,15 +187,15 @@ reagent_state = LIQUID color = "#C8A5DC" -/datum/reagent/medicine/styptic_powder/reaction_mob(mob/living/M, method=TOUCH, volume, show_message = 1) +/datum/reagent/medicine/styptic_powder/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(iscarbon(M) && M.stat != DEAD) if(method == PATCH) - M.adjustBruteLoss(-volume) + M.adjustBruteLoss(-reac_volume) if(show_message) M << "You feel your wounds knitting back together!" M.emote("scream") if(method == INGEST) - M.adjustToxLoss(0.5*volume) + M.adjustToxLoss(0.5*reac_volume) if(show_message) M << "You feel kind of ill. Maybe you ate a medicine you shouldn't have?" ..() @@ -235,7 +235,7 @@ M.adjustFireLoss(-0.25*REM) ..() -/datum/reagent/medicine/mine_salve/reaction_mob(mob/living/M, method=TOUCH, volume, show_message = 1) +/datum/reagent/medicine/mine_salve/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(iscarbon(M)) if(method == TOUCH) if(show_message) @@ -261,11 +261,11 @@ reagent_state = LIQUID color = "#C8A5DC" -/datum/reagent/medicine/synthflesh/reaction_mob(mob/living/M, method=TOUCH, volume,show_message = 1) +/datum/reagent/medicine/synthflesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume,show_message = 1) if(iscarbon(M) && M.stat != DEAD) if(method == PATCH) - M.adjustBruteLoss(-1.5*volume) - M.adjustFireLoss(-1.5*volume) + M.adjustBruteLoss(-1.5*reac_volume) + M.adjustFireLoss(-1.5*reac_volume) if(show_message) M << "You feel your burns healing and your flesh knitting together!" ..() @@ -653,7 +653,7 @@ color = "#C8A5DC" metabolization_rate = 0.5 * REAGENTS_METABOLISM -/datum/reagent/medicine/strange_reagent/reaction_mob(mob/living/carbon/human/M, method=TOUCH, volume) +/datum/reagent/medicine/strange_reagent/reaction_mob(mob/living/carbon/human/M, method=TOUCH, reac_volume) if(M.stat == DEAD) if(M.getBruteLoss() >= 100 || M.getFireLoss() >= 100) M.visible_message("[M]'s body convulses a bit, and then falls still once more.") diff --git a/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm index eb6522fc5b7..76ce0b07ebe 100644 --- a/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Other-Reagents.dm @@ -5,7 +5,7 @@ id = "blood" color = "#C80000" // rgb: 200, 0, 0 -/datum/reagent/blood/reaction_mob(mob/M, method=TOUCH, volume) +/datum/reagent/blood/reaction_mob(mob/M, method=TOUCH, reac_volume) var/datum/reagent/blood/self = src src = null if(self.data && self.data["viruses"]) @@ -48,11 +48,13 @@ src.data["viruses"] = preserve return 1 -/datum/reagent/blood/reaction_turf(turf/simulated/T, volume)//splash the blood all over the place - if(!istype(T)) return +/datum/reagent/blood/reaction_turf(turf/simulated/T, reac_volume)//splash the blood all over the place + if(!istype(T)) + return var/datum/reagent/blood/self = src src = null - if(!(volume >= 3)) return + if(reac_volume < 3) + return //var/datum/disease/D = self.data["virus"] if(!self.data["donor"] || istype(self.data["donor"], /mob/living/carbon/human)) var/obj/effect/decal/cleanable/blood/blood_prop = locate() in T //find some blood here @@ -93,7 +95,7 @@ id = "vaccine" color = "#C81040" // rgb: 200, 16, 64 -/datum/reagent/vaccine/reaction_mob(mob/M, method=TOUCH, volume) +/datum/reagent/vaccine/reaction_mob(mob/M, method=TOUCH, reac_volume) var/datum/reagent/vaccine/self = src src = null if(islist(self.data) && method == INGEST) @@ -117,11 +119,11 @@ * Water reaction to turf */ -/datum/reagent/water/reaction_turf(turf/simulated/T, volume) +/datum/reagent/water/reaction_turf(turf/simulated/T, reac_volume) if (!istype(T)) return var/CT = cooling_temperature src = null - if(volume >= 10) + if(reac_volume >= 10) T.MakeSlippery() for(var/mob/living/simple_animal/slime/M in T) @@ -140,7 +142,7 @@ * Water reaction to an object */ -/datum/reagent/water/reaction_obj(obj/O, volume) +/datum/reagent/water/reaction_obj(obj/O, reac_volume) src = null if(istype(O,/obj/item)) @@ -164,11 +166,11 @@ * Water reaction to a mob */ -/datum/reagent/water/reaction_mob(mob/living/M, method=TOUCH, volume)//Splashing people with water can help put them out! +/datum/reagent/water/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with water can help put them out! if(!istype(M, /mob/living)) return if(method == TOUCH) - M.adjust_fire_stacks(-(volume / 10)) + M.adjust_fire_stacks(-(reac_volume / 10)) ..() /datum/reagent/water/holywater @@ -199,10 +201,10 @@ holder.remove_reagent(src.id, 0.4) //fixed consumption to prevent balancing going out of whack return -/datum/reagent/water/holywater/reaction_turf(turf/simulated/T, volume) +/datum/reagent/water/holywater/reaction_turf(turf/simulated/T, reac_volume) ..() if(!istype(T)) return - if(volume>=10) + if(reac_volume>=10) for(var/obj/effect/rune/R in T) qdel(R) T.Bless() @@ -246,10 +248,10 @@ description = "Lubricant is a substance introduced between two moving surfaces to reduce the friction and wear between them. giggity." color = "#009CA8" // rgb: 0, 156, 168 -/datum/reagent/lube/reaction_turf(turf/simulated/T, volume) +/datum/reagent/lube/reaction_turf(turf/simulated/T, reac_volume) if (!istype(T)) return src = null - if(volume >= 1) + if(reac_volume >= 1) T.MakeSlippery(2) /datum/reagent/spraytan @@ -260,7 +262,7 @@ metabolization_rate = 10 * REAGENTS_METABOLISM // very fast, so it can be applied rapidly. But this changes on an overdose overdose_threshold = 11 //Slightly more than one un-nozzled spraybottle. -/datum/reagent/spraytan/reaction_mob(mob/living/M, method=TOUCH, volume, show_message = 1) +/datum/reagent/spraytan/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(istype(M, /mob/living/carbon/human)) if(method == PATCH || method == VAPOR) var/mob/living/carbon/human/N = M @@ -381,7 +383,7 @@ description = "An advanced corruptive toxin produced by slimes." color = "#13BC5E" // rgb: 19, 188, 94 -/datum/reagent/aslimetoxin/reaction_mob(mob/M, method=TOUCH, volume) +/datum/reagent/aslimetoxin/reaction_mob(mob/M, method=TOUCH, reac_volume) src = null if(method != TOUCH) M.ForceContractDisease(new /datum/disease/transformation/slime(0)) @@ -463,7 +465,7 @@ reagent_state = SOLID color = "#1C1300" // rgb: 30, 20, 0 -/datum/reagent/carbon/reaction_turf(turf/T, volume) +/datum/reagent/carbon/reaction_turf(turf/T, reac_volume) src = null if(!istype(T, /turf/space)) new /obj/effect/decal/cleanable/dirt(T) @@ -539,12 +541,12 @@ ..() return -/datum/reagent/radium/reaction_turf(turf/T, volume) +/datum/reagent/radium/reaction_turf(turf/T, reac_volume) src = null - if(volume >= 3) + if(reac_volume >= 3) if(!istype(T, /turf/space)) var/obj/effect/decal/cleanable/reagentdecal = new/obj/effect/decal/cleanable/greenglow(T) - reagentdecal.reagents.add_reagent("radium", volume) + reagentdecal.reagents.add_reagent("radium", reac_volume) /datum/reagent/sterilizine name = "Sterilizine" @@ -584,12 +586,12 @@ M.apply_effect(1/M.metabolism_efficiency,IRRADIATE,0) ..() -/datum/reagent/uranium/reaction_turf(turf/T, volume) +/datum/reagent/uranium/reaction_turf(turf/T, reac_volume) src = null - if(volume >= 3) + if(reac_volume >= 3) if(!istype(T, /turf/space)) var/obj/effect/decal/cleanable/reagentdecal = new/obj/effect/decal/cleanable/greenglow(T) - reagentdecal.reagents.add_reagent("uranium", volume) + reagentdecal.reagents.add_reagent("uranium", reac_volume) /datum/reagent/aluminium name = "Aluminium" @@ -611,11 +613,11 @@ description = "Required for welders. Flamable." color = "#660000" // rgb: 102, 0, 0 -/datum/reagent/fuel/reaction_mob(mob/living/M, method=TOUCH, volume)//Splashing people with welding fuel to make them easy to ignite! +/datum/reagent/fuel/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with welding fuel to make them easy to ignite! if(!istype(M, /mob/living)) return if(method == TOUCH || method == VAPOR) - M.adjust_fire_stacks(volume / 10) + M.adjust_fire_stacks(reac_volume / 10) return ..() @@ -629,15 +631,15 @@ description = "A compound used to clean things. Now with 50% more sodium hypochlorite!" color = "#A5F0EE" // rgb: 165, 240, 238 -/datum/reagent/space_cleaner/reaction_obj(obj/O, volume) +/datum/reagent/space_cleaner/reaction_obj(obj/O, reac_volume) if(istype(O,/obj/effect/decal/cleanable)) qdel(O) else if(O) O.clean_blood() -/datum/reagent/space_cleaner/reaction_turf(turf/T, volume) - if(volume >= 1) +/datum/reagent/space_cleaner/reaction_turf(turf/T, reac_volume) + if(reac_volume >= 1) T.clean_blood() for(var/obj/effect/decal/cleanable/C in T) qdel(C) @@ -646,10 +648,10 @@ M.adjustToxLoss(rand(5,10)) if(istype(T, /turf/simulated/floor)) var/turf/simulated/floor/F = T - if(volume >= 1) + if(reac_volume >= 1) F.dirt = 0 -/datum/reagent/space_cleaner/reaction_mob(mob/M, method=TOUCH, volume) +/datum/reagent/space_cleaner/reaction_mob(mob/M, method=TOUCH, reac_volume) if(method == TOUCH || VAPOR) if(iscarbon(M)) var/mob/living/carbon/C = M @@ -716,9 +718,9 @@ description = "Microscopic construction robots." color = "#535E66" // rgb: 83, 94, 102 -/datum/reagent/nanites/reaction_mob(mob/M, method=TOUCH, volume, show_message = 1, touch_protection = 0) +/datum/reagent/nanites/reaction_mob(mob/M, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0) src = null - if(method==PATCH || method==INGEST || (method == VAPOR && prob(min(volume,100)*(1 - touch_protection)))) + if(method==PATCH || method==INGEST || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection)))) M.ForceContractDisease(new /datum/disease/transformation/robot(0)) /datum/reagent/xenomicrobes @@ -727,9 +729,9 @@ description = "Microbes with an entirely alien cellular structure." color = "#535E66" // rgb: 83, 94, 102 -/datum/reagent/xenomicrobes/reaction_mob(mob/M, method=TOUCH, volume, show_message = 1, touch_protection = 0) +/datum/reagent/xenomicrobes/reaction_mob(mob/M, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0) src = null - if(method==PATCH || method==INGEST || (method == VAPOR && prob(min(volume,100)*(1 - touch_protection)))) + if(method==PATCH || method==INGEST || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection)))) M.ContractDisease(new /datum/disease/transformation/xeno(0)) /datum/reagent/fluorosurfactant//foam precursor @@ -908,7 +910,7 @@ reagent_state = LIQUID color = "#C8A5DC" -/datum/reagent/carpet/reaction_turf(turf/simulated/T, volume) +/datum/reagent/carpet/reaction_turf(turf/simulated/T, reac_volume) if(istype(T, /turf/simulated/floor/plating) || istype(T, /turf/simulated/floor/plasteel)) var/turf/simulated/floor/F = T F.ChangeTurf(/turf/simulated/floor/carpet) @@ -958,17 +960,17 @@ ..() return -/datum/reagent/colorful_reagent/reaction_mob(mob/living/M, volume) +/datum/reagent/colorful_reagent/reaction_mob(mob/living/M, reac_volume) if(M && isliving(M)) M.color = pick(random_color_list) ..() -/datum/reagent/colorful_reagent/reaction_obj(obj/O, volume) +/datum/reagent/colorful_reagent/reaction_obj(obj/O, reac_volume) if(O) O.color = pick(random_color_list) ..() -/datum/reagent/colorful_reagent/reaction_turf(turf/T, volume) +/datum/reagent/colorful_reagent/reaction_turf(turf/T, reac_volume) if(T) T.color = pick(random_color_list) ..() @@ -981,7 +983,7 @@ color = "#C8A5DC" var/list/potential_colors = list("0ad","a0f","f73","d14","d14","0b5","0ad","f73","fc2","084","05e","d22","fa0") // fucking hair code -/datum/reagent/hair_dye/reaction_mob(mob/living/M, method=TOUCH, volume) +/datum/reagent/hair_dye/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(method == TOUCH || method == VAPOR) if(M && ishuman(M)) var/mob/living/carbon/human/H = M @@ -996,7 +998,7 @@ reagent_state = LIQUID color = "#C8A5DC" -/datum/reagent/barbers_aid/reaction_mob(mob/living/M, method=TOUCH, volume) +/datum/reagent/barbers_aid/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(method == TOUCH || method == VAPOR) if(M && ishuman(M)) var/mob/living/carbon/human/H = M @@ -1013,7 +1015,7 @@ reagent_state = LIQUID color = "#C8A5DC" -/datum/reagent/concentrated_barbers_aid/reaction_mob(mob/living/M, method=TOUCH, volume) +/datum/reagent/concentrated_barbers_aid/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(method == TOUCH || method == VAPOR) if(M && ishuman(M)) var/mob/living/carbon/human/H = M diff --git a/code/modules/reagents/Chemistry-Reagents/Pyrotechnic-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Pyrotechnic-Reagents.dm index bf143c5d93b..c56242773f6 100644 --- a/code/modules/reagents/Chemistry-Reagents/Pyrotechnic-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Pyrotechnic-Reagents.dm @@ -6,14 +6,14 @@ reagent_state = SOLID color = "#673910" // rgb: 103, 57, 16 -/datum/reagent/thermite/reaction_turf(turf/T, volume) +/datum/reagent/thermite/reaction_turf(turf/T, reac_volume) src = null - if(volume >= 1 && istype(T, /turf/simulated/wall)) + if(reac_volume >= 1 && istype(T, /turf/simulated/wall)) var/turf/simulated/wall/Wall = T if(istype(Wall, /turf/simulated/wall/r_wall)) - Wall.thermite = Wall.thermite+(volume*2.5) + Wall.thermite = Wall.thermite+(reac_volume*2.5) else - Wall.thermite = Wall.thermite+(volume*10) + Wall.thermite = Wall.thermite+(reac_volume*10) Wall.overlays = list() Wall.overlays += image('icons/effects/effects.dmi',"thermite") @@ -48,28 +48,28 @@ M.adjustFireLoss(burndmg) ..() -/datum/reagent/clf3/reaction_turf(turf/simulated/T, volume) +/datum/reagent/clf3/reaction_turf(turf/simulated/T, reac_volume) if(istype(T, /turf/simulated/floor/plating)) var/turf/simulated/floor/plating/F = T if(prob(1 + F.burnt + 5*F.broken)) //broken or burnt plating is more susceptible to being destroyed F.ChangeTurf(F.baseturf) if(istype(T, /turf/simulated/floor/)) var/turf/simulated/floor/F = T - if(prob(volume/10)) + if(prob(reac_volume/10)) F.make_plating() - else if(prob(volume)) + else if(prob(reac_volume)) F.burn_tile() if(istype(F, /turf/simulated/floor/)) PoolOrNew(/obj/effect/hotspot, F) if(istype(T, /turf/simulated/wall/)) var/turf/simulated/wall/W = T - if(prob(volume/10)) + if(prob(reac_volume/10)) W.ChangeTurf(/turf/simulated/floor/plating) -/datum/reagent/clf3/reaction_mob(mob/living/M, method=TOUCH, volume) +/datum/reagent/clf3/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(istype(M)) if(method != INGEST) - M.adjust_fire_stacks(min(volume/5, 10)) + M.adjust_fire_stacks(min(reac_volume/5, 10)) M.IgniteMob() PoolOrNew(/obj/effect/hotspot, M.loc) @@ -129,8 +129,8 @@ description = "Catches you on fire and makes you ignite." reagent_state = LIQUID color = "#FF9999" - -/datum/reagent/phlogiston/reaction_mob(mob/living/M, method=TOUCH, volume) + +/datum/reagent/phlogiston/reaction_mob(mob/living/M, method=TOUCH, reac_volume) M.IgniteMob() ..() @@ -151,10 +151,10 @@ M.adjust_fire_stacks(1) ..() -/datum/reagent/napalm/reaction_mob(mob/living/M, method=TOUCH, volume) +/datum/reagent/napalm/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(istype(M)) if(method != INGEST) - M.adjust_fire_stacks(min(volume/4, 20)) + M.adjust_fire_stacks(min(reac_volume/4, 20)) /datum/reagent/cryostylane name = "Cryostylane" @@ -177,8 +177,8 @@ holder.handle_reactions() ..() -/datum/reagent/cryostylane/reaction_turf(turf/simulated/T, volume) - if(volume >= 5) +/datum/reagent/cryostylane/reaction_turf(turf/simulated/T, reac_volume) + if(reac_volume >= 5) for(var/mob/living/simple_animal/slime/M in T) M.adjustToxLoss(rand(15,30)) diff --git a/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm b/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm index 12b0e37ef09..e13de807739 100644 --- a/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents/Toxin-Reagents.dm @@ -28,13 +28,13 @@ color = "#13BC5E" // rgb: 19, 188, 94 toxpwr = 0 -/datum/reagent/toxin/mutagen/reaction_mob(mob/living/carbon/M, method=TOUCH, volume) +/datum/reagent/toxin/mutagen/reaction_mob(mob/living/carbon/M, method=TOUCH, reac_volume) if(!..()) return if(!istype(M) || !M.dna) return //No robots, AIs, aliens, Ians or other mobs should be affected by this. src = null - if((method==VAPOR && prob(min(33, volume))) || method==INGEST || method == PATCH) + if((method==VAPOR && prob(min(33, reac_volume))) || method==INGEST || method == PATCH) randmuti(M) if(prob(98)) randmutb(M) @@ -65,26 +65,22 @@ ..() return -/datum/reagent/toxin/plasma/reaction_obj(obj/O, volume) +/datum/reagent/toxin/plasma/reaction_obj(obj/O, reac_volume) src = null - /*if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/egg/slime)) - var/obj/item/weapon/reagent_containers/food/snacks/egg/slime/egg = O - if (egg.grown) - egg.Hatch()*/ - if((!O) || (!volume)) return 0 - O.atmos_spawn_air(SPAWN_TOXINS|SPAWN_20C, volume) + if((!O) || (!reac_volume)) return 0 + O.atmos_spawn_air(SPAWN_TOXINS|SPAWN_20C, reac_volume) -/datum/reagent/toxin/plasma/reaction_turf(turf/simulated/T, volume) +/datum/reagent/toxin/plasma/reaction_turf(turf/simulated/T, reac_volume) src = null if(istype(T)) - T.atmos_spawn_air(SPAWN_TOXINS|SPAWN_20C, volume) + T.atmos_spawn_air(SPAWN_TOXINS|SPAWN_20C, reac_volume) return -/datum/reagent/toxin/plasma/reaction_mob(mob/living/M, method=TOUCH, volume)//Splashing people with plasma is stronger than fuel! +/datum/reagent/toxin/plasma/reaction_mob(mob/living/M, method=TOUCH, reac_volume)//Splashing people with plasma is stronger than fuel! if(!istype(M, /mob/living)) return if(method == TOUCH || method == VAPOR) - M.adjust_fire_stacks(volume / 5) + M.adjust_fire_stacks(reac_volume / 5) return ..() @@ -181,7 +177,7 @@ color = "#49002E" // rgb: 73, 0, 46 toxpwr = 1 -/datum/reagent/toxin/plantbgone/reaction_obj(obj/O, volume) +/datum/reagent/toxin/plantbgone/reaction_obj(obj/O, reac_volume) if(istype(O,/obj/structure/alien/weeds/)) var/obj/structure/alien/weeds/alien_weeds = O alien_weeds.health -= rand(15,35) // Kills alien weeds pretty fast @@ -192,13 +188,13 @@ var/obj/effect/spacevine/SV = O SV.on_chem_effect(src) -/datum/reagent/toxin/plantbgone/reaction_mob(mob/living/M, method=TOUCH, volume) +/datum/reagent/toxin/plantbgone/reaction_mob(mob/living/M, method=TOUCH, reac_volume) src = null if(method == VAPOR) if(iscarbon(M)) var/mob/living/carbon/C = M if(!C.wear_mask) // If not wearing a mask - var/damage = min(round(0.4*volume, 0.1),10) + var/damage = min(round(0.4*reac_volume, 0.1),10) C.adjustToxLoss(damage) /datum/reagent/toxin/plantbgone/weedkiller @@ -215,13 +211,13 @@ color = "#4B004B" // rgb: 75, 0, 75 toxpwr = 1 -/datum/reagent/toxin/pestkiller/reaction_mob(mob/living/M, method=TOUCH, volume) +/datum/reagent/toxin/pestkiller/reaction_mob(mob/living/M, method=TOUCH, reac_volume) src = null if(method == VAPOR) if(iscarbon(M)) var/mob/living/carbon/C = M if(!C.wear_mask) // If not wearing a mask - var/damage = min(round(0.4*volume, 0.1),10) + var/damage = min(round(0.4*reac_volume, 0.1),10) C.adjustToxLoss(damage) /datum/reagent/toxin/spore @@ -459,9 +455,9 @@ metabolization_rate = 0.4 * REAGENTS_METABOLISM toxpwr = 0 -/datum/reagent/toxin/itching_powder/reaction_mob(mob/living/M, method=TOUCH, volume) +/datum/reagent/toxin/itching_powder/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(method != INGEST) - M.reagents.add_reagent("itching_powder", volume) + M.reagents.add_reagent("itching_powder", reac_volume) /datum/reagent/toxin/itching_powder/on_mob_life(mob/living/M) if(prob(15)) @@ -625,28 +621,28 @@ toxpwr = 1 var/acidpwr = 10 //the amount of protection removed from the armour -/datum/reagent/toxin/acid/reaction_mob(mob/living/carbon/C, method=TOUCH, volume) +/datum/reagent/toxin/acid/reaction_mob(mob/living/carbon/C, method=TOUCH, reac_volume) if(!istype(C)) return - volume = round(volume,0.1) + reac_volume = round(reac_volume,0.1) if(method == INGEST) - C.take_organ_damage(min(6*toxpwr, volume * toxpwr)) + C.take_organ_damage(min(6*toxpwr, reac_volume * toxpwr)) return - C.acid_act(acidpwr, toxpwr, volume) + C.acid_act(acidpwr, toxpwr, reac_volume) -/datum/reagent/toxin/acid/reaction_obj(obj/O, volume) +/datum/reagent/toxin/acid/reaction_obj(obj/O, reac_volume) if(istype(O.loc, /mob)) //handled in human acid_act() return - volume = round(volume,0.1) - O.acid_act(acidpwr, volume) + reac_volume = round(reac_volume,0.1) + O.acid_act(acidpwr, reac_volume) -/datum/reagent/toxin/acid/reaction_turf(turf/T, volume) +/datum/reagent/toxin/acid/reaction_turf(turf/T, reac_volume) if (!istype(T)) return src = null - volume = round(volume,0.1) + reac_volume = round(reac_volume,0.1) for(var/obj/O in T) - O.acid_act(acidpwr, volume) + O.acid_act(acidpwr, reac_volume) /datum/reagent/toxin/acid/fluacid name = "Fluorosulfuric acid" diff --git a/html/changelogs/phil235-VaporizeMethodReaction.yml b/html/changelogs/phil235-VaporizeMethodReaction.yml new file mode 100644 index 00000000000..3f66104303a --- /dev/null +++ b/html/changelogs/phil235-VaporizeMethodReaction.yml @@ -0,0 +1,8 @@ +author: phil235 + +delete-after: True + +changes: + - rscadd: "You can now partially protect yourself from blob attack effects by wearing impermeable clothes like hardsuits, medical clothes, masks, etc. Max protection effect is capped at 50%." + - rscdel: "Splashing someone with chemicals no longer inject those chemicals in their body." + - bugfix: "Fixes splashing acid on items or floor with items not having any effect." From dacf037cda11d16c506116501d2986bd4b3ecbc0 Mon Sep 17 00:00:00 2001 From: phil235 Date: Sat, 15 Aug 2015 23:17:46 +0200 Subject: [PATCH 028/108] Fixes epilepsy mutation leaving you always at super high jitteriness level. The jitteriness goes way down after the epileptic seizure ends (similar to door shocking jitter). --- code/datums/mutations.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm index b517e417d93..348a443bc8b 100644 --- a/code/datums/mutations.dm +++ b/code/datums/mutations.dm @@ -214,10 +214,12 @@ text_gain_indication = "You get a headache." /datum/mutation/human/epilepsy/on_life(mob/living/carbon/human/owner) - if ((prob(1) && owner.paralysis < 1)) + if((prob(1) && owner.paralysis < 1)) owner.visible_message("[owner] starts having a seizure!", "You have a seizure!") owner.Paralyse(10) owner.Jitter(1000) + spawn(90) + owner.jitteriness = 10 /datum/mutation/human/bad_dna From dcee74e9528fd1a741cb20669387f2b19415ed91 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Sat, 15 Aug 2015 21:41:19 -0500 Subject: [PATCH 029/108] Fixed the src.loc stuff --- code/modules/mining/mine_items.dm | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index f8c70412112..e564f744435 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -181,7 +181,7 @@ qdel(src) /obj/item/weapon/survivalcapsule/proc/load() - var/turf/start_turf = src.loc + var/turf/start_turf = get_turf(src.loc) var/turf/cur_turf var/x_size = 5 var/y_size = 5 @@ -194,9 +194,6 @@ room = spawn_room(start_turf, x_size, y_size, walltypes, floor_type, "Emergency Shelter") - start_turf = src.loc - - //Fill it cur_turf = locate(start_turf.x, start_turf.y-2, start_turf.z) new /obj/machinery/door/airlock/glass(cur_turf) From e05a127fd1e9221e21c4a0574e0741541908ec66 Mon Sep 17 00:00:00 2001 From: SconesC Date: Sat, 15 Aug 2015 21:26:10 -0700 Subject: [PATCH 030/108] Updates defib message when >180 damage --- code/game/objects/items/weapons/defib.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 37a582cac7b..25355fcd1a6 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -437,7 +437,7 @@ else if ((tplus > tlimit) || !H.getorgan(/obj/item/organ/internal/heart)) failed = "[defib] buzzes: Resuscitation failed - Heart tissue damage beyond point of no return. Further attempts futile." else if(total_burn >= 180 || total_brute >= 180) - failed = "[defib] buzzes: Resuscitation failed - Severe tissue damage detected." + failed = "[defib] buzzes: Resuscitation failed - Recovery of Patient impossible via defibrillator. Further attempts futile." else if(H.get_ghost() || !H.getorgan(/obj/item/organ/internal/brain)) failed = "[defib] buzzes: Resuscitation failed - No activity in patient's brain. Further attempts may be successful." @@ -480,4 +480,4 @@ update_icon() else user << "You need to target your patient's chest with [src]!" - return \ No newline at end of file + return From d1655e335a447786cc7dd90cf3869ab3d4666005 Mon Sep 17 00:00:00 2001 From: SconesC Date: Sat, 15 Aug 2015 21:27:49 -0700 Subject: [PATCH 031/108] makes it more clear --- code/game/objects/items/weapons/defib.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 25355fcd1a6..0ee75a39e48 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -437,7 +437,7 @@ else if ((tplus > tlimit) || !H.getorgan(/obj/item/organ/internal/heart)) failed = "[defib] buzzes: Resuscitation failed - Heart tissue damage beyond point of no return. Further attempts futile." else if(total_burn >= 180 || total_brute >= 180) - failed = "[defib] buzzes: Resuscitation failed - Recovery of Patient impossible via defibrillator. Further attempts futile." + failed = "[defib] buzzes: Resuscitation failed - Severe tissue damage makes recovery of Patient impossible via defibrillator. Further attempts futile." else if(H.get_ghost() || !H.getorgan(/obj/item/organ/internal/brain)) failed = "[defib] buzzes: Resuscitation failed - No activity in patient's brain. Further attempts may be successful." From c619e290485f1c623c63aedfb330d25080e8b80f Mon Sep 17 00:00:00 2001 From: Robustin Date: Sun, 16 Aug 2015 01:01:12 -0400 Subject: [PATCH 032/108] Reduced light/burn damage to Shadowlings Light damage from 10 to 7. Heat and Burn/Laser damage modifiers from 2x to 1.5x. --- code/game/gamemodes/shadowling/shadowling.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm index 37223bac1d2..acb36b6e0be 100644 --- a/code/game/gamemodes/shadowling/shadowling.dm +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -1,6 +1,6 @@ #define LIGHT_DAM_THRESHOLD 4 #define LIGHT_HEAL_THRESHOLD 2 -#define LIGHT_DAMAGE_TAKEN 10 +#define LIGHT_DAMAGE_TAKEN 7 /* SHADOWLING: A gamemode based on previously-run events @@ -232,8 +232,8 @@ Made by Xhuis id = "shadowling" say_mod = "chitters" specflags = list(NOBREATH,NOBLOOD,RADIMMUNE,NOGUNS) //Can't use guns due to muzzle flash - burnmod = 2 //2x burn damage lel - heatmod = 2 + burnmod = 1.5 //1.5x burn damage, 2x is excessive + heatmod = 1.5 /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 From fece9cf524817fc18f7515663b5f3855a2c64349 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Sun, 16 Aug 2015 10:49:51 -0500 Subject: [PATCH 033/108] I forgot how my own code worked --- code/modules/mining/mine_items.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index e564f744435..33aa5e00687 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -193,7 +193,9 @@ start_turf = locate(start_turf.x -2, start_turf.y - 2, start_turf.z) room = spawn_room(start_turf, x_size, y_size, walltypes, floor_type, "Emergency Shelter") - + + start_turf = get_turf(src.loc) + //Fill it cur_turf = locate(start_turf.x, start_turf.y-2, start_turf.z) new /obj/machinery/door/airlock/glass(cur_turf) From e2e7b3dc384c84873e8095d6eabcd7618af1bf04 Mon Sep 17 00:00:00 2001 From: SconesC Date: Sun, 16 Aug 2015 10:08:08 -0700 Subject: [PATCH 034/108] Why was it capitalized --- code/game/objects/items/weapons/defib.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 0ee75a39e48..7f5e121e441 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -437,7 +437,7 @@ else if ((tplus > tlimit) || !H.getorgan(/obj/item/organ/internal/heart)) failed = "[defib] buzzes: Resuscitation failed - Heart tissue damage beyond point of no return. Further attempts futile." else if(total_burn >= 180 || total_brute >= 180) - failed = "[defib] buzzes: Resuscitation failed - Severe tissue damage makes recovery of Patient impossible via defibrillator. Further attempts futile." + failed = "[defib] buzzes: Resuscitation failed - Severe tissue damage makes recovery of patient impossible via defibrillator. Further attempts futile." else if(H.get_ghost() || !H.getorgan(/obj/item/organ/internal/brain)) failed = "[defib] buzzes: Resuscitation failed - No activity in patient's brain. Further attempts may be successful." From f006f9d918af0e96f02e2735c143a1eec8ba25dd Mon Sep 17 00:00:00 2001 From: Remie Richards Date: Sun, 16 Aug 2015 19:36:44 +0100 Subject: [PATCH 035/108] Fixes some glitches with Orion Trail events, Fixes Orion Trail events not properly choosing from the entire pool of events. --- code/game/machinery/computer/arcade.dm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/code/game/machinery/computer/arcade.dm b/code/game/machinery/computer/arcade.dm index 6adfae84255..223f9024d2b 100644 --- a/code/game/machinery/computer/arcade.dm +++ b/code/game/machinery/computer/arcade.dm @@ -477,7 +477,7 @@ if(lings_aboard) if(event == ORION_TRAIL_LING || prob(55)) event = ORION_TRAIL_LING_ATTACK - event() + event() turns += 1 if(emagged) var/mob/living/carbon/M = usr //for some vars @@ -568,13 +568,13 @@ turns += 1 event = null else if(href_list["useengine"]) //use parts - engine -= 1 + engine = max(0, --engine) event = null else if(href_list["useelec"]) //use parts - electronics -= 1 + electronics = max(0, --electronics) event = null else if(href_list["usehull"]) //use parts - hull -= 1 + hull = max(0, --hull) event = null else if(href_list["wait"]) //wait 3 days food -= ((alive+lings_aboard)*2)*3 @@ -789,7 +789,7 @@ if(ORION_TRAIL_LING) eventdat += "Strange reports warn of changelings infiltrating crews on trips to Orion..." - if(settlers.len <= 1) + if(settlers.len <= 2) eventdat += "
Your crew's chance of reaching Orion is so slim the changelings likely avoided your ship..." eventdat += "

Continue

" eventdat += "

Close

" From dfae1e0b537379b452bde81ca296fdcfabe5e8bb Mon Sep 17 00:00:00 2001 From: Firecage Date: Sun, 16 Aug 2015 23:33:22 +0200 Subject: [PATCH 036/108] Changes a lot of del() to qdel() --- code/LINDA/LINDA_turf_tile.dm | 2 +- code/_onclick/hud/action.dm | 2 +- code/controllers/configuration.dm | 8 +++---- code/controllers/subsystem/radio.dm | 2 +- .../subsystem/server_maintenance.dm | 2 +- code/controllers/subsystem/ticker.dm | 8 +++---- code/datums/ai_laws.dm | 2 +- code/datums/diseases/_disease.dm | 4 ++-- code/datums/diseases/advance/advance.dm | 2 +- code/datums/gas_mixture.dm | 2 +- code/datums/modules.dm | 2 +- code/game/area/areas.dm | 2 +- code/game/atoms.dm | 2 +- code/game/gamemodes/cult/runes.dm | 10 ++++---- code/game/gamemodes/game_mode.dm | 2 +- code/game/gamemodes/wizard/spellbook.dm | 4 ++-- code/game/machinery/computer/medical.dm | 2 +- code/game/machinery/computer/security.dm | 12 +++++----- .../embedded_controller_base.dm | 2 +- code/game/machinery/magnet.dm | 2 +- code/game/machinery/overview.dm | 6 ++--- code/game/machinery/suit_storage_unit.dm | 4 ++-- .../telecomms/computers/logbrowser.dm | 2 +- code/game/mecha/mecha.dm | 6 ++--- code/game/mecha/mecha_construction_paths.dm | 6 ++--- code/game/objects/items/devices/camera_bug.dm | 2 +- code/game/objects/items/holotape.dm | 4 ++-- .../objects/items/weapons/storage/storage.dm | 2 +- .../game/objects/items/weapons/tanks/tanks.dm | 2 +- code/modules/admin/admin_ranks.dm | 2 +- code/modules/admin/verbs/SDQL2/SDQL_2.dm | 2 +- .../awaymissions/maploader/swapmaps.dm | 24 +++++++++---------- code/modules/crafting/guncrafting.dm | 8 +++---- code/modules/flufftext/Hallucination.dm | 4 ++-- code/modules/hydroponics/hydroponics.dm | 2 +- code/modules/hydroponics/seed_extractor.dm | 2 +- code/modules/mob/camera/camera.dm | 2 +- code/modules/mob/living/carbon/human/blood.dm | 2 +- code/modules/mob/living/silicon/ai/ai.dm | 4 ++-- code/modules/mob/living/simple_animal/worm.dm | 8 +++---- code/modules/mob/login.dm | 2 +- code/modules/power/apc.dm | 2 +- code/modules/projectiles/firing.dm | 2 +- code/modules/projectiles/projectile/magic.dm | 2 +- code/modules/research/rdconsole.dm | 6 ++--- 45 files changed, 91 insertions(+), 91 deletions(-) diff --git a/code/LINDA/LINDA_turf_tile.dm b/code/LINDA/LINDA_turf_tile.dm index f3929467d2a..25a35b48cfd 100644 --- a/code/LINDA/LINDA_turf_tile.dm +++ b/code/LINDA/LINDA_turf_tile.dm @@ -8,7 +8,7 @@ var/atmos_supeconductivity = 0 /turf/assume_air(datum/gas_mixture/giver) //use this for machines to adjust air - del(giver) + qdel(giver) return 0 /turf/return_air() diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/action.dm index 3f005c58c0f..a017a7a9022 100644 --- a/code/_onclick/hud/action.dm +++ b/code/_onclick/hud/action.dm @@ -45,7 +45,7 @@ if(button) if(T.client) T.client.screen -= button - del(button) + qdel(button) T.actions.Remove(src) T.update_action_buttons() owner = null diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index c8670e39a3d..d97c62f43b1 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -178,7 +178,7 @@ probabilities[M.config_tag] = M.probability if(M.votable) votable_modes += M.config_tag - del(M) + qdel(M) votable_modes += "secret" /datum/configuration/proc/load(filename, type = "config") //the type can also be game_options, in which case it uses a different switch. not making it separate to not copypaste code - Urist @@ -567,7 +567,7 @@ var/datum/game_mode/M = new T() if(M.config_tag && M.config_tag == mode_name) return M - del(M) + qdel(M) return new /datum/game_mode/extended() /datum/configuration/proc/get_runnable_modes() @@ -576,10 +576,10 @@ var/datum/game_mode/M = new T() //world << "DEBUG: [T], tag=[M.config_tag], prob=[probabilities[M.config_tag]]" if(!(M.config_tag in modes)) - del(M) + qdel(M) continue if(probabilities[M.config_tag]<=0) - del(M) + qdel(M) continue if(M.can_start()) runnable_modes[M] = probabilities[M.config_tag] diff --git a/code/controllers/subsystem/radio.dm b/code/controllers/subsystem/radio.dm index 25f172bf9da..110f48d8f42 100644 --- a/code/controllers/subsystem/radio.dm +++ b/code/controllers/subsystem/radio.dm @@ -29,7 +29,7 @@ var/datum/subsystem/radio/radio_controller frequency.remove_listener(device) if(frequency.devices.len == 0) - del(frequency) + qdel(frequency) frequencies -= f_text return 1 diff --git a/code/controllers/subsystem/server_maintenance.dm b/code/controllers/subsystem/server_maintenance.dm index 1aa7ef7d1cc..6a92044ac6d 100644 --- a/code/controllers/subsystem/server_maintenance.dm +++ b/code/controllers/subsystem/server_maintenance.dm @@ -11,7 +11,7 @@ if(!istype(C.mob, /mob/dead)) log_access("AFK: [key_name(C)]") C << "You have been inactive for more than 10 minutes and have been disconnected." - del(C) + qdel(C) if(config.sql_enabled) sql_poll_players() diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index 98fecb0227c..45aab6c2339 100644 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -137,7 +137,7 @@ var/datum/subsystem/ticker/ticker mode = config.pick_mode(master_mode) if(!mode.can_start()) world << "Unable to start [mode.name]. Not enough players, [mode.required_players] players and [mode.required_enemies] eligible antagonists needed. Reverting to pre-game lobby." - del(mode) + qdel(mode) SSjob.ResetOccupations() return 0 @@ -148,7 +148,7 @@ var/datum/subsystem/ticker/ticker if(!Debug2) if(!can_continue) - del(mode) + qdel(mode) world << "Error setting up [master_mode]. Reverting to pre-game lobby." SSjob.ResetOccupations() return 0 @@ -289,8 +289,8 @@ var/datum/subsystem/ticker/ticker flick("station_intact",cinematic) world << sound('sound/ambience/signal.ogg') sleep(100) - if(cinematic) del(cinematic) - if(temp_buckle) del(temp_buckle) + if(cinematic) qdel(cinematic) + if(temp_buckle) qdel(temp_buckle) return //Faster exit, since nothing happened else //Station nuked (nuke,explosion,summary) flick("intro_nuke",cinematic) diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index 0ce16230efc..74cd402bca3 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -134,7 +134,7 @@ src.ion += law /datum/ai_laws/proc/clear_inherent_laws() - del(src.inherent) + qdel(src.inherent) src.inherent = list() /datum/ai_laws/proc/add_supplied_law(number, law) diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm index 954446639f3..6b098310e6d 100644 --- a/code/datums/diseases/_disease.dm +++ b/code/datums/diseases/_disease.dm @@ -138,7 +138,7 @@ var/list/diseases = typesof(/datum/disease) - /datum/disease for(var/datum/disease/D in affected_mob.viruses) if(D != src) if(IsSame(D)) - del(D) + qdel(D) if(holder == affected_mob) if(affected_mob.stat != DEAD) @@ -156,7 +156,7 @@ var/list/diseases = typesof(/datum/disease) - /datum/disease if(!(type in affected_mob.resistances)) affected_mob.resistances += type remove_virus() - del(src) + qdel(src) /datum/disease/New() diff --git a/code/datums/diseases/advance/advance.dm b/code/datums/diseases/advance/advance.dm index 8d5b977c3d7..94e808667ae 100644 --- a/code/datums/diseases/advance/advance.dm +++ b/code/datums/diseases/advance/advance.dm @@ -107,7 +107,7 @@ var/list/advance_cures = list( if(resistance && !(id in affected_mob.resistances)) affected_mob.resistances[id] = id remove_virus() - del(src) //delete the datum to stop it processing + qdel(src) //delete the datum to stop it processing // Returns the advance disease with a different reference memory. /datum/disease/advance/Copy(process = 0) diff --git a/code/datums/gas_mixture.dm b/code/datums/gas_mixture.dm index 277773ea3d5..ff91a69b1d6 100644 --- a/code/datums/gas_mixture.dm +++ b/code/datums/gas_mixture.dm @@ -321,7 +321,7 @@ What are the archived variables for? trace_gases += corresponding corresponding.moles += trace_gas.moles -// del(giver) +// qdel(giver) return 1 /datum/gas_mixture/remove(amount) diff --git a/code/datums/modules.dm b/code/datums/modules.dm index e52a644d157..af693456543 100644 --- a/code/datums/modules.dm +++ b/code/datums/modules.dm @@ -24,7 +24,7 @@ var/list/modules = list( // global associative list var/mneed = mods.inmodlist(type) // find if this type has modules defined if(!mneed) // not found in module list? - del(src) // delete self, thus ending proc + qdel(src) // delete self, thus ending proc var/needed = mods.getbitmask(type) // get a bitmask for the number of modules in this object status = needed diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 316c437c912..9a0c7e18cd8 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -391,7 +391,7 @@ else qdel(AM) if(istype(T, /turf/simulated)) - del(T) + qdel(T) /*for(var/atom/movable/bug in src) // If someone (or something) is somehow still in the shuttle's docking area... if(ismob(bug)) diff --git a/code/game/atoms.dm b/code/game/atoms.dm index df257364a90..a8e58f82aef 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -59,7 +59,7 @@ return /atom/proc/assume_air(datum/gas_mixture/giver) - del(giver) + qdel(giver) return null /atom/proc/remove_air(amount) diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index ab505d83329..67066db6d70 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -1002,8 +1002,8 @@ var/list/sacrificed = list() usr.say("Uln Shogg Hafh[pick("'","`")]drn!") user << "\red You quietly prick your finger and make a pact with the geometer of blood to acquire more power." user.take_overall_damage(rand(5,20)) - del(user.head) - del(user.wear_suit) + qdel(user.head) + qdel(user.wear_suit) user.equip_to_slot_or_del(new /obj/item/clothing/head/magus(user), slot_head) user.equip_to_slot_or_del(new /obj/item/clothing/suit/magusred(user), slot_wear_suit) user.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(user), slot_shoes) @@ -1020,8 +1020,8 @@ var/list/sacrificed = list() user.put_in_hands(new /obj/item/weapon/gun/magic/wand/resurrection(user)) if (armorworn == "traveler" || armorworn == "marauder") usr.say("Tharanak n[pick("'","`")]ghft!") - del(user.head) - del(user.wear_suit) + qdel(user.head) + qdel(user.wear_suit) user.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/cult(user), slot_head) user.equip_to_slot_or_del(new /obj/item/clothing/suit/space/cult(user), slot_wear_suit) user.equip_to_slot_or_del(new /obj/item/clothing/shoes/cult(user), slot_shoes) @@ -1033,7 +1033,7 @@ var/list/sacrificed = list() if (armorworn == "marauder") user.spellremove(user) user.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/conjure/creature/cult(user) - del(src) + qdel(src) return ///Summon Shell: Summons a construct shell if there's four plasteel sheets on top of the rune diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 8986580d810..f27e6522c59 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -114,7 +114,7 @@ if(G.reroll_friendly) usable_modes += G else - del(G) + qdel(G) if(!usable_modes) message_admins("Convert_roundtype failed due to no valid modes to convert to. Please report this error to the Coders.") diff --git a/code/game/gamemodes/wizard/spellbook.dm b/code/game/gamemodes/wizard/spellbook.dm index eec319a8fba..631bb32388b 100644 --- a/code/game/gamemodes/wizard/spellbook.dm +++ b/code/game/gamemodes/wizard/spellbook.dm @@ -78,7 +78,7 @@ if(initial(S.name) == initial(aspell.name)) spell_levels = aspell.spell_level user.mind.spell_list.Remove(aspell) - del(S) + qdel(S) return cost * (spell_levels+1) return -1 /datum/spellbook_entry/proc/GetInfo() @@ -419,7 +419,7 @@ entries |= E categories |= E.category else - del(E) + qdel(E) tab = categories[1] /obj/item/weapon/spellbook/New() diff --git a/code/game/machinery/computer/medical.dm b/code/game/machinery/computer/medical.dm index 1eaaa0b7fd5..7bfbe2776ac 100644 --- a/code/game/machinery/computer/medical.dm +++ b/code/game/machinery/computer/medical.dm @@ -581,7 +581,7 @@ continue else if(prob(1)) - del(R) + qdel(R) continue ..(severity) diff --git a/code/game/machinery/computer/security.dm b/code/game/machinery/computer/security.dm index c87a35f2486..384199d95e7 100644 --- a/code/game/machinery/computer/security.dm +++ b/code/game/machinery/computer/security.dm @@ -418,7 +418,7 @@ What a mess.*/ if("Purge All Records") investigate_log("[usr.name] ([usr.key]) has purged all the security records.", "records") for(var/datum/data/record/R in data_core.security) - del(R) + qdel(R) data_core.security.Cut() temp = "All Security records deleted." @@ -667,7 +667,7 @@ What a mess.*/ investigate_log("[usr.name] ([usr.key]) has deleted the security records for [active1.fields["name"]].", "records") if(active2) data_core.security -= active2 - del(active2) + qdel(active2) if("Delete Record (ALL) Execute") if(active1) @@ -675,14 +675,14 @@ What a mess.*/ for(var/datum/data/record/R in data_core.medical) if((R.fields["name"] == active1.fields["name"] || R.fields["id"] == active1.fields["id"])) data_core.medical -= R - del(R) + qdel(R) break data_core.general -= active1 - del(active1) + qdel(active1) if(active2) data_core.security -= active2 - del(active2) + qdel(active2) else temp = "This function does not appear to be working at the moment. Our apologies." @@ -734,7 +734,7 @@ What a mess.*/ continue else if(prob(1)) - del(R) + qdel(R) continue ..(severity) diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index e528bf28b69..bde8908cf70 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -7,7 +7,7 @@ if(master) master.post_signal(signal, comm_line) else - del(signal) + qdel(signal) /datum/computer/file/embedded_program/proc/receive_user_command(command) diff --git a/code/game/machinery/magnet.dm b/code/game/machinery/magnet.dm index 43b767934ee..667f9735857 100644 --- a/code/game/machinery/magnet.dm +++ b/code/game/machinery/magnet.dm @@ -375,7 +375,7 @@ // N, S, E, W are directional // C is center // R is random (in magnetic field's bounds) - del(signal) + qdel(signal) break // break the loop if the character located is invalid signal.data["command"] = nextmove diff --git a/code/game/machinery/overview.dm b/code/game/machinery/overview.dm index 873a51797d2..dcdfd5a74e3 100644 --- a/code/game/machinery/overview.dm +++ b/code/game/machinery/overview.dm @@ -174,8 +174,8 @@ HI.Insert(I, frame=1, delay = 5) HI.Insert(J, frame=2, delay = 5) - del(I) - del(J) + qdel(I) + qdel(J) H.icon = HI H.layer = 25 usr.mapobjs += H @@ -294,7 +294,7 @@ var/icon/I = imap[i+1] H.icon = I - del(I) + qdel(I) H.layer = 25 usr.mapobjs += H diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index 67b8c167772..e14cbaaea61 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -393,12 +393,12 @@ for(var/obj/item/ITEM in src) ITEM.clean_blood() if(istype(STORAGE, /obj/item/weapon/reagent_containers/food)) - del(STORAGE) + qdel(STORAGE) else //It was supercycling, destroy everything src.HELMET = null src.SUIT = null src.MASK = null - del(STORAGE) + qdel(STORAGE) visible_message("With a loud whining noise, the Suit Storage Unit's door grinds open. Puffs of ashen smoke come out of its chamber.", 3) src.isbroken = 1 src.isopen = 1 diff --git a/code/game/machinery/telecomms/computers/logbrowser.dm b/code/game/machinery/telecomms/computers/logbrowser.dm index eca9a206429..c30b28534d5 100644 --- a/code/game/machinery/telecomms/computers/logbrowser.dm +++ b/code/game/machinery/telecomms/computers/logbrowser.dm @@ -197,7 +197,7 @@ temp = "- DELETED ENTRY: [D.name] -" SelectedServer.log_entries.Remove(D) - del(D) + qdel(D) else temp = "- FAILED: NO SELECTED MACHINE -" diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index 0e178a4218e..b405648f4dd 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -137,7 +137,7 @@ loc.assume_air(cabin_air) air_update_turf() else - del(cabin_air) + qdel(cabin_air) cabin_air = null qdel(spark_system) spark_system = null @@ -240,7 +240,7 @@ loc.assume_air(leaked_gas) air_update_turf() else - del(leaked_gas) + qdel(leaked_gas) if(internal_damage & MECHA_INT_SHORT_CIRCUIT) if(get_charge()) @@ -276,7 +276,7 @@ if(t_air) t_air.merge(removed) else //just delete the cabin gas, we're in space or some shit - del(removed) + qdel(removed) if(occupant) if(cell) diff --git a/code/game/mecha/mecha_construction_paths.dm b/code/game/mecha/mecha_construction_paths.dm index 8df632882a3..60c31405645 100644 --- a/code/game/mecha/mecha_construction_paths.dm +++ b/code/game/mecha/mecha_construction_paths.dm @@ -300,7 +300,7 @@ const_holder.icon = 'icons/mecha/mech_construction.dmi' const_holder.icon_state = "gygax0" const_holder.density = 1 - del(src) + qdel(src) return @@ -579,7 +579,7 @@ const_holder.icon = 'icons/mecha/mech_construction.dmi' const_holder.icon_state = "fireripley0" const_holder.density = 1 - del(src) + qdel(src) return @@ -801,7 +801,7 @@ var/obj/item/mecha_parts/chassis/const_holder = holder const_holder.construct = new /datum/construction/mecha/honker(const_holder) const_holder.density = 1 - del(src) + qdel(src) return diff --git a/code/game/objects/items/devices/camera_bug.dm b/code/game/objects/items/devices/camera_bug.dm index 9f8e79da8ea..59780eb60f0 100644 --- a/code/game/objects/items/devices/camera_bug.dm +++ b/code/game/objects/items/devices/camera_bug.dm @@ -48,7 +48,7 @@ if(expansion) qdel(expansion) expansion = null - del(src) + qdel(src) //Easier to just call del() than this nonsense // ya no, del() takes 0.8ds to run on avg. this takes less than 0.01 get_cameras() diff --git a/code/game/objects/items/holotape.dm b/code/game/objects/items/holotape.dm index 10cd8e08d6c..b663b3a655b 100644 --- a/code/game/objects/items/holotape.dm +++ b/code/game/objects/items/holotape.dm @@ -244,10 +244,10 @@ for (var/obj/item/holotape/P in cur) if(P.icon_state == icon_dir) N = 0 - del(P) + qdel(P) cur = get_step(cur,dir[i]) - del(src) + qdel(src) return #undef MAX_TAPE_RANGE diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 06d78149919..2cba8ba7037 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -196,7 +196,7 @@ New(obj/item/sample) if(!istype(sample)) - del(src) + qdel(src) sample_object = sample number = 1 diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index eb41ea7032d..3bad0781ef3 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -33,7 +33,7 @@ /obj/item/weapon/tank/Destroy() if(air_contents) - del(air_contents) + qdel(air_contents) SSobj.processing.Remove(src) diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index edbdb87b62d..735b00c6aac 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -11,7 +11,7 @@ var/list/admin_ranks = list() //list of all admin_rank datums switch(name) if("Removed",null,"") spawn(-1) - del(src) + qdel(src) throw EXCEPTION("invalid admin-rank name") return if(init_rights) rights = init_rights diff --git a/code/modules/admin/verbs/SDQL2/SDQL_2.dm b/code/modules/admin/verbs/SDQL2/SDQL_2.dm index 8ec3e3f2075..991ebb36886 100644 --- a/code/modules/admin/verbs/SDQL2/SDQL_2.dm +++ b/code/modules/admin/verbs/SDQL2/SDQL_2.dm @@ -180,7 +180,7 @@ query_tree += val pos++ - del(parser) + qdel(parser) return querys diff --git a/code/modules/awaymissions/maploader/swapmaps.dm b/code/modules/awaymissions/maploader/swapmaps.dm index 6c2cba1d0be..127af2e7a1e 100644 --- a/code/modules/awaymissions/maploader/swapmaps.dm +++ b/code/modules/awaymissions/maploader/swapmaps.dm @@ -156,7 +156,7 @@ swapmap if(z2>swapmaps_compiled_maxz ||\ y2>swapmaps_compiled_maxy ||\ x2>swapmaps_compiled_maxx) - del(src) + qdel(src) return x2=x?(x):world.maxx y2=y?(y):world.maxy @@ -179,12 +179,12 @@ swapmap if(!M.key) qdel(M) else M.loc=null areas[A.loc]=null - del(A) + qdel(A) // delete areas that belong only to this map for(var/area/a in areas) - if(a && !a.contents.len) del(a) + if(a && !a.contents.len) qdel(a) if(x2>=world.maxx || y2>=world.maxy || z2>=world.maxz) CutXYZ() - del(areas) + qdel(areas) ..() /* @@ -241,7 +241,7 @@ swapmap sleep() S.cd=oldcd locked=0 - del(areas) + qdel(areas) Read(savefile/S,_id,turf/locorner) var/x @@ -297,7 +297,7 @@ swapmap sleep() S.cd=oldcd locked=0 - del(areas) + qdel(areas) /* Find an empty block on the world map in which to load this map. @@ -321,7 +321,7 @@ swapmap x1=l[1] y1=l[2] z1=l[3] - del(l) + qdel(l) x2+=x1-1 y2+=y1-1 z2+=z1-1 @@ -377,7 +377,7 @@ swapmap // save and delete proc/Unload() Save() - del(src) + qdel(src) proc/Save() if(id==src) return 0 @@ -472,7 +472,7 @@ atom l=l.Copy() for(M in src) if(M.key) l-=M if(l.len) S["contents"]<Your form morphs into that of a [randomize]." - del(M) + qdel(M) return new_mob /obj/item/projectile/magic/animate diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index a3e8c47888d..de15fe46165 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -60,7 +60,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, check_tech = new T() if(check_tech.id == ID) return_name = check_tech.name - del(check_tech) + qdel(check_tech) check_tech = null break @@ -94,7 +94,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, temp_reagent = new R() if(temp_reagent.id == ID) return_name = temp_reagent.name - del(temp_reagent) + qdel(temp_reagent) temp_reagent = null break return return_name @@ -575,7 +575,7 @@ won't update every console in existence) but it's more of a hassle to do. Also, var/choice = alert("R&D Console Database Reset", "Are you sure you want to reset the R&D console's database? Data lost cannot be recovered.", "Continue", "Cancel") if(choice == "Continue") screen = 0.0 - del(files) + qdel(files) files = new /datum/research(src) spawn(20) screen = 1.6 From 14b3dcbd65ed5de6182b1e1b54f54c93c9ac0403 Mon Sep 17 00:00:00 2001 From: CorruptComputer Date: Sun, 16 Aug 2015 16:53:33 -0500 Subject: [PATCH 037/108] deletes computerfiles.dm and minor edit to atoms.dm --- code/datums/computerfiles.dm | 7 ------- code/game/atoms.dm | 6 +----- 2 files changed, 1 insertion(+), 12 deletions(-) delete mode 100644 code/datums/computerfiles.dm diff --git a/code/datums/computerfiles.dm b/code/datums/computerfiles.dm deleted file mode 100644 index 37ba1ec51e0..00000000000 --- a/code/datums/computerfiles.dm +++ /dev/null @@ -1,7 +0,0 @@ -/datum - computer - var/name - folder - var/list/datum/computer/contents = list() - - file \ No newline at end of file diff --git a/code/game/atoms.dm b/code/game/atoms.dm index df257364a90..48e0768810f 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -284,12 +284,8 @@ var/list/blood_splatter_icons = list() var/mob/living/carbon/human/H = M if(NOBLOOD in H.dna.species.specflags) return 0 - if(rejects_blood()) + if(rejects_blood() || !istype(M) || !check_dna_integrity(M)) return 0 - if(!istype(M)) - return 0 - if(!check_dna_integrity(M)) //check dna is valid and create/setup if necessary - return 0 //no dna! return 1 /obj/add_blood(mob/living/carbon/M) From a27b781541c66c91f0efb6d1a9133bba78247c2b Mon Sep 17 00:00:00 2001 From: CorruptComputer Date: Sun, 16 Aug 2015 16:57:41 -0500 Subject: [PATCH 038/108] what the fuck, who did this? --- tgstation.dme | 1 - 1 file changed, 1 deletion(-) diff --git a/tgstation.dme b/tgstation.dme index 7677d19fc8f..25bc98a1e2f 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -153,7 +153,6 @@ #include "code\controllers\subsystem\shuttles\supply.dm" #include "code\datums\ai_laws.dm" #include "code\datums\browser.dm" -#include "code\datums\computerfiles.dm" #include "code\datums\datacore.dm" #include "code\datums\datumvars.dm" #include "code\datums\debug.dm" From 89f79a139773aed0989db11c64a70a813cf619ff Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Sun, 16 Aug 2015 18:36:12 -0400 Subject: [PATCH 039/108] Hopefully fixes #11238 by removing the strike code, overload lights now causes sparks, window to put someone into a revenant increased to 10 seconds. --- .../living/simple_animal/revenant/revenant.dm | 20 ++++++++----------- .../revenant/revenant_abilities.dm | 10 +++++++++- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm index a59553b7832..0a984a21f4b 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm @@ -17,6 +17,7 @@ response_help = "passes through" response_disarm = "swings at" response_harm = "punches through" + unsuitable_atmos_damage = 0 atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 maxbodytemp = INFINITY @@ -25,6 +26,7 @@ status_flags = 0 wander = 0 density = 0 + flying = 1 anchored = 1 var/essence = 25 //The resource of revenants. Max health is equal to three times this amount @@ -33,7 +35,6 @@ var/essence_regen_amount = 2 //How much essence regenerates var/essence_min = 1 //The minimum amount of essence a revenant can have; by default, it never drops below one var/essence_accumulated = 0 //How much essence the revenant has stolen - var/strikes = 0 //How many times a revenant can die before dying for good var/revealed = 0 //If the revenant can take damage from normal sources. var/inhibited = 0 //If the revenant's abilities are blocked by a chaplain's power. @@ -41,11 +42,6 @@ ..() if(essence < essence_min) essence = essence_min - if(strikes > 0) - strikes-- - src << "Your essence has dropped below critical levels. You barely manage to save yourself - [strikes ? "you can't keep this up!" : "next time, it's death."]" - else if(strikes <= 0) - death() if(essence_regenerating && !inhibited && essence < essence_regen_cap) //While inhibited, essence will not regenerate essence += essence_regen_amount if(essence > essence_regen_cap) @@ -57,6 +53,9 @@ /mob/living/simple_animal/revenant/ex_act(severity, target) return 1 //Immune to the effects of explosions. +/mob/living/simple_animal/revenant/blob_act() + return //blah blah blobs aren't in tune with the spirit world, or something. + /mob/living/simple_animal/revenant/ClickOn(atom/A, params) //Copypaste from ghost code - revenants can't interact with the world directly. if(client.buildmode) build_click(src, client.buildmode, params, A) @@ -114,8 +113,8 @@ src << "Objective #2: [objective2.explanation_text]" ticker.mode.traitors |= src.mind //Necessary for announcing if(!src.giveSpells()) - message_admins("Revenant was created but has no mind. Trying again in five seconds.") - spawn(50) + message_admins("Revenant was created but has no mind. Trying again in ten seconds.") + spawn(100) if(!src.giveSpells()) message_admins("Revenant still has no mind. Deleting...") qdel(src) @@ -130,8 +129,6 @@ return 0 /mob/living/simple_animal/revenant/death() - if(strikes) - return 0 //Impossible to die with strikes still active ..(1) src << "NO! No... it's too late, you can feel yourself fading..." notransform = 1 @@ -151,7 +148,6 @@ /mob/living/simple_animal/revenant/attackby(obj/item/W, mob/living/user, params) - ..() if(istype(W, /obj/item/weapon/nullrod)) visible_message("[src] violently flinches!", \ "As the null rod passes through you, you feel your essence draining away!") @@ -159,7 +155,7 @@ inhibited = 1 spawn(30) inhibited = 0 - + ..() /mob/living/simple_animal/revenant/proc/castcheck(essence_cost) diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm index 40dea02e25d..4bd9418c2e9 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm @@ -57,6 +57,7 @@ if(!target.stat) user << "They are now powerful enough to fight off your draining." target << "You feel something tugging across your body before subsiding." + return //hey, wait a minute... user << "You begin siphoning essence from [target]'s soul." if(target.stat != DEAD) target << "You feel a horribly unpleasant draining sensation as your grip on life weakens..." @@ -138,12 +139,19 @@ if(!L.on) return L.visible_message("\The [L] suddenly flares brightly and begins to spark!") - sleep(20) + sleep(10) + var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread + s.set_up(4, 1, L) + s.start() + sleep(10) for(var/mob/living/M in orange(4, L)) if(M == user) return M.Beam(L,icon_state="lightning",icon='icons/effects/effects.dmi',time=5) M.electrocute_act(25, "[L.name]") + var/datum/effect/effect/system/spark_spread/z = new /datum/effect/effect/system/spark_spread + z.set_up(4, 1, M) + z.start() playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1) user.reveal(80) From 2ee2c8513e652ca31c49253bbd1c9f39b7f6f8ce Mon Sep 17 00:00:00 2001 From: Firecage Date: Mon, 17 Aug 2015 00:51:23 +0200 Subject: [PATCH 040/108] This fixes the Syndicate Carbine. --- .../projectiles/guns/projectile/automatic.dm | 13 +++++++++++-- .../projectiles/guns/projectile/launchers.dm | 4 ++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/code/modules/projectiles/guns/projectile/automatic.dm b/code/modules/projectiles/guns/projectile/automatic.dm index 45660958359..8b1aaecd735 100644 --- a/code/modules/projectiles/guns/projectile/automatic.dm +++ b/code/modules/projectiles/guns/projectile/automatic.dm @@ -190,13 +190,22 @@ burst_size = 3 fire_delay = 2 pin = /obj/item/device/firing_pin/implant/pindicate -/obj/item/weapon/gun/projectile/automatic/m90/unrestricted - pin = /obj/item/device/firing_pin + /obj/item/weapon/gun/projectile/automatic/m90/New() ..() underbarrel = new /obj/item/weapon/gun/projectile/revolver/grenadelauncher(src) update_icon() return + +/obj/item/weapon/gun/projectile/automatic/m90/unrestricted + pin = /obj/item/device/firing_pin + +/obj/item/weapon/gun/projectile/automatic/m90/unrestricted/New() + ..() + underbarrel = new /obj/item/weapon/gun/projectile/revolver/grenadelauncher/unrestricted(src) + update_icon() + return + /obj/item/weapon/gun/projectile/automatic/m90/afterattack(atom/target, mob/living/user, flag, params) if(select == 2) underbarrel.afterattack(target, user, flag, params) diff --git a/code/modules/projectiles/guns/projectile/launchers.dm b/code/modules/projectiles/guns/projectile/launchers.dm index 4bddd2d3ce4..506f51e306c 100644 --- a/code/modules/projectiles/guns/projectile/launchers.dm +++ b/code/modules/projectiles/guns/projectile/launchers.dm @@ -9,6 +9,10 @@ mag_type = /obj/item/ammo_box/magazine/internal/cylinder/grenadelauncher fire_sound = 'sound/weapons/grenadelaunch.ogg' w_class = 3 + pin = /obj/item/device/firing_pin/implant/pindicate + +/obj/item/weapon/gun/projectile/revolver/grenadelauncher/unrestricted + pin = /obj/item/device/firing_pin /obj/item/weapon/gun/projectile/revolver/grenadelauncher/attackby(obj/item/A, mob/user, params) ..() From 45e484f0722038434e6fd052c046807b50d6de44 Mon Sep 17 00:00:00 2001 From: Aranclanos Date: Sun, 16 Aug 2015 20:26:45 -0300 Subject: [PATCH 041/108] Mimic ranged crates will spawn as their parent if they are not created by a staff of animation. Cleans a bit mimic.dm, copypaste and some bad code (like spawning some projectile types just to get a variable) --- .../mob/living/simple_animal/hostile/mimic.dm | 159 ++++++------------ 1 file changed, 48 insertions(+), 111 deletions(-) diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index 4c99fd62ca2..5e0f67211e6 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -1,7 +1,3 @@ -// -// Abstract Class -// - /mob/living/simple_animal/hostile/mimic name = "crate" desc = "A rectangular steel crate." @@ -37,19 +33,10 @@ ghostize() qdel(src) - - -// -// Crate Mimic -// - - // Aggro when you try to open them. Will also pickup loot when spawns and drop it when dies. /mob/living/simple_animal/hostile/mimic/crate - attacktext = "bites" speak_emote = list("clatters") - stop_automated_movement = 1 wander = 0 var/attempt_open = 0 @@ -96,7 +83,6 @@ icon_state = initial(icon_state) /mob/living/simple_animal/hostile/mimic/crate/death() - var/obj/structure/closet/crate/C = new(get_turf(src)) // Put loot in crate for(var/obj/O in src) @@ -113,21 +99,18 @@ C.visible_message("\The [src] knocks down \the [C]!", \ "\The [src] knocks you down!") -// -// Copy Mimic -// + var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/cable, /obj/structure/window) /mob/living/simple_animal/hostile/mimic/copy - health = 100 maxHealth = 100 var/mob/living/creator = null // the creator var/destroy_objects = 0 var/knockdown_people = 0 -/mob/living/simple_animal/hostile/mimic/copy/New(loc, var/obj/copy, var/mob/living/creator, var/destroy_original = 0) +/mob/living/simple_animal/hostile/mimic/copy/New(loc, obj/copy, mob/living/creator, destroy_original = 0) ..(loc) CopyObject(copy, creator, destroy_original) @@ -137,13 +120,11 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca death() /mob/living/simple_animal/hostile/mimic/copy/death() - for(var/atom/movable/M in src) M.loc = get_turf(src) ..() /mob/living/simple_animal/hostile/mimic/copy/ListTargets() - // Return a list of targets that isn't the creator . = ..() return . - creator @@ -159,9 +140,7 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca return 0 /mob/living/simple_animal/hostile/mimic/copy/proc/CopyObject(obj/O, mob/living/creator, destroy_original = 0) - if(destroy_original || CheckObject(O)) - O.loc = src name = O.name desc = O.desc @@ -169,7 +148,6 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca icon_state = O.icon_state icon_living = icon_state overlays = O.overlays - if(istype(O, /obj/structure) || istype(O, /obj/machinery)) health = (anchored * 50) + 50 destroy_objects = 1 @@ -183,15 +161,13 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca melee_damage_lower = 2 + I.force melee_damage_upper = 2 + I.force move_to_delay = 2 * I.w_class + 1 - maxHealth = health if(creator) - src.creator = creator + creator = creator faction += "\ref[creator]" // very unique if(destroy_original) qdel(O) return 1 - return /mob/living/simple_animal/hostile/mimic/copy/DestroySurroundings() if(destroy_objects) @@ -207,9 +183,7 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca C.visible_message("\The [src] knocks down \the [C]!", \ "\The [src] knocks you down!") -// -// Machine Mimics (Made by Malf AI) -// + /mob/living/simple_animal/hostile/mimic/copy/machine speak = list("HUMANS ARE IMPERFECT!", "YOU SHALL BE ASSIMILATED!", "YOU ARE HARMING YOURSELF", "You have been deemed hazardous. Will you comply?", \ @@ -225,93 +199,57 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca return 0 return ..() -// -//animated blasters, wands, etc -// + /mob/living/simple_animal/hostile/mimic/copy/ranged - name = "animated shooty gun" - desc = "there's something fishy here." - environment_smash = 0 //needed? seems weird for them to do so - ranged = 1 - retreat_distance = 1 //just enough to shoot - minimum_distance = 6 - projectiletype = /obj/item/projectile/magic/ - projectilesound = 'sound/items/bikehorn.ogg' - casingtype = null - emote_see = list("aims menacingly") var/obj/item/weapon/gun/TrueGun = null - var/obj/item/weapon/gun/magic/Zapstick = list() - var/obj/item/weapon/gun/projectile/Pewgun = list() - var/obj/item/weapon/gun/energy/Zapgun = list() - -/mob/living/simple_animal/hostile/mimic/copy/ranged/New(loc, var/obj/copy, var/mob/living/creator, var/destroy_original = 0) - ..() - + var/obj/item/weapon/gun/magic/Zapstick + var/obj/item/weapon/gun/projectile/Pewgun + var/obj/item/weapon/gun/energy/Zapgun /mob/living/simple_animal/hostile/mimic/copy/ranged/CopyObject(obj/O, mob/living/creator, destroy_original = 0) - if(destroy_original || CheckObject(O)) - - O.loc = src - name = O.name - desc = O.desc - icon = O.icon - icon_state = O.icon_state - icon_living = icon_state - - if(istype(O, /obj/item/weapon/gun)) //leaving for sanity i guess - var/obj/item/weapon/gun/G = O - health = 15 * G.w_class - melee_damage_upper = G.force - melee_damage_lower = G.force - max(0, (G.force / 2)) - move_to_delay = 2 * G.w_class + 1 - projectilesound = G.fire_sound - TrueGun = G - - if(istype(G, /obj/item/weapon/gun/magic)) - Zapstick = G - var/obj/item/ammo_casing/magic/Zapshot = new Zapstick.ammo_type //this is done because ammo_type.proj_type can't be directly checked - projectiletype = Zapshot.projectile_type - qdel(Zapshot) //is this needed? i dare not risk piles of nullspace bullets - - if(istype(G, /obj/item/weapon/gun/projectile)) - Pewgun = G - var/obj/item/ammo_box/magazine/Pewmag = new Pewgun.mag_type //same problem, mag_type.ammo_type.proj_type can't be checked directly - var/obj/item/ammo_casing/Pewshot = new Pewmag.ammo_type - projectiletype = Pewshot.projectile_type - casingtype = Pewmag.ammo_type - qdel(Pewshot) - qdel(Pewmag) - - if(istype(G, /obj/item/weapon/gun/energy)) - Zapgun = G - var/selectfiresetting = Zapgun.select - var/obj/item/ammo_casing/energy/Energyammotype = Zapgun.ammo_type[selectfiresetting] - projectiletype = Energyammotype.projectile_type - - maxHealth = health - if(creator) - src.creator = creator - faction += "\ref[creator]" - if(destroy_original) - qdel(O) - return 1 - return + if(..()) + emote_see = list("aims menacingly") + environment_smash = 0 //needed? seems weird for them to do so + ranged = 1 + retreat_distance = 1 //just enough to shoot + minimum_distance = 6 + var/obj/item/weapon/gun/G = O + melee_damage_upper = G.force + melee_damage_lower = G.force - max(0, (G.force / 2)) + move_to_delay = 2 * G.w_class + 1 + projectilesound = G.fire_sound + TrueGun = G + if(istype(G, /obj/item/weapon/gun/magic)) + Zapstick = G + var/obj/item/ammo_casing/magic/M = Zapstick.ammo_type + projectiletype = initial(M.projectile_type) + if(istype(G, /obj/item/weapon/gun/projectile)) + Pewgun = G + var/obj/item/ammo_box/magazine/M = Pewgun.mag_type + var/obj/item/ammo_casing/A = initial(M.ammo_type) + projectiletype = initial(A.projectile_type) + casingtype = initial(M.ammo_type) + if(istype(G, /obj/item/weapon/gun/energy)) + Zapgun = G + var/selectfiresetting = Zapgun.select + var/obj/item/ammo_casing/energy/E = Zapgun.ammo_type[selectfiresetting] + projectiletype = initial(E.projectile_type) /mob/living/simple_animal/hostile/mimic/copy/ranged/OpenFire(the_target) if(Zapgun) - if(Zapgun.power_supply) //sanity + if(Zapgun.power_supply) var/obj/item/ammo_casing/energy/shot = Zapgun.ammo_type[Zapgun.select] - if(Zapgun.power_supply.charge >= shot.e_cost) //if she can zap + if(Zapgun.power_supply.charge >= shot.e_cost) Zapgun.power_supply.use(shot.e_cost) Zapgun.update_icon() - ..() //zap 'em - if(Zapstick) + ..() + else if(Zapstick) if(Zapstick.charges) Zapstick.charges-- Zapstick.update_icon() ..() - if(Pewgun) + else if(Pewgun) if(Pewgun.chambered) if(Pewgun.chambered.BB) qdel(Pewgun.chambered.BB) @@ -320,7 +258,7 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca ..() else visible_message("The [src] clears a jam!") - Pewgun.chambered.loc = src.loc //rip revolver immersions, blame shotgun snowflake procs + Pewgun.chambered.loc = loc //rip revolver immersions, blame shotgun snowflake procs Pewgun.chambered = null if(Pewgun.magazine && Pewgun.magazine.stored_ammo.len) Pewgun.chambered = Pewgun.magazine.get_round(0) @@ -330,11 +268,10 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca Pewgun.chambered = Pewgun.magazine.get_round(0) Pewgun.chambered.loc = Pewgun visible_message("The [src] cocks itself!") - - else //if somehow the mimic has no weapon - src.ranged = 0 //BANZAIIII - src.retreat_distance = 0 - src.minimum_distance = 1 - src.icon_state = TrueGun.icon_state - src.icon_living = TrueGun.icon_state - return \ No newline at end of file + else + ranged = 0 //BANZAIIII + retreat_distance = 0 + minimum_distance = 1 + return + icon_state = TrueGun.icon_state + icon_living = TrueGun.icon_state \ No newline at end of file From 0951213f85092b4cb8e6a53e1845492344465848 Mon Sep 17 00:00:00 2001 From: phil235 Date: Mon, 17 Aug 2015 02:11:27 +0200 Subject: [PATCH 042/108] Use Krausus' fix for Paradise station to replace my laggy spawn(0) fix. --- code/game/objects/explosion.dm | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/code/game/objects/explosion.dm b/code/game/objects/explosion.dm index 5502ef807ee..682fc5293fe 100644 --- a/code/game/objects/explosion.dm +++ b/code/game/objects/explosion.dm @@ -35,6 +35,7 @@ if(!epicenter) return var/max_range = max(devastation_range, heavy_impact_range, light_impact_range, flame_range) + var/list/cached_exp_block = list() if(adminlog) message_admins("Explosion with size ([devastation_range], [heavy_impact_range], [light_impact_range], [flame_range]) in area [epicenter.loc.name] ([epicenter.x],[epicenter.y],[epicenter.z])") @@ -81,7 +82,23 @@ var/y0 = epicenter.y var/z0 = epicenter.z - for(var/turf/T in trange(max_range, epicenter)) + var/list/affected_turfs = trange(max_range, epicenter) + + if(config.reactionary_explosions) + for(var/turf/T in affected_turfs) // we cache the explosion block rating of every turf in the explosion area + cached_exp_block[T] = 0 + if(T.density && T.explosion_block) + cached_exp_block[T] += T.explosion_block + + for(var/obj/machinery/door/D in T) + if(D.density && D.explosion_block) + cached_exp_block[T] += D.explosion_block + + for(var/obj/structure/window/W in T) + if(W.reinf && W.fulltile) + cached_exp_block[T] += W.explosion_block + + for(var/turf/T in affected_turfs) var/dist = cheap_hypotenuse(T.x, T.y, x0, y0) @@ -89,16 +106,7 @@ var/turf/Trajectory = T while(Trajectory != epicenter) Trajectory = get_step_towards(Trajectory, epicenter) - if(Trajectory.density && Trajectory.explosion_block) - dist += Trajectory.explosion_block - - for(var/obj/machinery/door/D in Trajectory) - if(D.density && D.explosion_block) - dist += D.explosion_block - - for(var/obj/structure/window/W in Trajectory) - if(W.reinf && W.fulltile) - dist += W.explosion_block + dist += cached_exp_block[Trajectory] var/flame_dist = 0 var/throw_dist = dist @@ -117,8 +125,7 @@ if(flame_dist && prob(40) && !istype(T, /turf/space) && !T.density) PoolOrNew(/obj/effect/hotspot, T) //Mostly for ambience! if(dist > 0) - spawn(0) - T.ex_act(dist) + T.ex_act(dist) //--- THROW ITEMS AROUND --- From 0dbc04d6a7d1f33a8adfb28513a5738e989ce6cd Mon Sep 17 00:00:00 2001 From: Aranclanos Date: Sun, 16 Aug 2015 21:34:53 -0300 Subject: [PATCH 043/108] Fixes the alien hud icon for infected people not appearing. If a mob is infected by a changeling egg, aliens won't get the hud icon. --- code/game/objects/effects/aliens.dm | 2 +- code/modules/mob/living/carbon/alien/alien.dm | 7 ++++--- code/modules/mob/living/carbon/alien/special/facehugger.dm | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index aaca5674ed5..49a5cb83c4b 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -419,7 +419,7 @@ return var/mob/living/carbon/C = AM - if(C.stat == CONSCIOUS && C.status_flags & XENO_HOST) + if(C.stat == CONSCIOUS && C.getorgan(/obj/item/organ/internal/body_egg/alien_embryo)) return Burst(0) diff --git a/code/modules/mob/living/carbon/alien/alien.dm b/code/modules/mob/living/carbon/alien/alien.dm index e2adcf9323b..ae838e5cff3 100644 --- a/code/modules/mob/living/carbon/alien/alien.dm +++ b/code/modules/mob/living/carbon/alien/alien.dm @@ -149,9 +149,10 @@ Des: Gives the client of the alien an image on each infected mob. if (client) for (var/mob/living/C in mob_list) if(C.status_flags & XENO_HOST) - var/obj/item/organ/internal/body_egg/alien_embryo/A = getorgan(/obj/item/organ/internal/body_egg/alien_embryo) - var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]") - client.images += I + var/obj/item/organ/internal/body_egg/alien_embryo/A = C.getorgan(/obj/item/organ/internal/body_egg/alien_embryo) + if(A) + var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[A.stage]") + client.images += I return diff --git a/code/modules/mob/living/carbon/alien/special/facehugger.dm b/code/modules/mob/living/carbon/alien/special/facehugger.dm index 4c2aee91be8..1a9ba9601a2 100644 --- a/code/modules/mob/living/carbon/alien/special/facehugger.dm +++ b/code/modules/mob/living/carbon/alien/special/facehugger.dm @@ -177,7 +177,7 @@ var/const/MAX_ACTIVE_TIME = 400 Die() icon_state = "[initial(icon_state)]_impregnated" - if(!target.getlimb(/obj/item/organ/limb/robot/chest) && !(target.status_flags & XENO_HOST)) + if(!target.getlimb(/obj/item/organ/limb/robot/chest) && !target.getorgan(/obj/item/organ/internal/body_egg/alien_embryo)) new /obj/item/organ/internal/body_egg/alien_embryo(target) if(iscorgi(target)) From e4b21e30d36bff2e8e0ad27263debc9f8532aef3 Mon Sep 17 00:00:00 2001 From: Jordie0608 Date: Mon, 17 Aug 2015 15:24:50 +1000 Subject: [PATCH 044/108] autoconvert notes to sql procs --- code/controllers/configuration.dm | 4 + code/modules/admin/admin.dm | 2 +- code/modules/admin/player_notes.dm | 117 ---------------------------- code/modules/admin/sql_notes.dm | 69 +++++++++++++--- code/modules/client/client procs.dm | 3 + config/config.txt | 5 +- 6 files changed, 72 insertions(+), 128 deletions(-) delete mode 100644 code/modules/admin/player_notes.dm diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index c8670e39a3d..7d6a0b3a608 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -163,6 +163,8 @@ var/reactionary_explosions = 0 //If we use reactionary explosions, explosions that react to walls and doors + var/autoconvert_notes = 0 //if all connecting player's notes should attempt to be converted to the database + /datum/configuration/New() var/list/L = typesof(/datum/game_mode) - /datum/game_mode for(var/T in L) @@ -343,6 +345,8 @@ if (world.log != newlog) world.log << "Now logging runtimes to data/logs/runtimes/runtime-[time2text(world.realtime, "YYYY-MM-DD")].log" world.log = newlog + if("autoconvert_notes") + config.autoconvert_notes = 1 else diary << "Unknown setting in configuration: '[name]'" diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 71e35f2ff89..e40f3490f91 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -47,7 +47,7 @@ var/global/floorIsLava = 0 body += "Ban | " body += "Jobban | " body += "Identity Ban | " - body += "Notes | " + body += "Notes | " body += "Watchlist Flag " if(M.client) diff --git a/code/modules/admin/player_notes.dm b/code/modules/admin/player_notes.dm deleted file mode 100644 index 040ac99ef48..00000000000 --- a/code/modules/admin/player_notes.dm +++ /dev/null @@ -1,117 +0,0 @@ -//This stuff was originally intended to be integrated into the ban-system I was working on -//but it's safe to say that'll never be finished. So I've merged it into the current player panel. -//enjoy ~Carn - -#define NOTESFILE "data/player_notes.sav" //where the player notes are saved - -/proc/see_own_notes() - if(!config.see_own_notes) - return - var/ckey = usr.client.ckey - if(!ckey) - usr << "Error: No ckey found." - return - var/savefile/notesfile = new(NOTESFILE) - if(!notesfile) - usr << "Error: Cannot access [NOTESFILE]" - return - notesfile.cd = "/[ckey]" - var/dat = "Notes for [ckey]:
" - while(!notesfile.eof) - var/note - notesfile >> note - dat += note + "
" - var/datum/browser/popup = new(usr, "player_notes", "Player Notes", 700, 400) - popup.set_content(dat) - popup.open() - - -/datum/admins/proc/notes_show(ckey) - usr << browse("Player Notes[notes_gethtml(ckey)]","window=player_notes;size=700x400") - - -/datum/admins/proc/notes_gethtml(ckey) - var/savefile/notesfile = new(NOTESFILE) - if(!notesfile) return "Error: Cannot access [NOTESFILE]" - if(ckey) - . = "Notes for [ckey]: \[+\]
" - notesfile.cd = "/[ckey]" - var/index = 1 - while( !notesfile.eof ) - var/note - notesfile >> note - . += "[note] \[-\]
" - index++ - else - . = "All Notes: \[+\]
" - notesfile.cd = "/" - for(var/dir in notesfile.dir) - . += "[dir]
" - return - - -//handles adding notes to the end of a ckey's buffer -//originally had seperate entries such as var/by to record who left the note and when -//but the current bansystem is a heap of dung. -/proc/notes_add(ckey, note, lognote = 0) - if(!ckey) - ckey = ckey(input(usr,"Who would you like to add notes for?","Enter a ckey",null) as text|null) - if(!ckey) return - - if(!note) - note = html_encode(input(usr,"Enter your note:","Enter some text",null) as message|null) - if(!note) return - - var/savefile/notesfile = new(NOTESFILE) - if(!notesfile) return - notesfile.cd = "/[ckey]" - notesfile.eof = 1 //move to the end of the buffer - notesfile << "[time2text(world.realtime,"DD-MMM-YYYY")] | [note][(usr && usr.ckey)?" ~[usr.ckey]":""]" - - if(lognote)//don't need an admin log for the notes applied automatically during bans. - message_admins("[key_name(usr)] added note '[note]' to [ckey]") - log_admin("[key_name(usr)] added note '[note]' to [ckey]") - - return - -//handles removing entries from the buffer, or removing the entire directory if no start_index is given -/proc/notes_remove(ckey, start_index, end_index) - var/savefile/notesfile = new(NOTESFILE) - var/admin_msg - if(!notesfile) return - - if(!ckey) - notesfile.cd = "/" - ckey = ckey(input(usr,"Who would you like to remove notes for?","Enter a ckey",null) as null|anything in notesfile.dir) - if(!ckey) return - - if(start_index) - notesfile.cd = "/[ckey]" - var/list/noteslist = list() - if(!end_index) end_index = start_index - var/index = 0 - while( !notesfile.eof ) - index++ - var/temp - notesfile >> temp - if( (start_index <= index) && (index <= end_index) ) - admin_msg = temp - continue - - noteslist += temp - - notesfile.eof = -2 //Move to the start of the buffer and then erase. - - for( var/note in noteslist ) - notesfile << note - - message_admins("[key_name(usr)] removed a note '[admin_msg]' from [ckey]") - log_admin("[key_name(usr)] removed a note '[admin_msg]' from [ckey]") - - if(noteslist.len == 0) - notesfile.cd = "/" - notesfile.dir.Remove(ckey) - message_admins("[ckey] has no notes and was removed from the notes list.") - return - -#undef NOTESFILE \ No newline at end of file diff --git a/code/modules/admin/sql_notes.dm b/code/modules/admin/sql_notes.dm index fe9aeeeb2c5..54af84cb2b9 100644 --- a/code/modules/admin/sql_notes.dm +++ b/code/modules/admin/sql_notes.dm @@ -1,4 +1,4 @@ -proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1) +/proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1, server) if(!dbcon.IsConnected()) usr << "Failed to establish database connection." return @@ -28,10 +28,10 @@ proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1) adminckey = usr.ckey if(!adminckey) return - var/server - if (config && config.server_name) - server = config.server_name var/admin_sql_ckey = sanitizeSQL(adminckey) + if(!server) + if (config && config.server_name) + server = config.server_name var/DBQuery/query_noteadd = dbcon.NewQuery("INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server) VALUES ('[target_sql_ckey]', '[timestamp]', '[notetext]', '[admin_sql_ckey]', '[server]')") if(!query_noteadd.Execute()) var/err = query_noteadd.ErrorMsg() @@ -40,9 +40,9 @@ proc/add_note(target_ckey, notetext, timestamp, adminckey, logged = 1) if(logged) log_admin("[key_name(usr)] has added a note to [target_ckey]: [notetext]") message_admins("[key_name_admin(usr)] has added a note to [target_ckey]:
[notetext]") - show_note(target_ckey) + show_note(target_ckey) -proc/remove_note(note_id) +/proc/remove_note(note_id) var/ckey var/notetext var/adminckey @@ -69,7 +69,7 @@ proc/remove_note(note_id) message_admins("[key_name_admin(usr)] has removed a note made by [adminckey] from [ckey]:
[notetext]") show_note(ckey) -proc/edit_note(note_id) +/proc/edit_note(note_id) if(!dbcon.IsConnected()) usr << "Failed to establish database connection." return @@ -100,7 +100,7 @@ proc/edit_note(note_id) message_admins("[key_name_admin(usr)] has edited [target_ckey]'s note made by [adminckey] from
[old_note]
to
[new_note]") show_note(target_ckey) -proc/show_note(target_ckey, index, linkless = 0) +/proc/show_note(target_ckey, index, linkless = 0) var/output var/navbar var/ruler @@ -160,4 +160,55 @@ proc/show_note(target_ckey, index, linkless = 0) else output += "
\[Add Note\]
" output += ruler - usr << browse(output, "window=show_notes;size=900x500") \ No newline at end of file + usr << browse(output, "window=show_notes;size=900x500") + +/proc/regex_note_sql_extract(str, exp) + return new /datum/regex(str, exp, call(LIBREGEX_LIBRARY, "regEx_find")(str, exp)) + +#define NOTESFILE "data/player_notes.sav" +//if the AUTOCONVERT_NOTES is turned on, anytime a player connects this will be run to try and add all their notes to the databas +/proc/convert_notes_sql(ckey) + var/savefile/notesfile = new(NOTESFILE) + if(!notesfile) + log_game("Error: Cannot access [NOTESFILE]") + return + notesfile.cd = "/[ckey]" + while(!notesfile.eof) + var/notetext + notesfile >> notetext + var/server + if (config && config.server_name) + server = config.server_name + var/regex = "^(\\d{2}-\\w{3}-\\d{4}) \\| (.+) ~(\\w+)$" + var/datum/regex/results = regex_note_sql_extract(notetext, regex) + var/timestamp = results.str(2) + notetext = results.str(3) + var/adminckey = results.str(4) + var/DBQuery/query_convert_time = dbcon.NewQuery("SELECT ADDTIME(STR_TO_DATE('[timestamp]','%d-%b-%Y'), '0')") + if(!query_convert_time.Execute()) + var/err = query_convert_time.ErrorMsg() + log_game("SQL ERROR converting timestamp. Error : \[[err]\]\n") + return + if(query_convert_time.NextRow()) + timestamp = query_convert_time.item[1] + if(ckey && notetext && timestamp && adminckey && server) + add_note(ckey, notetext, timestamp, adminckey, 0, server) + else + notesfile.cd = "/" + notesfile.dir.Remove(ckey) + +/*alternatively this proc can be run once to pass through every note and attempt to convert it before deleting the file, if done then AUTOCONVERT_NOTES should be turned off +this proc can take several minutes to execute fully if converting and cause DD to hang if converting a lot of notes; it's not advised to do so while a server is live +/proc/mass_convert_notes() + world << "Beginning mass note conversion" + var/savefile/notesfile = new(NOTESFILE) + if(!notesfile) + log_game("Error: Cannot access [NOTESFILE]") + return + notesfile.cd = "/" + for(var/ckey in notesfile.dir) + convert_notes_sql(ckey) + world << "Deleting NOTESFILE" + fdel(NOTESFILE) + world << "Finished mass note conversion, remember to turn off AUTOCONVERT_NOTES"*/ +#undef NOTESFILE \ No newline at end of file diff --git a/code/modules/client/client procs.dm b/code/modules/client/client procs.dm index 15de84c0369..233fee84513 100644 --- a/code/modules/client/client procs.dm +++ b/code/modules/client/client procs.dm @@ -175,6 +175,9 @@ var/next_external_rsc = 0 else winset(src, "rpane.changelogb", "background-color=#eaeaea;font-style=bold") + if (config && config.autoconvert_notes) + convert_notes_sql(ckey) + ////////////// //DISCONNECT// ////////////// diff --git a/config/config.txt b/config/config.txt index c40c7cc783f..6f12881387b 100644 --- a/config/config.txt +++ b/config/config.txt @@ -193,4 +193,7 @@ NOTIFY_NEW_PLAYER_AGE 0 #AGGRESSIVE_CHANGELOG ## Uncomment to have the game log runtimes to the log folder. (Note: this disables normal output in dd/ds, so it should be left off for testing. -#LOG_RUNTIMES \ No newline at end of file +#LOG_RUNTIMES + +##Comment this out if you've used the mass conversion sql proc for notes or want to stop converting notes +AUTOCONVERT_NOTES \ No newline at end of file From 005f0321086ba35626374e0c71df8812c3eb50dd Mon Sep 17 00:00:00 2001 From: Firecage Date: Mon, 17 Aug 2015 11:37:21 +0200 Subject: [PATCH 045/108] Changes a qdel back to del --- code/controllers/subsystem/server_maintenance.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/controllers/subsystem/server_maintenance.dm b/code/controllers/subsystem/server_maintenance.dm index 6a92044ac6d..1aa7ef7d1cc 100644 --- a/code/controllers/subsystem/server_maintenance.dm +++ b/code/controllers/subsystem/server_maintenance.dm @@ -11,7 +11,7 @@ if(!istype(C.mob, /mob/dead)) log_access("AFK: [key_name(C)]") C << "You have been inactive for more than 10 minutes and have been disconnected." - qdel(C) + del(C) if(config.sql_enabled) sql_poll_players() From f2f97006cd28c09c61e3867ed37aa3e5c54d6288 Mon Sep 17 00:00:00 2001 From: Remie Richards Date: Mon, 17 Aug 2015 13:06:04 +0100 Subject: [PATCH 046/108] Adds an animation to being electrocuted, like in cartoons! Adds some arguments to mutant bodypart icon procs to correctly render them in black for the duration of the animation. --- code/modules/mob/living/carbon/human/human.dm | 35 +++++++++- .../mob/living/carbon/human/species.dm | 64 +++++++++++------- icons/mob/human.dmi | Bin 71502 -> 80456 bytes 3 files changed, 72 insertions(+), 27 deletions(-) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 795c7e68da7..5c4bdac893b 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -280,7 +280,12 @@ heart_attack = 0 if(stat == CONSCIOUS) src << "You feel your heart beating again!" - return ..(shock_damage,source,siemens_coeff) + + . = ..(shock_damage,source,siemens_coeff) + if(.) + electrocution_animation(40) + + /mob/living/carbon/human/Topic(href, href_list) if(usr.canUseTopic(src, BE_CLOSE, NO_DEXTERY)) @@ -801,4 +806,30 @@ H.bloody_hands = 0 H.bloody_hands_mob = null H.update_inv_gloves() - update_icons() //apply the now updated overlays to the mob \ No newline at end of file + update_icons() //apply the now updated overlays to the mob + + + +//Turns a mob black, flashes a skeleton overlay +//Just like a cartoon! +/mob/living/carbon/human/proc/electrocution_animation(anim_duration) + //Handle mutant parts if possible + if(dna && dna.species) + dna.species.handle_mutant_bodyparts(src, "black") + dna.species.update_color(src, "black") + dna.species.handle_hair(src, "black") + overlays += "electrocuted_base" + spawn(anim_duration) + if(src) + if(dna && dna.species) + dna.species.handle_mutant_bodyparts(src) + dna.species.update_color(src) + dna.species.handle_hair(src) + overlays -= "electrocuted_base" + + else //or just do a generic animation + var/list/viewing = list() + for(var/mob/M in viewers(src)) + if(M.client) + viewing += M.client + flick_overlay(image(icon,src,"electrocuted_generic",MOB_LAYER+1), viewing, anim_duration) \ No newline at end of file diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index db366b79fb0..cbeb7e2f7ed 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -118,7 +118,7 @@ else return "[id]" -/datum/species/proc/update_color(mob/living/carbon/human/H) +/datum/species/proc/update_color(mob/living/carbon/human/H, forced_colour) H.remove_overlay(SPECIES_LAYER) var/image/standing @@ -135,7 +135,11 @@ spec_base = image("icon" = 'icons/mob/human.dmi', "icon_state" = icon_state_string, "layer" = -SPECIES_LAYER) - spec_base.color = "#[H.dna.features["mcolor"]]" + if(!forced_colour) + spec_base.color = "#[H.dna.features["mcolor"]]" + else + spec_base.color = forced_colour + standing = spec_base if(standing) @@ -143,7 +147,7 @@ H.apply_overlay(SPECIES_LAYER) -/datum/species/proc/handle_hair(mob/living/carbon/human/H) +/datum/species/proc/handle_hair(mob/living/carbon/human/H, forced_colour) H.remove_overlay(HAIR_LAYER) var/datum/sprite_accessory/S @@ -156,13 +160,17 @@ img_facial_s = image("icon" = S.icon, "icon_state" = "[S.icon_state]_s", "layer" = -HAIR_LAYER) - if(hair_color) - if(hair_color == "mutcolor") - img_facial_s.color = "#" + H.dna.features["mcolor"] + if(!forced_colour) + if(hair_color) + if(hair_color == "mutcolor") + img_facial_s.color = "#" + H.dna.features["mcolor"] + else + img_facial_s.color = "#" + hair_color else - img_facial_s.color = "#" + hair_color + img_facial_s.color = "#" + H.facial_hair_color else - img_facial_s.color = "#" + H.facial_hair_color + img_facial_s.color = forced_colour + img_facial_s.alpha = hair_alpha standing += img_facial_s @@ -184,13 +192,16 @@ img_hair_s = image("icon" = S.icon, "icon_state" = "[S.icon_state]_s", "layer" = -HAIR_LAYER) - if(hair_color) - if(hair_color == "mutcolor") - img_hair_s.color = "#" + H.dna.features["mcolor"] + if(!forced_colour) + if(hair_color) + if(hair_color == "mutcolor") + img_hair_s.color = "#" + H.dna.features["mcolor"] + else + img_hair_s.color = "#" + hair_color else - img_hair_s.color = "#" + hair_color + img_hair_s.color = "#" + H.hair_color else - img_hair_s.color = "#" + H.hair_color + img_hair_s.color = forced_colour img_hair_s.alpha = hair_alpha standing += img_hair_s @@ -246,7 +257,7 @@ return -/datum/species/proc/handle_mutant_bodyparts(mob/living/carbon/human/H) +/datum/species/proc/handle_mutant_bodyparts(mob/living/carbon/human/H, forced_colour) var/list/bodyparts_to_add = mutant_bodyparts.Copy() var/list/relevent_layers = list(BODY_BEHIND_LAYER, BODY_ADJ_LAYER, BODY_FRONT_LAYER) var/list/standing = list() @@ -359,18 +370,21 @@ I = image("icon" = 'icons/mob/mutant_bodyparts.dmi', "icon_state" = icon_string, "layer" =- layer) if(!(H.disabilities & HUSK)) - switch(S.color_src) - if(MUTCOLORS) - I.color = "#[H.dna.features["mcolor"]]" - if(HAIR) - if(hair_color == "mutcolor") + if(!forced_colour) + switch(S.color_src) + if(MUTCOLORS) I.color = "#[H.dna.features["mcolor"]]" - else - I.color = "#[H.hair_color]" - if(FACEHAIR) - I.color = "#[H.facial_hair_color]" - if(EYECOLOR) - I.color = "#[H.eye_color]" + if(HAIR) + if(hair_color == "mutcolor") + I.color = "#[H.dna.features["mcolor"]]" + else + I.color = "#[H.hair_color]" + if(FACEHAIR) + I.color = "#[H.facial_hair_color]" + if(EYECOLOR) + I.color = "#[H.eye_color]" + else + I.color = forced_colour standing += I if(S.hasinner) diff --git a/icons/mob/human.dmi b/icons/mob/human.dmi index 2156fd46e0a325136f8c7773c42076bdaa67463e..cb72485b1bc42d00de8030da0d20f5fa32053b8f 100644 GIT binary patch literal 80456 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 From 5681bbbd9becd97019a74b32fe8ae24e1f7fc4c9 Mon Sep 17 00:00:00 2001 From: Remie Richards Date: Mon, 17 Aug 2015 14:16:05 +0100 Subject: [PATCH 047/108] Updates human species to use update_color(), fixing humans not flashing black for the duration of the electrocution animation. Minor restructuring of redundant lines in update_icons.dm --- code/modules/mob/living/carbon/human/human.dm | 8 ++++---- code/modules/mob/living/carbon/human/species.dm | 17 ++++++++++++----- .../mob/living/carbon/human/update_icons.dm | 12 ++---------- 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 5c4bdac893b..ec19362de9b 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -815,16 +815,16 @@ /mob/living/carbon/human/proc/electrocution_animation(anim_duration) //Handle mutant parts if possible if(dna && dna.species) - dna.species.handle_mutant_bodyparts(src, "black") - dna.species.update_color(src, "black") - dna.species.handle_hair(src, "black") + dna.species.handle_mutant_bodyparts(src,"black") + dna.species.handle_hair(src,"black") + dna.species.update_color(src,"black") overlays += "electrocuted_base" spawn(anim_duration) if(src) if(dna && dna.species) dna.species.handle_mutant_bodyparts(src) - dna.species.update_color(src) dna.species.handle_hair(src) + dna.species.update_color(src) overlays -= "electrocuted_base" else //or just do a generic animation diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index cbeb7e2f7ed..bcad1cea1af 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -125,17 +125,24 @@ var/g = (H.gender == FEMALE) ? "f" : "m" - if(MUTCOLORS in specflags) + if((MUTCOLORS in specflags) || use_skintones) var/image/spec_base var/icon_state_string = "[id]_" - if(sexes) - icon_state_string += "[g]_s" + + if(use_skintones) + if(sexes) + icon_state_string = "[H.skin_tone]_[g]_s" + else + icon_state_string = "[H.skin_tone]_s" else - icon_state_string += "_s" + if(sexes) + icon_state_string += "[g]_s" + else + icon_state_string += "_s" spec_base = image("icon" = 'icons/mob/human.dmi', "icon_state" = icon_state_string, "layer" = -SPECIES_LAYER) - if(!forced_colour) + if(!forced_colour && !use_skintones) spec_base.color = "#[H.dna.features["mcolor"]]" else spec_base.color = forced_colour diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm index 8f8f5829970..69d80ba80ba 100644 --- a/code/modules/mob/living/carbon/human/update_icons.dm +++ b/code/modules/mob/living/carbon/human/update_icons.dm @@ -53,7 +53,6 @@ Please contact me on #coderbus IRC. ~Carnie x */ /mob/living/carbon/human/proc/update_base_icon_state() - //var/race = dna ? dna.mutantrace : null if(dna) base_icon_state = dna.species.update_base_icon_state(src) else @@ -68,7 +67,6 @@ Please contact me on #coderbus IRC. ~Carnie x //UPDATES OVERLAYS FROM OVERLAYS_STANDING //TODO: Remove all instances where this proc is called. It used to be the fastest way to swap between standing/lying. /mob/living/carbon/human/update_icons() - update_hud() //TODO: remove the need for this if(overlays.len != overlays_standing.len) @@ -79,7 +77,6 @@ Please contact me on #coderbus IRC. ~Carnie x update_transform() - //DAMAGE OVERLAYS //constructs damage icon for each organ from mask * damage field and saves it in our overlays_ lists /mob/living/carbon/human/update_damage_overlays() @@ -123,14 +120,9 @@ Please contact me on #coderbus IRC. ~Carnie x /mob/living/carbon/human/proc/update_body() remove_overlay(BODY_LAYER) + update_base_icon_state() + if(dna) - base_icon_state = dna.species.update_base_icon_state(src) - else - update_base_icon_state() - - icon_state = "[base_icon_state]_s" - - if(dna) // didn't want to have a duplicate if(dna) here, but due to the ordering of the code this was the only way dna.species.handle_body(src) /mob/living/carbon/human/update_fire() From dd359896da1ad341064ac70084ca7471cc0d355d Mon Sep 17 00:00:00 2001 From: GunHog Date: Mon, 17 Aug 2015 11:37:19 -0500 Subject: [PATCH 048/108] Fixes teleporter deconstruction Teleporter console and hub components did not call ..() in their destroy, making it possible to spawn multiple machine frames by using a crowbar rapidly in the few seconds it takes for the hub component to be deleted. - Adds missing parent calls to fix the issue. --- code/game/machinery/teleporter.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/machinery/teleporter.dm b/code/game/machinery/teleporter.dm index e341ca965b6..4b0725b060c 100644 --- a/code/game/machinery/teleporter.dm +++ b/code/game/machinery/teleporter.dm @@ -25,6 +25,7 @@ if (power_station) power_station.teleporter_console = null power_station = null + ..() /obj/machinery/computer/teleporter/proc/link_power_station() if(power_station) @@ -268,6 +269,7 @@ if (power_station) power_station.teleporter_hub = null power_station = null + ..() /obj/machinery/teleport/hub/RefreshParts() var/A = 0 From f4791fa6c440149dfbc7e3aa040d066b11e6c64d Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Mon, 17 Aug 2015 18:51:09 -0400 Subject: [PATCH 049/108] REVENANTS MILDLY LESS COMMON. I'm not all that surprised they were too common, I set this pretty generously. --- .../mob/living/simple_animal/revenant/revenant_spawn_event.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm b/code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm index b89653728ab..0db127f03ae 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm @@ -3,9 +3,9 @@ /datum/round_event_control/revenant name = "Spawn Revenant" typepath = /datum/round_event/revenant - weight = 30 + weight = 20 max_occurrences = 3 - earliest_start = 3000 //Meant to mix things up early-game. + earliest_start = 6000 //Meant to mix things up early-game. /datum/round_event/revenant From 2c5a3360c515d2545d73ddff0fa454d7843b4b02 Mon Sep 17 00:00:00 2001 From: Orange Borg Date: Tue, 18 Aug 2015 14:35:55 +1200 Subject: [PATCH 050/108] clean up world.dm The war on commented code and bad comments continues --- code/world.dm | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/code/world.dm b/code/world.dm index d515df42aed..9635e3fe995 100644 --- a/code/world.dm +++ b/code/world.dm @@ -19,10 +19,6 @@ #endif //logs var/date_string = time2text(world.realtime, "YYYY/MM-Month/DD-Day") -// if(revdata && istext(revdata.revision) && length(revdata.revision)>7) -// log = file("data/logs/runtime/[copytext(revdata.revision,1,8)].log") -// else -// log = file("data/logs/runtime/[time2text(world.realtime,"YYYY-MM")].log") //funtimelog href_logfile = file("data/logs/[date_string] hrefs.htm") diary = file("data/logs/[date_string].log") diaryofmeanpeople = file("data/logs/[date_string] Attack.log") @@ -46,7 +42,6 @@ investigate_reset() if(config && config.server_name != null && config.server_suffix && world.port > 0) - // dumb and hardcoded but I don't care~ config.server_name += " #[(world.port % 1000) / 100]" timezoneOffset = text2num(time2text(0,"hh")) * 36000 @@ -128,7 +123,7 @@ if(input["key"] != global.comms_key) return "Bad Key" else -#define CHAT_PULLR 64 //for some reason this has to be here, not sure why. Look in preferences.dm for the "proper" definition. +#define CHAT_PULLR 64 //defined in preferences.dm, but not available here at compilation time for(var/client/C in clients) if(C.prefs && (C.prefs.chat_toggles & CHAT_PULLR)) C << "PR: [input["announce"]]" @@ -156,7 +151,6 @@ #ifdef dellogging var/log = file("data/logs/del.log") log << time2text(world.realtime) - //mergeSort(del_counter, /proc/cmp_descending_associative) //still testing the sorting procs. Use notepad++ to sort the resultant logfile for now. for(var/index in del_counter) var/count = del_counter[index] if(count > 10) @@ -170,7 +164,6 @@ for(var/client/C in clients) if(config.server) //if you set a server location in config.txt, it sends you there instead of trying to reconnect to the same world address. -- NeoFite C << link("byond://[config.server]") - // Note: all clients automatically connect to the world after it restarts ..(0) @@ -295,4 +288,4 @@ var/failed_db_connections = 0 else return 1 -#undef FAILED_DB_CONNECTION_CUTOFF \ No newline at end of file +#undef FAILED_DB_CONNECTION_CUTOFF From 7d3e671a728cae21a6b70d64e0b87ca4bf044762 Mon Sep 17 00:00:00 2001 From: Orange Borg Date: Tue, 18 Aug 2015 14:44:01 +1200 Subject: [PATCH 051/108] Move eject check, clean up dead code in SSU --- code/game/machinery/suit_storage_unit.dm | 86 ++++++++---------------- 1 file changed, 27 insertions(+), 59 deletions(-) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index e881e2f0a30..fb7c9548e6f 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -10,19 +10,24 @@ icon_state = "close" anchored = 1 density = 1 + //Vars to hold internal items var/mob/living/OCCUPANT = null var/obj/item/clothing/suit/space/SUIT = null - var/SUIT_TYPE = null var/obj/item/clothing/head/helmet/space/HELMET = null + var/obj/item/clothing/mask/MASK = null + var/obj/item/STORAGE = null + + //Base types on creation + var/SUIT_TYPE = null var/HELMET_TYPE = null - var/obj/item/clothing/mask/MASK = null //All the stuff that's gonna be stored insiiiiiiiiiiiiiiiiiiide, nyoro~n - var/MASK_TYPE = null //Erro's idea on standarising SSUs whle keeping creation of other SSU types easy: Make a child SSU, name it something then set the TYPE vars to your desired suit output. New() should take it from there by itself. - var/obj/item/STORAGE = null //One-slot storage slot for anything... food not recommended + var/MASK_TYPE = null var/STORAGE_TYPE = null + + //Machine related vars var/isopen = 0 var/islocked = 0 var/isUV = 0 - var/ispowered = 1 //starts powered + var/ispowered = 1 var/isbroken = 0 var/issuperUV = 0 var/panelopen = 0 @@ -30,7 +35,6 @@ var/cycletime_left = 0 -//The units themselves///////////////// /obj/machinery/suit_storage_unit/standard_unit SUIT_TYPE = /obj/item/clothing/suit/space/eva @@ -168,17 +172,13 @@ dat+= "Suit storage unit: Maintenance panel" dat+= "Maintenance panel controls
" dat+= "The panel is ridden with controls, button and meters, labeled in strange signs and symbols that
you cannot understand. Probably the manufactoring world's language.
Among other things, a few controls catch your eye.

" - dat+= text("A small dial with a \"ë\" symbol embroidded on it. It's pointing towards a gauge that reads [].
Turn towards []
",(src.issuperUV ? "15nm" : "185nm"),src,(src.issuperUV ? "185nm" : "15nm") ) + dat+= text("A small dial with a \"ë\" symbol embroidded on it. It's pointing towards a gauge that reads [].
Turn towards []
",(src.issuperUV ? "15nm" : "185nm"),src,(src.issuperUV ? "185nm" : "15nm") ) dat+= text("A thick old-style button, with 2 grimy LED lights next to it. The [] LED is on.
Press button",(src.safetieson? "GREEN" : "RED"),src) dat+= text("

Close panel", user) - //user << browse(dat, "window=ssu_m_panel;size=400x500") - //onclose(user, "ssu_m_panel") else if(src.isUV) //The thing is running its cauterisation cycle. You have to wait. dat += "Suit storage unit" dat+= "Unit is cauterising contents with selected UV ray intensity. Please wait.
" - //dat+= "Cycle end in: [src.cycletimeleft()] seconds. " - //user << browse(dat, "window=ssu_cycling_panel;size=400x500") - //onclose(user, "ssu_cycling_panel") + else if(!src.isbroken) @@ -208,14 +208,12 @@ dat+= text("Unit status: []",(src.islocked? "**LOCKED**
" : "**UNLOCKED**
") ) dat+= text("Start Disinfection cycle
",src) dat += text("

Close control panel", user) - //user << browse(dat, "window=Suit Storage Unit;size=400x500") - //onclose(user, "Suit Storage Unit") + else //Ohhhh shit it's dirty or broken! Let's inform the guy. dat+= "Suit storage unit" dat+= "Unit chamber is too contaminated to continue usage. Please call for a qualified individual to perform maintenance.

" dat+= text("
Close control panel", user) - //user << browse(dat, "window=suit_storage_unit;size=400x500") - //onclose(user, "suit_storage_unit") + var/datum/browser/popup = new(user, "suit_storage_unit", "Suit Storage Unit", 440, 500) popup.set_content(dat) @@ -227,7 +225,7 @@ /obj/machinery/suit_storage_unit/Topic(href, href_list) //I fucking HATE this proc if(..()) return - if(usr == src.OCCUPANT) //No unlocking yourself out! + if(usr == src.OCCUPANT) return if ((usr.contents.Find(src) || ((get_dist(src, usr) <= 1) && istype(src.loc, /turf))) || (istype(usr, /mob/living/silicon/ai))) usr.set_machine(src) @@ -253,29 +251,15 @@ src.eject_occupant(usr) src.updateUsrDialog() src.update_icon() - /*if (href_list["refresh"]) - src.updateUsrDialog()*/ src.add_fingerprint(usr) return /obj/machinery/suit_storage_unit/proc/toggleUV(mob/user) -// var/protected = 0 -// var/mob/living/carbon/human/H = user if(!src.panelopen) return - - /*if(istype(H)) //Let's check if the guy's wearing electrically insulated gloves - if(H.gloves) - var/obj/item/clothing/gloves/G = H.gloves - if(istype(G,/obj/item/clothing/gloves/yellow)) - protected = 1 - - if(!protected) - playsound(src.loc, "sparks", 75, 1, -1) - user << "You try to touch the controls but you get zapped. There must be a short circuit somewhere." - return*/ - else //welp, the guy is protected, we can continue + + else if(src.issuperUV) user << "You slide the dial back towards \"185nm\"." src.issuperUV = 0 @@ -286,21 +270,8 @@ /obj/machinery/suit_storage_unit/proc/togglesafeties(mob/user) -// var/protected = 0 -// var/mob/living/carbon/human/H = user if(!src.panelopen) //Needed check due to bugs return - - /*if(istype(H)) //Let's check if the guy's wearing electrically insulated gloves - if(H.gloves) - var/obj/item/clothing/gloves/G = H.gloves - if(istype(G,/obj/item/clothing/gloves/yellow) ) - protected = 1 - - if(!protected) - playsound(src.loc, "sparks", 75, 1, -1) - user << "You try to touch the controls but you get zapped. There must be a short circuit somewhere." - return*/ else user << "You push the button. The coloured LED next to it changes." src.safetieson = !src.safetieson @@ -319,12 +290,13 @@ MASK = null /obj/machinery/suit_storage_unit/proc/eject_storage() - if(STORAGE) - eject(STORAGE) - STORAGE = null + eject(STORAGE) + STORAGE = null /obj/machinery/suit_storage_unit/proc/eject(atom/movable/ITEM) - ITEM.loc = src.loc + //Check item still exists - if not, then usually someone has already ejected the item + if(ITEM) + ITEM.loc = src.loc /obj/machinery/suit_storage_unit/proc/dump_everything() for(var/obj/item/ITEM in src) @@ -365,7 +337,7 @@ if(src.OCCUPANT && src.safetieson) user << "WARNING: Biological entity detected in the confines of the Unit's storage. Cannot initiate cycle." return - if(!src.HELMET && !src.MASK && !src.SUIT && !src.STORAGE && !src.OCCUPANT ) //shit's empty yo + if(!src.HELMET && !src.MASK && !src.SUIT && !src.STORAGE && !src.OCCUPANT ) user << "Unit storage bays empty. Nothing to disinfect -- Aborting." return user << "You start the Unit's cauterisation cycle." @@ -376,7 +348,7 @@ src.update_icon() src.updateUsrDialog() - var/i //our counter + var/i spawn(0) for(i=0,i<4,++i) sleep(50) @@ -404,7 +376,7 @@ src.isbroken = 1 src.isopen = 1 src.islocked = 0 - src.eject_occupant(OCCUPANT) //Mixing up these two lines causes bug. DO NOT DO IT. + src.eject_occupant(OCCUPANT) src.isUV = 0 //Cycle ends src.update_icon() src.updateUsrDialog() @@ -422,8 +394,6 @@ if (!src.OCCUPANT) return -// for(var/obj/O in src) -// O.loc = src.loc if (src.OCCUPANT.client) if(user != OCCUPANT) @@ -437,7 +407,7 @@ src.OCCUPANT.loc = src.loc src.OCCUPANT = null if(!src.isopen) - src.isopen = 1 + src.isopeen = 1 src.update_icon() return @@ -495,7 +465,7 @@ M.client.eye = src M.loc = src src.OCCUPANT = M - src.isopen = 0 //Close the thing after the guy gets inside + src.isopen = 0 src.update_icon() src.add_fingerprint(user) @@ -596,5 +566,3 @@ user << "The console controls are far too complicated for your tiny brain!" return - -//////////////////////////////REMINDER: Make it lock once you place some fucker inside. From 28866b07ad391025f17115888229bfaf2711598d Mon Sep 17 00:00:00 2001 From: Orange Borg Date: Tue, 18 Aug 2015 14:51:02 +1200 Subject: [PATCH 052/108] Fix spelling error introduce in cleanup of SSU code --- code/game/machinery/suit_storage_unit.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/machinery/suit_storage_unit.dm b/code/game/machinery/suit_storage_unit.dm index fb7c9548e6f..4ba8fe8a619 100644 --- a/code/game/machinery/suit_storage_unit.dm +++ b/code/game/machinery/suit_storage_unit.dm @@ -407,7 +407,7 @@ src.OCCUPANT.loc = src.loc src.OCCUPANT = null if(!src.isopen) - src.isopeen = 1 + src.isopen = 1 src.update_icon() return From eb30a83028903ed6455c260a1bcd685bc031c90b Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Mon, 17 Aug 2015 23:11:16 -0400 Subject: [PATCH 053/108] Splits defile into two abilities, Defile and Malfunction. Harvest now can be activated by clicking the target while in range. Defile affects a 7x7 area, damaging windows, tiring humans, and corrupting tiles. Malfunction affects a 9x9 area, emagging bots, disabling cyborgs, and emping or emagging machines. Defile and Overload Lights now briefly stun you so you can't just trigger and run instantly. Fixed a bunch of Harvest bugs. --- code/game/machinery/alarm.dm | 6 +- code/game/machinery/portable_turret.dm | 2 +- .../living/simple_animal/revenant/revenant.dm | 101 +++++++++- .../revenant/revenant_abilities.dm | 177 ++++++++---------- code/modules/power/singularity/emitter.dm | 3 +- 5 files changed, 180 insertions(+), 109 deletions(-) diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm index cfcd3967614..ca14b8c64ae 100644 --- a/code/game/machinery/alarm.dm +++ b/code/game/machinery/alarm.dm @@ -810,7 +810,8 @@ /obj/machinery/alarm/emag_act(mob/user) if(!emagged) src.emagged = 1 - user.visible_message("Sparks fly out of the [src]!", "You emag the [src], disabling its safeties.") + if(user) + user.visible_message("Sparks fly out of the [src]!", "You emag the [src], disabling its safeties.") playsound(src.loc, 'sound/effects/sparks4.ogg', 50, 1) return @@ -938,7 +939,8 @@ FIRE ALARM /obj/machinery/firealarm/emag_act(mob/user) if(!emagged) src.emagged = 1 - user.visible_message("Sparks fly out of the [src]!", "You emag the [src], disabling its thermal sensors.") + if(user) + user.visible_message("Sparks fly out of the [src]!", "You emag the [src], disabling its thermal sensors.") playsound(src.loc, 'sound/effects/sparks4.ogg', 50, 1) return diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 707abc57f65..f0a2c610a61 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -1092,7 +1092,7 @@ Status: []
"}, user << "You short out the turret controls' access analysis module." emagged = 1 locked = 0 - if(user.machine==src) + if(user && user.machine==src) src.attack_hand(user) /obj/machinery/turretid/attack_ai(mob/user) diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm index 0a984a21f4b..6019eac3842 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm @@ -37,6 +37,9 @@ var/essence_accumulated = 0 //How much essence the revenant has stolen var/revealed = 0 //If the revenant can take damage from normal sources. var/inhibited = 0 //If the revenant's abilities are blocked by a chaplain's power. + var/essence_drained = 0 //How much essence the revenant has drained. + var/draining = 0 //If the revenant is draining someone. + var/list/drained_mobs = list() //Cannot harvest the same mob twice /mob/living/simple_animal/revenant/Life() ..() @@ -78,6 +81,77 @@ if(world.time <= next_move) return A.attack_ghost(src) + if(ishuman(A) && in_range(src, A)) + Harvest(A, src) + + +/mob/living/simple_animal/revenant/proc/Harvest(mob/living/carbon/human/tar, mob/living/simple_animal/revenant/user = usr) + if(!user.castcheck(-30)) + return + var/mob/living/carbon/human/target = tar + if(user.draining) + user << "You are already siphoning the essence of a soul!" + return + if(target in user.drained_mobs) + user << "[target]'s soul is dead and empty." + return + if(!target.stat) + user << "This being's soul is too strong to harvest." + if(prob(10)) + target << "You feel as if you are being watched." + return + draining = 1 + essence_drained = 2 + user << "You search for the soul of [target]." + sleep(10) + if(target) //did they get deleted in that second? + if(target.ckey) + user << "Their soul burns with intelligence." + essence_drained += 2 + if(target.stat != DEAD) + user << "Their soul blazes with life!" + essence_drained += 2 + else + user << "Their soul is weak and faltering." + sleep(20) + if(target) //did they get deleted NOW? + switch(essence_drained) + if(1 to 2) + user << "[target] will not yield much essence. Still, every bit counts." + if(3 to 4) + user << "[target] will yield an average amount of essence." + if(5 to INFINITY) + user << "Such a feast! [target] will yield much essence to you." + sleep(30) + if(target) //how about now + if(!in_range(user, target)) + user << "You are not close enough to siphon [target]'s soul. The link has been broken." + draining = 0 + return + if(!target.stat) + user << "They are now powerful enough to fight off your draining." + target << "You feel something tugging across your body before subsiding." + draining = 0 + return //hey, wait a minute... + user << "You begin siphoning essence from [target]'s soul." + if(target.stat != DEAD) + target << "You feel a horribly unpleasant draining sensation as your grip on life weakens..." + user.icon_state = "revenant_draining" + user.reveal(65) + user.stun(65) + target.visible_message("[target] suddenly rises slightly into the air, their skin turning an ashy gray.") + target.Beam(user,icon_state="drain_life",icon='icons/effects/effects.dmi',time=60) + if(target) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining. + user.change_essence_amount(essence_drained * 5, 0, target) + user << "[target]'s soul has been considerably weakened and will yield no more essence for the time being." + target.visible_message("[target] gently slumps back onto the ground.") + drained_mobs.Add(target) + target.death(0) + user.icon_state = "revenant_idle" + draining = 0 + draining = 0 + return + /mob/living/simple_animal/revenant/say(message) return 0 //Revenants cannot speak out loud. @@ -125,6 +199,7 @@ src.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_transmit src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_light src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_defile + src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_malf return 1 return 0 @@ -196,21 +271,33 @@ -/mob/living/simple_animal/revenant/proc/reveal(time, stun) +/mob/living/simple_animal/revenant/proc/reveal(time) var/mob/living/simple_animal/revenant/R = usr if(!istype(usr) || !usr) return + if(time <= 0) + return R.revealed = 1 R.invisibility = 0 - if(stun) - R.notransform = 1 - R << "You have been revealed[stun ? " and cannot move" : ""]." + R << "You have been revealed." spawn(time) R.revealed = 0 R.invisibility = INVISIBILITY_OBSERVER - if(stun) - R.notransform = 0 - R << "You are once more concealed[stun ? " and can move again" : ""]." + R << "You are once more concealed." + +/mob/living/simple_animal/revenant/proc/stun(time) + var/mob/living/simple_animal/revenant/R = usr + if(!istype(usr) || !usr) + return + if(time <= 0) + return + R.notransform = 1 + R << "You cannot move!" + spawn(time) + R.notransform = 0 + R << "You can move again!" + + /datum/objective/revenant dangerrating = 10 diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm index 4bd9418c2e9..137c80317c1 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm @@ -1,102 +1,29 @@ //Harvest Essence: The bread and butter of the revenant. The basic way of harvesting additional essence. /obj/effect/proc_holder/spell/targeted/revenant_harvest - name = "Harvest (0E)" + name = "Harvest" desc = "Siphons the lingering spectral essence from a human, empowering yourself." panel = "Revenant Abilities" - charge_max = 100 //Short cooldown + charge_max = 0 //No cooldown clothes_req = 0 range = 1 - var/essence_drained = 0 - var/draining - var/list/drained_mobs = list() //Cannot harvest the same mob twice /obj/effect/proc_holder/spell/targeted/revenant_harvest/cast(list/targets, mob/living/simple_animal/revenant/user = usr) - if(!user.castcheck(0)) - charge_counter = charge_max - return for(var/mob/living/carbon/human/target in targets) spawn(0) - if(draining) - user << "You are already siphoning the essence of a soul!" - charge_counter = charge_max - return - if(target in drained_mobs) - user << "[target]'s soul is dead and empty." - charge_counter = charge_max - return - if(!target.stat) - user << "This being's soul is too strong to harvest." - if(prob(10)) - target << "You feel as if you are being watched." - return - draining = 1 - essence_drained = 2 - user << "You search for the soul of [target]." - sleep(10) - if(target.ckey) - user << "Their soul burns with intelligence." - essence_drained += 2 - if(target.stat != DEAD) - user << "Their soul blazes with life!" - essence_drained += 2 - else - user << "Their soul is weak and faltering." - sleep(20) - switch(essence_drained) - if(1 to 2) - user << "[target] will not yield much essence. Still, every bit counts." - if(3 to 4) - user << "[target] will yield an average amount of essence." - if(5 to INFINITY) - user << "Such a feast! [target] will yield much essence to you." - sleep(30) - if(!in_range(user, target)) - user << "You are not close enough to siphon [target]'s soul. The link has been broken." - draining = 0 - return - if(!target.stat) - user << "They are now powerful enough to fight off your draining." - target << "You feel something tugging across your body before subsiding." - return //hey, wait a minute... - user << "You begin siphoning essence from [target]'s soul." - if(target.stat != DEAD) - target << "You feel a horribly unpleasant draining sensation as your grip on life weakens..." - user.icon_state = "revenant_draining" - user.reveal(65,1) - target.visible_message("[target] suddenly rises slightly into the air, their skin turning an ashy gray.") - target.Beam(user,icon_state="drain_life",icon='icons/effects/effects.dmi',time=60) - target.death(0) - target.visible_message("[target] gently slumps back onto the ground.") - user.icon_state = "revenant_idle" - user.change_essence_amount(essence_drained * 5, 0, target) - user << "[target]'s soul has been considerably weakened and will yield no more essence for the time being." - drained_mobs.Add(target) - draining = 0 + user.Harvest(target, user) //Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob for 5E. /obj/effect/proc_holder/spell/targeted/revenant_transmit - name = "Transmit (5E)" + name = "Transmit" desc = "Telepathically transmits a message to the target." - panel = "Revenant Abilities (Locked)" - charge_max = 50 + panel = "Revenant Abilities" + charge_max = 0 clothes_req = 0 - range = -1 - include_user = 1 - var/locked = 1 + range = 7 + include_user = 0 /obj/effect/proc_holder/spell/targeted/revenant_transmit/cast(list/targets, mob/living/simple_animal/revenant/user = usr) - if(!user.castcheck(-5)) - charge_counter = charge_max - return - if(locked) - usr << "You have unlocked Transmit!" - locked = 0 - charge_counter = charge_max - panel = "Revenant Abilities" - range = 7 - include_user = 0 - return for(var/mob/living/M in targets) spawn(0) var/msg = stripped_input(usr, "What do you wish to tell [M]?", null, "") @@ -115,6 +42,8 @@ charge_max = 200 clothes_req = 0 range = 1 + var/reveal = 80 + var/stun = 10 var/locked = 1 /obj/effect/proc_holder/spell/aoe_turf/revenant_light/cast(list/targets, mob/living/simple_animal/revenant/user = usr) @@ -126,7 +55,7 @@ name = "Overload Lights (20E)" panel = "Revenant Abilities" locked = 0 - range = 5 + range = 6 charge_counter = charge_max return if(!user.castcheck(-20)) @@ -153,29 +82,32 @@ z.set_up(4, 1, M) z.start() playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1) - user.reveal(80) + user.reveal(reveal) + user.stun(stun) //Defile: Corrupts nearby stuff, unblesses floor tiles. /obj/effect/proc_holder/spell/aoe_turf/revenant_defile - name = "Defile (40E)" - desc = "Twists and corrupts certain nearby objects. Also dispels holy auras on floors, but not salt lines." + name = "Defile (35E)" + desc = "Twists and corrupts the nearby area. Also dispels holy auras on floors, but not salt lines." panel = "Revenant Abilities (Locked)" charge_max = 200 clothes_req = 0 range = 1 + var/reveal = 100 + var/stun = 10 var/locked = 1 /obj/effect/proc_holder/spell/aoe_turf/revenant_defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr) if(locked) - if(!user.castcheck(-40)) + if(!user.castcheck(-35)) charge_counter = charge_max return user << "You have unlocked Defile!" name = "Defile (20E)" panel = "Revenant Abilities" locked = 0 - range = 4 + range = 3 charge_counter = charge_max return if(!user.castcheck(-20)) @@ -185,22 +117,71 @@ spawn(0) if(T.flags & NOJAUNT) T.flags -= NOJAUNT - for(var/obj/machinery/bot/bot in T.contents) - bot.locked = 0 - bot.open = 1 - bot.emagged = 2 - bot.Emag(null) + if(!istype(T, /turf/simulated/wall/cult) && istype(T, /turf/simulated/wall) && prob(30)) + T.ChangeTurf(/turf/simulated/wall/cult) + if(!istype(T, /turf/simulated/floor/engine/cult) && istype(T, /turf/simulated/floor) && prob(30)) + T.ChangeTurf(/turf/simulated/floor/engine/cult) for(var/mob/living/carbon/human/human in T.contents) human << "You suddenly feel tired." - human.adjustStaminaLoss(50) + human.adjustStaminaLoss(35) + for(var/obj/structure/window/window in T.contents) + window.hit(rand(50,125)) + for(var/obj/machinery/light/light in T.contents) + light.flicker() //spooky + user.reveal(reveal) + user.stun(stun) + + +//Malfunction: Makes bad stuff happen to robots and machines. +/obj/effect/proc_holder/spell/aoe_turf/revenant_malf + name = "Malfunction (50E)" + desc = "Corrupts and damages nearby machines and mechanical objects." + panel = "Revenant Abilities (Locked)" + charge_max = 150 + clothes_req = 0 + range = 1 + var/reveal = 60 + var/stun = 30 + var/locked = 1 + +/obj/effect/proc_holder/spell/aoe_turf/revenant_malf/cast(list/targets, mob/living/simple_animal/revenant/user = usr) + if(locked) + if(!user.castcheck(-35)) + charge_counter = charge_max + return + user << "You have unlocked Malfunction!" + name = "Malfunction (15E)" + panel = "Revenant Abilities" + locked = 0 + range = 4 + charge_counter = charge_max + return + if(!user.castcheck(-15)) + charge_counter = charge_max + return + for(var/turf/T in targets) + spawn(0) + for(var/obj/machinery/bot/bot in T.contents) + if(!bot.emagged) + bot.locked = 0 + bot.open = 1 + bot.Emag(null) for(var/mob/living/silicon/robot/robot in T.contents) robot.visible_message("[robot] lets out an alarm!", \ "01001111 01010110 01000101 01010010 01001100 01001111 01000001 01000100") //Translates to "OVERLOAD" robot << 'sound/misc/interference.ogg' robot.emp_act(2) playsound(robot, 'sound/machines/warning-buzzer.ogg', 50, 1) - for(var/obj/structure/window/window in T.contents) - window.hit(rand(50,200)) - for(var/obj/machinery/light/light in T.contents) - light.flicker() //spooky - user.reveal(100) + for(var/mob/living/carbon/human/human in T.contents) + human << "You feel a burst of cold throughout your body..." + human.emp_act(2) + for(var/obj/machinery/mach in T.contents) + switch(rand(1,6)) + if(1) + mach.emp_act(1) + if(2 to 3) + mach.emp_act(2) + if(4) + mach.emag_act(null) + user.reveal(reveal) + user.stun(stun) \ No newline at end of file diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm index 23e6468096f..a054fece023 100644 --- a/code/modules/power/singularity/emitter.dm +++ b/code/modules/power/singularity/emitter.dm @@ -264,4 +264,5 @@ if(!emagged) locked = 0 emagged = 1 - user.visible_message("[user.name] emags the [src.name].","You short out the lock.") + if(user) + user.visible_message("[user.name] emags the [src.name].","You short out the lock.") From d2735f42a0fd32fdf60c2e393f16393ca0d394ed Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Mon, 17 Aug 2015 23:21:12 -0400 Subject: [PATCH 054/108] Changelog, changelogs are fun! --- html/changelogs/revenants.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 html/changelogs/revenants.yml diff --git a/html/changelogs/revenants.yml b/html/changelogs/revenants.yml new file mode 100644 index 00000000000..ac8fb389e39 --- /dev/null +++ b/html/changelogs/revenants.yml @@ -0,0 +1,10 @@ +author: Joan + +delete-after: True + +changes: + - rscadd: "Added a new revenant ability; Malfunction. It does bad stuff to machines." + - tweak: "Defile and Overload Lights now briefly stun the revenant." + - tweak: "You can now Harvest a target by clicking on them while next to them." + - bugfix: "Harvest no longer leaves you draining if the target is deleted mid-drain attempt." + - rscdel: "Defile no longer emags bots or disables cyborgs, Malfunction does that now." From 735a5bc5a1dddf00ad38b1d00438d4677d09888c Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Mon, 17 Aug 2015 23:24:45 -0400 Subject: [PATCH 055/108] there was no bug here --- code/modules/mob/living/simple_animal/revenant/revenant.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm index 6019eac3842..1a4ef7641cc 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm @@ -86,7 +86,7 @@ /mob/living/simple_animal/revenant/proc/Harvest(mob/living/carbon/human/tar, mob/living/simple_animal/revenant/user = usr) - if(!user.castcheck(-30)) + if(!user.castcheck(0)) return var/mob/living/carbon/human/target = tar if(user.draining) From 1d9bf04edcc6ee876855f1c6f6235b9fd5a094b3 Mon Sep 17 00:00:00 2001 From: Aranclanos Date: Tue, 18 Aug 2015 03:02:09 -0300 Subject: [PATCH 056/108] Adds a Destroy() for the disposal pipe trunk. Fixes vent_gas() from the disposal holder from trying to update the air while GCed --- code/modules/recycling/disposal-structures.dm | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/code/modules/recycling/disposal-structures.dm b/code/modules/recycling/disposal-structures.dm index ca1364644be..3511e08142e 100644 --- a/code/modules/recycling/disposal-structures.dm +++ b/code/modules/recycling/disposal-structures.dm @@ -59,7 +59,6 @@ if(!D.trunk) D.expel(src) // no trunk connected, so expel immediately return - loc = D.trunk active = 1 dir = DOWN @@ -122,11 +121,9 @@ playsound(src.loc, 'sound/effects/clang.ogg', 50, 0, 0) // called to vent all gas in holder to a location -/obj/structure/disposalholder/proc/vent_gas(atom/location) - if(location) - location.assume_air(gas) // vent all gas to turf - air_update_turf() - return +/obj/structure/disposalholder/proc/vent_gas(turf/T) + T.assume_air(gas) + T.air_update_turf() /obj/structure/disposalholder/allow_drop() return 1 @@ -637,6 +634,16 @@ update() return +/obj/structure/disposalpipe/trunk/Destroy() + if(linked) + if(istype(linked, /obj/structure/disposaloutlet)) + var/obj/structure/disposaloutlet/D = linked + D.trunk = null + else if(istype(linked, /obj/machinery/disposal)) + var/obj/machinery/disposal/D = linked + D.trunk = null + ..() + /obj/structure/disposalpipe/trunk/proc/getlinked() linked = null var/obj/machinery/disposal/D = locate() in src.loc From c4fad66eb4cf3dae4c35c3e53af20ad033202641 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Tue, 18 Aug 2015 02:05:41 -0500 Subject: [PATCH 057/108] Update Chemistry-Recipes.dm --- code/modules/reagents/Chemistry-Recipes.dm | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index e7f7014e135..217a18b28b2 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -48,6 +48,16 @@ /mob/living/simple_animal/hostile/poison, /mob/living/simple_animal/hostile/blob, /mob/living/simple_animal/ascendant_shadowling + /mob/living/simple_animal/hostile/guardian, + /mob/living/simple_animal/hostile/guardian/fire, + /mob/living/simple_animal/hostile/guardian/punch, + /mob/living/simple_animal/hostile/guardian/fast, + /mob/living/simple_animal/hostile/guardian/healer, + /mob/living/simple_animal/hostile/guardian/ranged, + /mob/living/simple_animal/hostile/guardian/bluespace, + /mob/living/simple_animal/hostile/guardian/bomb, + /mob/living/simple_animal/hostile/guardian/shield, + /mob/living/simple_animal/hostile/guardian/scout )//exclusion list for things you don't want the reaction to create. var/list/meancritters = typesof(/mob/living/simple_animal/hostile) - blocked // list of possible hostile mobs var/list/nicecritters = list(/mob/living/simple_animal/crab, @@ -118,4 +128,4 @@ for(var/i = 0, i < moving_power, i++) sleep(2) if(!step_towards(X, T)) - break \ No newline at end of file + break From 54a32d21c2a8514b19edd2d88a8d21b58b3d48ca Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Tue, 18 Aug 2015 02:21:08 -0500 Subject: [PATCH 058/108] Comma --- code/modules/reagents/Chemistry-Recipes.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index 217a18b28b2..780991c4938 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -47,7 +47,7 @@ /mob/living/simple_animal/hostile/mining_drone, /mob/living/simple_animal/hostile/poison, /mob/living/simple_animal/hostile/blob, - /mob/living/simple_animal/ascendant_shadowling + /mob/living/simple_animal/ascendant_shadowling, /mob/living/simple_animal/hostile/guardian, /mob/living/simple_animal/hostile/guardian/fire, /mob/living/simple_animal/hostile/guardian/punch, From 9ecee2251b492d93911db15a8586896eddf3bf0d Mon Sep 17 00:00:00 2001 From: Memendia Date: Tue, 18 Aug 2015 00:42:30 -0700 Subject: [PATCH 059/108] Grammar Fix Fixes Shiina Kishida activates the C-4 and holds it above >>> his <<< head! It looks like she's going out with a bang! --- code/game/objects/items/weapons/explosives.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/explosives.dm b/code/game/objects/items/weapons/explosives.dm index 84db5d73cb8..6572831cd53 100644 --- a/code/game/objects/items/weapons/explosives.dm +++ b/code/game/objects/items/weapons/explosives.dm @@ -22,7 +22,7 @@ ..() /obj/item/weapon/c4/suicide_act(mob/user) - user.visible_message("[user] activates the [src.name] and holds it above his head! It looks like \he's going out with a bang!") + user.visible_message("[user] activates the [src.name] and holds it above \his head! It looks like \he's going out with a bang!") var/message_say = "FOR NO RAISIN!" if(user.mind) if(user.mind.special_role) From 60715b165923dc3b6c95f0549d4b149132d25a9a Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Tue, 18 Aug 2015 04:20:09 -0500 Subject: [PATCH 060/108] On second thought I'm removing scout anyway --- code/modules/reagents/Chemistry-Recipes.dm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index 780991c4938..eb27d64550c 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -56,8 +56,7 @@ /mob/living/simple_animal/hostile/guardian/ranged, /mob/living/simple_animal/hostile/guardian/bluespace, /mob/living/simple_animal/hostile/guardian/bomb, - /mob/living/simple_animal/hostile/guardian/shield, - /mob/living/simple_animal/hostile/guardian/scout + /mob/living/simple_animal/hostile/guardian/shield )//exclusion list for things you don't want the reaction to create. var/list/meancritters = typesof(/mob/living/simple_animal/hostile) - blocked // list of possible hostile mobs var/list/nicecritters = list(/mob/living/simple_animal/crab, From 30ce209f8dc4abb4e0781ac84dfc37883472ad32 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Tue, 18 Aug 2015 04:31:46 -0500 Subject: [PATCH 061/108] Guardian Updates --- .../living/simple_animal/guardian/guardian.dm | 115 ++++++++++++++---- 1 file changed, 88 insertions(+), 27 deletions(-) diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index b102ef80167..c5f22262531 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -115,7 +115,7 @@ var/input = stripped_input(src, "Please enter a message to tell your summoner.", "Guardian", "") for(var/mob/M in mob_list) - if(M == src.summoner) + if(M == src.summoner || (M in dead_mob_list)) M << "[src]: [input]" src << "[src]: [input]" @@ -125,8 +125,12 @@ set desc = "Communicate telepathically with your guardian." var/input = stripped_input(src, "Please enter a message to tell your guardian.", "Message", "") - for(var/mob/living/simple_animal/hostile/guardian/M in mob_list) - if(M.summoner == src) + for(var/mob/M in mob_list) + if(istype (M, /mob/living/simple_animal/hostile/guardian)) + var/mob/living/simple_animal/hostile/guardian/G = M + if(G.summoner == src) + G << "[src]: [input]" + else if (M in dead_mob_list) M << "[src]: [input]" src << "[src]: [input]" @@ -138,8 +142,8 @@ /mob/living/simple_animal/hostile/guardian/fire a_intent = "help" - melee_damage_lower = 10 - melee_damage_upper = 10 + melee_damage_lower = 15 + melee_damage_upper = 15 attack_sound = 'sound/items/Welder.ogg' attacktext = "sears" damage_transfer = 0.7 @@ -149,6 +153,7 @@ magic_fluff_string = "..And draw Atmosia, bringer of cleansing fires!" tech_fluff_string = "Boot sequence complete. Incendiary combat modules loaded. Nanoswarm online." bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of igniting enemies on touch." + pass_flags = PASSMOB /mob/living/simple_animal/hostile/guardian/fire/Crossed(AM as mob|obj) @@ -224,21 +229,6 @@ tech_fluff_string = "Boot sequence complete. Defensive modules active. Nanoswarm online." bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, helpless, but invulnerable." -//Scout. No damage, high range, high mobility, low resistance - -/mob/living/simple_animal/hostile/guardian/scout - range = 255 - incorporeal_move = 1 - damage_transfer = 1.2 - melee_damage_lower = 0 - melee_damage_upper = 0 - alpha = 60 - friendly = "quietly assesses" - playstyle_string = "As a scout type, you are incapable of attacking, but have infinite range, can pass through walls, and crawl through vents." - magic_fluff_string = "..And draw the AI, all seeing and all knowing." - tech_fluff_string = "Boot sequence complete. Surveillance modules loaded. Nanoswarm online." - bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, helpless, but near invsible, and capable of near unlimited travel." - //Healer /mob/living/simple_animal/hostile/guardian/healer @@ -264,6 +254,9 @@ C.adjustOxyLoss(-5) C.adjustToxLoss(-5) + +///////////////////Ranged + /obj/item/projectile/guardian name = "crystal spray" icon_state = "guardian" @@ -272,6 +265,7 @@ /mob/living/simple_animal/hostile/guardian/ranged a_intent = "help" + friendly = "quietly assesses" melee_damage_lower = 10 melee_damage_upper = 10 damage_transfer = 1.2 @@ -280,10 +274,78 @@ projectilesound = 'sound/effects/hit_on_shattered_glass.ogg' ranged = 1 range = 13 - playstyle_string = "As a ranged type, you have only light damage resistance, but are capable of spraying shards of crystal at incredibly high speed." + playstyle_string = "As a ranged type, you have only light damage resistance, but are capable of spraying shards of crystal at incredibly high speed. You can also deploy surveillance snares to monitor enemy movement. Finally, you can switch to scout mode, in which you can't attack, but can move without limit." magic_fluff_string = "..And draw the Sentinel, an alien master of ranged combat." tech_fluff_string = "Boot sequence complete. Ranged combat modules active. Nanoswarm online." bio_fluff_string = "Your scarab swarm finishes mutating and stirs to life, capable of spraying shards of crystal." + var/list/snares = list() + var/toggle = FALSE + +/mob/living/simple_animal/hostile/guardian/ranged/verb/ToggleMode() + set name = "Toggle Mode" + set category = "Guardian" + set desc = "Toggle between combat and scout modes." + if(src.loc == summoner) + if(toggle) + ranged = 1 + melee_damage_lower = 10 + melee_damage_upper = 10 + alpha = 255 + range = 13 + incorporeal_move = 0 + src << "You switch to combat mode." + else + ranged = 0 + melee_damage_lower = 0 + melee_damage_upper = 0 + alpha = 60 + range = 255 + incorporeal_move = 0 + src << "You switch to scout mode." + else + src << "You have to be recalled to toggle modes!." + + + +/mob/living/simple_animal/hostile/guardian/ranged/verb/Snare() + set name = "Set Surveillance Trap" + set category = "Guardian" + set desc = "Set an invisible trap that will alert you when living creatures walk over it. Max of 5" + if(src.snares.len <6) + var/turf/snare_loc = get_turf(src.loc) + var/obj/item/effect/snare/S = new /obj/item/effect/snare(snare_loc) + S.spawner = src + S.name = "[get_area(snare_loc)] trap ([rand(1, 1000)])" + src.snares |= S + src << "Surveillance trap deployed!" + else + src << "You have too many traps deployed. Delete some first." + +/mob/living/simple_animal/hostile/guardian/ranged/verb/DisarmSnare() + set name = "Remove Surveillance Trap" + set category = "Guardian" + set desc = "Disarm unwanted surveillance traps." + var/picked_snare = input(src, "Pick which trap to disarm", "Disarm Trap") as null|anything in src.snares + if(picked_snare) + qdel(picked_snare) + src << "Snare disarmed." + +/obj/item/effect/snare + name = "snare" + desc = "You shouldn't be seeing this!" + var/mob/living/spawner + invisibility = 1 + + +/obj/item/effect/snare/Crossed(AM as mob|obj) + if(istype(AM, /mob/living/)) + var/turf/snare_loc = get_turf(src.loc) + if(spawner) + spawner << "[AM] has crossed your surveillance trap at [get_area(snare_loc)]." + + + +///Bluespace /mob/living/simple_animal/hostile/guardian/bluespace @@ -307,6 +369,9 @@ if(!M.anchored && M != src.summoner) do_teleport(M, M, 10) + +////Bomb + /mob/living/simple_animal/hostile/guardian/bomb melee_damage_lower = 15 melee_damage_upper = 15 @@ -339,7 +404,6 @@ var/mob/living/spawner - /obj/item/weapon/guardian_bomb/proc/disguise(var/obj/A) A.loc = src stored_obj = A @@ -395,7 +459,7 @@ var/use_message = "You shuffle the deck..." var/used_message = "All the cards seem to be blank now." var/failure_message = "..And draw a card! It's...blank? Maybe you should try again later." - var/list/possible_guardians = list("Fire", "Standard", "Scout", "Shield", "Ranged", "Healer", "Fast", "Explosive") + var/list/possible_guardians = list("Fire", "Standard", "Shield", "Ranged", "Healer", "Fast", "Explosive") var/random = TRUE /obj/item/weapon/guardiancreator/attack_self(mob/living/user) @@ -439,7 +503,7 @@ if(random) gaurdiantype = pick(possible_guardians) else - gaurdiantype = input(user, "Pick the type pf [mob_name]", "[mob_name] Creation") as null|anything in possible_guardians + gaurdiantype = input(user, "Pick the type of [mob_name]", "[mob_name] Creation") as null|anything in possible_guardians var/pickedtype = /mob/living/simple_animal/hostile/guardian/punch var/picked_color = randomColor(0) switch(gaurdiantype) @@ -450,9 +514,6 @@ if("Standard") pickedtype = /mob/living/simple_animal/hostile/guardian/punch - if("Scout") - pickedtype = /mob/living/simple_animal/hostile/guardian/scout - if("Shield") pickedtype = /mob/living/simple_animal/hostile/guardian/shield From 6b8ab6641a86bb51ce12b203dae5c57f5588ad77 Mon Sep 17 00:00:00 2001 From: Aranclanos Date: Tue, 18 Aug 2015 06:52:57 -0300 Subject: [PATCH 062/108] Replaces the Cut() usage in the processing lists from the different controllers for a Remove() --- code/controllers/subsystem/air.dm | 4 +--- code/controllers/subsystem/bots.dm | 4 +--- code/controllers/subsystem/diseases.dm | 4 +--- code/controllers/subsystem/events.dm | 4 +--- code/controllers/subsystem/lighting.dm | 4 +--- code/controllers/subsystem/nanoUI.dm | 4 +--- code/controllers/subsystem/objects.dm | 6 ++---- code/controllers/subsystem/shuttles.dm | 7 ++----- 8 files changed, 10 insertions(+), 27 deletions(-) diff --git a/code/controllers/subsystem/air.dm b/code/controllers/subsystem/air.dm index c3d63b689a4..6c45cc35ae7 100644 --- a/code/controllers/subsystem/air.dm +++ b/code/controllers/subsystem/air.dm @@ -95,13 +95,11 @@ var/datum/subsystem/air/SSair /datum/subsystem/air/proc/process_pipenets() - var/i=1 for(var/thing in networks) if(thing) thing:process() - ++i continue - networks.Cut(i, i+1) + networks.Remove(thing) /datum/subsystem/air/proc/process_atmos_machinery() diff --git a/code/controllers/subsystem/bots.dm b/code/controllers/subsystem/bots.dm index 3a4d79d1cf3..6f71bb62d9b 100644 --- a/code/controllers/subsystem/bots.dm +++ b/code/controllers/subsystem/bots.dm @@ -14,11 +14,9 @@ var/datum/subsystem/bots/SSbot /datum/subsystem/bots/fire() var/seconds = wait * 0.1 - var/i=1 for(var/thing in processing) if(thing && !thing:gc_destroyed) spawn(-1) thing:bot_process(seconds) - ++i continue - processing.Cut(i, i+1) \ No newline at end of file + processing.Remove(thing) \ No newline at end of file diff --git a/code/controllers/subsystem/diseases.dm b/code/controllers/subsystem/diseases.dm index d28785d947f..76343a81bec 100644 --- a/code/controllers/subsystem/diseases.dm +++ b/code/controllers/subsystem/diseases.dm @@ -13,10 +13,8 @@ var/datum/subsystem/diseases/SSdisease ..("P:[processing.len]") /datum/subsystem/diseases/fire() - var/i=1 for(var/thing in processing) if(thing) thing:process() - ++i continue - processing.Cut(i,i+1) + processing.Remove(thing) diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index e2dfe59a2eb..b381803ba67 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -36,13 +36,11 @@ var/datum/subsystem/events/SSevent /datum/subsystem/events/fire() checkEvent() - var/i=1 for(var/thing in running) if(thing) thing:process() - ++i continue - running.Cut(i,i+1) + running.Remove(thing) //checks if we should select a random event yet, and reschedules if necessary diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm index 053241cd2e7..38389bf704f 100644 --- a/code/controllers/subsystem/lighting.dm +++ b/code/controllers/subsystem/lighting.dm @@ -71,13 +71,11 @@ var/datum/subsystem/lighting/SSlighting if(z_level) //we need to loop through to clear only shifted turfs from the list. or we will cause errors - var/i=1 for(var/thing in changed_turfs) var/turf/T = thing if(T.z in z_start to z_finish) - ++i continue - changed_turfs.Cut(i, i+1) + changed_turfs.Remove(thing) else changed_turfs.Cut() diff --git a/code/controllers/subsystem/nanoUI.dm b/code/controllers/subsystem/nanoUI.dm index feb60fce007..5ec4344fee7 100644 --- a/code/controllers/subsystem/nanoUI.dm +++ b/code/controllers/subsystem/nanoUI.dm @@ -38,12 +38,10 @@ var/datum/subsystem/nano/SSnano /datum/subsystem/nano/fire() - var/i=1 for(var/thing in SSnano.processing_uis) if(thing) var/datum/nanoui/ui = thing if(ui.src_object && ui.user) ui.process() - ++i continue - processing_uis.Cut(i, i+1) + processing_uis.Remove(thing) diff --git a/code/controllers/subsystem/objects.dm b/code/controllers/subsystem/objects.dm index 35236b38fb6..61c7b804aea 100644 --- a/code/controllers/subsystem/objects.dm +++ b/code/controllers/subsystem/objects.dm @@ -31,16 +31,14 @@ var/datum/subsystem/objects/SSobj /datum/subsystem/objects/fire() - var/i=1 for(var/thing in SSobj.processing) if(thing) thing:process(wait) - ++i continue - SSobj.processing.Cut(i, i+1) + SSobj.processing.Remove(thing) for(var/obj/burningobj in SSobj.burning) if(burningobj && (burningobj.burn_state == 1)) if(burningobj.burn_world_time < world.time) burningobj.burn() else - SSobj.burning -= burningobj \ No newline at end of file + SSobj.burning.Remove(burningobj) \ No newline at end of file diff --git a/code/controllers/subsystem/shuttles.dm b/code/controllers/subsystem/shuttles.dm index d578f1c501c..534a8095519 100644 --- a/code/controllers/subsystem/shuttles.dm +++ b/code/controllers/subsystem/shuttles.dm @@ -61,15 +61,12 @@ var/datum/subsystem/shuttle/SSshuttle /datum/subsystem/shuttle/fire() points += points_per_decisecond * wait - - var/i=1 for(var/thing in mobile) if(thing) var/obj/docking_port/mobile/P = thing P.check() - ++i continue - mobile.Cut(i, i+1) + mobile.Remove(thing) /datum/subsystem/shuttle/proc/getShuttle(id) for(var/obj/docking_port/mobile/M in mobile) @@ -306,7 +303,7 @@ var/datum/subsystem/shuttle/SSshuttle var/obj/structure/largecrate/LC = Crate LC.manifest = slip LC.update_icon() - + return Crate /datum/subsystem/shuttle/proc/generateSupplyOrder(packId, _orderedby, _orderedbyRank, _comment) From 0f6a9ba19bba2b16a4fe69401acf5b76565e95fb Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Tue, 18 Aug 2015 05:04:57 -0500 Subject: [PATCH 063/108] Fix --- code/modules/mob/living/simple_animal/guardian/guardian.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index c5f22262531..20d53d04ede 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -327,6 +327,7 @@ set desc = "Disarm unwanted surveillance traps." var/picked_snare = input(src, "Pick which trap to disarm", "Disarm Trap") as null|anything in src.snares if(picked_snare) + src.snares -= picked_snare qdel(picked_snare) src << "Snare disarmed." From 2c8389c3402f706f5b5696afc41845d2fc07615e Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Tue, 18 Aug 2015 11:50:23 -0400 Subject: [PATCH 064/108] YOU SPEAK, I OBEY. Fixes the stuff, as ordered, at least hopefully in the right way. Tweaks Malfunction a bit to reduce the chance of random emagging; it'll mostly be emp_act now. --- .../living/simple_animal/revenant/revenant.dm | 75 +++++++++---------- .../revenant/revenant_abilities.dm | 12 +-- 2 files changed, 41 insertions(+), 46 deletions(-) diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm index 1a4ef7641cc..9e6a33a4d7a 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm @@ -82,74 +82,69 @@ return A.attack_ghost(src) if(ishuman(A) && in_range(src, A)) - Harvest(A, src) + src.Harvest(A) -/mob/living/simple_animal/revenant/proc/Harvest(mob/living/carbon/human/tar, mob/living/simple_animal/revenant/user = usr) - if(!user.castcheck(0)) +/mob/living/simple_animal/revenant/proc/Harvest(mob/living/carbon/human/target) + if(!src.castcheck(0)) return - var/mob/living/carbon/human/target = tar - if(user.draining) - user << "You are already siphoning the essence of a soul!" + if(src.draining) + src << "You are already siphoning the essence of a soul!" return - if(target in user.drained_mobs) - user << "[target]'s soul is dead and empty." + if(target in src.drained_mobs) + src << "[target]'s soul is dead and empty." return if(!target.stat) - user << "This being's soul is too strong to harvest." + src << "This being's soul is too strong to harvest." if(prob(10)) target << "You feel as if you are being watched." return - draining = 1 - essence_drained = 2 - user << "You search for the soul of [target]." - sleep(10) - if(target) //did they get deleted in that second? + src.draining = 1 + src.essence_drained = 2 + src << "You search for the soul of [target]." + if(do_after(src, 10, 3, 0, target)) //did they get deleted in that second? if(target.ckey) - user << "Their soul burns with intelligence." - essence_drained += 2 + src << "Their soul burns with intelligence." + src.essence_drained += 2 if(target.stat != DEAD) - user << "Their soul blazes with life!" - essence_drained += 2 + src << "Their soul blazes with life!" + src.essence_drained += 2 else - user << "Their soul is weak and faltering." - sleep(20) - if(target) //did they get deleted NOW? + src << "Their soul is weak and faltering." + if(do_after(src, 20, 6, 0, target)) //did they get deleted NOW? switch(essence_drained) if(1 to 2) - user << "[target] will not yield much essence. Still, every bit counts." + src << "[target] will not yield much essence. Still, every bit counts." if(3 to 4) - user << "[target] will yield an average amount of essence." + src << "[target] will yield an average amount of essence." if(5 to INFINITY) - user << "Such a feast! [target] will yield much essence to you." - sleep(30) - if(target) //how about now - if(!in_range(user, target)) - user << "You are not close enough to siphon [target]'s soul. The link has been broken." + src << "Such a feast! [target] will yield much essence to you." + if(do_after(src, 30, 9, 0, target)) //how about now + if(!in_range(src, target)) + src << "You are not close enough to siphon [target]'s soul. The link has been broken." draining = 0 return if(!target.stat) - user << "They are now powerful enough to fight off your draining." + src << "They are now powerful enough to fight off your draining." target << "You feel something tugging across your body before subsiding." draining = 0 return //hey, wait a minute... - user << "You begin siphoning essence from [target]'s soul." + src << "You begin siphoning essence from [target]'s soul." if(target.stat != DEAD) target << "You feel a horribly unpleasant draining sensation as your grip on life weakens..." - user.icon_state = "revenant_draining" - user.reveal(65) - user.stun(65) + src.icon_state = "revenant_draining" + src.reveal(65) + src.stun(65) target.visible_message("[target] suddenly rises slightly into the air, their skin turning an ashy gray.") - target.Beam(user,icon_state="drain_life",icon='icons/effects/effects.dmi',time=60) + target.Beam(src,icon_state="drain_life",icon='icons/effects/effects.dmi',time=60) if(target) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining. - user.change_essence_amount(essence_drained * 5, 0, target) - user << "[target]'s soul has been considerably weakened and will yield no more essence for the time being." + src.change_essence_amount(essence_drained * 5, 0, target) + src << "[target]'s soul has been considerably weakened and will yield no more essence for the time being." target.visible_message("[target] gently slumps back onto the ground.") - drained_mobs.Add(target) + src.drained_mobs.Add(target) target.death(0) - user.icon_state = "revenant_idle" - draining = 0 - draining = 0 + src.icon_state = "revenant_idle" + draining = 0 return diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm index 137c80317c1..3e7de25b612 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm @@ -10,7 +10,7 @@ /obj/effect/proc_holder/spell/targeted/revenant_harvest/cast(list/targets, mob/living/simple_animal/revenant/user = usr) for(var/mob/living/carbon/human/target in targets) spawn(0) - user.Harvest(target, user) + user.Harvest(target) //Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob for 5E. @@ -146,7 +146,7 @@ /obj/effect/proc_holder/spell/aoe_turf/revenant_malf/cast(list/targets, mob/living/simple_animal/revenant/user = usr) if(locked) - if(!user.castcheck(-35)) + if(!user.castcheck(-50)) charge_counter = charge_max return user << "You have unlocked Malfunction!" @@ -176,12 +176,12 @@ human << "You feel a burst of cold throughout your body..." human.emp_act(2) for(var/obj/machinery/mach in T.contents) - switch(rand(1,6)) - if(1) + switch(rand(1,10)) + if(1 to 3) mach.emp_act(1) - if(2 to 3) + if(4 to 9) mach.emp_act(2) - if(4) + if(10) mach.emag_act(null) user.reveal(reveal) user.stun(stun) \ No newline at end of file From 40343617898c226163e00a035c0490ee236f347c Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Tue, 18 Aug 2015 12:55:42 -0400 Subject: [PATCH 065/108] Malfunction now uses empulse instead of copypasta code. Reduces how much power gets drained from the APC when a machine is EMPed; right now, four machines could fully discharge an APC. Obeys the Remie, no unneeded src. Slightly upped the stun on defile and overload light(go slower, revenants!) --- code/game/machinery/machinery.dm | 2 +- .../living/simple_animal/revenant/revenant.dm | 36 +++++++++---------- .../revenant/revenant_abilities.dm | 27 ++++---------- 3 files changed, 26 insertions(+), 39 deletions(-) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 4952544aeb7..826b2db3be2 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -141,7 +141,7 @@ Class Procs: /obj/machinery/emp_act(severity) if(use_power && stat == 0) - use_power(7500/severity) + use_power(750/severity) var/obj/effect/overlay/pulse2 = new/obj/effect/overlay ( src.loc ) pulse2.icon = 'icons/effects/effects.dmi' diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm index 9e6a33a4d7a..50a81068d94 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm @@ -82,16 +82,16 @@ return A.attack_ghost(src) if(ishuman(A) && in_range(src, A)) - src.Harvest(A) + Harvest(A) /mob/living/simple_animal/revenant/proc/Harvest(mob/living/carbon/human/target) - if(!src.castcheck(0)) + if(!castcheck(0)) return - if(src.draining) + if(draining) src << "You are already siphoning the essence of a soul!" return - if(target in src.drained_mobs) + if(target in drained_mobs) src << "[target]'s soul is dead and empty." return if(!target.stat) @@ -99,16 +99,16 @@ if(prob(10)) target << "You feel as if you are being watched." return - src.draining = 1 - src.essence_drained = 2 + draining = 1 + essence_drained = 2 src << "You search for the soul of [target]." if(do_after(src, 10, 3, 0, target)) //did they get deleted in that second? if(target.ckey) src << "Their soul burns with intelligence." - src.essence_drained += 2 + essence_drained += 2 if(target.stat != DEAD) src << "Their soul blazes with life!" - src.essence_drained += 2 + essence_drained += 2 else src << "Their soul is weak and faltering." if(do_after(src, 20, 6, 0, target)) //did they get deleted NOW? @@ -120,10 +120,6 @@ if(5 to INFINITY) src << "Such a feast! [target] will yield much essence to you." if(do_after(src, 30, 9, 0, target)) //how about now - if(!in_range(src, target)) - src << "You are not close enough to siphon [target]'s soul. The link has been broken." - draining = 0 - return if(!target.stat) src << "They are now powerful enough to fight off your draining." target << "You feel something tugging across your body before subsiding." @@ -132,18 +128,22 @@ src << "You begin siphoning essence from [target]'s soul." if(target.stat != DEAD) target << "You feel a horribly unpleasant draining sensation as your grip on life weakens..." - src.icon_state = "revenant_draining" - src.reveal(65) - src.stun(65) + icon_state = "revenant_draining" + reveal(65) + stun(65) target.visible_message("[target] suddenly rises slightly into the air, their skin turning an ashy gray.") target.Beam(src,icon_state="drain_life",icon='icons/effects/effects.dmi',time=60) if(target) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining. - src.change_essence_amount(essence_drained * 5, 0, target) + change_essence_amount(essence_drained * 5, 0, target) src << "[target]'s soul has been considerably weakened and will yield no more essence for the time being." target.visible_message("[target] gently slumps back onto the ground.") - src.drained_mobs.Add(target) + drained_mobs.Add(target) target.death(0) - src.icon_state = "revenant_idle" + icon_state = "revenant_idle" + else + src << "You are not close enough to siphon [target]'s soul. The link has been broken." + draining = 0 + return draining = 0 return diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm index 3e7de25b612..392bf34fd05 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm @@ -43,7 +43,7 @@ clothes_req = 0 range = 1 var/reveal = 80 - var/stun = 10 + var/stun = 20 var/locked = 1 /obj/effect/proc_holder/spell/aoe_turf/revenant_light/cast(list/targets, mob/living/simple_animal/revenant/user = usr) @@ -95,7 +95,7 @@ clothes_req = 0 range = 1 var/reveal = 100 - var/stun = 10 + var/stun = 20 var/locked = 1 /obj/effect/proc_holder/spell/aoe_turf/revenant_defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr) @@ -117,9 +117,9 @@ spawn(0) if(T.flags & NOJAUNT) T.flags -= NOJAUNT - if(!istype(T, /turf/simulated/wall/cult) && istype(T, /turf/simulated/wall) && prob(30)) + if(!istype(T, /turf/simulated/wall/cult) && istype(T, /turf/simulated/wall) && prob(40)) T.ChangeTurf(/turf/simulated/wall/cult) - if(!istype(T, /turf/simulated/floor/engine/cult) && istype(T, /turf/simulated/floor) && prob(30)) + if(!istype(T, /turf/simulated/floor/engine/cult) && istype(T, /turf/simulated/floor) && prob(40)) T.ChangeTurf(/turf/simulated/floor/engine/cult) for(var/mob/living/carbon/human/human in T.contents) human << "You suddenly feel tired." @@ -166,22 +166,9 @@ bot.locked = 0 bot.open = 1 bot.Emag(null) - for(var/mob/living/silicon/robot/robot in T.contents) - robot.visible_message("[robot] lets out an alarm!", \ - "01001111 01010110 01000101 01010010 01001100 01001111 01000001 01000100") //Translates to "OVERLOAD" - robot << 'sound/misc/interference.ogg' - robot.emp_act(2) - playsound(robot, 'sound/machines/warning-buzzer.ogg', 50, 1) - for(var/mob/living/carbon/human/human in T.contents) - human << "You feel a burst of cold throughout your body..." - human.emp_act(2) for(var/obj/machinery/mach in T.contents) - switch(rand(1,10)) - if(1 to 3) - mach.emp_act(1) - if(4 to 9) - mach.emp_act(2) - if(10) - mach.emag_act(null) + if(prob(10)) + mach.emag_act(null) + empulse(user.loc, 3, 5) user.reveal(reveal) user.stun(stun) \ No newline at end of file From ba3ec31deb5cc700740205459c2289a1f2e8c84e Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Tue, 18 Aug 2015 12:15:40 -0500 Subject: [PATCH 066/108] Toggle fixes --- code/modules/mob/living/simple_animal/guardian/guardian.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index 20d53d04ede..02c92727ad6 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -294,14 +294,16 @@ range = 13 incorporeal_move = 0 src << "You switch to combat mode." + toggle = FALSE else ranged = 0 melee_damage_lower = 0 melee_damage_upper = 0 alpha = 60 range = 255 - incorporeal_move = 0 + incorporeal_move = 1 src << "You switch to scout mode." + toggle = TRUE else src << "You have to be recalled to toggle modes!." From 46c69b442b9220184f99a70c681aeb4e68742cea Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Tue, 18 Aug 2015 13:27:35 -0400 Subject: [PATCH 067/108] Fixes xhuis's shit. Also fixes a bug where you would use essence if you tried to use an ability while inhibited. --- .../living/simple_animal/revenant/revenant.dm | 58 +++++++++---------- 1 file changed, 27 insertions(+), 31 deletions(-) diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm index 50a81068d94..320d608c047 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm @@ -229,68 +229,64 @@ /mob/living/simple_animal/revenant/proc/castcheck(essence_cost) - var/mob/living/simple_animal/revenant/user = usr - if(!istype(user) || !user) + if(!src) return - var/turf/T = get_turf(usr) + var/turf/T = get_turf(src) if(istype(T, /turf/simulated/wall)) - user << "You cannot use abilities from inside of a wall." + src << "You cannot use abilities from inside of a wall." return 0 - if(!user.change_essence_amount(essence_cost, 1)) - user << "You lack the essence to use that ability." + if(src.inhibited) + src << "Your powers have been suppressed by nulling energy!" return 0 - if(user.inhibited) - user << "Your powers have been suppressed by nulling energy!" + if(!src.change_essence_amount(essence_cost, 1)) + src << "You lack the essence to use that ability." return 0 return 1 /mob/living/simple_animal/revenant/proc/change_essence_amount(essence_amt, silent = 0, source = null) - var/mob/living/simple_animal/revenant/user = usr - if(!istype(usr) || !usr) + if(!src) return - if(user.essence + essence_amt <= 0) + if(essence + essence_amt <= 0) return - user.essence += essence_amt - user.essence = max(0, user.essence) + essence += essence_amt + essence = max(0, essence) if(essence_amt > 0) - user.essence_accumulated += essence_amt - user.essence_accumulated = max(0, user.essence_accumulated) + essence_accumulated += essence_amt + essence_accumulated = max(0, essence_accumulated) if(!silent) if(essence_amt > 0) - user << "Gained [essence_amt]E from [source]." + src << "Gained [essence_amt]E from [source]." else - user << "Lost [essence_amt]E from [source]." + src << "Lost [essence_amt]E from [source]." return 1 /mob/living/simple_animal/revenant/proc/reveal(time) - var/mob/living/simple_animal/revenant/R = usr - if(!istype(usr) || !usr) + if(!src) return if(time <= 0) return - R.revealed = 1 - R.invisibility = 0 - R << "You have been revealed." + revealed = 1 + invisibility = 0 + src << "You have been revealed." spawn(time) - R.revealed = 0 - R.invisibility = INVISIBILITY_OBSERVER - R << "You are once more concealed." + revealed = 0 + invisibility = INVISIBILITY_OBSERVER + src << "You are once more concealed." /mob/living/simple_animal/revenant/proc/stun(time) - var/mob/living/simple_animal/revenant/R = usr - if(!istype(usr) || !usr) + if(!src) return if(time <= 0) return - R.notransform = 1 - R << "You cannot move!" + notransform = 1 + src << "You cannot move!" spawn(time) - R.notransform = 0 - R << "You can move again!" + notransform = 0 + src << "You can move again!" From da15c99460bfb778d32b9cd1fe2c6a95f36b90e6 Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Tue, 18 Aug 2015 14:09:58 -0400 Subject: [PATCH 068/108] Wait shit that shouldn't be indented~ --- code/game/machinery/machinery.dm | 2 +- .../mob/living/simple_animal/revenant/revenant_abilities.dm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 826b2db3be2..4952544aeb7 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -141,7 +141,7 @@ Class Procs: /obj/machinery/emp_act(severity) if(use_power && stat == 0) - use_power(750/severity) + use_power(7500/severity) var/obj/effect/overlay/pulse2 = new/obj/effect/overlay ( src.loc ) pulse2.icon = 'icons/effects/effects.dmi' diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm index 392bf34fd05..4bf79a19aaa 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm @@ -169,6 +169,6 @@ for(var/obj/machinery/mach in T.contents) if(prob(10)) mach.emag_act(null) - empulse(user.loc, 3, 5) + empulse(user.loc, 3, 5) user.reveal(reveal) user.stun(stun) \ No newline at end of file From f633dcd21a65d78c873880d45506d70f18b0e11a Mon Sep 17 00:00:00 2001 From: sybil-tgstation13 Date: Tue, 18 Aug 2015 19:45:05 +0000 Subject: [PATCH 069/108] Automatic changelog compile --- html/changelog.html | 23 +++++++++++ html/changelogs/.all_changelog.yml | 21 ++++++++++ html/changelogs/Supermichael777-PR-#11163.yml | 8 ---- html/changelogs/bustygoku-10975.yml | 6 --- html/changelogs/c0-RnDupdate.yml | 40 ------------------- html/changelogs/phil235 - JanicartFixes.yml | 7 ---- 6 files changed, 44 insertions(+), 61 deletions(-) delete mode 100644 html/changelogs/Supermichael777-PR-#11163.yml delete mode 100644 html/changelogs/bustygoku-10975.yml delete mode 100644 html/changelogs/c0-RnDupdate.yml delete mode 100644 html/changelogs/phil235 - JanicartFixes.yml diff --git a/html/changelog.html b/html/changelog.html index 2161dfe8fef..c36cdd27f70 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,6 +55,29 @@ -->
+

18 August 2015

+

CoreOverload updated:

+
    +
  • Added a new low-tech eye cyberimplant in RnD - welding shield implant.
  • +
  • Implanter and empty implant case added to protolathe.
  • +
  • You can sell tech disks and maxed reliability design disks in cargo for supply points.
  • +
  • DA menu shows current research levels.
  • +
  • You can print cyberimplants in updated mech fab.
  • +
+

Supermichael777 updated:

+
    +
  • Added an ooc hotkey for borgs = O. They simply didn't have one and it was a consistency issue
  • +
  • Also added Ctrl+O as an any mode keycombo so you dont have to backspace and type ooc. Added to hotkey mode to remain consistent with all other Ctrl combos
  • +
+

bustygoku updated:

+
    +
  • Most backpacks now have 21 or more slots, but are still weight restricted. What this means is that you can have a lot of tiny weight items, but only 7 medium items just like before.
  • +
+

phil235 updated:

+
    +
  • Janicart rider no longer slip on wet floor or bananas. Moving on a floor tile with lube while buckled (chair, roller bed, etc) will make you fall off.
  • +
+

16 August 2015

Joan updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 935d513282d..52a113eb2ac 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -1601,3 +1601,24 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. MMMiracles: - tweak: Revamps bioterror darts into a less-lethal, syringe form. Removed the coniine and spore toxins to keep it solely for quiet take-downs. +2015-08-18: + CoreOverload: + - rscadd: Added a new low-tech eye cyberimplant in RnD - welding shield implant. + - rscadd: Implanter and empty implant case added to protolathe. + - rscadd: You can sell tech disks and maxed reliability design disks in cargo for + supply points. + - tweak: DA menu shows current research levels. + - tweak: You can print cyberimplants in updated mech fab. + Supermichael777: + - bugfix: Added an ooc hotkey for borgs = O. They simply didn't have one and it + was a consistency issue + - rscadd: Also added Ctrl+O as an any mode keycombo so you dont have to backspace + and type ooc. Added to hotkey mode to remain consistent with all other Ctrl + combos + bustygoku: + - tweak: Most backpacks now have 21 or more slots, but are still weight restricted. + What this means is that you can have a lot of tiny weight items, but only 7 + medium items just like before. + phil235: + - tweak: Janicart rider no longer slip on wet floor or bananas. Moving on a floor + tile with lube while buckled (chair, roller bed, etc) will make you fall off. diff --git a/html/changelogs/Supermichael777-PR-#11163.yml b/html/changelogs/Supermichael777-PR-#11163.yml deleted file mode 100644 index 79b90558790..00000000000 --- a/html/changelogs/Supermichael777-PR-#11163.yml +++ /dev/null @@ -1,8 +0,0 @@ -author: Supermichael777 - -delete-after: True - -changes: - - bugfix: "Added an ooc hotkey for borgs = O. They simply didn't have one and it was a consistency issue" - - rscadd: "Also added Ctrl+O as an any mode keycombo so you dont have to backspace and type ooc. Added to hotkey mode to remain consistent with all other Ctrl combos" - diff --git a/html/changelogs/bustygoku-10975.yml b/html/changelogs/bustygoku-10975.yml deleted file mode 100644 index f34e1e56ba6..00000000000 --- a/html/changelogs/bustygoku-10975.yml +++ /dev/null @@ -1,6 +0,0 @@ -author: bustygoku - -delete-after: True - -changes: - - tweak: "Most backpacks now have 21 or more slots, but are still weight restricted. What this means is that you can have a lot of tiny weight items, but only 7 medium items just like before." diff --git a/html/changelogs/c0-RnDupdate.yml b/html/changelogs/c0-RnDupdate.yml deleted file mode 100644 index 84812a8a855..00000000000 --- a/html/changelogs/c0-RnDupdate.yml +++ /dev/null @@ -1,40 +0,0 @@ -################################ -# Example Changelog File -# -# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. -# -# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) -# When it is, any changes listed below will disappear. -# -# Valid Prefixes: -# bugfix -# wip (For works in progress) -# tweak -# soundadd -# sounddel -# rscadd (general adding of nice things) -# rscdel (general deleting of nice things) -# imageadd -# imagedel -# spellcheck (typo fixes) -# experiment -# tgs (TG-ported fixes?) -################################# - -# Your name. -author: CoreOverload - -# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. -delete-after: True - -# Any changes you've made. See valid prefix list above. -# INDENT WITH TWO SPACES. NOT TABS. SPACES. -# SCREW THIS UP AND IT WON'T WORK. -# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. -# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. -changes: - - rscadd: "Added a new low-tech eye cyberimplant in RnD - welding shield implant." - - rscadd: "Implanter and empty implant case added to protolathe." - - rscadd: "You can sell tech disks and maxed reliability design disks in cargo for supply points." - - tweak: "DA menu shows current research levels." - - tweak: "You can print cyberimplants in updated mech fab." \ No newline at end of file diff --git a/html/changelogs/phil235 - JanicartFixes.yml b/html/changelogs/phil235 - JanicartFixes.yml deleted file mode 100644 index 21617e26dce..00000000000 --- a/html/changelogs/phil235 - JanicartFixes.yml +++ /dev/null @@ -1,7 +0,0 @@ - -author: phil235 - -delete-after: True - -changes: - - tweak: "Janicart rider no longer slip on wet floor or bananas. Moving on a floor tile with lube while buckled (chair, roller bed, etc) will make you fall off." From 166818a67b1d36a8f4682976ccce6f7390acc984 Mon Sep 17 00:00:00 2001 From: Oisin100 Date: Tue, 18 Aug 2015 23:53:01 +0200 Subject: [PATCH 070/108] Changed String to Definition --- code/datums/mutations.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/datums/mutations.dm b/code/datums/mutations.dm index f9516df1068..1bf987869b1 100644 --- a/code/datums/mutations.dm +++ b/code/datums/mutations.dm @@ -364,7 +364,7 @@ if(T.lighting_lumcount <= 2) owner.alpha -= 25 else - if(!owner.dna.check_mutation("Chameleon")) + if(!owner.dna.check_mutation(CHAMELEON)) owner.alpha = round(255 * 0.80) /datum/mutation/human/stealth/on_losing(mob/living/carbon/human/owner) From 8f1c084d23e8abe82e68afef671ef604ddb93e5e Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Tue, 18 Aug 2015 21:12:08 -0700 Subject: [PATCH 071/108] Fixes pulling bug that led to FUN! QUICK MERGE, MAJOR FUN REMOVAL. --- code/modules/mob/mob.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 3c0e579eb5f..e5dd2c589dc 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -376,7 +376,7 @@ var/list/slot_equipment_priority = list( \ //this and stop_pulling really ought to be /mob/living procs /mob/proc/start_pulling(atom/movable/AM) - if ( !AM || !src || src==AM || !isturf(src.loc) ) //if there's no person pulling OR the person is pulling themself OR the object being pulled is inside something: abort! + if ( !AM || !src || src==AM || !isturf(AM.loc) ) //if there's no person pulling OR the person is pulling themself OR the object being pulled is inside something: abort! return if (!( AM.anchored )) AM.add_fingerprint(src) @@ -975,4 +975,4 @@ var/list/slot_equipment_priority = list( \ //override to avoid rotating pixel_xy on mobs /mob/shuttleRotate(rotation) - dir = angle2dir(rotation+dir2angle(dir)) \ No newline at end of file + dir = angle2dir(rotation+dir2angle(dir)) From 5be606c18e1d4e976ba6fa48edd4c084a17516a2 Mon Sep 17 00:00:00 2001 From: Jordie0608 Date: Wed, 19 Aug 2015 15:09:59 +1000 Subject: [PATCH 072/108] injection fixes --- code/modules/admin/sql_notes.dm | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/code/modules/admin/sql_notes.dm b/code/modules/admin/sql_notes.dm index 54af84cb2b9..6659e7e804b 100644 --- a/code/modules/admin/sql_notes.dm +++ b/code/modules/admin/sql_notes.dm @@ -32,6 +32,7 @@ if(!server) if (config && config.server_name) server = config.server_name + server = sanitizeSQL(server) var/DBQuery/query_noteadd = dbcon.NewQuery("INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server) VALUES ('[target_sql_ckey]', '[timestamp]', '[notetext]', '[admin_sql_ckey]', '[server]')") if(!query_noteadd.Execute()) var/err = query_noteadd.ErrorMsg() @@ -51,7 +52,8 @@ return if(!note_id) return - var/DBQuery/query_find_note_del = dbcon.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id = '[note_id]'") + note_id = text2num(note_id) + var/DBQuery/query_find_note_del = dbcon.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id = [note_id]") if(!query_find_note_del.Execute()) var/err = query_find_note_del.ErrorMsg() log_game("SQL ERROR obtaining ckey, notetext, adminckey from notes table. Error : \[[err]\]\n") @@ -60,7 +62,7 @@ ckey = query_find_note_del.item[1] notetext = query_find_note_del.item[2] adminckey = query_find_note_del.item[3] - var/DBQuery/query_del_note = dbcon.NewQuery("DELETE FROM [format_table_name("notes")] WHERE id = '[note_id]'") + var/DBQuery/query_del_note = dbcon.NewQuery("DELETE FROM [format_table_name("notes")] WHERE id = [note_id]") if(!query_del_note.Execute()) var/err = query_del_note.ErrorMsg() log_game("SQL ERROR removing note from table. Error : \[[err]\]\n") @@ -75,9 +77,10 @@ return if(!note_id) return + note_id = text2num(note_id) var/target_ckey var/sql_ckey = sanitizeSQL(usr.ckey) - var/DBQuery/query_find_note_edit = dbcon.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id = '[note_id]'") + var/DBQuery/query_find_note_edit = dbcon.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id = [note_id]") if(!query_find_note_edit.Execute()) var/err = query_find_note_edit.ErrorMsg() log_game("SQL ERROR obtaining notetext from notes table. Error : \[[err]\]\n") @@ -89,16 +92,17 @@ var/new_note = input("Input new note", "New Note", "[old_note]") as message if(!new_note) return + new_note = sanitizeSQL(new_note) var/edit_text = "Edited by [sql_ckey] on [SQLtime()] from
    [old_note]
    to
    [new_note]
    " edit_text = sanitizeSQL(edit_text) - var/DBQuery/query_update_note = dbcon.NewQuery("UPDATE [format_table_name("notes")] SET notetext = '[new_note]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE (id = '[note_id]')") + var/DBQuery/query_update_note = dbcon.NewQuery("UPDATE [format_table_name("notes")] SET notetext = '[new_note]', last_editor = '[sql_ckey]', edits = CONCAT(IFNULL(edits,''),'[edit_text]') WHERE id = [note_id]") if(!query_update_note.Execute()) var/err = query_update_note.ErrorMsg() log_game("SQL ERROR editing note. Error : \[[err]\]\n") return log_admin("[key_name(usr)] has edited [target_ckey]'s note made by [adminckey] from [old_note] to [new_note]") message_admins("[key_name_admin(usr)] has edited [target_ckey]'s note made by [adminckey] from
    [old_note]
    to
    [new_note]") - show_note(target_ckey) + show_note(target_ckey) /proc/show_note(target_ckey, index, linkless = 0) var/output @@ -115,7 +119,8 @@ if(!linkless) output = navbar if(target_ckey) - var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT id, timestamp, notetext, adminckey, last_editor, server FROM [format_table_name("notes")] WHERE ckey = '[target_ckey]'") + var/target_sql_ckey = sanitizeSQL(target_ckey) + var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT id, timestamp, notetext, adminckey, last_editor, server FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]'") if(!query_get_notes.Execute()) var/err = query_get_notes.ErrorMsg() log_game("SQL ERROR obtaining ckey, notetext, adminckey, last_editor, server from notes table. Error : \[[err]\]\n") @@ -142,6 +147,7 @@ var/search output += "
    \[Add Note\]
    " output += ruler + index = sanitizeSQL(index) switch(index) if(1) search = "^." @@ -193,7 +199,6 @@ timestamp = query_convert_time.item[1] if(ckey && notetext && timestamp && adminckey && server) add_note(ckey, notetext, timestamp, adminckey, 0, server) - else notesfile.cd = "/" notesfile.dir.Remove(ckey) From f4cf549ac8921cf43cb00a38d48e3301c1b5826e Mon Sep 17 00:00:00 2001 From: Jordie0608 Date: Wed, 19 Aug 2015 15:24:44 +1000 Subject: [PATCH 073/108] noted that bygex is required now --- README.md | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 3b602db293d..f56bd08c861 100644 --- a/README.md +++ b/README.md @@ -73,15 +73,8 @@ and the server should start up and be ready to join. ###HOSTING ON LINUX We use BYGEX for some of our text replacement related code. Unfortunately, we -only have a windows dll included right now. If you're up to it, you can head -over to https://code.google.com/p/byond-regex/ and compile it for linux. - -Otherwise, edit the file `code/_compile_options.dm`, and comment out: -`#define USE_BYGEX` -at the bottom, so that it looks like this: -`//#define USE_BYGEX` -Recompile the codebase afterwards. - +only have a windows dll included right now. You can find a version known to compile on linux, along with some basic install instructions here +https://github.com/optimumtact/byond-regex ##UPDATING @@ -140,4 +133,4 @@ All code before commit 333c566b88108de218d882840e61928a9b759d8f on 2014/31/12 at including tools unless their readme specifies otherwise. See LICENSE-AGPLv3.txt and LICENSE-GPLv3.txt for more details. All content including icons and sound is under a Creative Commons 3.0 BY-SA -license (http://creativecommons.org/licenses/by-sa/3.0/). +license (http://creativecommons.org/licenses/by-sa/3.0/). \ No newline at end of file From 5e430b3384a131dc82e7639a9622fe8a8333f28b Mon Sep 17 00:00:00 2001 From: Jordie Date: Wed, 19 Aug 2015 17:18:13 +1000 Subject: [PATCH 074/108] span4cheri --- code/modules/admin/sql_notes.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/admin/sql_notes.dm b/code/modules/admin/sql_notes.dm index 6659e7e804b..fbc01b16544 100644 --- a/code/modules/admin/sql_notes.dm +++ b/code/modules/admin/sql_notes.dm @@ -12,7 +12,7 @@ log_game("SQL ERROR obtaining ckey from notes table. Error : \[[err]\]\n") return if(!query_find_ckey.NextRow()) - usr << "[new_ckey] has not been seen before, you can only add notes to known players." + usr << "[new_ckey] has not been seen before, you can only add notes to known players." return else target_ckey = new_ckey @@ -216,4 +216,4 @@ this proc can take several minutes to execute fully if converting and cause DD t world << "Deleting NOTESFILE" fdel(NOTESFILE) world << "Finished mass note conversion, remember to turn off AUTOCONVERT_NOTES"*/ -#undef NOTESFILE \ No newline at end of file +#undef NOTESFILE From bac3cc0b6d38f2beba96f15bcb1bd5e9a1d5ceba Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Wed, 19 Aug 2015 04:38:11 -0500 Subject: [PATCH 075/108] Changelog --- .../living/simple_animal/guardian/guardian.dm | 1 + html/changelogs/Kor-PR-STANDPROUD.yml | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 html/changelogs/Kor-PR-STANDPROUD.yml diff --git a/code/modules/mob/living/simple_animal/guardian/guardian.dm b/code/modules/mob/living/simple_animal/guardian/guardian.dm index c5f22262531..595647e68da 100644 --- a/code/modules/mob/living/simple_animal/guardian/guardian.dm +++ b/code/modules/mob/living/simple_animal/guardian/guardian.dm @@ -23,6 +23,7 @@ melee_damage_lower = 15 melee_damage_upper = 15 butcher_results = list(/obj/item/weapon/ectoplasm = 1) + AIStatus = AI_OFF var/cooldown = 0 var/damage_transfer = 1 //how much damage from each attack we transfer to the owner var/mob/living/summoner diff --git a/html/changelogs/Kor-PR-STANDPROUD.yml b/html/changelogs/Kor-PR-STANDPROUD.yml new file mode 100644 index 00000000000..1abff6dad64 --- /dev/null +++ b/html/changelogs/Kor-PR-STANDPROUD.yml @@ -0,0 +1,36 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# wip (For works in progress) +# tweak +# soundadd +# sounddel +# rscadd (general adding of nice things) +# rscdel (general deleting of nice things) +# imageadd +# imagedel +# spellcheck (typo fixes) +# experiment +# tgs (TG-ported fixes?) +################################# + +# Your name. +author: Kor + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - rscadd: "The Ranged and Scout guardian types have been merged, and gained a new surveillance snare ability." From 1586d3000e1e100691a90f3fc9137d98041ef08d Mon Sep 17 00:00:00 2001 From: Jordie0608 Date: Wed, 19 Aug 2015 20:13:15 +1000 Subject: [PATCH 076/108] changelog --- html/changelog.html | 21 +++++++++++ html/changelogs/.all_changelog.yml | 18 ++++++++++ html/changelogs/Kor-PR-STANDPROUD.yml | 36 ------------------- html/changelogs/bgobandit - newcrates.yml | 4 --- .../phil235-VaporizeMethodReaction.yml | 8 ----- 5 files changed, 39 insertions(+), 48 deletions(-) delete mode 100644 html/changelogs/Kor-PR-STANDPROUD.yml delete mode 100644 html/changelogs/bgobandit - newcrates.yml delete mode 100644 html/changelogs/phil235-VaporizeMethodReaction.yml diff --git a/html/changelog.html b/html/changelog.html index c36cdd27f70..f5224993ae6 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -55,6 +55,27 @@ -->
    +

    19 August 2015

    +

    Kor updated:

    +
      +
    • The Ranged and Scout guardian types have been merged, and gained a new surveillance snare ability.
    • +
    • Escape pods now have computers to control launching early during code red or deltaor when emagged.
    • +
    +

    SconcesC updated:

    +
      +
    • Added Military Belts to traitor uplinks.
    • +
    +

    bgobandit updated:

    +
      +
    • CentComm now offers its cargo department toys, as well as detective gear so their boss can figure out which tech wasted all the points on them.
    • +
    +

    phil235 updated:

    +
      +
    • You can now partially protect yourself from blob attack effects by wearing impermeable clothes like hardsuits, medical clothes, masks, etc. Max protection effect is capped at 50%.
    • +
    • Splashing someone with chemicals no longer inject those chemicals in their body.
    • +
    • Fixes splashing acid on items or floor with items not having any effect.
    • +
    +

    18 August 2015

    CoreOverload updated:

      diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 52a113eb2ac..ba1b910b21c 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -1622,3 +1622,21 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. phil235: - tweak: Janicart rider no longer slip on wet floor or bananas. Moving on a floor tile with lube while buckled (chair, roller bed, etc) will make you fall off. +2015-08-19: + Kor: + - rscadd: The Ranged and Scout guardian types have been merged, and gained a new + surveillance snare ability. + - rscadd: Escape pods now have computers to control launching early during code + red or deltaor when emagged. + SconcesC: + - rscadd: Added Military Belts to traitor uplinks. + bgobandit: + - rscadd: CentComm now offers its cargo department toys, as well as detective gear + so their boss can figure out which tech wasted all the points on them. + phil235: + - rscadd: You can now partially protect yourself from blob attack effects by wearing + impermeable clothes like hardsuits, medical clothes, masks, etc. Max protection + effect is capped at 50%. + - rscdel: Splashing someone with chemicals no longer inject those chemicals in their + body. + - bugfix: Fixes splashing acid on items or floor with items not having any effect. diff --git a/html/changelogs/Kor-PR-STANDPROUD.yml b/html/changelogs/Kor-PR-STANDPROUD.yml deleted file mode 100644 index 1abff6dad64..00000000000 --- a/html/changelogs/Kor-PR-STANDPROUD.yml +++ /dev/null @@ -1,36 +0,0 @@ -################################ -# Example Changelog File -# -# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. -# -# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) -# When it is, any changes listed below will disappear. -# -# Valid Prefixes: -# bugfix -# wip (For works in progress) -# tweak -# soundadd -# sounddel -# rscadd (general adding of nice things) -# rscdel (general deleting of nice things) -# imageadd -# imagedel -# spellcheck (typo fixes) -# experiment -# tgs (TG-ported fixes?) -################################# - -# Your name. -author: Kor - -# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. -delete-after: True - -# Any changes you've made. See valid prefix list above. -# INDENT WITH TWO SPACES. NOT TABS. SPACES. -# SCREW THIS UP AND IT WON'T WORK. -# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. -# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. -changes: - - rscadd: "The Ranged and Scout guardian types have been merged, and gained a new surveillance snare ability." diff --git a/html/changelogs/bgobandit - newcrates.yml b/html/changelogs/bgobandit - newcrates.yml deleted file mode 100644 index 8377c32b219..00000000000 --- a/html/changelogs/bgobandit - newcrates.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: bgobandit -delete-after: True -changes: - - rscadd: "CentComm now offers its cargo department toys, as well as detective gear so their boss can figure out which tech wasted all the points on them." diff --git a/html/changelogs/phil235-VaporizeMethodReaction.yml b/html/changelogs/phil235-VaporizeMethodReaction.yml deleted file mode 100644 index 3f66104303a..00000000000 --- a/html/changelogs/phil235-VaporizeMethodReaction.yml +++ /dev/null @@ -1,8 +0,0 @@ -author: phil235 - -delete-after: True - -changes: - - rscadd: "You can now partially protect yourself from blob attack effects by wearing impermeable clothes like hardsuits, medical clothes, masks, etc. Max protection effect is capped at 50%." - - rscdel: "Splashing someone with chemicals no longer inject those chemicals in their body." - - bugfix: "Fixes splashing acid on items or floor with items not having any effect." From b1bafb0f7f50276725aa10ba88a37852c125f087 Mon Sep 17 00:00:00 2001 From: Jordie0608 Date: Wed, 19 Aug 2015 20:16:37 +1000 Subject: [PATCH 077/108] spellfix --- html/changelog.html | 6 +++--- html/changelogs/.all_changelog.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index f5224993ae6..e24345d0a5f 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -59,9 +59,9 @@

      Kor updated:

      • The Ranged and Scout guardian types have been merged, and gained a new surveillance snare ability.
      • -
      • Escape pods now have computers to control launching early during code red or deltaor when emagged.
      • +
      • Escape pods now have computers to control launching early during code red or delta or when emagged.
      -

      SconcesC updated:

      +

      SconesC updated:

      • Added Military Belts to traitor uplinks.
      @@ -72,7 +72,7 @@

      phil235 updated:

      • You can now partially protect yourself from blob attack effects by wearing impermeable clothes like hardsuits, medical clothes, masks, etc. Max protection effect is capped at 50%.
      • -
      • Splashing someone with chemicals no longer inject those chemicals in their body.
      • +
      • Splashing someone with chemicals no longer injects those chemicals in their body.
      • Fixes splashing acid on items or floor with items not having any effect.
      diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index ba1b910b21c..4aeab0a49ec 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -1627,8 +1627,8 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - rscadd: The Ranged and Scout guardian types have been merged, and gained a new surveillance snare ability. - rscadd: Escape pods now have computers to control launching early during code - red or deltaor when emagged. - SconcesC: + red or delta or when emagged. + SconesC: - rscadd: Added Military Belts to traitor uplinks. bgobandit: - rscadd: CentComm now offers its cargo department toys, as well as detective gear @@ -1637,6 +1637,6 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - rscadd: You can now partially protect yourself from blob attack effects by wearing impermeable clothes like hardsuits, medical clothes, masks, etc. Max protection effect is capped at 50%. - - rscdel: Splashing someone with chemicals no longer inject those chemicals in their + - rscdel: Splashing someone with chemicals no longer injects those chemicals in their body. - bugfix: Fixes splashing acid on items or floor with items not having any effect. From 41811cddefaf67692b8227500d9d874a882d228d Mon Sep 17 00:00:00 2001 From: Jordie0608 Date: Wed, 19 Aug 2015 20:18:53 +1000 Subject: [PATCH 078/108] korlikesbuttslog --- html/changelog.html | 1 - html/changelogs/.all_changelog.yml | 2 -- 2 files changed, 3 deletions(-) diff --git a/html/changelog.html b/html/changelog.html index e24345d0a5f..e5a240a8b27 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -59,7 +59,6 @@

      Kor updated:

      • The Ranged and Scout guardian types have been merged, and gained a new surveillance snare ability.
      • -
      • Escape pods now have computers to control launching early during code red or delta or when emagged.

      SconesC updated:

        diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 4aeab0a49ec..119380d217c 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -1626,8 +1626,6 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. Kor: - rscadd: The Ranged and Scout guardian types have been merged, and gained a new surveillance snare ability. - - rscadd: Escape pods now have computers to control launching early during code - red or delta or when emagged. SconesC: - rscadd: Added Military Belts to traitor uplinks. bgobandit: From 94344cd4712237ad28fa4c0a8fa643c2a4fc9b29 Mon Sep 17 00:00:00 2001 From: Jordie0608 Date: Wed, 19 Aug 2015 21:10:36 +1000 Subject: [PATCH 079/108] changes gold slime core hostile mob list to whitelist --- .../living/simple_animal/hostile/syndicate.dm | 2 +- code/modules/reagents/Chemistry-Recipes.dm | 79 +++++++++---------- 2 files changed, 39 insertions(+), 42 deletions(-) diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 38987cf6d27..9e6358e8a21 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -132,7 +132,7 @@ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 mob_size = MOB_SIZE_TINY - flying + flying = 1 speak_emote = list("states") /mob/living/simple_animal/hostile/viscerator/death(gibbed) diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index eb27d64550c..610522c91df 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -24,48 +24,45 @@ /datum/chemical_reaction/proc/chemical_mob_spawn(datum/reagents/holder, amount_to_spawn, reaction_name, mob_faction = "chemicalsummon") if(holder && holder.my_atom) - var/blocked = list(/mob/living/simple_animal/hostile, - /mob/living/simple_animal/hostile/pirate, - /mob/living/simple_animal/hostile/pirate/ranged, - /mob/living/simple_animal/hostile/russian, - /mob/living/simple_animal/hostile/russian/ranged, - /mob/living/simple_animal/hostile/syndicate, - /mob/living/simple_animal/hostile/syndicate/melee, - /mob/living/simple_animal/hostile/syndicate/melee/space, - /mob/living/simple_animal/hostile/syndicate/ranged, - /mob/living/simple_animal/hostile/syndicate/ranged/space, - /mob/living/simple_animal/hostile/alien/queen/large, - /mob/living/simple_animal/hostile/mushroom, - /mob/living/simple_animal/hostile/asteroid, - /mob/living/simple_animal/hostile/retaliate, - /mob/living/simple_animal/hostile/asteroid/basilisk, - /mob/living/simple_animal/hostile/asteroid/goldgrub, - /mob/living/simple_animal/hostile/asteroid/goliath, - /mob/living/simple_animal/hostile/asteroid/hivelord, - /mob/living/simple_animal/hostile/asteroid/hivelordbrood, - /mob/living/simple_animal/hostile/carp/holocarp, - /mob/living/simple_animal/hostile/mining_drone, - /mob/living/simple_animal/hostile/poison, - /mob/living/simple_animal/hostile/blob, - /mob/living/simple_animal/ascendant_shadowling, - /mob/living/simple_animal/hostile/guardian, - /mob/living/simple_animal/hostile/guardian/fire, - /mob/living/simple_animal/hostile/guardian/punch, - /mob/living/simple_animal/hostile/guardian/fast, - /mob/living/simple_animal/hostile/guardian/healer, - /mob/living/simple_animal/hostile/guardian/ranged, - /mob/living/simple_animal/hostile/guardian/bluespace, - /mob/living/simple_animal/hostile/guardian/bomb, - /mob/living/simple_animal/hostile/guardian/shield - )//exclusion list for things you don't want the reaction to create. - var/list/meancritters = typesof(/mob/living/simple_animal/hostile) - blocked // list of possible hostile mobs + var/list/meancritters = list(/mob/living/simple_animal/hostile/blob/blobspore, // list of possible hostile mobs + /mob/living/simple_animal/hostile/blob/blobbernaut, + /mob/living/simple_animal/hostile/carp/ranged/chaos, + /mob/living/simple_animal/hostile/carp/ranged, + /mob/living/simple_animal/hostile/carp/megacarp, + /mob/living/simple_animal/hostile/carp/eyeball, + /mob/living/simple_animal/hostile/carp, + /mob/living/simple_animal/hostile/alien/drone, + /mob/living/simple_animal/hostile/alien/sentinel, + /mob/living/simple_animal/hostile/alien/queen, + /mob/living/simple_animal/hostile/alien, + /mob/living/simple_animal/hostile/bear/Hudson, + /mob/living/simple_animal/hostile/bear, + /mob/living/simple_animal/hostile/poison/bees, + /mob/living/simple_animal/hostile/poison/giant_spider/nurse, + /mob/living/simple_animal/hostile/poison/giant_spider/hunter, + /mob/living/simple_animal/hostile/poison/giant_spider, + /mob/living/simple_animal/hostile/creature, + /mob/living/simple_animal/hostile/faithless, + /mob/living/simple_animal/hostile/headcrab, + /mob/living/simple_animal/hostile/hivebot/range, + /mob/living/simple_animal/hostile/hivebot/rapid, + /mob/living/simple_animal/hostile/hivebot/strong, + /mob/living/simple_animal/hostile/hivebot, + /mob/living/simple_animal/hostile/killertomato, + /mob/living/simple_animal/hostile/mimic/crate, + /mob/living/simple_animal/hostile/mimic, + /mob/living/simple_animal/hostile/statue, + /mob/living/simple_animal/hostile/viscerator, + /mob/living/simple_animal/hostile/tree/festivus, + /mob/living/simple_animal/hostile/tree) + var/list/nicecritters = list(/mob/living/simple_animal/crab, - /mob/living/simple_animal/mouse, - /mob/living/simple_animal/lizard, - /mob/living/simple_animal/parrot, - /mob/living/simple_animal/butterfly, - /mob/living/simple_animal/cow, - /mob/living/simple_animal/chicken) // and possible friendly mobs + /mob/living/simple_animal/mouse, + /mob/living/simple_animal/lizard, + /mob/living/simple_animal/parrot, + /mob/living/simple_animal/butterfly, + /mob/living/simple_animal/cow, + /mob/living/simple_animal/chicken) // and possible friendly mobs nicecritters += typesof(/mob/living/simple_animal/pet) - /mob/living/simple_animal/pet var/atom/A = holder.my_atom var/turf/T = get_turf(A) From 20e57adf8948c5622e5fb1de6ef3c3b31472eb2c Mon Sep 17 00:00:00 2001 From: erwgd Date: Wed, 19 Aug 2015 15:16:12 +0100 Subject: [PATCH 080/108] Added salt shaker and pepper mill to food crate --- code/datums/supplypacks.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/datums/supplypacks.dm b/code/datums/supplypacks.dm index 175ec10a0fd..311699f3819 100644 --- a/code/datums/supplypacks.dm +++ b/code/datums/supplypacks.dm @@ -759,6 +759,8 @@ var/list/all_supply_groups = list(supply_emergency,supply_security,supply_engine /obj/item/weapon/reagent_containers/food/condiment/rice, /obj/item/weapon/reagent_containers/food/condiment/milk, /obj/item/weapon/reagent_containers/food/condiment/soymilk, + /obj/item/weapon/reagent_containers/food/condiment/saltshaker, + /obj/item/weapon/reagent_containers/food/condiment/peppermill, /obj/item/weapon/storage/fancy/egg_box, /obj/item/weapon/reagent_containers/food/condiment/enzyme, /obj/item/weapon/reagent_containers/food/condiment/sugar, From cf58eac3d864b4c809084b24d8d56bb511979106 Mon Sep 17 00:00:00 2001 From: sybil-tgstation13 Date: Wed, 19 Aug 2015 14:40:10 +0000 Subject: [PATCH 081/108] Automatic changelog compile --- html/changelogs/.all_changelog.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 119380d217c..0d7841e5e4f 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -1635,6 +1635,6 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - rscadd: You can now partially protect yourself from blob attack effects by wearing impermeable clothes like hardsuits, medical clothes, masks, etc. Max protection effect is capped at 50%. - - rscdel: Splashing someone with chemicals no longer injects those chemicals in their - body. + - rscdel: Splashing someone with chemicals no longer injects those chemicals in + their body. - bugfix: Fixes splashing acid on items or floor with items not having any effect. From a1b557ab02213bf1ebbe62e2d00bf447c16ecbf7 Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Wed, 19 Aug 2015 11:06:37 -0400 Subject: [PATCH 082/108] Harvest ability is dead and gone, just click them, nerd. --- .../mob/living/simple_animal/revenant/revenant.dm | 1 - .../simple_animal/revenant/revenant_abilities.dm | 15 --------------- html/changelogs/revenants.yml | 2 +- 3 files changed, 1 insertion(+), 17 deletions(-) diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm index 320d608c047..2659dc577ff 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm @@ -190,7 +190,6 @@ /mob/living/simple_animal/revenant/proc/giveSpells() if(src.mind) - src.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_harvest src.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_transmit src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_light src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_defile diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm index 4bf79a19aaa..6de716e3180 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm @@ -1,18 +1,3 @@ -//Harvest Essence: The bread and butter of the revenant. The basic way of harvesting additional essence. -/obj/effect/proc_holder/spell/targeted/revenant_harvest - name = "Harvest" - desc = "Siphons the lingering spectral essence from a human, empowering yourself." - panel = "Revenant Abilities" - charge_max = 0 //No cooldown - clothes_req = 0 - range = 1 - -/obj/effect/proc_holder/spell/targeted/revenant_harvest/cast(list/targets, mob/living/simple_animal/revenant/user = usr) - for(var/mob/living/carbon/human/target in targets) - spawn(0) - user.Harvest(target) - - //Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob for 5E. /obj/effect/proc_holder/spell/targeted/revenant_transmit name = "Transmit" diff --git a/html/changelogs/revenants.yml b/html/changelogs/revenants.yml index ac8fb389e39..9389625b64f 100644 --- a/html/changelogs/revenants.yml +++ b/html/changelogs/revenants.yml @@ -6,5 +6,5 @@ changes: - rscadd: "Added a new revenant ability; Malfunction. It does bad stuff to machines." - tweak: "Defile and Overload Lights now briefly stun the revenant." - tweak: "You can now Harvest a target by clicking on them while next to them." - - bugfix: "Harvest no longer leaves you draining if the target is deleted mid-drain attempt." + - bugfix: "Harvesting no longer leaves you draining if the target is deleted mid-drain attempt." - rscdel: "Defile no longer emags bots or disables cyborgs, Malfunction does that now." From 9d79bf77ed1ec402341ea7c7f31647f499df7d85 Mon Sep 17 00:00:00 2001 From: sybil-tgstation13 Date: Wed, 19 Aug 2015 15:26:25 +0000 Subject: [PATCH 083/108] Automatic changelog compile --- html/changelog.html | 8 ++++++++ html/changelogs/.all_changelog.yml | 8 ++++++++ html/changelogs/revenants.yml | 10 ---------- 3 files changed, 16 insertions(+), 10 deletions(-) delete mode 100644 html/changelogs/revenants.yml diff --git a/html/changelog.html b/html/changelog.html index e5a240a8b27..74b09bfbaa3 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,14 @@ -->

        19 August 2015

        +

        Joan updated:

        +
          +
        • Added a new revenant ability; Malfunction. It does bad stuff to machines.
        • +
        • Defile and Overload Lights now briefly stun the revenant.
        • +
        • You can now Harvest a target by clicking on them while next to them.
        • +
        • Harvesting no longer leaves you draining if the target is deleted mid-drain attempt.
        • +
        • Defile no longer emags bots or disables cyborgs, Malfunction does that now.
        • +

        Kor updated:

        • The Ranged and Scout guardian types have been merged, and gained a new surveillance snare ability.
        • diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index 0d7841e5e4f..eac761cfbc9 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -1623,6 +1623,14 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. - tweak: Janicart rider no longer slip on wet floor or bananas. Moving on a floor tile with lube while buckled (chair, roller bed, etc) will make you fall off. 2015-08-19: + Joan: + - rscadd: Added a new revenant ability; Malfunction. It does bad stuff to machines. + - tweak: Defile and Overload Lights now briefly stun the revenant. + - tweak: You can now Harvest a target by clicking on them while next to them. + - bugfix: Harvesting no longer leaves you draining if the target is deleted mid-drain + attempt. + - rscdel: Defile no longer emags bots or disables cyborgs, Malfunction does that + now. Kor: - rscadd: The Ranged and Scout guardian types have been merged, and gained a new surveillance snare ability. diff --git a/html/changelogs/revenants.yml b/html/changelogs/revenants.yml deleted file mode 100644 index 9389625b64f..00000000000 --- a/html/changelogs/revenants.yml +++ /dev/null @@ -1,10 +0,0 @@ -author: Joan - -delete-after: True - -changes: - - rscadd: "Added a new revenant ability; Malfunction. It does bad stuff to machines." - - tweak: "Defile and Overload Lights now briefly stun the revenant." - - tweak: "You can now Harvest a target by clicking on them while next to them." - - bugfix: "Harvesting no longer leaves you draining if the target is deleted mid-drain attempt." - - rscdel: "Defile no longer emags bots or disables cyborgs, Malfunction does that now." From 37bd15dd1bb2f9f5bb127a17fc4904b3a643ab12 Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Wed, 19 Aug 2015 08:36:22 -0700 Subject: [PATCH 084/108] adds some sane sorting to sql notes. --- code/modules/admin/sql_notes.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/admin/sql_notes.dm b/code/modules/admin/sql_notes.dm index fbc01b16544..730e4531575 100644 --- a/code/modules/admin/sql_notes.dm +++ b/code/modules/admin/sql_notes.dm @@ -120,7 +120,7 @@ output = navbar if(target_ckey) var/target_sql_ckey = sanitizeSQL(target_ckey) - var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT id, timestamp, notetext, adminckey, last_editor, server FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]'") + var/DBQuery/query_get_notes = dbcon.NewQuery("SELECT id, timestamp, notetext, adminckey, last_editor, server FROM [format_table_name("notes")] WHERE ckey = '[target_sql_ckey]' ORDER BY timestamp") if(!query_get_notes.Execute()) var/err = query_get_notes.ErrorMsg() log_game("SQL ERROR obtaining ckey, notetext, adminckey, last_editor, server from notes table. Error : \[[err]\]\n") @@ -155,7 +155,7 @@ search = "^\[^\[:alpha:\]\]" else search = "^[index]" - var/DBQuery/query_list_notes = dbcon.NewQuery("SELECT DISTINCT ckey FROM [format_table_name("notes")] WHERE ckey REGEXP '[search]'") + var/DBQuery/query_list_notes = dbcon.NewQuery("SELECT DISTINCT ckey FROM [format_table_name("notes")] WHERE ckey REGEXP '[search]' ORDER BY ckey") if(!query_list_notes.Execute()) var/err = query_list_notes.ErrorMsg() log_game("SQL ERROR obtaining ckey from notes table. Error : \[[err]\]\n") From 0d2e094c76684ae853c80ac9986c3dbbf6023841 Mon Sep 17 00:00:00 2001 From: WJohn Date: Wed, 19 Aug 2015 13:31:40 -0400 Subject: [PATCH 085/108] Minor table sprite change. I've heard complaints of people saying the current table sprites look flat, and I think it's because I removed this little bright line at the bottom and on corners that made em shiny in order to make it consistent with wooden tables. I've brought it back here. ![](http://i.imgur.com/yUTqAqN.png) --- .../obj/smooth_structures/reinforced_table.dmi | Bin 831 -> 842 bytes icons/obj/smooth_structures/table.dmi | Bin 666 -> 670 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/obj/smooth_structures/reinforced_table.dmi b/icons/obj/smooth_structures/reinforced_table.dmi index be12e9f5fb597e431153b8cf4191caee71a3e901..85de93594f947258ac4b1abc95e366f06be01fa1 100644 GIT binary patch delta 597 zcmV-b0;>JL2FeDII1R|i$X;Gvz`(#LiY>~KMa+LBNklT*7zy|6CDh^O-;{Hci30s>w#Bm%`nCAEAtMFh%J{-%tU9KwAw#Jxj4gxH#;JA60 z0xTLUIBs&^7{JO{!EuvYvw+?8ftwcCGkH!d(3RK{$fXoNTFPs79 zt)zb$VBT7PMTB|#dMar=Vbr`ImJ-Jr~aNmWeP4~e8o~)pK zv0?$w;ZOcz0k8EaXjh{S9H975DX?jSg{I zToy)&5UDwAB*MglU4aTr2j)iLjU(TT0`gXpK!ne0eTxyc%L4lzs}K6VKMnxNHH3h? zGlyK|2*^7XhXE@^`Mx&}0<)(L1fEXw^}&!2by@tA>mR{^As?z*JVNnl1GWARtw4VT zDo}yz0;vy>UucLoqa+~Z?zV1(l>6`6z<55G2#n{0iNJW3BNZ4;JyLM!K? j6GDmql){}g`MJ$E&y_ai=6o{!00000NkvXXu0mjfON$qe delta 586 zcmV-Q0=50h2EPW7I1OH2UdYJEz`(%ypmCUyMa+L0NklT-A`vyHgrE!AZ{|+l*Yg30f#xV`k{6AXZ!+|()Ebn%?s%_U{O&2i%^Hb37RMCg#p}S-|&M2JUK!0)rkc> z$EWfB#N!=bqfQ;Jfm{G-mb6FV0 zL!{=g5f2w0>^(}hXtqaVbG60fm2oVKm4!Oz^QE(~_ z16GO(?ZG$*%>ITDcskA32V-`q>*`Z(egp@`>`?XU9*Qp;sPa3s0u`u01(pR;A0U6f z&=PM(i-457TUie&_utY$@hPYC!G*wdm18L|nR+Y*N`J#9nGY79axxz*?xEbW*|Ll$ z30~EDBJ>+3Ra;LoMce)^A)u=nSauIm2o(3Q`}I(?@U1`v76$&qSQg(8rGdRC5uksj zNC1ryKK2fSCr;}c)ZYJwoaVX!IMp%<`Tc|e@cfuDtDi6cPW^@aenKempHlg&CO^0N Y20@i9L>|hXa{vGU07*qoM6N<$f;UYP6#xJL diff --git a/icons/obj/smooth_structures/table.dmi b/icons/obj/smooth_structures/table.dmi index 3037760db9931ecf3a237b2292cc6a09958b50d8..ffd88a84fc7aacfa166c1b32e9415aca155202a4 100644 GIT binary patch delta 446 zcmV;v0YUzn1)c?vBq113OjJd{z`#L4L413Asi~>R$jFe8kX~M1z`(#IFjpv%Ldt)7 zNklUeoOeU|hr7{a@99A+6!DHN2J%>W51O~1EYNB{MEH! zO49d|)U{yF(w#%<009EL1pLhn)-nJA0t9#pc=!dp!6<|K|4OAKf#o`}nVcoiu=ffO zAizVw-cL}p12`bKEYkj9Sufi$P`!sxNipZBcR4Dl&5Gu{IM_WX9PI8x4i10UhhccI z`8=g})Byqn2=MNp_6_O_0vr}>uLpO6?X}EKu)WK%7yR)Cy$59;zYm+wcP|H9p8pT< z6^SGsUPvS!5Aml=;<#xG5FkK+0Nufb#08{tiU$~@^R!3K7uwDf79brI7m)U$3rM@r o1tcSDI#0+$&k&w^o=}-LR&x^Iatf)aaxkwwaXc}YY; zRA_Ex=_BFK<;7D9t$*FiNwc zW?JNV{#2*F@bzs0r9m-)QXiUsK&cN+pfHk?1q{M+M0(9V_FHK*Fv@q%UtJ5PBz-SQ zT?^(c-8rNV5Fo%yz~9_pEdvlBK!B%!hhM-Oj54_YuT)ABSgsSB$yovod#?Zi0z3rl z{RBljfCGZdBJB^B^|BoU)q4n)6myPxm!p!}tZ2?B2fGJ_gWY||!QuLUFboeipQrSW zIzWH`0p1^?Z_j0i1`Tqc4kx1g< zg+$`<5P!-fj+?ds0RjXF&>dVzTtGUfcz`iFPkZEiq3t|j0n$Nn0cjt)fV2x;Kr*tX k^MpL~4B@Hg36*&Rf^XmvKcA`Qm;e9(07*qoM6N<$f)hi=QUCw| From 565537986635f27836b44f0c515170ae14b735dd Mon Sep 17 00:00:00 2001 From: Aranclanos Date: Thu, 20 Aug 2015 08:11:48 -0300 Subject: [PATCH 086/108] Fixes the watchlist edit option not working at all --- code/modules/admin/topic.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index e611c96300d..3093d959d6d 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1157,7 +1157,7 @@ var/DBQuery/query_reason = dbcon.NewQuery("SELECT ckey, reason FROM [format_table_name("watch")] WHERE (ckey = '[sql_ckey]')") query_reason.Execute() if(query_reason.NextRow()) - var/watch_reason = query_reason.item[3] + var/watch_reason = query_reason.item[2] var/new_reason = input("Insert new reason", "New Reason", "[watch_reason]", null) as null|text new_reason = sanitizeSQL(new_reason) if(!new_reason) From 6fe5f23e551823e29e6b481346b8d349b4b57288 Mon Sep 17 00:00:00 2001 From: Supermichael777 Date: Thu, 20 Aug 2015 15:06:42 -0400 Subject: [PATCH 087/108] Updates dank memes. updates Bar memes to reflect recent rule changes/be funny. --- code/game/objects/structures/barsigns.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm index 7c4637a2df8..12b74f0efbe 100644 --- a/code/game/objects/structures/barsigns.dm +++ b/code/game/objects/structures/barsigns.dm @@ -246,7 +246,7 @@ /datum/barsign/emergencyrumparty name = "The Emergency Rum Party" icon = "emergencyrumparty" - desc = "Still serving drinks that were banned years ago." + desc = "Recently relicenced after a long closure." /datum/barsign/combocafe name = "The Combo Cafe" @@ -276,7 +276,7 @@ /datum/barsign/thenet name = "The Net" icon = "thenet" - desc = "The sea of drinkformation." //you couldn't come up with something better? + desc = "You just seem to get caught up in it for hours." //you couldn't come up with something better? /datum/barsign/hiddensigns From beaf153e2a665998dd71fe8dad299c814a71094d Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Thu, 20 Aug 2015 12:25:46 -0700 Subject: [PATCH 088/108] Uhh, Why do I have commit access? --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 544f4940db7..5437433fc0c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -##/tg/station v1.0.1 +##/tg/station v1.0.1 [![Build Status](https://travis-ci.org/tgstation/-tg-station.png)](https://travis-ci.org/tgstation/-tg-station) From e66bf6f5a15dacbeefec59c135b8031bb91f7645 Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Thu, 20 Aug 2015 12:43:57 -0700 Subject: [PATCH 089/108] And for my final act of griffing the code base. --- config/admins.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/admins.txt b/config/admins.txt index f708dcc3df4..789c36cc02d 100644 --- a/config/admins.txt +++ b/config/admins.txt @@ -32,7 +32,7 @@ korphaeron = Game Master nodrak = Game Master carnwennan = Game Master ikarrus = Game Master -cheridan = Game Master +cheridan = Admin Observer giacomand = Game Master rockdtben = Game Master sieve = Game Master @@ -91,4 +91,4 @@ drovidicorv = Game Master Dunc = Game Master MMMiracles = Game Master bear1ake = Game Master -CoreOverload = Game Master \ No newline at end of file +CoreOverload = Game Master From 2f50fecaa105740eae11dc90ffd2ea307f1328fc Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Thu, 20 Aug 2015 17:32:19 -0400 Subject: [PATCH 090/108] A: Fuck this, it's terrible and B: All supported maps already pixel-shift these, there's no need for this code at all except to confuse and frustrate new mappers trying to place door timers. --- code/game/machinery/doors/brigdoors.dm | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/game/machinery/doors/brigdoors.dm b/code/game/machinery/doors/brigdoors.dm index d6d5f886095..c9a24cb6b5d 100644 --- a/code/game/machinery/doors/brigdoors.dm +++ b/code/game/machinery/doors/brigdoors.dm @@ -38,9 +38,6 @@ Radio = new/obj/item/device/radio(src) Radio.listening = 0 - pixel_x = ((src.dir & 3)? (0) : (src.dir == 4 ? 32 : -32)) - pixel_y = ((src.dir & 3)? (src.dir ==1 ? 24 : -32) : (0)) - spawn(20) for(var/obj/machinery/door/window/brigdoor/M in range(20, src)) if (M.id == src.id) From e0c6c710c2e667182ff283fa30273f782981099c Mon Sep 17 00:00:00 2001 From: Supermichael777 Date: Thu, 20 Aug 2015 20:08:23 -0400 Subject: [PATCH 091/108] Update barsigns.dm --- code/game/objects/structures/barsigns.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/objects/structures/barsigns.dm b/code/game/objects/structures/barsigns.dm index 12b74f0efbe..f09ec051c67 100644 --- a/code/game/objects/structures/barsigns.dm +++ b/code/game/objects/structures/barsigns.dm @@ -246,7 +246,7 @@ /datum/barsign/emergencyrumparty name = "The Emergency Rum Party" icon = "emergencyrumparty" - desc = "Recently relicenced after a long closure." + desc = "Recently relicensed after a long closure." /datum/barsign/combocafe name = "The Combo Cafe" @@ -276,7 +276,7 @@ /datum/barsign/thenet name = "The Net" icon = "thenet" - desc = "You just seem to get caught up in it for hours." //you couldn't come up with something better? + desc = "You just seem to get caught up in it for hours." /datum/barsign/hiddensigns From 62c9fc636852fe33989791ffe90f36bc055a9dca Mon Sep 17 00:00:00 2001 From: Aranclanos Date: Thu, 20 Aug 2015 21:44:56 -0300 Subject: [PATCH 092/108] Fixes ninja stealth not working at all --- code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm b/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm index 107502ce151..c7a1f0f143d 100644 --- a/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm +++ b/code/modules/ninja/suit/n_suit_verbs/ninja_stealth.dm @@ -18,7 +18,7 @@ Contents: U << "You don't have enough power to enable Stealth!" return s_active=!s_active - animate(U, U.alpha = 0,time = 15) + animate(U, alpha = 0,time = 15) U.visible_message("[U.name] vanishes into thin air!", \ "You are now invisible to normal detection.") return @@ -30,7 +30,7 @@ Contents: return 0 if(s_active) s_active=!s_active - animate(U, U.alpha = 255, time = 15) + animate(U, alpha = 255, time = 15) U.visible_message("[U.name] appears from thin air!", \ "You are now visible.") return 1 From db57f5834b8dc3fffb87777fe9e5f4d2cfa2a644 Mon Sep 17 00:00:00 2001 From: Aranclanos Date: Thu, 20 Aug 2015 22:34:03 -0300 Subject: [PATCH 093/108] Fixes a runtime caused when interacting with a hat-less Ian --- code/modules/mob/living/simple_animal/friendly/dog.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index bc0ebe9883b..83766139bb4 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -275,7 +275,9 @@ return valid /mob/living/simple_animal/pet/dog/corgi/proc/update_corgi_fluff() - switch(src.inventory_head.type) + if(!inventory_head) + return + switch(inventory_head.type) if(/obj/item/clothing/head/helmet) name = "Sergeant [real_name]" desc = "The ever-loyal, the ever-vigilant." From 9f953a2816a63f8a4f22c5bed589c4495dc85d98 Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Thu, 20 Aug 2015 23:45:13 -0700 Subject: [PATCH 094/108] Fixes spawn relevant triggering WAY too often. 20, as an event weighting, happens twice as often as rad storm, a 10 weighted event. Its way too much. I put it to 7 weight, halfway between rad storm (10) and meteor storm (5) --- .../mob/living/simple_animal/revenant/revenant_spawn_event.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm b/code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm index 0db127f03ae..0cb19dab3da 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant_spawn_event.dm @@ -3,7 +3,7 @@ /datum/round_event_control/revenant name = "Spawn Revenant" typepath = /datum/round_event/revenant - weight = 20 + weight = 7 max_occurrences = 3 earliest_start = 6000 //Meant to mix things up early-game. From 6f4c89c5ff4bcb5a7b837fb16b5f6a9ddd8da8a0 Mon Sep 17 00:00:00 2001 From: Aranclanos Date: Fri, 21 Aug 2015 05:22:20 -0300 Subject: [PATCH 095/108] Fixes the nuclear disk from not spawning under really specific circumstances --- code/game/objects/items/weapons/storage/storage.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index 0a3ce5f865d..f4179092429 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -481,4 +481,5 @@ /obj/item/weapon/storage/handle_atom_del(atom/A) if(A in contents) + usr = null remove_from_storage(A,null) From dd6e735e71395a80ab47f139b7d1793df61ab4f9 Mon Sep 17 00:00:00 2001 From: Aranclanos Date: Fri, 21 Aug 2015 07:14:56 -0300 Subject: [PATCH 096/108] The remove_from_storage() call from handle_atom_del() will stop dropping the objects on null, to avoid having other storage objects with items inside in a null location. --- code/game/objects/items/weapons/storage/storage.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weapons/storage/storage.dm b/code/game/objects/items/weapons/storage/storage.dm index f4179092429..fdd4aea2842 100644 --- a/code/game/objects/items/weapons/storage/storage.dm +++ b/code/game/objects/items/weapons/storage/storage.dm @@ -482,4 +482,4 @@ /obj/item/weapon/storage/handle_atom_del(atom/A) if(A in contents) usr = null - remove_from_storage(A,null) + remove_from_storage(A, loc) From 43a151ae4e2857b431e257c889d99e163f0661b1 Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Fri, 21 Aug 2015 18:14:00 -0500 Subject: [PATCH 097/108] Fix --- code/modules/mob/living/bloodcrawl.dm | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/code/modules/mob/living/bloodcrawl.dm b/code/modules/mob/living/bloodcrawl.dm index 3283c0ebb4f..212272026a4 100644 --- a/code/modules/mob/living/bloodcrawl.dm +++ b/code/modules/mob/living/bloodcrawl.dm @@ -35,13 +35,16 @@ sleep(30) playsound(get_turf(src),'sound/magic/Demon_consume.ogg', 100, 1) sleep(30) - src << "You devour [kidnapped]. Your health is fully restored." - src.adjustBruteLoss(-1000) - src.adjustFireLoss(-1000) - src.adjustOxyLoss(-1000) - src.adjustToxLoss(-1000) - kidnapped.ghostize() - qdel(kidnapped) + if(kidnapped) + src << "You devour [kidnapped]. Your health is fully restored." + src.adjustBruteLoss(-1000) + src.adjustFireLoss(-1000) + src.adjustOxyLoss(-1000) + src.adjustToxLoss(-1000) + kidnapped.ghostize() + qdel(kidnapped) + else + src << "You happily devour...nothing? Your meal escaped at some point!" src.notransform = 0 /mob/living/proc/phasein(obj/effect/decal/cleanable/B) From 73aac62ce665f2081eb227fce32bfdd0c2474d6b Mon Sep 17 00:00:00 2001 From: KorPhaeron Date: Fri, 21 Aug 2015 18:14:33 -0500 Subject: [PATCH 098/108] Changed wording --- code/modules/mob/living/bloodcrawl.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/bloodcrawl.dm b/code/modules/mob/living/bloodcrawl.dm index 212272026a4..a58fd4401a4 100644 --- a/code/modules/mob/living/bloodcrawl.dm +++ b/code/modules/mob/living/bloodcrawl.dm @@ -44,7 +44,7 @@ kidnapped.ghostize() qdel(kidnapped) else - src << "You happily devour...nothing? Your meal escaped at some point!" + src << "You happily devour...nothing? Your meal vanished at some point!" src.notransform = 0 /mob/living/proc/phasein(obj/effect/decal/cleanable/B) From 5824fedc175135ec40302d965b833f7223b08b01 Mon Sep 17 00:00:00 2001 From: Jordie0608 Date: Sat, 22 Aug 2015 16:49:13 +1000 Subject: [PATCH 099/108] gold core spawnable as var --- code/game/gamemodes/blob/blobs/blob_mobs.dm | 3 +- .../simple_animal/friendly/butterfly.dm | 1 + .../mob/living/simple_animal/friendly/cat.dm | 3 + .../mob/living/simple_animal/friendly/crab.dm | 4 +- .../mob/living/simple_animal/friendly/dog.dm | 4 ++ .../simple_animal/friendly/farm_animals.dm | 3 + .../mob/living/simple_animal/friendly/fox.dm | 4 +- .../living/simple_animal/friendly/lizard.dm | 1 + .../living/simple_animal/friendly/mouse.dm | 2 + .../mob/living/simple_animal/hostile/alien.dm | 2 + .../mob/living/simple_animal/hostile/bear.dm | 1 + .../mob/living/simple_animal/hostile/bees.dm | 1 + .../mob/living/simple_animal/hostile/carp.dm | 2 + .../living/simple_animal/hostile/creature.dm | 2 +- .../living/simple_animal/hostile/faithless.dm | 1 + .../simple_animal/hostile/giant_spider.dm | 1 + .../living/simple_animal/hostile/headcrab.dm | 1 + .../living/simple_animal/hostile/hivebot.dm | 1 + .../simple_animal/hostile/killertomato.dm | 1 + .../mob/living/simple_animal/hostile/mimic.dm | 2 + .../living/simple_animal/hostile/statue.dm | 1 + .../living/simple_animal/hostile/syndicate.dm | 1 + .../mob/living/simple_animal/hostile/tree.dm | 1 + .../mob/living/simple_animal/parrot.dm | 2 + .../mob/living/simple_animal/simple_animal.dm | 2 + code/modules/reagents/Chemistry-Recipes.dm | 72 +++++-------------- 26 files changed, 61 insertions(+), 58 deletions(-) diff --git a/code/game/gamemodes/blob/blobs/blob_mobs.dm b/code/game/gamemodes/blob/blobs/blob_mobs.dm index 440967945ab..cad8505781d 100644 --- a/code/game/gamemodes/blob/blobs/blob_mobs.dm +++ b/code/game/gamemodes/blob/blobs/blob_mobs.dm @@ -39,6 +39,7 @@ var/obj/effect/blob/factory/factory = null var/list/human_overlays = list() var/is_zombie = 0 + gold_core_spawnable = 1 /mob/living/simple_animal/hostile/blob/blobspore/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume) ..() @@ -161,7 +162,7 @@ force_threshold = 10 environment_smash = 3 mob_size = MOB_SIZE_LARGE - + gold_core_spawnable = 1 /mob/living/simple_animal/hostile/blob/blobbernaut/blob_act() return diff --git a/code/modules/mob/living/simple_animal/friendly/butterfly.dm b/code/modules/mob/living/simple_animal/friendly/butterfly.dm index b1af5b5230e..a020baf05a9 100644 --- a/code/modules/mob/living/simple_animal/friendly/butterfly.dm +++ b/code/modules/mob/living/simple_animal/friendly/butterfly.dm @@ -16,6 +16,7 @@ pass_flags = PASSTABLE | PASSGRILLE | PASSMOB ventcrawler = 2 mob_size = MOB_SIZE_TINY + gold_core_spawnable = 2 /mob/living/simple_animal/butterfly/New() ..() diff --git a/code/modules/mob/living/simple_animal/friendly/cat.dm b/code/modules/mob/living/simple_animal/friendly/cat.dm index 3268bd3007e..9c253d5d9c1 100644 --- a/code/modules/mob/living/simple_animal/friendly/cat.dm +++ b/code/modules/mob/living/simple_animal/friendly/cat.dm @@ -20,6 +20,7 @@ response_help = "pets" response_disarm = "gently pushes aside" response_harm = "kicks" + gold_core_spawnable = 2 //RUNTIME IS ALIVE! SQUEEEEEEEE~ /mob/living/simple_animal/pet/cat/Runtime @@ -31,6 +32,7 @@ gender = FEMALE var/turns_since_scan = 0 var/mob/living/simple_animal/mouse/movement_target + gold_core_spawnable = 0 /mob/living/simple_animal/pet/cat/Runtime/Life() //MICE! @@ -69,6 +71,7 @@ /mob/living/simple_animal/pet/cat/Proc name = "Proc" + gold_core_spawnable = 0 /mob/living/simple_animal/pet/cat/kitten name = "kitten" diff --git a/code/modules/mob/living/simple_animal/friendly/crab.dm b/code/modules/mob/living/simple_animal/friendly/crab.dm index ef3ce5448ad..7bf0522ab86 100644 --- a/code/modules/mob/living/simple_animal/friendly/crab.dm +++ b/code/modules/mob/living/simple_animal/friendly/crab.dm @@ -19,6 +19,7 @@ ventcrawler = 2 var/obj/item/inventory_head var/obj/item/inventory_mask + gold_core_spawnable = 2 /mob/living/simple_animal/crab/Life() ..() @@ -40,4 +41,5 @@ desc = "It's Coffee, the other pet!" response_help = "pets" response_disarm = "gently pushes aside" - response_harm = "stomps" \ No newline at end of file + response_harm = "stomps" + gold_core_spawnable = 0 \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index bc0ebe9883b..e179fcee28d 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -29,6 +29,7 @@ var/obj/item/inventory_head var/obj/item/inventory_back var/facehugger + gold_core_spawnable = 2 /mob/living/simple_animal/pet/dog/pug name = "\improper pug" @@ -39,6 +40,7 @@ icon_living = "pug" icon_dead = "pug_dead" butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/pug = 3) + gold_core_spawnable = 2 /mob/living/simple_animal/pet/dog/corgi/New() ..() @@ -388,6 +390,7 @@ response_help = "pets" response_disarm = "bops" response_harm = "kicks" + gold_core_spawnable = 0 /mob/living/simple_animal/pet/dog/corgi/Ian/Life() ..() @@ -511,6 +514,7 @@ response_harm = "kicks" var/turns_since_scan = 0 var/puppies = 0 + gold_core_spawnable = 0 //Lisa already has a cute bow! /mob/living/simple_animal/pet/dog/corgi/Lisa/Topic(href, href_list) diff --git a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm index 96b24a86fe7..440798466fb 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -105,6 +105,7 @@ attack_sound = 'sound/weapons/punch1.ogg' health = 50 var/datum/reagents/udder = null + gold_core_spawnable = 2 /mob/living/simple_animal/cow/New() udder = new(50) @@ -169,6 +170,7 @@ var/amount_grown = 0 pass_flags = PASSTABLE | PASSGRILLE | PASSMOB mob_size = MOB_SIZE_TINY + gold_core_spawnable = 2 /mob/living/simple_animal/chick/New() ..() @@ -219,6 +221,7 @@ var/global/chicken_count = 0 var/list/feedMessages = list("It clucks happily.","It clucks happily.") var/list/layMessage = list("lays an egg.","squats down and croons.","begins making a huge racket.","begins clucking raucously.") var/list/validColors = list("brown","black","white") + gold_core_spawnable = 2 /mob/living/simple_animal/chicken/New() ..() diff --git a/code/modules/mob/living/simple_animal/friendly/fox.dm b/code/modules/mob/living/simple_animal/friendly/fox.dm index fefd67e907a..a6c4768344b 100644 --- a/code/modules/mob/living/simple_animal/friendly/fox.dm +++ b/code/modules/mob/living/simple_animal/friendly/fox.dm @@ -17,8 +17,10 @@ response_help = "pets" response_disarm = "gently pushes aside" response_harm = "kicks" + gold_core_spawnable = 2 //Captain fox /mob/living/simple_animal/pet/fox/Renault name = "Renault" - desc = "Renault, the Captain's trustworthy fox. I wonder what it says?" \ No newline at end of file + desc = "Renault, the Captain's trustworthy fox. I wonder what it says?" + gold_core_spawnable = 0 \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/friendly/lizard.dm b/code/modules/mob/living/simple_animal/friendly/lizard.dm index b03101df7f1..e958eea35e9 100644 --- a/code/modules/mob/living/simple_animal/friendly/lizard.dm +++ b/code/modules/mob/living/simple_animal/friendly/lizard.dm @@ -18,3 +18,4 @@ density = 0 pass_flags = PASSTABLE | PASSMOB mob_size = MOB_SIZE_SMALL + gold_core_spawnable = 2 diff --git a/code/modules/mob/living/simple_animal/friendly/mouse.dm b/code/modules/mob/living/simple_animal/friendly/mouse.dm index 9b0bc3afd0c..fbe54636bcb 100644 --- a/code/modules/mob/living/simple_animal/friendly/mouse.dm +++ b/code/modules/mob/living/simple_animal/friendly/mouse.dm @@ -22,6 +22,7 @@ pass_flags = PASSTABLE | PASSGRILLE | PASSMOB mob_size = MOB_SIZE_TINY var/body_color //brown, gray and white, leave blank for random + gold_core_spawnable = 2 /mob/living/simple_animal/mouse/New() ..() @@ -77,6 +78,7 @@ response_help = "pets" response_disarm = "gently pushes aside" response_harm = "splats" + gold_core_spawnable = 0 /obj/item/trash/deadmouse name = "dead mouse" diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm index 08ca902017d..56465782b39 100644 --- a/code/modules/mob/living/simple_animal/hostile/alien.dm +++ b/code/modules/mob/living/simple_animal/hostile/alien.dm @@ -29,6 +29,7 @@ see_in_dark = 8 see_invisible = SEE_INVISIBLE_MINIMUM unique_name = 1 + gold_core_spawnable = 1 /mob/living/simple_animal/hostile/alien/drone name = "alien drone" @@ -130,6 +131,7 @@ butcher_results = list(/obj/item/weapon/reagent_containers/food/snacks/meat/slab/xeno = 10, /obj/item/stack/sheet/animalhide/xeno = 2) mob_size = MOB_SIZE_LARGE + gold_core_spawnable = 0 /obj/item/projectile/neurotox name = "neurotoxin" diff --git a/code/modules/mob/living/simple_animal/hostile/bear.dm b/code/modules/mob/living/simple_animal/hostile/bear.dm index 651d97dcb56..b091ed92d39 100644 --- a/code/modules/mob/living/simple_animal/hostile/bear.dm +++ b/code/modules/mob/living/simple_animal/hostile/bear.dm @@ -33,6 +33,7 @@ maxbodytemp = 1500 faction = list("russian") + gold_core_spawnable = 1 //SPACE BEARS! SQUEEEEEEEE~ OW! FUCK! IT BIT MY HAND OFF!! /mob/living/simple_animal/hostile/bear/Hudson diff --git a/code/modules/mob/living/simple_animal/hostile/bees.dm b/code/modules/mob/living/simple_animal/hostile/bees.dm index 5c9265578f8..7e1e6677337 100644 --- a/code/modules/mob/living/simple_animal/hostile/bees.dm +++ b/code/modules/mob/living/simple_animal/hostile/bees.dm @@ -21,6 +21,7 @@ pass_flags = PASSTABLE | PASSGRILLE | PASSMOB mob_size = MOB_SIZE_SMALL flying = 1 + gold_core_spawnable = 1 //Spaceborn beings don't get hurt by space atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm index dd872f00853..1fdef2619ff 100644 --- a/code/modules/mob/living/simple_animal/hostile/carp.dm +++ b/code/modules/mob/living/simple_animal/hostile/carp.dm @@ -31,6 +31,7 @@ faction = list("carp") flying = 1 + gold_core_spawnable = 1 /mob/living/simple_animal/hostile/carp/Process_Spacemove(movement_dir = 0) return 1 //No drifting in space for space carp! //original comments do not steal @@ -45,6 +46,7 @@ icon_state = "holocarp" icon_living = "holocarp" maxbodytemp = INFINITY + gold_core_spawnable = 0 /mob/living/simple_animal/hostile/carp/holocarp/death() ..(1) diff --git a/code/modules/mob/living/simple_animal/hostile/creature.dm b/code/modules/mob/living/simple_animal/hostile/creature.dm index 173d8ff913f..66dc786c974 100644 --- a/code/modules/mob/living/simple_animal/hostile/creature.dm +++ b/code/modules/mob/living/simple_animal/hostile/creature.dm @@ -13,4 +13,4 @@ attack_sound = 'sound/weapons/bite.ogg' faction = list("creature") speak_emote = list("screams") - + gold_core_spawnable = 1 diff --git a/code/modules/mob/living/simple_animal/hostile/faithless.dm b/code/modules/mob/living/simple_animal/hostile/faithless.dm index c74afd3be1b..a85c82a9cf9 100644 --- a/code/modules/mob/living/simple_animal/hostile/faithless.dm +++ b/code/modules/mob/living/simple_animal/hostile/faithless.dm @@ -26,6 +26,7 @@ minbodytemp = 0 faction = list("faithless") + gold_core_spawnable = 1 /mob/living/simple_animal/hostile/faithless/Process_Spacemove(movement_dir = 0) return 1 diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index 9eb111c521e..a8a4cdc4357 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -45,6 +45,7 @@ attacktext = "bites" attack_sound = 'sound/weapons/bite.ogg' unique_name = 1 + gold_core_spawnable = 1 //nursemaids - these create webs and eggs /mob/living/simple_animal/hostile/poison/giant_spider/nurse diff --git a/code/modules/mob/living/simple_animal/hostile/headcrab.dm b/code/modules/mob/living/simple_animal/hostile/headcrab.dm index 587e686d67d..18160d68ad2 100644 --- a/code/modules/mob/living/simple_animal/hostile/headcrab.dm +++ b/code/modules/mob/living/simple_animal/hostile/headcrab.dm @@ -20,6 +20,7 @@ ventcrawler = 2 var/datum/mind/origin var/egg_lain = 0 + gold_core_spawnable = 1 /mob/living/simple_animal/hostile/headcrab/proc/Infect(mob/living/carbon/victim) var/obj/item/organ/internal/body_egg/changeling_egg/egg = new(victim) diff --git a/code/modules/mob/living/simple_animal/hostile/hivebot.dm b/code/modules/mob/living/simple_animal/hostile/hivebot.dm index ce67552c952..37981ec6a39 100644 --- a/code/modules/mob/living/simple_animal/hostile/hivebot.dm +++ b/code/modules/mob/living/simple_animal/hostile/hivebot.dm @@ -21,6 +21,7 @@ atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 0 speak_emote = list("states") + gold_core_spawnable = 1 /mob/living/simple_animal/hostile/hivebot/range name = "hivebot" diff --git a/code/modules/mob/living/simple_animal/hostile/killertomato.dm b/code/modules/mob/living/simple_animal/hostile/killertomato.dm index 4677cb50cc9..5c032e21bc7 100644 --- a/code/modules/mob/living/simple_animal/hostile/killertomato.dm +++ b/code/modules/mob/living/simple_animal/hostile/killertomato.dm @@ -23,3 +23,4 @@ atmos_requirements = list("min_oxy" = 5, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) minbodytemp = 150 maxbodytemp = 500 + gold_core_spawnable = 1 diff --git a/code/modules/mob/living/simple_animal/hostile/mimic.dm b/code/modules/mob/living/simple_animal/hostile/mimic.dm index 5e0f67211e6..877739d8bd8 100644 --- a/code/modules/mob/living/simple_animal/hostile/mimic.dm +++ b/code/modules/mob/living/simple_animal/hostile/mimic.dm @@ -26,6 +26,7 @@ faction = list("mimic") move_to_delay = 9 + gold_core_spawnable = 1 /mob/living/simple_animal/hostile/mimic/death() ..(1) @@ -109,6 +110,7 @@ var/global/list/protected_objects = list(/obj/structure/table, /obj/structure/ca var/mob/living/creator = null // the creator var/destroy_objects = 0 var/knockdown_people = 0 + gold_core_spawnable = 0 /mob/living/simple_animal/hostile/mimic/copy/New(loc, obj/copy, mob/living/creator, destroy_original = 0) ..(loc) diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm index 8ff2d451a10..491fd2c1440 100644 --- a/code/modules/mob/living/simple_animal/hostile/statue.dm +++ b/code/modules/mob/living/simple_animal/hostile/statue.dm @@ -44,6 +44,7 @@ var/cannot_be_seen = 1 var/mob/living/creator = null + gold_core_spawnable = 1 // No movement while seen code. diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm index 9e6358e8a21..f04ded89b18 100644 --- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm +++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm @@ -134,6 +134,7 @@ mob_size = MOB_SIZE_TINY flying = 1 speak_emote = list("states") + gold_core_spawnable = 1 /mob/living/simple_animal/hostile/viscerator/death(gibbed) ..(gibbed) diff --git a/code/modules/mob/living/simple_animal/hostile/tree.dm b/code/modules/mob/living/simple_animal/hostile/tree.dm index 0acc9aad7ef..fa43d85572e 100644 --- a/code/modules/mob/living/simple_animal/hostile/tree.dm +++ b/code/modules/mob/living/simple_animal/hostile/tree.dm @@ -33,6 +33,7 @@ faction = list("hostile") var/drop_type = /obj/item/stack/sheet/mineral/wood + gold_core_spawnable = 1 /mob/living/simple_animal/hostile/tree/AttackingTarget() ..() diff --git a/code/modules/mob/living/simple_animal/parrot.dm b/code/modules/mob/living/simple_animal/parrot.dm index 41c36669023..f600071a076 100644 --- a/code/modules/mob/living/simple_animal/parrot.dm +++ b/code/modules/mob/living/simple_animal/parrot.dm @@ -56,6 +56,7 @@ friendly = "grooms" mob_size = MOB_SIZE_SMALL flying = 1 + gold_core_spawnable = 2 var/parrot_damage_upper = 10 var/parrot_state = PARROT_WANDER //Hunt for a perch when created @@ -809,6 +810,7 @@ name = "Poly" desc = "Poly the Parrot. An expert on quantum cracker theory." speak = list("Poly wanna cracker!", ":e Check the singlo, you chucklefucks!",":e Wire the solars, you lazy bums!",":e WHO TOOK THE DAMN HARDSUITS?",":e OH GOD ITS FREE CALL THE SHUTTLE") + gold_core_spawnable = 0 /mob/living/simple_animal/parrot/Poly/New() ears = new /obj/item/device/radio/headset/headset_eng(src) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 64a70739e32..dd15c2f2a49 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -57,6 +57,8 @@ var/obj/item/weapon/card/id/access_card = null //innate access uses an internal ID card var/flying = 0 //whether it's flying or touching the ground. + var/gold_core_spawnable = 0 //if 1 can be spawned by plasma with gold core, 2 are 'friendlies' spawned with blood + /mob/living/simple_animal/New() ..() verbs -= /mob/verb/observe diff --git a/code/modules/reagents/Chemistry-Recipes.dm b/code/modules/reagents/Chemistry-Recipes.dm index 610522c91df..51d3caf2b15 100644 --- a/code/modules/reagents/Chemistry-Recipes.dm +++ b/code/modules/reagents/Chemistry-Recipes.dm @@ -24,46 +24,15 @@ /datum/chemical_reaction/proc/chemical_mob_spawn(datum/reagents/holder, amount_to_spawn, reaction_name, mob_faction = "chemicalsummon") if(holder && holder.my_atom) - var/list/meancritters = list(/mob/living/simple_animal/hostile/blob/blobspore, // list of possible hostile mobs - /mob/living/simple_animal/hostile/blob/blobbernaut, - /mob/living/simple_animal/hostile/carp/ranged/chaos, - /mob/living/simple_animal/hostile/carp/ranged, - /mob/living/simple_animal/hostile/carp/megacarp, - /mob/living/simple_animal/hostile/carp/eyeball, - /mob/living/simple_animal/hostile/carp, - /mob/living/simple_animal/hostile/alien/drone, - /mob/living/simple_animal/hostile/alien/sentinel, - /mob/living/simple_animal/hostile/alien/queen, - /mob/living/simple_animal/hostile/alien, - /mob/living/simple_animal/hostile/bear/Hudson, - /mob/living/simple_animal/hostile/bear, - /mob/living/simple_animal/hostile/poison/bees, - /mob/living/simple_animal/hostile/poison/giant_spider/nurse, - /mob/living/simple_animal/hostile/poison/giant_spider/hunter, - /mob/living/simple_animal/hostile/poison/giant_spider, - /mob/living/simple_animal/hostile/creature, - /mob/living/simple_animal/hostile/faithless, - /mob/living/simple_animal/hostile/headcrab, - /mob/living/simple_animal/hostile/hivebot/range, - /mob/living/simple_animal/hostile/hivebot/rapid, - /mob/living/simple_animal/hostile/hivebot/strong, - /mob/living/simple_animal/hostile/hivebot, - /mob/living/simple_animal/hostile/killertomato, - /mob/living/simple_animal/hostile/mimic/crate, - /mob/living/simple_animal/hostile/mimic, - /mob/living/simple_animal/hostile/statue, - /mob/living/simple_animal/hostile/viscerator, - /mob/living/simple_animal/hostile/tree/festivus, - /mob/living/simple_animal/hostile/tree) - - var/list/nicecritters = list(/mob/living/simple_animal/crab, - /mob/living/simple_animal/mouse, - /mob/living/simple_animal/lizard, - /mob/living/simple_animal/parrot, - /mob/living/simple_animal/butterfly, - /mob/living/simple_animal/cow, - /mob/living/simple_animal/chicken) // and possible friendly mobs - nicecritters += typesof(/mob/living/simple_animal/pet) - /mob/living/simple_animal/pet + var/list/meancritters = list() // list of possible hostile mobs + var/list/nicecritters = list() // and possible friendly mobs + for(var/T in typesof(/mob/living/simple_animal)) + var/mob/living/simple_animal/M = new T + switch(M.gold_core_spawnable) + if(1) + meancritters += M.type + if(2) + nicecritters += M.type var/atom/A = holder.my_atom var/turf/T = get_turf(A) var/area/my_area = get_area(T) @@ -83,22 +52,17 @@ for(var/mob/living/carbon/C in viewers(get_turf(holder.my_atom), null)) C.flash_eyes() for(var/i = 1, i <= amount_to_spawn, i++) + var/chosen if (reaction_name == "Friendly Gold Slime") - var/chosen = pick(nicecritters) - var/mob/living/simple_animal/C = new chosen - C.faction |= mob_faction - C.loc = get_turf(holder.my_atom) - if(prob(50)) - for(var/j = 1, j <= rand(1, 3), j++) - step(C, pick(NORTH,SOUTH,EAST,WEST)) + chosen = pick(nicecritters) else - var/chosen = pick(meancritters) - var/mob/living/simple_animal/hostile/C = new chosen - C.faction |= mob_faction - C.loc = get_turf(holder.my_atom) - if(prob(50)) - for(var/j = 1, j <= rand(1, 3), j++) - step(C, pick(NORTH,SOUTH,EAST,WEST)) + chosen = pick(meancritters) + var/mob/living/simple_animal/C = new chosen + C.faction |= mob_faction + C.loc = get_turf(holder.my_atom) + if(prob(50)) + for(var/j = 1, j <= rand(1, 3), j++) + step(C, pick(NORTH,SOUTH,EAST,WEST)) /datum/chemical_reaction/proc/goonchem_vortex(turf/simulated/T, setting_type, range) for(var/atom/movable/X in orange(range, T)) From 68a28e5ac2bba141e333f92ea2a1bf9ce7b79458 Mon Sep 17 00:00:00 2001 From: Jordie0608 Date: Sat, 22 Aug 2015 18:58:10 +1000 Subject: [PATCH 100/108] stops mindless revenants from despawning --- .../living/simple_animal/revenant/revenant.dm | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm index 2659dc577ff..22d6da50275 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm @@ -181,21 +181,10 @@ src.mind.objectives += objective2 src << "Objective #2: [objective2.explanation_text]" ticker.mode.traitors |= src.mind //Necessary for announcing - if(!src.giveSpells()) - message_admins("Revenant was created but has no mind. Trying again in ten seconds.") - spawn(100) - if(!src.giveSpells()) - message_admins("Revenant still has no mind. Deleting...") - qdel(src) - -/mob/living/simple_animal/revenant/proc/giveSpells() - if(src.mind) - src.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_transmit - src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_light - src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_defile - src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_malf - return 1 - return 0 + mob_spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_transmit + mob_spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_light + mob_spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_defile + mob_spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_malf /mob/living/simple_animal/revenant/death() ..(1) From 977ecfc5db76dde9ad52aa10df38268a38ffd395 Mon Sep 17 00:00:00 2001 From: Aranclanos Date: Sat, 22 Aug 2015 07:16:28 -0300 Subject: [PATCH 101/108] Fixes transfer_identity() sending the wrong argument for hardset_dna(), causing some errors. --- code/game/dna.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/dna.dm b/code/game/dna.dm index c8c0ceb4cd1..826d8468f9a 100644 --- a/code/game/dna.dm +++ b/code/game/dna.dm @@ -35,7 +35,7 @@ destination.dna.unique_enzymes = unique_enzymes destination.dna.uni_identity = uni_identity destination.dna.blood_type = blood_type - hardset_dna(destination, null, null, null, null, species) + hardset_dna(destination, null, null, null, null, species.type) destination.dna.features = features destination.dna.real_name = real_name destination.dna.mutations = mutations From bf6b830fb0dfa39c54cc94683805f7e07949dea5 Mon Sep 17 00:00:00 2001 From: phil235 Date: Sun, 23 Aug 2015 14:47:44 +0200 Subject: [PATCH 102/108] Fixes action button not updating correctly sometimes (b/c the change from del to qdel means the button wasn't null after Removal which fucks with the action update procs) Fixes infinite loop when deleting a camera mob.(Destroy calls qdel which calls Destroy) --- code/_onclick/hud/action.dm | 1 + code/modules/mob/camera/camera.dm | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/code/_onclick/hud/action.dm b/code/_onclick/hud/action.dm index a017a7a9022..b9c8254054b 100644 --- a/code/_onclick/hud/action.dm +++ b/code/_onclick/hud/action.dm @@ -46,6 +46,7 @@ if(T.client) T.client.screen -= button qdel(button) + button = null T.actions.Remove(src) T.update_action_buttons() owner = null diff --git a/code/modules/mob/camera/camera.dm b/code/modules/mob/camera/camera.dm index 6de267b0aff..eb3f4a6c8d0 100644 --- a/code/modules/mob/camera/camera.dm +++ b/code/modules/mob/camera/camera.dm @@ -14,10 +14,6 @@ /mob/camera/experience_pressure_difference() return -/mob/camera/Destroy() - ..() - qdel(src) - /mob/camera/Login() ..() update_interface() \ No newline at end of file From 7b2262e7299372ef83ef3eac1c01cffee251140e Mon Sep 17 00:00:00 2001 From: phil235 Date: Sun, 23 Aug 2015 18:14:40 +0200 Subject: [PATCH 103/108] Fixes bodybag not visually opening or closing. --- code/game/objects/items/bodybag.dm | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index 866a51ea5f4..af8ffb76809 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -65,9 +65,6 @@ ..() if (tagged) overlays += "bodybag_label" - else - overlays.Cut() - /obj/structure/closet/body_bag/close() if(..()) From 69575145321ee89502f6fecb659985622da038b8 Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Sun, 23 Aug 2015 14:09:35 -0700 Subject: [PATCH 104/108] Fixes a rounding error causing dynamic wait to be sluggish to kick in --- code/controllers/master_controller.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index a4639a42327..31bdbd542a8 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -103,7 +103,7 @@ calculate the longest number of ticks the MC can wait between each cycle without var/oldwait = SS.wait var/GlobalCostDelta = (SSCostPerSecond-(SS.cost/(SS.wait/10)))-1 var/NewWait = MC_AVERAGE(oldwait,(SS.cost-SS.dwait_buffer+GlobalCostDelta)*SS.dwait_delta) - SS.wait = Clamp(round(NewWait,world.tick_lag),SS.dwait_lower,SS.dwait_upper) + SS.wait = Clamp(NewWait,SS.dwait_lower,SS.dwait_upper) if (oldwait != SS.wait) calculateGCD() SS.next_fire += SS.wait @@ -147,4 +147,4 @@ calculate the longest number of ticks the MC can wait between each cycle without msg += "\t [varname] = [varval]\n" world.log << msg - subsystems = master_controller.subsystems \ No newline at end of file + subsystems = master_controller.subsystems From b81ea02552e1d9c123bb632b5964a0db1c8ee2b3 Mon Sep 17 00:00:00 2001 From: Aranclanos Date: Mon, 24 Aug 2015 04:25:47 -0300 Subject: [PATCH 105/108] Hardsuit helmets will now store the suit as a var and they will qdel eachother when deleted. --- code/modules/clothing/spacesuits/hardsuit.dm | 1 + code/modules/clothing/suits/toggles.dm | 14 +++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/code/modules/clothing/spacesuits/hardsuit.dm b/code/modules/clothing/spacesuits/hardsuit.dm index 06bdfc347d6..334c76fca27 100644 --- a/code/modules/clothing/spacesuits/hardsuit.dm +++ b/code/modules/clothing/spacesuits/hardsuit.dm @@ -10,6 +10,7 @@ var/basestate = "hardsuit" var/brightness_on = 4 //luminosity when on var/on = 0 + var/obj/item/clothing/suit/space/hardsuit/suit item_color = "engineering" //Determines used sprites: hardsuit[on]-[color] and hardsuit[on]-[color]2 (lying down sprite) action_button_name = "Toggle Helmet Light" flags = BLOCKHAIR | STOPSPRESSUREDMAGE | THICKMATERIAL | NODROP diff --git a/code/modules/clothing/suits/toggles.dm b/code/modules/clothing/suits/toggles.dm index d8d1f409691..9a3efc5d2ad 100644 --- a/code/modules/clothing/suits/toggles.dm +++ b/code/modules/clothing/suits/toggles.dm @@ -90,7 +90,6 @@ user << "Alt-click on [src] to toggle the [togglename]." //Hardsuit toggle code - /obj/item/clothing/suit/space/hardsuit/New() MakeHelmet() if(!jetpack) @@ -98,15 +97,24 @@ verbs -= /obj/item/clothing/suit/space/hardsuit/verb/Jetpack_Rockets ..() /obj/item/clothing/suit/space/hardsuit/Destroy() - qdel(helmet) + if(helmet) + helmet.suit = null + qdel(helmet) qdel(jetpack) ..() +/obj/item/clothing/head/helmet/space/hardsuit/Destroy() + if(suit) + suit.helmet = null + qdel(suit) + ..() + /obj/item/clothing/suit/space/hardsuit/proc/MakeHelmet() if(!helmettype) return if(!helmet) var/obj/item/clothing/head/helmet/space/hardsuit/W = new helmettype(src) + W.suit = src helmet = W /obj/item/clothing/suit/space/hardsuit/ui_action_click() @@ -121,7 +129,7 @@ ..() /obj/item/clothing/suit/space/hardsuit/proc/RemoveHelmet() - if(!helmettype) + if(!helmet) return suittoggled = 0 if(ishuman(helmet.loc)) From a9b555d57e0348cc680487d0dbeba9df4b60ed57 Mon Sep 17 00:00:00 2001 From: Aranclanos Date: Mon, 24 Aug 2015 05:11:36 -0300 Subject: [PATCH 106/108] Fixes a runtime where the xeno hallucination fails to find a vent to spawn the alien. --- code/modules/flufftext/Hallucination.dm | 27 +++++++++++++------------ 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/code/modules/flufftext/Hallucination.dm b/code/modules/flufftext/Hallucination.dm index 98a01e01182..64a7e9fc72f 100644 --- a/code/modules/flufftext/Hallucination.dm +++ b/code/modules/flufftext/Hallucination.dm @@ -188,19 +188,20 @@ Gunshots/explosions/opening doors/less rare audio (done) if(!U.welded) pump = U break - xeno = new(pump.loc,target) - sleep(10) - xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32) - xeno.throw_at(target,7,1, spin = 0, diagonals_first = 1) - sleep(10) - xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32) - xeno.throw_at(pump,7,1, spin = 0, diagonals_first = 1) - sleep(10) - var/xeno_name = xeno.name - target << "[xeno_name] begins climbing into the ventilation system..." - sleep(10) - qdel(xeno) - target << "[xeno_name] scrambles into the ventilation ducts!" + if(pump) + xeno = new(pump.loc,target) + sleep(10) + xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32) + xeno.throw_at(target,7,1, spin = 0, diagonals_first = 1) + sleep(10) + xeno.update_icon("alienh_leap",'icons/mob/alienleap.dmi',-32,-32) + xeno.throw_at(pump,7,1, spin = 0, diagonals_first = 1) + sleep(10) + var/xeno_name = xeno.name + target << "[xeno_name] begins climbing into the ventilation system..." + sleep(10) + qdel(xeno) + target << "[xeno_name] scrambles into the ventilation ducts!" qdel(src) /obj/effect/hallucination/singularity_scare From 909658f240bf38255643174317f17de3019c22d5 Mon Sep 17 00:00:00 2001 From: Supermichael777 Date: Mon, 24 Aug 2015 14:20:31 -0400 Subject: [PATCH 107/108] Update buckling.dm --- code/game/objects/buckling.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/buckling.dm b/code/game/objects/buckling.dm index 0c781f27f9b..88a0b285c62 100644 --- a/code/game/objects/buckling.dm +++ b/code/game/objects/buckling.dm @@ -88,7 +88,7 @@ M.visible_message(\ "[M.name] is buckled to [src] by [user.name]!",\ "You are buckled to [src] by [user.name]!",\ - "You heat metal clanking.") + "You hear metal clanking.") /obj/proc/user_unbuckle_mob(mob/user) var/mob/living/M = unbuckle_mob() From 908da0a29a1cd5281b347066ce5a07a10ca87b1c Mon Sep 17 00:00:00 2001 From: Kyle Spier-Swenson Date: Tue, 25 Aug 2015 10:07:51 -0700 Subject: [PATCH 108/108] Update subsystems.dm --- code/controllers/subsystems.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/controllers/subsystems.dm b/code/controllers/subsystems.dm index 88e3451a4d2..5c3c9a50f72 100644 --- a/code/controllers/subsystems.dm +++ b/code/controllers/subsystems.dm @@ -47,7 +47,7 @@ /datum/subsystem/proc/stat_entry(msg) var/dwait = "" if (dynamic_wait) - dwait = "DWait:[wait]ds " + dwait = "DWait:[round(wait,0.1)]ds " stat(name, "[round(cost,0.001)]ds\t[dwait][msg]") @@ -59,4 +59,4 @@ //usually called via datum/subsystem/New() when replacing a subsystem (i.e. due to a recurring crash) //should attempt to salvage what it can from the old instance of subsystem -/datum/subsystem/proc/Recover() \ No newline at end of file +/datum/subsystem/proc/Recover()