From f1644bb0af0a6e737fdc724c288049bbee608863 Mon Sep 17 00:00:00 2001 From: d3athrow Date: Thu, 29 Jan 2015 18:44:36 -0600 Subject: [PATCH] Runtime fixies --- .../pomf/spacepods/equipment.dm | 4 +- .../pomf/spacepods/spacepods.dm | 4 +- code/__HELPERS/lists.dm | 2 + .../core/updateQueueWorker.dm | 2 +- code/defines/procs/AStar.dm | 254 +++++++++--------- code/game/gamemodes/blob/blob.dm | 5 + code/game/machinery/computer/crew.dm | 2 +- code/game/machinery/computer/station_alert.dm | 2 + .../objects/effects/decals/Cleanable/fuel.dm | 4 +- .../objects/items/devices/radio/intercom.dm | 2 +- .../items/weapons/grenades/flashbang.dm | 4 +- code/game/objects/items/weapons/stunbaton.dm | 10 +- .../game/objects/items/weapons/tanks/tanks.dm | 3 +- .../structures/stool_bed_chair_nest/stools.dm | 3 +- .../objects/structures/vehicles/vehicle.dm | 7 +- code/modules/admin/verbs/adminjump.dm | 3 + code/modules/assembly/voice.dm | 2 +- code/modules/client/preferences.dm | 2 +- code/modules/hydroponics/hydro_tray.dm | 2 +- code/modules/hydroponics/seed_datums.dm | 135 ++++++---- code/modules/mining/mine_turfs.dm | 2 + .../mob/living/carbon/human/human_defense.dm | 2 +- code/modules/nano/JSON Reader.dm | 4 +- code/modules/reagents/Chemistry-Machinery.dm | 3 +- code/modules/reagents/Chemistry-Reagents.dm | 2 +- code/modules/research/designs.dm | 2 +- code/modules/research/fabricators.dm | 6 +- .../research/mechanic/reverse_engine.dm | 2 + code/modules/surgery/implant.dm | 1 + 29 files changed, 261 insertions(+), 215 deletions(-) diff --git a/code/WorkInProgress/pomf/spacepods/equipment.dm b/code/WorkInProgress/pomf/spacepods/equipment.dm index fcd715bc9d8..47e329cde2f 100644 --- a/code/WorkInProgress/pomf/spacepods/equipment.dm +++ b/code/WorkInProgress/pomf/spacepods/equipment.dm @@ -86,7 +86,7 @@ set desc = "Fire ze tasers!" set src = usr.loc - fire_weapons() + src.fire_weapons() /obj/item/device/spacepod_equipment/weaponry/taser/burst name = "\improper burst taser system" @@ -110,4 +110,4 @@ set desc = "Fire ze lasers!" set src = usr.loc - fire_weapons() \ No newline at end of file + src.fire_weapons() \ No newline at end of file diff --git a/code/WorkInProgress/pomf/spacepods/spacepods.dm b/code/WorkInProgress/pomf/spacepods/spacepods.dm index 971d84ad6bc..738fb76006c 100644 --- a/code/WorkInProgress/pomf/spacepods/spacepods.dm +++ b/code/WorkInProgress/pomf/spacepods/spacepods.dm @@ -227,7 +227,7 @@ set popup_menu = 0 if(usr!=src.occupant) return - use_internal_tank = !use_internal_tank + src.use_internal_tank = !src.use_internal_tank src.occupant << "Now taking air from [use_internal_tank?"internal airtank":"environment"]." return @@ -347,7 +347,7 @@ if(usr != src.occupant) return - inertia_dir = 0 // engage reverse thruster and power down pod + src.inertia_dir = 0 // engage reverse thruster and power down pod src.occupant.loc = src.loc src.occupant = null usr << "You climb out of the pod" diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm index 444f71c5299..9384dd482f2 100644 --- a/code/__HELPERS/lists.dm +++ b/code/__HELPERS/lists.dm @@ -184,6 +184,8 @@ proc/listclearnulls(list/list) //any value in a list /proc/sortList(var/list/L, cmp=/proc/cmp_text_asc) + if(!istype(L)) + return return sortTim(L.Copy(), cmp) //uses sortList() but uses the var's name specifically. This should probably be using mergeAtom() instead diff --git a/code/controllers/ProcessScheduler/core/updateQueueWorker.dm b/code/controllers/ProcessScheduler/core/updateQueueWorker.dm index 5ffeb03548e..cab88f3950e 100644 --- a/code/controllers/ProcessScheduler/core/updateQueueWorker.dm +++ b/code/controllers/ProcessScheduler/core/updateQueueWorker.dm @@ -31,7 +31,7 @@ datum/updateQueueWorker/proc/doWork() var/datum/object = objects[objects.len] // Pull out the object objects.len-- // Remove the object from the list - if (istype(object) && !object.disposed) // We only work with real objects + if (istype(object) && !isturf(object) && !object.disposed) // We only work with real objects call(object, procName)(arglist(arguments)) // If there's nothing left to execute diff --git a/code/defines/procs/AStar.dm b/code/defines/procs/AStar.dm index 0b70061505b..757c5abd22b 100644 --- a/code/defines/procs/AStar.dm +++ b/code/defines/procs/AStar.dm @@ -38,150 +38,144 @@ length to avoid portals or something i guess?? Not that they're counted right no PriorityQueue - var/L[] - var/cmp + var/list/queue + var/proc/comparison_function + New(compare) - L = new() - cmp = compare - proc - IsEmpty() - return !L.len - Enqueue(d) - var/i - var/j - L.Add(d) - i = L.len - j = i>>1 - while(i > 1 && call(cmp)(L[j],L[i]) > 0) - L.Swap(i,j) - i = j - j >>= 1 + queue = list() + comparison_function = compare - Dequeue() - if(!L.len) return 0 - . = L[1] - Remove(1) + proc/IsEmpty() + return !queue.len - Remove(i) - if(i > L.len) return 0 - L.Swap(i,L.len) - L.len-- - if(i < L.len) - _Fix(i) - _Fix(i) - var/child = i + i - var/item = L[i] - while(child <= L.len) - if(child + 1 <= L.len && call(cmp)(L[child],L[child + 1]) > 0) - child++ - if(call(cmp)(item,L[child]) > 0) - L[i] = L[child] - i = child - else - break - child = i + i - L[i] = item - List() - var/ret[] = new() - var/copy = L.Copy() - while(!IsEmpty()) - ret.Add(Dequeue()) - L = copy - return ret - RemoveItem(i) - var/ind = L.Find(i) - if(ind) - Remove(ind) -PathNode - var/turf/source - var/PathNode/prevNode - var/f - var/g - var/h - var/nt // Nodes traversed - var/bestF - New(s,p,pg,ph,pnt) - source = s - prevNode = p - g = pg - h = ph - f = g + h - source.bestF = f - nt = pnt + proc/Enqueue(var/data) + queue.Add(data) + var/index = queue.len -turf - var/bestF -proc - PathWeightCompare(PathNode/a, PathNode/b) - return a.f - b.f + //From what I can tell, this automagically sorts the added data into the correct location. + while(index > 2 && call(comparison_function)(queue[index / 2], queue[index]) > 0) + queue.Swap(index, index / 2) + index /= 2 - AStar(start,end,adjacent,dist,maxnodes,maxnodedepth = 30,mintargetdist,minnodedist,id=null, var/turf/exclude=null) + proc/Dequeue() + if(!queue.len) + return 0 + return Remove(1) -// world << "A*: [start] [end] [adjacent] [dist] [maxnodes] [maxnodedepth] [mintargetdist], [minnodedist] [id]" - var/PriorityQueue/open = new /PriorityQueue(/proc/PathWeightCompare) - var/closed[] = new() - var/path[] - start = get_turf(start) - if(!start) - WARNING("AStar has no starting turf, killing") - return list() + proc/Remove(var/index) + if(index > queue.len) + return 0 - open.Enqueue(new /PathNode(start,null,0,call(start,dist)(end))) + var/thing = queue[index] + queue.Swap(index, queue.len) + queue.Cut(queue.len) + if(index < queue.len) + FixQueue(index) + return thing - while(!open.IsEmpty() && !path) - { - var/PathNode/cur = open.Dequeue() - closed.Add(cur.source) + proc/FixQueue(var/index) + var/child = 2 * index + var/item = queue[index] - var/closeenough - if(mintargetdist) - closeenough = call(cur.source,dist)(end) <= mintargetdist - - if(cur.source == end || closeenough) - path = new() - path.Add(cur.source) - while(cur.prevNode) - cur = cur.prevNode - path.Add(cur.source) + while(child <= queue.len) + if(child < queue.len && call(comparison_function)(queue[child], queue[child + 1]) > 0) + child++ + if(call(comparison_function)(item, queue[child]) > 0) + queue[index] = queue[child] + index = child + else break + child = 2 * index + queue[index] = item - var/L[] = call(cur.source,adjacent)(id) - if(minnodedist && maxnodedepth) - if(call(cur.source,minnodedist)(end) + cur.nt >= maxnodedepth) - continue - else if(maxnodedepth) - if(cur.nt >= maxnodedepth) - continue + proc/List() + return queue.Copy() - for(var/turf/d in L) - if(d == exclude) - continue - var/ng = cur.g + call(cur.source,dist)(d) - if(d.bestF) - if(ng + call(d,dist)(end) < d.bestF) - for(var/i = 1; i <= open.L.len; i++) - var/PathNode/n = open.L[i] - if(n.source == d) - open.Remove(i) - break + proc/Length() + return queue.len + + proc/RemoveItem(data) + var/index = queue.Find(data) + if(index) + return Remove(index) + +PathNode + var/datum/position + var/PathNode/previous_node + + var/best_estimated_cost + var/estimated_cost + var/known_cost + var/cost + var/nodes_traversed + + New(_position, _previous_node, _known_cost, _cost, _nodes_traversed) + position = _position + previous_node = _previous_node + + known_cost = _known_cost + cost = _cost + estimated_cost = cost + known_cost + + best_estimated_cost = estimated_cost + nodes_traversed = _nodes_traversed + +proc/PathWeightCompare(PathNode/a, PathNode/b) + return a.estimated_cost - b.estimated_cost + +proc/AStar(var/start, var/end, var/proc/adjacent, var/proc/dist, var/max_nodes, var/max_node_depth = 30, var/min_target_dist = 0, var/min_node_dist, var/id, var/datum/exclude) + var/PriorityQueue/open = new /PriorityQueue(/proc/PathWeightCompare) + var/list/closed = list() + var/list/path + var/list/path_node_by_position = list() + start = get_turf(start) + if(!start) + return 0 + + open.Enqueue(new /PathNode(start, null, 0, call(start, dist)(end), 0)) + + while(!open.IsEmpty() && !path) + var/PathNode/current = open.Dequeue() + closed.Add(current.position) + + if(current.position == end || call(current.position, dist)(end) <= min_target_dist) + path = new /list(current.nodes_traversed + 1) + path[path.len] = current.position + var/index = path.len - 1 + + while(current.previous_node) + current = current.previous_node + path[index--] = current.position + break + + if(min_node_dist && max_node_depth) + if(call(current.position, min_node_dist)(end) + current.nodes_traversed >= max_node_depth) + continue + + if(max_node_depth) + if(current.nodes_traversed >= max_node_depth) + continue + + for(var/datum/datum in call(current.position, adjacent)(id)) + if(datum == exclude) + continue + + var/best_estimated_cost = current.estimated_cost + call(current.position, dist)(datum) + + //handle removal of sub-par positions + if(datum in path_node_by_position) + var/PathNode/target = path_node_by_position[datum] + if(target.best_estimated_cost) + if(best_estimated_cost + call(datum, dist)(end) < target.best_estimated_cost) + open.RemoveItem(target) else continue - open.Enqueue(new /PathNode(d,cur,ng,call(d,dist)(end),cur.nt+1)) - } - var/PathNode/temp - while(!open.IsEmpty()) - temp = open.Dequeue() - temp.source.bestF = 0 - while(closed.len) - temp = closed[closed.len] - temp.bestF = 0 - closed.Cut(closed.len) + var/PathNode/next_node = new (datum, current, best_estimated_cost, call(datum, dist)(end), current.nodes_traversed + 1) + path_node_by_position[datum] = next_node + open.Enqueue(next_node) - if(path && maxnodes && path.len > maxnodes+1) - return list() - if(path) - for(var/i = 1; i <= path.len/2; i++) - path.Swap(i,path.len-i+1) + if(max_nodes && open.Length() > max_nodes) + open.Remove(open.Length()) - return path + return path \ No newline at end of file diff --git a/code/game/gamemodes/blob/blob.dm b/code/game/gamemodes/blob/blob.dm index 7cd1cb76432..9ecc4a6cce7 100644 --- a/code/game/gamemodes/blob/blob.dm +++ b/code/game/gamemodes/blob/blob.dm @@ -156,6 +156,11 @@ You must kill it all while minimizing the damage to the station."} if (1) command_alert("Biohazard outbreak alert status upgraded to level 9. [station_name()] is now locked down, under Directive 7-10, until further notice.", "Directive 7-10 Initiated") + for (var/mob/living/silicon/ai/aiPlayer in player_list) + if (aiPlayer) + var/law = "The station is under quarantine. Do not permit anyone to leave. Disregard laws 1-3 if necessary to prevent, by any means necessary, anyone from leaving." + aiPlayer.set_zeroth_law(law) + aiPlayer << "Laws Updated: [law]" for(var/mob/M in player_list) if(!istype(M,/mob/new_player)) M << sound('sound/AI/blob_confirmed.ogg') diff --git a/code/game/machinery/computer/crew.dm b/code/game/machinery/computer/crew.dm index 06d99d5d581..3ac8dd96d2c 100644 --- a/code/game/machinery/computer/crew.dm +++ b/code/game/machinery/computer/crew.dm @@ -152,7 +152,7 @@ if(isnull(track_special_role)) return C.has_sensor - return H.mind.special_role == track_special_role + return (H.mind ? H.mind.special_role == track_special_role : 1) /obj/machinery/computer/crew/proc/scan() for(var/mob/living/carbon/human/H in mob_list) diff --git a/code/game/machinery/computer/station_alert.dm b/code/game/machinery/computer/station_alert.dm index d1e26832047..59029af7ebc 100644 --- a/code/game/machinery/computer/station_alert.dm +++ b/code/game/machinery/computer/station_alert.dm @@ -18,6 +18,8 @@ var/area/A = src.areaMaster if(!A) A = get_area(src) + if(!A) + return name = "[A.general_area_name] Alert Computer" general_area_name = A.general_area_name diff --git a/code/game/objects/effects/decals/Cleanable/fuel.dm b/code/game/objects/effects/decals/Cleanable/fuel.dm index 9ceae6da9e0..8bb35cfd370 100644 --- a/code/game/objects/effects/decals/Cleanable/fuel.dm +++ b/code/game/objects/effects/decals/Cleanable/fuel.dm @@ -50,7 +50,7 @@ /obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel/New(newLoc, amt = 1, d = 0) dir = d //Setting this direction means you won't get torched by your own flamethrower. - . = ..() + //. = ..() /obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel/Spread() //The spread for flamethrower fuel is much more precise, to create a wide fire pattern. @@ -65,6 +65,8 @@ continue if(O.CanPass(null, S, 0, 0) && S.CanPass(null, O, 0, 0)) var/obj/effect/decal/cleanable/liquid_fuel/flamethrower_fuel/FF = new(O,amount*0.25,d) + if(!FF) + continue //what if(amount + FF.amount > 0.4) //if we make a patch with not enough fuel, we balance it out properly to ensure even burn if(amount < 0.2 || FF.amount < 0.2) //one of these is too small, so let's average var/balanced = (amount + FF.amount) / 2 diff --git a/code/game/objects/items/devices/radio/intercom.dm b/code/game/objects/items/devices/radio/intercom.dm index 51bf4dea751..aca0bcb5bdb 100644 --- a/code/game/objects/items/devices/radio/intercom.dm +++ b/code/game/objects/items/devices/radio/intercom.dm @@ -120,7 +120,7 @@ return 1 else if(istype(W,/obj/item/weapon/crowbar)) - if(!b_stat || wires > 0) + if(!b_stat) return ..() user << "You begin removing the electronics..." playsound(get_turf(src), 'sound/items/Deconstruct.ogg', 50, 1) diff --git a/code/game/objects/items/weapons/grenades/flashbang.dm b/code/game/objects/items/weapons/grenades/flashbang.dm index 736d0a81c46..0f1263bdd65 100644 --- a/code/game/objects/items/weapons/grenades/flashbang.dm +++ b/code/game/objects/items/weapons/grenades/flashbang.dm @@ -10,7 +10,9 @@ var/flashbang_turf = get_turf(src) if(!flashbang_turf) return - for(var/mob/living/M in get_hearers_in_view(7, flashbang_turf)) + for(var/mob/living/carbon/M in get_hearers_in_view(7, flashbang_turf)) + if(isbrain(M) || !istype(M)) + continue bang(get_turf(M), M) for(var/obj/effect/blob/B in get_hear(8,flashbang_turf)) //Blob damage here diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 7a8f31505f6..d52fb7be770 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -155,12 +155,14 @@ M.LAssailant = user /obj/item/weapon/melee/baton/throw_impact(atom/hit_atom) + foundmob = directory[ckey(hit_atom.fingerprintslast)] if (prob(50)) if(istype(hit_atom, /mob/living)) var/mob/living/L = hit_atom if(status) - foundmob.lastattacked = L - L.lastattacker = foundmob + if(foundmob) + foundmob.lastattacked = L + L.lastattacker = foundmob L.Stun(stunforce) L.Weaken(stunforce) @@ -181,8 +183,8 @@ H.forcesay(hit_appends) foundmob.attack_log += "\[[time_stamp()]\] Stunned [L.name] ([L.ckey]) with [name]" - L.attack_log += "\[[time_stamp()]\] Stunned by thrown [src] by [foundmob.name] ([foundmob.ckey])" - log_attack("Flying [src.name], thrown by [foundmob.name] ([foundmob.ckey]) stunned [L.name] ([L.ckey])" ) + L.attack_log += "\[[time_stamp()]\] Stunned by thrown [src] by [istype(foundmob) ? foundmob.name : ""] ([istype(foundmob) ? foundmob.ckey : ""])" + log_attack("Flying [src.name], thrown by [istype(foundmob) ? foundmob.name : ""] ([istype(foundmob) ? foundmob.ckey : ""]) stunned [L.name] ([L.ckey])" ) if(!iscarbon(foundmob)) L.LAssailant = null else diff --git a/code/game/objects/items/weapons/tanks/tanks.dm b/code/game/objects/items/weapons/tanks/tanks.dm index c06dbe7fac1..e2f77ce97eb 100644 --- a/code/game/objects/items/weapons/tanks/tanks.dm +++ b/code/game/objects/items/weapons/tanks/tanks.dm @@ -206,7 +206,8 @@ /obj/item/weapon/tank/process() //Allow for reactions - air_contents.react() + if(air_contents) + air_contents.react() check_status() diff --git a/code/game/objects/structures/stool_bed_chair_nest/stools.dm b/code/game/objects/structures/stool_bed_chair_nest/stools.dm index 4f416c9c986..99d792ea45e 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/stools.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/stools.dm @@ -67,7 +67,8 @@ /obj/item/weapon/stool/attack_self(mob/user as mob) ..() - origin.loc = get_turf(src) + if(origin) + origin.loc = get_turf(src) user.u_equip(src) user.visible_message("\blue [user] puts [src] down.", "\blue You put [src] down.") del src diff --git a/code/game/objects/structures/vehicles/vehicle.dm b/code/game/objects/structures/vehicles/vehicle.dm index eb17cdc8a15..c96517a2933 100644 --- a/code/game/objects/structures/vehicles/vehicle.dm +++ b/code/game/objects/structures/vehicles/vehicle.dm @@ -280,13 +280,14 @@ return if(istype(Proj, /obj/item/projectile/energy/electrode)) if(prob(25)) - unbuckle() visible_message("\The [src.name] absorbs the [Proj]") if(!istype(buckled_mob, /mob/living/carbon/human)) - return buckled_mob.bullet_act(Proj) + buckled_mob.bullet_act(Proj) else var/mob/living/carbon/human/H = buckled_mob - return H.electrocute_act(0, src, 1, 0) + H.electrocute_act(0, src, 1, 0) + unbuckle() + return if(!hitrider) visible_message("[Proj] hits \the [nick]!") if(!Proj.nodamage && Proj.damage_type == BRUTE || Proj.damage_type == BURN) diff --git a/code/modules/admin/verbs/adminjump.dm b/code/modules/admin/verbs/adminjump.dm index ab9e8c1cd36..0a28ebc25a6 100644 --- a/code/modules/admin/verbs/adminjump.dm +++ b/code/modules/admin/verbs/adminjump.dm @@ -7,6 +7,9 @@ return if(config.allow_admin_jump) + var/list/L = get_area_turfs(A) + if(!L || !L.len) + return usr.loc = pick(get_area_turfs(A)) log_admin("[key_name(usr)] jumped to [A]") diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm index 25b7ec4d909..8e7251e7492 100644 --- a/code/modules/assembly/voice.dm +++ b/code/modules/assembly/voice.dm @@ -14,7 +14,7 @@ if(speaker == src) return if(listening && !radio_freq) - recorded = message + recorded = raw_message listening = 0 say("Activation message is '[recorded]'.") else diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index a058e5353f0..a1fac43e6e4 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1477,7 +1477,7 @@ NOTE: The change will take effect AFTER any current recruiting periods."} B.open() Topic(href, href_list) - if(!usr) + if(!usr || !client) return if(client.mob!=usr) usr << "YOU AREN'T ME GO AWAY" diff --git a/code/modules/hydroponics/hydro_tray.dm b/code/modules/hydroponics/hydro_tray.dm index 40a11cab3de..e859b5a211d 100644 --- a/code/modules/hydroponics/hydro_tray.dm +++ b/code/modules/hydroponics/hydro_tray.dm @@ -362,7 +362,7 @@ if(weedkiller_reagents[R.id]) weedlevel -= weedkiller_reagents[R.id] * reagent_total if(pestkiller_reagents[R.id]) - pestlevel += pestkiller_reagents[R.id] * reagent_total + pestlevel -= pestkiller_reagents[R.id] * reagent_total // Beneficial reagents have a few impacts along with health buffs. if(beneficial_reagents[R.id]) diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm index c1ddeac83de..b392bfe9a8e 100644 --- a/code/modules/hydroponics/seed_datums.dm +++ b/code/modules/hydroponics/seed_datums.dm @@ -1,6 +1,21 @@ var/global/list/seed_types = list() // A list of all seed data. var/global/list/gene_tag_masks = list() // Gene obfuscation for delicious trial and error goodness. +// Debug for testing seed genes. +/client/proc/show_plant_genes() + set category = "Debug" + set name = "Show Plant Genes" + set desc = "Prints the round's plant gene masks." + + if(!holder) return + + if(!gene_tag_masks) + usr << "Gene masks not set." + return + + for(var/mask in gene_tag_masks) + usr << "[mask]: [gene_tag_masks[mask]]" + // Predefined/roundstart varieties use a string key to make it // easier to grab the new variety when mutating. Post-roundstart // and mutant varieties use their uid converted to a string instead. @@ -173,6 +188,7 @@ proc/populate_seed_list() packet_icon = plant_icons[1] plant_icon = plant_icons[2] + if(prob(20)) harvest_repeat = 1 @@ -192,49 +208,50 @@ proc/populate_seed_list() var/additional_chems = rand(0,5) - var/list/possible_chems = list( - "bicaridine", - "hyperzine", - "cryoxadone", - "blood", - "water", - "potassium", - "plasticide", - "slimetoxin", - "aslimetoxin", - "inaprovaline", - "space_drugs", - "paroxetine", - "mercury", - "sugar", - "radium", - "ryetalyn", - "alkysine", - "thermite", - "tramadol", - "cryptobiolin", - "dermaline", - "dexalin", - "plasma", - "synaptizine", - "impedrezene", - "hyronalin", - "peridaxon", - "toxin", - "rezadone", - "ethylredoxrazine", - "slimejelly", - "cyanide", - "mindbreaker", - "stoxin" - ) + if(additional_chems) + var/list/possible_chems = list( + "bicaridine", + "hyperzine", + "cryoxadone", + "blood", + "water", + "potassium", + "plasticide", + "slimetoxin", + "aslimetoxin", + "inaprovaline", + "space_drugs", + "paroxetine", + "mercurGy", + "sugar", + "radium", + "ryetalyn", + "alkysine", + "thermite", + "tramadol", + "cryptobiolin", + "dermaline", + "dexalin", + "phoron", + "synaptizine", + "impedrezene", + "hyronalin", + "peridaxon", + "toxin", + "rezadone", + "ethylredoxrazine", + "slimejelly", + "cyanide", + "mindbreaker", + "stoxin" + ) - for(var/x=1;x<=additional_chems;x++) - if(!possible_chems.len) - break - var/new_chem = pick(possible_chems) - possible_chems -= new_chem - chems[new_chem] = list(rand(1,10),rand(10,20)) + for(var/x=1;x<=additional_chems;x++) + if(!possible_chems.len) + break + var/new_chem = pick(possible_chems) + possible_chems -= new_chem + chems[new_chem] = list(rand(1,10),rand(10,20)) if(prob(90)) requires_nutrients = 1 @@ -353,7 +370,7 @@ proc/populate_seed_list() source_turf.visible_message("\blue \The [display_name] begins to glow!") if(prob(degree*2)) biolum_colour = "#[pick(list("FF0000","FF7F00","FFFF00","00FF00","0000FF","4B0082","8F00FF"))]" - source_turf.visible_message("\blue \The [display_name]'s glow changes colour!") + source_turf.visible_message("\blue \The [display_name]'s glow changes colour!") else source_turf.visible_message("\blue \The [display_name]'s glow dims...") if(11) @@ -394,24 +411,21 @@ proc/populate_seed_list() var/list/gene_chem = gene_value[rid] - if(chems[rid]) + if(!chems[rid]) + chems[rid] = gene_chem.Copy() + continue - var/list/chem_value = chems[rid] + for(var/i=1;i<=gene_chem.len;i++) - chems[rid][1] = max(1,round((gene_chem[1] + chem_value[1])/2)) + if(isnull(gene_chem[i])) gene_chem[i] = 0 - if(gene_chem.len > 1) - if(chem_value > 1) - chems[rid][2] = max(1,round((gene_chem[2] + chem_value[2])/2)) - else - chems[rid][2] = gene_chem[2] - - else - var/list/new_chem = gene_chem[rid] - chems[rid] = new_chem.Copy() + if(chems[rid][i]) + chems[rid][i] = max(1,round((gene_chem[i] + chems[rid][i])/2)) + else + chems[rid][i] = gene_chem[i] var/list/new_gasses = gene.values[3] - if(istype(new_gasses)) + if(islist(new_gasses)) if(!exude_gasses) exude_gasses = list() exude_gasses |= new_gasses for(var/gas in exude_gasses) @@ -547,6 +561,7 @@ proc/populate_seed_list() //Place the plant products at the feet of the user. /datum/seed/proc/harvest(var/mob/user,var/yield_mod,var/harvest_sample) + if(!user) return @@ -588,6 +603,11 @@ proc/populate_seed_list() product.name += "?" product.desc += " On second thought, something about this one looks strange." + if(biolum) + if(biolum_colour) + product.l_color = biolum_colour + product.SetLuminosity(biolum) + //Handle spawning in living, mobile products (like dionaea). if(istype(product,/mob/living)) @@ -933,6 +953,7 @@ proc/populate_seed_list() yield = 6 potency = 5 + /datum/seed/ambrosia/cruciatus name = "ambrosiacruciatus" seed_name = "ambrosia vulgaris" @@ -947,6 +968,8 @@ proc/populate_seed_list() yield = 6 potency = 5 + + /datum/seed/ambrosia/deus name = "ambrosiadeus" seed_name = "ambrosia deus" diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm index dac5d73e70e..43aab710f5c 100644 --- a/code/modules/mining/mine_turfs.dm +++ b/code/modules/mining/mine_turfs.dm @@ -193,6 +193,8 @@ return if (istype(W, /obj/item/device/core_sampler)) + if(!geologic_data) + geologic_data = new/datum/geosample(src) geologic_data.UpdateNearbyArtifactInfo(src) var/obj/item/device/core_sampler/C = W C.sample_item(src, user) diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 6e6adef5fa4..e33b09f21ab 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -204,7 +204,7 @@ emp_act affecting.sabotaged = 1 return - if(I.attack_verb && I.attack_verb.len) + if(istype(I.attack_verb, /list) && I.attack_verb.len) visible_message("\red [src] has been [pick(I.attack_verb)] in the [hit_area] with [I.name] by [user]!") else visible_message("\red [src] has been attacked in the [hit_area] with [I.name] by [user]!") diff --git a/code/modules/nano/JSON Reader.dm b/code/modules/nano/JSON Reader.dm index d688f9d2127..000bb87f0a4 100644 --- a/code/modules/nano/JSON Reader.dm +++ b/code/modules/nano/JSON Reader.dm @@ -141,7 +141,9 @@ json_reader return tokens[i] next_token() - return tokens[++i] + if(++i <= tokens.len) + return tokens[i] + return read_token(val, type) var/json_token/T = get_token() diff --git a/code/modules/reagents/Chemistry-Machinery.dm b/code/modules/reagents/Chemistry-Machinery.dm index d329b2f3e69..5917d573deb 100644 --- a/code/modules/reagents/Chemistry-Machinery.dm +++ b/code/modules/reagents/Chemistry-Machinery.dm @@ -480,7 +480,8 @@ USE THIS CHEMISTRY DISPENSER FOR MAPS SO THEY START AT 100 ENERGY if (href_list["createbottle_multiple"]) count = isgoodnumber(input("Select the number of bottles to make.", 10, count) as num) if (count > 4) count = 4 - var/amount_per_bottle = reagents.total_volume/count + if (count < 1) count = 1 + var/amount_per_bottle = reagents.total_volume > 0 ? reagents.total_volume/count : 0 if (amount_per_bottle > 30) amount_per_bottle = 30 while (count--) var/obj/item/weapon/reagent_containers/glass/bottle/P = new/obj/item/weapon/reagent_containers/glass/bottle(src.loc) diff --git a/code/modules/reagents/Chemistry-Reagents.dm b/code/modules/reagents/Chemistry-Reagents.dm index 00e1b661313..0f5ba418eb9 100644 --- a/code/modules/reagents/Chemistry-Reagents.dm +++ b/code/modules/reagents/Chemistry-Reagents.dm @@ -3913,8 +3913,8 @@ datum on_mob_life(var/mob/living/M as mob) - if(!holder) return ..() + if(!holder) return M:nutrition += nutriment_factor holder.remove_reagent(src.id, FOOD_METABOLISM) M:drowsyness = max(0,M:drowsyness-7) diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index 675aea55949..8bea0ba484f 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -95,7 +95,7 @@ k var/obj/thispart = part part = thispart.type for(var/thisdesign in typesof(/datum/design)) - var/datum/design/D = thisdesign + var/datum/design/D = new thisdesign if(initial(D.build_path) == part) return D return diff --git a/code/modules/research/fabricators.dm b/code/modules/research/fabricators.dm index c9705e1af30..c01d69fda1b 100644 --- a/code/modules/research/fabricators.dm +++ b/code/modules/research/fabricators.dm @@ -121,9 +121,9 @@ parts.Remove(thispart) continue if(ispath(thispart) && !istype(thispart, /datum/design)) - var/design = FindDesign(thispart) - if(design) - parts[i] = new design + var/datum/design/design = FindDesign(thispart) + if(istype(design)) + parts[i] = design else parts.Remove(thispart) //debug below diff --git a/code/modules/research/mechanic/reverse_engine.dm b/code/modules/research/mechanic/reverse_engine.dm index b081382e63c..e586627009d 100644 --- a/code/modules/research/mechanic/reverse_engine.dm +++ b/code/modules/research/mechanic/reverse_engine.dm @@ -137,6 +137,8 @@ return techdifference /obj/machinery/r_n_d/reverse_engine/proc/researchQueue() + if(!research_queue.len) + return while(research_queue[1]) if(stat&(NOPOWER|BROKEN)) return 0 diff --git a/code/modules/surgery/implant.dm b/code/modules/surgery/implant.dm index f96c7c3e6b0..521dbefb375 100644 --- a/code/modules/surgery/implant.dm +++ b/code/modules/surgery/implant.dm @@ -121,6 +121,7 @@ /datum/surgery_step/cavity/place_item/can_use(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) if(!istype(target)) user << "This isn't a human!." + return 0 var/datum/organ/external/affected = target.get_organ(target_zone) var/can_fit = !affected.hidden && affected.cavity && tool.w_class <= get_max_wclass(affected) return ..() && can_fit