diff --git a/.travis.yml b/.travis.yml index 0c74f2f8a45..80e0a0bf214 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ sudo: false env: BYOND_MAJOR="508" BYOND_MINOR="1293" - MACRO_COUNT=1171 + MACRO_COUNT=1154 cache: directories: diff --git a/baystation12.dme b/baystation12.dme index e71f36f3f7f..4a902dd743c 100644 --- a/baystation12.dme +++ b/baystation12.dme @@ -148,7 +148,6 @@ #include "code\datums\computerfiles.dm" #include "code\datums\crew.dm" #include "code\datums\datacore.dm" -#include "code\datums\datumvars.dm" #include "code\datums\disease.dm" #include "code\datums\mind.dm" #include "code\datums\mixed.dm" @@ -863,6 +862,7 @@ #include "code\modules\admin\player_panel.dm" #include "code\modules\admin\topic.dm" #include "code\modules\admin\ToRban.dm" +#include "code\modules\admin\callproc\callproc.dm" #include "code\modules\admin\DB ban\functions.dm" #include "code\modules\admin\permissionverbs\permissionedit.dm" #include "code\modules\admin\secrets\admin_secrets\admin_logs.dm" @@ -932,6 +932,9 @@ #include "code\modules\admin\verbs\striketeam.dm" #include "code\modules\admin\verbs\ticklag.dm" #include "code\modules\admin\verbs\tripAI.dm" +#include "code\modules\admin\view_variables\helpers.dm" +#include "code\modules\admin\view_variables\topic.dm" +#include "code\modules\admin\view_variables\view_variables.dm" #include "code\modules\alarm\alarm.dm" #include "code\modules\alarm\alarm_handler.dm" #include "code\modules\alarm\atmosphere_alarm.dm" diff --git a/code/__defines/chemistry.dm b/code/__defines/chemistry.dm index 7091ea81d72..31bdcc94694 100644 --- a/code/__defines/chemistry.dm +++ b/code/__defines/chemistry.dm @@ -21,8 +21,9 @@ #define IS_VOX 2 #define IS_SKRELL 3 #define IS_UNATHI 4 -#define IS_XENOS 5 -#define IS_MACHINE 6 +#define IS_TAJARA 5 +#define IS_XENOS 6 +#define IS_MACHINE 7 #define CE_STABLE "stable" // Inaprovaline #define CE_ANTIBIOTIC "antibiotic" // Spaceacilin diff --git a/code/__defines/machinery.dm b/code/__defines/machinery.dm index 13df4a5160e..53929f0713d 100644 --- a/code/__defines/machinery.dm +++ b/code/__defines/machinery.dm @@ -4,7 +4,7 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called // It's a conversion constant. power_used*CELLRATE = charge_provided, or charge_used/CELLRATE = power_provided // Doors! -#define DOOR_CRUSH_DAMAGE 10 +#define DOOR_CRUSH_DAMAGE 20 #define ALIEN_SELECT_AFK_BUFFER 1 // How many minutes that a person can be AFK before not being allowed to be an alien. // Channel numbers for power. @@ -26,9 +26,6 @@ var/global/defer_powernet_rebuild = 0 // True if net rebuild will be called #define AI_CAMERA_LUMINOSITY 6 -// Those networks can only be accessed by pre-existing terminals. AIs and new terminals can't use them. -var/list/restricted_camera_networks = list("thunder","ERT","NUKE","Secret") - // Camera networks #define NETWORK_CRESCENT "Crescent" #define NETWORK_CIVILIAN_EAST "Civilian East" @@ -37,9 +34,10 @@ var/list/restricted_camera_networks = list("thunder","ERT","NUKE","Secret") #define NETWORK_ENGINE "Engine" #define NETWORK_ENGINEERING "Engineering" #define NETWORK_ENGINEERING_OUTPOST "Engineering Outpost" -#define NETWORK_ERT "ERT" +#define NETWORK_ERT "ZeEmergencyResponseTeam" #define NETWORK_EXODUS "Exodus" #define NETWORK_MEDICAL "Medical" +#define NETWORK_MERCENARY "MercurialNet" #define NETWORK_MINE "MINE" #define NETWORK_RESEARCH "Research" #define NETWORK_RESEARCH_OUTPOST "Research Outpost" @@ -47,7 +45,10 @@ var/list/restricted_camera_networks = list("thunder","ERT","NUKE","Secret") #define NETWORK_PRISON "Prison" #define NETWORK_SECURITY "Security" #define NETWORK_TELECOM "Tcomsat" -#define NETWORK_THUNDER "thunder" +#define NETWORK_THUNDER "Thunderdome" + +// Those networks can only be accessed by pre-existing terminals. AIs and new terminals can't use them. +var/list/restricted_camera_networks = list(NETWORK_ERT,NETWORK_MERCENARY,"Secret") //singularity defines diff --git a/code/__defines/species_languages.dm b/code/__defines/species_languages.dm index fccfbaa2ef5..e204cdb977a 100644 --- a/code/__defines/species_languages.dm +++ b/code/__defines/species_languages.dm @@ -42,5 +42,3 @@ #define INNATE 64 // All mobs can be assumed to speak and understand this language. (audible emotes) #define NO_TALK_MSG 128 // Do not show the "\The [speaker] talks into \the [radio]" message #define NO_STUTTER 256 // No stuttering, slurring, or other speech problems -#define COMMON_VERBS 512 // Robots will apply regular verbs to this - diff --git a/code/_helpers/unsorted.dm b/code/_helpers/unsorted.dm index e6bd820adaa..986c8c448a3 100644 --- a/code/_helpers/unsorted.dm +++ b/code/_helpers/unsorted.dm @@ -646,7 +646,7 @@ proc/GaussRandRound(var/sigma,var/roundto) else return get_step(ref, base_dir) -/proc/do_mob(var/mob/user, var/mob/target, var/delay, var/numticks = 5, var/needhand = 1) //This is quite an ugly solution but i refuse to use the old request system. +/proc/do_mob(var/mob/user, var/mob/target, var/delay = 30, var/numticks = 5, var/needhand = 1) //This is quite an ugly solution but i refuse to use the old request system. if(!user || !target) return 0 if(numticks == 0) return 0 diff --git a/code/game/antagonist/antagonist_print.dm b/code/game/antagonist/antagonist_print.dm index c25ea20747b..1fd3df90db4 100644 --- a/code/game/antagonist/antagonist_print.dm +++ b/code/game/antagonist/antagonist_print.dm @@ -72,13 +72,26 @@ if(H && H.uplink_owner && H.uplink_owner == ply) TC_uses += H.used_TC uplink_true = 1 - var/list/refined_log = new() - for(var/datum/uplink_item/UI in H.purchase_log) - refined_log.Add("[H.purchase_log[UI]]x[UI.log_icon()][UI.name]") - purchases = english_list(refined_log, nothing_text = "") + purchases += get_uplink_purchases(H) if(uplink_true) text += " (used [TC_uses] TC)" if(purchases) text += "
[purchases]" - return text \ No newline at end of file + return text + +/proc/print_ownerless_uplinks() + var/has_printed = 0 + for(var/obj/item/device/uplink/H in world_uplinks) + if(isnull(H.uplink_owner) && H.used_TC) + if(!has_printed) + has_printed = 1 + world << "Ownerless Uplinks" + world << "[H.loc] (used [H.used_TC] TC)" + world << get_uplink_purchases(H) + +/proc/get_uplink_purchases(var/obj/item/device/uplink/H) + var/list/refined_log = new() + for(var/datum/uplink_item/UI in H.purchase_log) + refined_log.Add("[H.purchase_log[UI]]x[UI.log_icon()][UI.name]") + . = english_list(refined_log, nothing_text = "") diff --git a/code/game/antagonist/outsider/mercenary.dm b/code/game/antagonist/outsider/mercenary.dm index f703818e471..7315eb418ff 100644 --- a/code/game/antagonist/outsider/mercenary.dm +++ b/code/game/antagonist/outsider/mercenary.dm @@ -45,9 +45,7 @@ var/datum/antagonist/mercenary/mercs player.equip_to_slot_or_del(new /obj/item/weapon/reagent_containers/pill/cyanide(player), slot_in_backpack) if (player.mind == leader) - var/obj/item/device/radio/uplink/U = new(player.loc) - U.hidden_uplink.uplink_owner = player.mind - U.hidden_uplink.uses = 40 + var/obj/item/device/radio/uplink/U = new(player.loc, player.mind, 40) player.put_in_hands(U) player.update_icons() diff --git a/code/game/atoms.dm b/code/game/atoms.dm index 057b55750fd..a660b6c5890 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -415,7 +415,7 @@ its easier to just keep the beam vertical. return src.germ_level = 0 if(istype(blood_DNA, /list)) - del(blood_DNA) + blood_DNA.Cut() return 1 diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index d869740f8bc..412e9033d4d 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -292,6 +292,8 @@ var/global/list/additional_antag_types = list() sleep(10) antag.check_victory() antag.print_player_summary() + sleep(10) + print_ownerless_uplinks() var/clients = 0 var/surviving_humans = 0 diff --git a/code/game/machinery/computer/camera.dm b/code/game/machinery/computer/camera.dm index 4b8b9a9acf3..3090e7ab7af 100644 --- a/code/game/machinery/computer/camera.dm +++ b/code/game/machinery/computer/camera.dm @@ -255,7 +255,7 @@ name = "head mounted camera monitor" desc = "Used to access the built-in cameras in helmets." icon_state = "syndicam" - network = list("NUKE") + network = list(NETWORK_MERCENARY) circuit = null /obj/machinery/computer/security/nuclear/New() diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm index 5e39ed13d3f..7d2a1bbe0f2 100644 --- a/code/game/machinery/portable_turret.dm +++ b/code/game/machinery/portable_turret.dm @@ -413,7 +413,6 @@ var/list/turret_icons /obj/machinery/porta_turret/ex_act(severity) switch (severity) if (1) - del(src) qdel(src) if (2) if (prob(25)) @@ -701,7 +700,7 @@ var/list/turret_icons playsound(loc, 'sound/items/Crowbar.ogg', 75, 1) user << "You dismantle the turret construction." new /obj/item/stack/material/steel( loc, 5) - qdel(src) // qdel + qdel(src) return if(1) diff --git a/code/game/objects/items/devices/PDA/PDA.dm b/code/game/objects/items/devices/PDA/PDA.dm index ece1028cb6d..9ee23b2fee9 100644 --- a/code/game/objects/items/devices/PDA/PDA.dm +++ b/code/game/objects/items/devices/PDA/PDA.dm @@ -1042,7 +1042,7 @@ var/global/list/obj/item/device/pda/PDAs = list() /obj/item/device/pda/proc/new_message(var/sending_unit, var/sender, var/sender_job, var/message) var/reception_message = "\icon[src] Message from [sender] ([sender_job]), \"[message]\" (Reply)" - new_info(message_silent, newstone, reception_message) + new_info(message_silent, ttone, reception_message) log_pda("[usr] (PDA: [sending_unit]) sent \"[message]\" to [name]") new_message = 1 diff --git a/code/game/objects/items/devices/flashlight.dm b/code/game/objects/items/devices/flashlight.dm index a9c8acd1bbd..a2707fd01f0 100644 --- a/code/game/objects/items/devices/flashlight.dm +++ b/code/game/objects/items/devices/flashlight.dm @@ -140,7 +140,8 @@ name = "flare" desc = "A red standard-issue flare. There are instructions on the side reading 'pull cord, make light'." w_class = 2.0 - brightness_on = 7 // Pretty bright. + brightness_on = 8 // Pretty bright. + light_power = 3 light_color = "#e58775" icon_state = "flare" item_state = "flare" diff --git a/code/game/objects/items/devices/spy_bug.dm b/code/game/objects/items/devices/spy_bug.dm index d3b9d706d80..063e7a85cea 100644 --- a/code/game/objects/items/devices/spy_bug.dm +++ b/code/game/objects/items/devices/spy_bug.dm @@ -135,7 +135,7 @@ /obj/machinery/camera/spy // These cheap toys are accessible from the mercenary camera console as well - network = list("NUKE") + network = list(NETWORK_MERCENARY) /obj/machinery/camera/spy/New() ..() diff --git a/code/game/objects/items/devices/uplink.dm b/code/game/objects/items/devices/uplink.dm index 2023c881a91..5675877d393 100644 --- a/code/game/objects/items/devices/uplink.dm +++ b/code/game/objects/items/devices/uplink.dm @@ -7,13 +7,13 @@ A list of items and costs is stored under the datum of every game mode, alongsid */ /obj/item/device/uplink - var/welcome // Welcoming menu message - var/uses // Numbers of crystals - var/list/ItemsCategory // List of categories with lists of items - var/list/ItemsReference // List of references with an associated item - var/list/nanoui_items // List of items for NanoUI use - var/nanoui_menu = 0 // The current menu we are in - var/list/nanoui_data = new // Additional data for NanoUI use + var/welcome = "Welcome, Operative" // Welcoming menu message + var/uses // Numbers of crystals + var/list/ItemsCategory // List of categories with lists of items + var/list/ItemsReference // List of references with an associated item + var/list/nanoui_items // List of items for NanoUI use + var/nanoui_menu = 0 // The current menu we are in + var/list/nanoui_data = new // Additional data for NanoUI use var/list/purchase_log = new var/datum/mind/uplink_owner = null @@ -22,11 +22,12 @@ A list of items and costs is stored under the datum of every game mode, alongsid /obj/item/device/uplink/nano_host() return loc -/obj/item/device/uplink/New(var/location, var/datum/mind/owner) +/obj/item/device/uplink/New(var/location, var/datum/mind/owner, var/telecrystals = DEFAULT_TELECRYSTAL_AMOUNT) ..() src.uplink_owner = owner purchase_log = list() world_uplinks += src + uses = telecrystals /obj/item/device/uplink/Destroy() world_uplinks -= src @@ -212,4 +213,4 @@ A list of items and costs is stored under the datum of every game mode, alongsid /obj/item/device/radio/headset/uplink/New() ..() hidden_uplink = new(src) - hidden_uplink.uses = 10 + hidden_uplink.uses = DEFAULT_TELECRYSTAL_AMOUNT diff --git a/code/game/objects/items/weapons/storage/secure.dm b/code/game/objects/items/weapons/storage/secure.dm index ebd76a64a50..8b11055d40f 100644 --- a/code/game/objects/items/weapons/storage/secure.dm +++ b/code/game/objects/items/weapons/storage/secure.dm @@ -169,42 +169,6 @@ src.add_fingerprint(user) return - //I consider this worthless but it isn't my code so whatever. Remove or uncomment. - /*attack(mob/M as mob, mob/living/user as mob) - if ((CLUMSY in user.mutations) && prob(50)) - user << "The [src] slips out of your hand and hits your head." - user.take_organ_damage(10) - user.Paralyse(2) - return - - M.attack_log += text("\[[time_stamp()]\] Has been attacked with [src.name] by [user.name] ([user.ckey])") - user.attack_log += text("\[[time_stamp()]\] Used the [src.name] to attack [M.name] ([M.ckey])") - - log_attack("[user.name] ([user.ckey]) attacked [M.name] ([M.ckey]) with [src.name] (INTENT: [uppertext(user.a_intent)])") - - var/t = user:zone_sel.selecting - if (t == "head") - if(ishuman(M)) - var/mob/living/carbon/human/H = M - if (H.stat < 2 && H.health < 50 && prob(90)) - // ******* Check - if (istype(H, /obj/item/clothing/head) && H.flags & 8 && prob(80)) - H << "The helmet protects you from being hit hard in the head!" - return - var/time = rand(2, 6) - if (prob(75)) - H.Paralyse(time) - else - H.Stun(time) - if(H.stat != 2) H.stat = 1 - for(var/mob/O in viewers(H, null)) - O.show_message(text("[] has been knocked unconscious!", H), 1, "You hear someone fall.", 2) - else - H << text("[] tried to knock you unconcious!",user) - H.eye_blurry += 3 - - return*/ - // ----------------------------- // Secure Safe // ----------------------------- diff --git a/code/js/view_variables.js b/code/js/view_variables.js new file mode 100644 index 00000000000..86ca8cadc69 --- /dev/null +++ b/code/js/view_variables.js @@ -0,0 +1,33 @@ +function updateSearch() { + var filter_text = document.getElementById('filter'); + var filter = filter_text.value.toLowerCase(); + + var vars_ol = document.getElementById('vars'); + var lis = vars_ol.children; + // the above line can be changed to vars_ol.getElementsByTagName("li") to filter child lists too + // potential todo: implement a per-admin toggle for this + + for(var i = 0; i < lis.length; i++) { + var li = lis[i]; + if(filter == "" || li.innerText.toLowerCase().indexOf(filter) != -1) { + li.style.display = "block"; + } else { + li.style.display = "none"; + } + } +} + +function selectTextField() { + var filter_text = document.getElementById('filter'); + filter_text.focus(); + filter_text.select(); +} + +function loadPage(list) { + if(list.options[list.selectedIndex].value == "") { + return; + } + + location.href=list.options[list.selectedIndex].value; + list.selectedIndex = 0; +} diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 2ad2acfbcf7..a4f2bf4a69b 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -183,6 +183,7 @@ var/list/admin_verbs_debug = list( /client/proc/show_plant_genes, /client/proc/enable_debug_verbs, /client/proc/callproc, + /client/proc/callproc_target, /client/proc/toggledebuglogs, /client/proc/SDQL_query, /client/proc/SDQL2_query, @@ -194,6 +195,7 @@ var/list/admin_verbs_debug = list( var/list/admin_verbs_paranoid_debug = list( /client/proc/callproc, + /client/proc/callproc_target, /client/proc/debug_controller ) @@ -263,6 +265,7 @@ var/list/admin_verbs_hideable = list( /client/proc/restart_controller, /client/proc/cmd_admin_list_open_jobs, /client/proc/callproc, + /client/proc/callproc_target, /client/proc/Debug2, /client/proc/reload_admins, /client/proc/kill_air, diff --git a/code/modules/admin/callproc/callproc.dm b/code/modules/admin/callproc/callproc.dm new file mode 100644 index 00000000000..9b3da2b92fe --- /dev/null +++ b/code/modules/admin/callproc/callproc.dm @@ -0,0 +1,152 @@ + +/client/proc/callproc() + set category = "Debug" + set name = "Advanced ProcCall" + + if(!check_rights(R_DEBUG)) return + if(config.debugparanoid && !check_rights(R_ADMIN)) return + + var/target = null + var/targetselected = 0 + + switch(alert("Proc owned by something?",, "Yes", "No", "Cancel")) + if("Yes") + targetselected=1 + switch(input("Proc owned by...", "Owner", null) as null|anything in list("Obj", "Mob", "Area or Turf", "Client")) + if("Obj") + target = input("Select target:", "Target") as null|obj in world + if("Mob") + target = input("Select target:", "Target", usr) as null|mob in world + if("Area or Turf") + target = input("Select target:", "Target", get_turf(usr)) as null|area|turf in world + if("Client") + target = input("Select target:", "Target", usr.client) as null|anything in clients + else + return + if(!target) + usr << "Proc call cancelled." + return + if("Cancel") + return + if("No") + ; // do nothing + + callproc_targetpicked(targetselected, target) + +/client/proc/callproc_target(atom/A in world) + set category = "Debug" + set name = "Advanced ProcCall Target" + + if(!check_rights(R_DEBUG)) return + if(config.debugparanoid && !check_rights(R_ADMIN)) return + + callproc_targetpicked(1, A) + +/client/proc/callproc_targetpicked(hastarget, datum/target) + + // this needs checking again here because VV's 'Call Proc' option directly calls this proc with the target datum + if(!check_rights(R_DEBUG)) return + if(config.debugparanoid && !check_rights(R_ADMIN)) return + + var/returnval = null + + var/procname = input("Proc name", "Proc") as null|text + if(!procname) return + + if(hastarget) + if(!target) + usr << "Your callproc target no longer exists." + return + if(!hascall(target, procname)) + usr << "\The [target] has no call [procname]()" + return + + var/list/arguments = list() + var/done = 0 + var/current = null + + while(!done) + if(hastarget && !target) + usr << "Your callproc target no longer exists." + return + switch(input("Type of [arguments.len+1]\th variable", "argument [arguments.len+1]") as null|anything in list( + "finished", "null", "text", "num", "type", "obj reference", "mob reference", + "area/turf reference", "icon", "file", "client", "mob's area", "marked datum")) + if(null) + return + + if("finished") + done = 1 + + if("null") + current = null + + if("text") + current = input("Enter text for [arguments.len+1]\th argument") as null|text + if(isnull(current)) return + + if("num") + current = input("Enter number for [arguments.len+1]\th argument") as null|num + if(isnull(current)) return + + if("type") + current = input("Select type for [arguments.len+1]\th argument") as null|anything in typesof(/obj, /mob, /area, /turf) + if(isnull(current)) return + + if("obj reference") + current = input("Select object for [arguments.len+1]\th argument") as null|obj in world + if(isnull(current)) return + + if("mob reference") + current = input("Select mob for [arguments.len+1]\th argument") as null|mob in world + if(isnull(current)) return + + if("area/turf reference") + current = input("Select area/turf for [arguments.len+1]\th argument") as null|area|turf in world + if(isnull(current)) return + + if("icon") + current = input("Provide icon for [arguments.len+1]\th argument") as null|icon + if(isnull(current)) return + + if("client") + current = input("Select client for [arguments.len+1]\th argument") as null|anything in clients + if(isnull(current)) return + + if("mob's area") + var/mob/M = input("Select mob to take area for [arguments.len+1]\th argument") as null|mob in world + if(!M) return + current = get_area(M) + if(!current) + switch(alert("\The [M] appears to not have an area; do you want to pass null instead?",, "Yes", "Cancel")) + if("Yes") + ; // do nothing + if("Cancel") + return + + if("marked datum") + current = holder.marked_datum + if(!current) + switch(alert("You do not currently have a marked datum; do you want to pass null instead?",, "Yes", "Cancel")) + if("Yes") + ; // do nothing + if("Cancel") + return + if(!done) + arguments += current + + if(hastarget) + if(!target) + usr << "Your callproc target no longer exists." + return + log_admin("[key_name(src)] called [target]'s [procname]() with [arguments.len ? "the arguments [list2params(arguments)]" : "no arguments"].") + if(arguments.len) + returnval = call(target, procname)(arglist(arguments)) + else + returnval = call(target, procname)() + else + log_admin("[key_name(src)] called [procname]() with [arguments.len ? "the arguments [list2params(arguments)]" : "no arguments"].") + returnval = call(procname)(arglist(arguments)) + + usr << "[procname]() returned: [isnull(returnval) ? "null" : returnval]" + feedback_add_details("admin_verb","APC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/admin/verbs/debug.dm b/code/modules/admin/verbs/debug.dm index d2fba72b79a..11591be4b13 100644 --- a/code/modules/admin/verbs/debug.dm +++ b/code/modules/admin/verbs/debug.dm @@ -14,139 +14,7 @@ feedback_add_details("admin_verb","DG2") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! - - -/* 21st Sept 2010 -Updated by Skie -- Still not perfect but better! -Stuff you can't do: -Call proc /mob/proc/make_dizzy() for some player -Because if you select a player mob as owner it tries to do the proc for -/mob/living/carbon/human/ instead. And that gives a run-time error. -But you can call procs that are of type /mob/living/carbon/human/proc/ for that player. -*/ - -/client/proc/callproc() - set category = "Debug" - set name = "Advanced ProcCall" - - if(!check_rights(R_DEBUG)) return - if(config.debugparanoid && !check_rights(R_ADMIN)) return - - spawn(0) - var/target = null - var/targetselected = 0 - var/lst[] // List reference - lst = new/list() // Make the list - var/returnval = null - var/class = null - - switch(alert("Proc owned by something?",,"Yes","No")) - if("Yes") - targetselected = 1 - class = input("Proc owned by...","Owner",null) as null|anything in list("Obj","Mob","Area or Turf","Client") - switch(class) - if("Obj") - target = input("Enter target:","Target",usr) as obj in world - if("Mob") - target = input("Enter target:","Target",usr) as mob in world - if("Area or Turf") - target = input("Enter target:","Target",usr.loc) as area|turf in world - if("Client") - var/list/keys = list() - for(var/client/C) - keys += C - target = input("Please, select a player!", "Selection", null, null) as null|anything in keys - else - return - if("No") - target = null - targetselected = 0 - - var/procname = input("Proc path, eg: /proc/fake_blood","Path:", null) as text|null - if(!procname) return - - if(targetselected) - if(!target) - usr << "Your target no longer exists." - return - if(!hascall(target,procname)) - usr << "Error: callproc(): target has no such call [procname]." - return - else - if(copytext(procname, 1, 7) == "/proc/") - // nothing - else if(copytext(procname, 1, 6) == "proc/") - procname = "/[procname]" - else if(copytext(procname, 1, 2) == "/") - procname = "/proc[procname]" - else - procname = "/proc/[procname]" - // Procs have the strange property that text2path will return non-null, but ispath() will return false. - var/path = text2path(procname) - if(!path || ispath(path)) - usr << "Invalid proc [procname]" - return - - var/argnum = input("Number of arguments","Number:",0) as num|null - if(!argnum && (argnum!=0)) return - - lst.len = argnum // Expand to right length - //TODO: make a list to store whether each argument was initialised as null. - //Reason: So we can abort the proccall if say, one of our arguments was a mob which no longer exists - //this will protect us from a fair few errors ~Carn - - var/i - for(i=1, iError: callproc(): owner of proc no longer exists." - return - log_admin("[key_name(src)] called [target]'s [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") - returnval = call(target,procname)(arglist(lst)) // Pass the lst as an argument list to the proc - else - log_admin("[key_name(src)] called [procname]() with [lst.len ? "the arguments [list2params(lst)]":"no arguments"].") - returnval = call(procname)(arglist(lst)) // Pass the lst as an argument list to the proc - - usr << "[procname] returned: [returnval ? returnval : "null"]" - feedback_add_details("admin_verb","APC") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! +// callproc moved to code/modules/admin/callproc /client/proc/Cell() set category = "Debug" diff --git a/code/modules/admin/view_variables/helpers.dm b/code/modules/admin/view_variables/helpers.dm new file mode 100644 index 00000000000..44d524e06d3 --- /dev/null +++ b/code/modules/admin/view_variables/helpers.dm @@ -0,0 +1,93 @@ + +// Keep these two together, they *must* be defined on both +// If /client ever becomes /datum/client or similar, they can be merged +/client/proc/get_view_variables_header() + return "[src]" +/datum/proc/get_view_variables_header() + return "[src]" + +/atom/get_view_variables_header() + return {" + [src] +
+ << + [dir2text(dir)] + >> + + "} + +/mob/living/get_view_variables_header() + return {" + [src] +
<< [dir2text(dir)] >> +
[ckey ? ckey : "No ckey"] / [real_name ? real_name : "No real name"] +
+ BRUTE:[getBruteLoss()] + FIRE:[getFireLoss()] + TOXIN:[getToxLoss()] + OXY:[getOxyLoss()] + CLONE:[getCloneLoss()] + BRAIN:[getBrainLoss()] +
+ "} + +// Same for these as for get_view_variables_header() above +/client/proc/get_view_variables_options() + return "" +/datum/proc/get_view_variables_options() + return "" + +/mob/get_view_variables_options() + return ..() + {" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + "} + +/mob/living/carbon/human/get_view_variables_options() + return ..() + {" + + + + + + + "} + +/obj/get_view_variables_options() + return ..() + {" + + + + "} + +/turf/get_view_variables_options() + return ..() + {" + + + "} diff --git a/code/datums/datumvars.dm b/code/modules/admin/view_variables/topic.dm similarity index 53% rename from code/datums/datumvars.dm rename to code/modules/admin/view_variables/topic.dm index 75ffcba6e85..c842170b6b1 100644 --- a/code/datums/datumvars.dm +++ b/code/modules/admin/view_variables/topic.dm @@ -1,416 +1,4 @@ -// reference: /client/proc/modify_variables(var/atom/O, var/param_var_name = null, var/autodetect_class = 0) - -client - proc/debug_variables(datum/D in world) - set category = "Debug" - set name = "View Variables" - //set src in world - - - if(!usr.client || !usr.client.holder) - usr << "You need to be an administrator to access this." - return - - - var/title = "" - var/body = "" - - if(!D) return - if(istype(D, /atom)) - var/atom/A = D - title = "[A.name] (\ref[A]) = [A.type]" - - #ifdef VARSICON - if (A.icon) - body += debug_variable("icon", new/icon(A.icon, A.icon_state, A.dir), 0) - #endif - - var/icon/sprite - - if(istype(D,/atom)) - var/atom/AT = D - if(AT.icon && AT.icon_state) - sprite = new /icon(AT.icon, AT.icon_state) - usr << browse_rsc(sprite, "view_vars_sprite.png") - - title = "[D] (\ref[D]) = [D.type]" - - body += {" "} - - body += "" - - body += "
" - - if(sprite) - body += "" - - body += "
" - else - body += "
" - - body += "
" - - if(istype(D,/atom)) - var/atom/A = D - if(isliving(A)) - body += "[D]" - if(A.dir) - body += "
<< [dir2text(A.dir)] >>" - var/mob/living/M = A - body += "
[M.ckey ? M.ckey : "No ckey"] / [M.real_name ? M.real_name : "No real name"]" - body += {" -
- BRUTE:[M.getBruteLoss()] - FIRE:[M.getFireLoss()] - TOXIN:[M.getToxLoss()] - OXY:[M.getOxyLoss()] - CLONE:[M.getCloneLoss()] - BRAIN:[M.getBrainLoss()] - - - - "} - else - body += "[D]" - if(A.dir) - body += "
<< [dir2text(A.dir)] >>" - else - body += "[D]" - - body += "
" - - body += "
" - - var/formatted_type = text("[D.type]") - if(length(formatted_type) > 25) - var/middle_point = length(formatted_type) / 2 - var/splitpoint = findtext(formatted_type,"/",middle_point) - if(splitpoint) - formatted_type = "[copytext(formatted_type,1,splitpoint)]
[copytext(formatted_type,splitpoint)]" - else - formatted_type = "Type too long" //No suitable splitpoint (/) found. - - body += "
[formatted_type]" - - if(src.holder && src.holder.marked_datum && src.holder.marked_datum == D) - body += "
Marked Object" - - body += "
" - - body += "
Refresh" - - //if(ismob(D)) - // body += "
Show player panel

" - - body += {"
-
" - - body += "

" - - body += "E - Edit, tries to determine the variable type by itself.
" - body += "C - Change, asks you for the var type first.
" - body += "M - Mass modify: changes this variable for all objects of this type.

" - - body += "
Search:

" - - body += "
    " - - var/list/names = list() - for (var/V in D.vars) - names += V - - names = sortList(names) - - for (var/V in names) - body += debug_variable(V, D.vars[V], 0, D) - - body += "
" - - var/html = "" - if (title) - html += "[title]" - html += {""} - html += "" - html += body - - html += {" - - "} - - html += "" - - usr << browse(html, "window=variables\ref[D];size=475x650") - - return - - proc/debug_variable(name, value, level, var/datum/DA = null) - var/html = "" - - if(DA) - html += "
  • (E) (C) (M) " - else - html += "
  • " - - if (isnull(value)) - html += "[name] = null" - - else if (istext(value)) - html += "[name] = \"[value]\"" - - else if (isicon(value)) - #ifdef VARSICON - var/icon/I = new/icon(value) - var/rnd = rand(1,10000) - var/rname = "tmp\ref[I][rnd].png" - usr << browse_rsc(I, rname) - html += "[name] = ([value]) " - #else - html += "[name] = /icon ([value])" - #endif - -/* else if (istype(value, /image)) - #ifdef VARSICON - var/rnd = rand(1, 10000) - var/image/I = value - - src << browse_rsc(I.icon, "tmp\ref[value][rnd].png") - html += "[name] = " - #else - html += "[name] = /image ([value])" - #endif -*/ - else if (isfile(value)) - html += "[name] = '[value]'" - - else if (istype(value, /datum)) - var/datum/D = value - html += "[name] \ref[value] = [D.type]" - - else if (istype(value, /client)) - var/client/C = value - html += "[name] \ref[value] = [C] [C.type]" - // - else if (istype(value, /list)) - var/list/L = value - html += "[name] = /list ([L.len])" - - if (L.len > 0 && !(name == "underlays" || name == "overlays" || name == "vars" || L.len > 500)) - // not sure if this is completely right... - if(0) //(L.vars.len > 0) - html += "
      " - html += "
    " - else - html += "" - - else - html += "[name] = [value]" - - html += "
  • " - - return html - /client/proc/view_var_Topic(href, href_list, hsrc) //This should all be moved over to datum/admins/Topic() or something ~Carn if( (usr.client != src) || !src.holder ) @@ -945,11 +533,14 @@ client message_admins("[key_name(usr)] dealt [amount] amount of [Text] damage to [L]") href_list["datumrefresh"] = href_list["mobToDamage"] + else if(href_list["call_proc"]) + var/datum/D = locate(href_list["call_proc"]) + if(istype(D) || istype(D, /client)) // can call on clients too, not just datums + callproc_targetpicked(1, D) + if(href_list["datumrefresh"]) var/datum/DAT = locate(href_list["datumrefresh"]) - if(!istype(DAT, /datum)) - return - src.debug_variables(DAT) + if(istype(DAT, /datum) || istype(DAT, /client)) + debug_variables(DAT) return - diff --git a/code/modules/admin/view_variables/view_variables.dm b/code/modules/admin/view_variables/view_variables.dm new file mode 100644 index 00000000000..e624d2df05a --- /dev/null +++ b/code/modules/admin/view_variables/view_variables.dm @@ -0,0 +1,160 @@ + +// Variables to not even show in the list. +// step_* and bound_* are here because they literally break the game and do nothing else. +// parent_type is here because it's pointless to show in VV. +/var/list/view_variables_hide_vars = list("bound_x", "bound_y", "bound_height", "bound_width", "bounds", "parent_type", "step_x", "step_y", "step_size") +// Variables not to expand the lists of. Vars is pointless to expand, and overlays/underlays cannot be expanded. +/var/list/view_variables_dont_expand = list("overlays", "underlays", "vars") + +/client/proc/debug_variables(datum/D in world) + set category = "Debug" + set name = "View Variables" + + if(!check_rights(0)) + return + + if(!D) + return + + var/icon/sprite + if(istype(D, /atom)) + var/atom/A = D + if(A.icon && A.icon_state) + sprite = icon(A.icon, A.icon_state) + usr << browse_rsc(sprite, "view_vars_sprite.png") + + usr << browse_rsc('code/js/view_variables.js', "view_variables.js") + + var/html = {" + + + + [D] (\ref[D] - [D.type]) + + + +
    + + + +
    + + [sprite ? "" : ""] + +
    [D.get_view_variables_header()]
    +
    + [replacetext("[D.type]", "/", "/")] + [holder.marked_datum == D ? "
    Marked Object" : ""] +
    +
    +
    + Refresh +
    + +
    +
    +
    +
    +
    + + E - Edit, tries to determine the variable type by itself.
    + C - Change, asks you for the var type first.
    + M - Mass modify: changes this variable for all objects of this type.
    +
    +
    + + + +
    +
    + Search: +
    +
    + +
    +
    +
      + [make_view_variables_var_list(D)] +
    + + + "} + + usr << browse(html, "window=variables\ref[D];size=475x650") + + +/proc/make_view_variables_var_list(datum/D) + . = "" + var/list/variables = list() + for(var/x in D.vars) + if(x in view_variables_hide_vars) + continue + variables += x + variables = sortList(variables) + for(var/x in variables) + . += make_view_variables_var_entry(D, x, D.vars[x]) + +/proc/make_view_variables_var_entry(datum/D, varname, value, level=0) + var/ecm = null + var/vtext = null + var/extra = null + + if(D) + ecm = {" + (E) + (C) + (M) + "} + + if(isnull(value)) + vtext = "null" + else if(istext(value)) + vtext = "\"[value]\"" + else if(isicon(value)) + vtext = "[value]" + else if(isfile(value)) + vtext = "'[value]'" + else if(istype(value, /datum)) + var/datum/DA = value + if("[DA]" == "[DA.type]" || !"[DA]") + vtext = "\ref[DA] - [DA.type]" + else + vtext = "\ref[DA] - [DA] ([DA.type])" + else if(istype(value, /client)) + var/client/C = value + vtext = "\ref[C] - [C] ([C.type])" + else if(islist(value)) + var/list/L = value + vtext = "/list ([L.len])" + if(!(varname in view_variables_dont_expand) && L.len > 0 && L.len < 100) + extra = "" + else + vtext = "[value]" + + return "
  • [ecm][varname] = [vtext][extra]
  • " diff --git a/code/modules/clothing/spacesuits/rig/suits/merc.dm b/code/modules/clothing/spacesuits/rig/suits/merc.dm index 22add920141..1c699203001 100644 --- a/code/modules/clothing/spacesuits/rig/suits/merc.dm +++ b/code/modules/clothing/spacesuits/rig/suits/merc.dm @@ -1,6 +1,6 @@ /obj/item/clothing/head/helmet/space/rig/merc light_overlay = "helmet_light_dual_green" - camera_networks = list("NUKE") + camera_networks = list(NETWORK_MERCENARY) /obj/item/weapon/rig/merc name = "crimson hardsuit control module" diff --git a/code/modules/clothing/spacesuits/void/merc.dm b/code/modules/clothing/spacesuits/void/merc.dm index 481e536e741..5db4e882eb7 100644 --- a/code/modules/clothing/spacesuits/void/merc.dm +++ b/code/modules/clothing/spacesuits/void/merc.dm @@ -7,7 +7,7 @@ armor = list(melee = 60, bullet = 50, laser = 30,energy = 15, bomb = 35, bio = 100, rad = 60) siemens_coefficient = 0.6 species_restricted = list("Human") - camera_networks = list("NUKE") + camera_networks = list(NETWORK_MERCENARY) light_overlay = "helmet_light_green" //todo: species-specific light overlays /obj/item/clothing/suit/space/void/merc diff --git a/code/modules/mining/abandonedcrates.dm b/code/modules/mining/abandonedcrates.dm index 7fa2022d36a..038591b735e 100644 --- a/code/modules/mining/abandonedcrates.dm +++ b/code/modules/mining/abandonedcrates.dm @@ -16,6 +16,7 @@ for(var/i in 1 to codelen) code += pick(digits) + digits -= code[code.len] generate_loot() @@ -166,7 +167,7 @@ user << "The crate's anti-tamper system activates!" var/turf/T = get_turf(src.loc) explosion(T, 0, 0, 1, 2) - del(src) + qdel(src) /obj/structure/closet/crate/secure/loot/emag_act(var/remaining_charges, var/mob/user) if (locked) diff --git a/code/modules/mob/language/generic.dm b/code/modules/mob/language/generic.dm index 17a145ae021..d93edf3ac2d 100644 --- a/code/modules/mob/language/generic.dm +++ b/code/modules/mob/language/generic.dm @@ -25,7 +25,7 @@ speech_verb = "says" whisper_verb = "whispers" key = "0" - flags = RESTRICTED | COMMON_VERBS + flags = RESTRICTED syllables = list("blah","blah","blah","bleh","meh","neh","nah","wah") //TODO flag certain languages to use the mob-type specific say_quote and then get rid of these. diff --git a/code/modules/mob/living/bot/secbot.dm b/code/modules/mob/living/bot/secbot.dm index 1820ee93abc..a6f479f7044 100644 --- a/code/modules/mob/living/bot/secbot.dm +++ b/code/modules/mob/living/bot/secbot.dm @@ -183,6 +183,7 @@ if(!Adjacent(target)) awaiting_surrender = 5 // I'm done playing nice mode = SECBOT_HUNT + return var/threat = check_threat(target) if(threat < 4) target = null diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 13f7b640a7a..91248854b9a 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -696,6 +696,28 @@ number += 2 return number +//Used by various things that knock people out by applying blunt trauma to the head. +//Checks that the species has a "head" (brain containing organ) and that hit_zone refers to it. +/mob/living/carbon/human/proc/headcheck(var/target_zone, var/brain_tag = "brain") + if(!species.has_organ[brain_tag]) + return 0 + + var/obj/item/organ/affecting = internal_organs_by_name[brain_tag] + + target_zone = check_zone(target_zone) + if(!affecting || affecting.parent_organ != target_zone) + return 0 + + //if the parent organ is significantly larger than the brain organ, then hitting it is not guaranteed + var/obj/item/organ/parent = get_organ(target_zone) + if(!parent) + return 0 + + if(parent.w_class > affecting.w_class + 1) + return prob(100 / 2**(parent.w_class - affecting.w_class - 1)) + + return 1 + /mob/living/carbon/human/IsAdvancedToolUser(var/silent) if(species.has_fine_manipulation) return 1 diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 9d5fce632d4..3d46417b2d7 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -16,14 +16,14 @@ emp_act var/obj/item/organ/external/organ = get_organ() - //Shields + //Shields var/shield_check = check_shields(P.damage, P, null, def_zone, "the [P.name]") if(shield_check) if(shield_check < 0) return shield_check else P.on_hit(src, 2, def_zone) - return 2 + return 2 //Shrapnel if(P.can_embed()) @@ -146,21 +146,21 @@ emp_act ..() /mob/living/carbon/human/resolve_item_attack(obj/item/I, mob/living/user, var/target_zone) - if(check_attack_throat(I, user)) + if(check_attack_throat(I, user)) return null if(user == src) // Attacking yourself can't miss return target_zone - var/hit_zone = get_zone_with_miss_chance(target_zone, src) + var/hit_zone = get_zone_with_miss_chance(target_zone, src) if(!hit_zone) visible_message("\The [user] misses [src] with \the [I]!") return null - + if(check_shields(I.force, I, user, target_zone, "the [I.name]")) - return - + return null + var/obj/item/organ/external/affecting = get_organ(hit_zone) if (!affecting || (affecting.status & ORGAN_DESTROYED) || affecting.is_stump()) user << "They are missing that limb!" @@ -174,7 +174,7 @@ emp_act return //should be prevented by attacked_with_item() but for sanity. visible_message("[src] has been [I.attack_verb.len? pick(I.attack_verb) : "attacked"] in the [affecting.name] with [I.name] by [user]!") - + var/blocked = run_armor_check(hit_zone, "melee", I.armor_penetration, "Your armor has protected your [affecting.name].", "Your armor has softened the blow to your [affecting.name].") standard_weapon_hit_effects(I, user, effective_force, blocked, hit_zone) @@ -182,32 +182,40 @@ emp_act /mob/living/carbon/human/standard_weapon_hit_effects(obj/item/I, mob/living/user, var/effective_force, var/blocked, var/hit_zone) var/obj/item/organ/external/affecting = get_organ(hit_zone) - if(!affecting) + if(!affecting) return 0 // Handle striking to cripple. if(user.a_intent == I_DISARM) - effective_force /= 2 - if(..(I, effective_force, blocked, hit_zone)) - attack_joint(affecting, I, blocked) - else + effective_force /= 2 //half the effective force + if(!..(I, effective_force, blocked, hit_zone)) return 0 + + attack_joint(affecting, I, blocked) //but can dislocate joints else if(!..()) return 0 - + if(effective_force > 10 || effective_force >= 5 && prob(33)) forcesay(hit_appends) //forcesay checks stat already - if(prob(25 + (effective_force * 2))) - if(!((I.damtype == BRUTE) || (I.damtype == HALLOSS))) - return - + if((I.damtype == BRUTE || I.damtype == HALLOSS) && prob(25 + (effective_force * 2))) + if(!stat) + if(headcheck(hit_zone)) + //Harder to score a stun but if you do it lasts a bit longer + if(prob(effective_force)) + visible_message("[src] [species.knockout_message]") + apply_effect(20, PARALYZE, blocked) + else + //Easier to score a stun but lasts less time + if(prob(effective_force + 10)) + visible_message("[src] has been knocked down!") + apply_effect(6, WEAKEN, blocked) + + //Apply blood if(!(I.flags & NOBLOODY)) I.add_blood(src) - - var/bloody = 0 + if(prob(33)) - bloody = 1 var/turf/location = loc if(istype(location, /turf/simulated)) location.add_blood(src) @@ -217,28 +225,19 @@ emp_act H.bloody_body(src) H.bloody_hands(src) - if(!stat) switch(hit_zone) - if("head")//Harder to score a stun but if you do it lasts a bit longer - if(prob(effective_force)) - apply_effect(20, PARALYZE, blocked) - visible_message("\The [src] has been knocked unconscious!") - if(bloody)//Apply blood - if(wear_mask) - wear_mask.add_blood(src) - update_inv_wear_mask(0) - if(head) - head.add_blood(src) - update_inv_head(0) - if(glasses && prob(33)) - glasses.add_blood(src) - update_inv_glasses(0) - if("chest")//Easier to score a stun but lasts less time - if(prob(effective_force + 10)) - apply_effect(6, WEAKEN, blocked) - visible_message("\The [src] has been knocked down!") - if(bloody) - bloody_body(src) + if("head") + if(wear_mask) + wear_mask.add_blood(src) + update_inv_wear_mask(0) + if(head) + head.add_blood(src) + update_inv_head(0) + if(glasses && prob(33)) + glasses.add_blood(src) + update_inv_glasses(0) + if("chest") + bloody_body(src) return 1 @@ -445,4 +444,3 @@ emp_act perm += perm_by_part[part] return perm - diff --git a/code/modules/mob/living/carbon/human/species/species.dm b/code/modules/mob/living/carbon/human/species/species.dm index 23907be8619..e711fec2e37 100644 --- a/code/modules/mob/living/carbon/human/species/species.dm +++ b/code/modules/mob/living/carbon/human/species/species.dm @@ -66,6 +66,7 @@ var/dusted_anim = "dust-h" var/death_sound var/death_message = "seizes up and falls limp, their eyes dead and lifeless..." + var/knockout_message = "has been knocked unconscious!" // Environment tolerance/life processes vars. var/reagent_tag //Used for metabolizing reagents. diff --git a/code/modules/mob/living/carbon/human/species/station/station.dm b/code/modules/mob/living/carbon/human/species/station/station.dm index f34bc482af6..e4c31a14471 100644 --- a/code/modules/mob/living/carbon/human/species/station/station.dm +++ b/code/modules/mob/living/carbon/human/species/station/station.dm @@ -279,6 +279,8 @@ brute_mod = 1.875 // 100% * 1.875 * 0.8 (robolimbs) ~= 150% burn_mod = 1.875 // So they take 50% extra damage from brute/burn overall. show_ssd = "flashing a 'system offline' glyph on their monitor" + death_message = "gives one shrill beep before falling lifeless." + knockout_message = "encounters a hardware fault and suddenly reboots!" warning_low_pressure = 50 hazard_low_pressure = 0 diff --git a/code/modules/mob/living/carbon/resist.dm b/code/modules/mob/living/carbon/resist.dm index a5ad3f58450..52363b16224 100644 --- a/code/modules/mob/living/carbon/resist.dm +++ b/code/modules/mob/living/carbon/resist.dm @@ -2,7 +2,7 @@ /mob/living/carbon/process_resist() //drop && roll - if(on_fire) + if(on_fire && !buckled) fire_stacks -= 1.2 Weaken(3) spin(32,2) diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm index ab79044b196..d34d5cceea9 100644 --- a/code/modules/mob/living/living.dm +++ b/code/modules/mob/living/living.dm @@ -573,21 +573,12 @@ default behaviour is: set name = "Resist" set category = "IC" - if(can_resist()) + if(!(stat || next_move > world.time)) setClickCooldown(20) resist_grab() - if(!weakened && !restrained()) + if(!weakened) process_resist() -/mob/living/proc/can_resist() - //need to allow !canmove, or otherwise neck grabs can't be resisted - //similar thing with weakened and pinning - if(stat) - return 0 - if(!canClick()) - return 0 - return 1 - /mob/living/proc/process_resist() //Getting out of someone's inventory. if(istype(src.loc, /obj/item/weapon/holder)) diff --git a/code/modules/mob/living/say.dm b/code/modules/mob/living/say.dm index 3546d69acff..460a16d3df4 100644 --- a/code/modules/mob/living/say.dm +++ b/code/modules/mob/living/say.dm @@ -161,19 +161,13 @@ proc/get_radio_key_from_channel(var/channel) else speaking = get_default_language() - if (speaking) - // This is broadcast to all mobs with the language, - // irrespective of distance or anything else. - if(speaking.flags & HIVEMIND) - speaking.broadcast(src,trim(message)) - return 1 - //If we've gotten this far, keep going! - if(speaking.flags & COMMON_VERBS) - verb = say_quote(message) - else - verb = speaking.get_spoken_verb(copytext(message, length(message))) - else - verb = say_quote(message) + // This is broadcast to all mobs with the language, + // irrespective of distance or anything else. + if(speaking && (speaking.flags & HIVEMIND)) + speaking.broadcast(src,trim(message)) + return 1 + + verb = say_quote(message, speaking) if(is_muzzled()) src << "You're muzzled and cannot speak!" diff --git a/code/modules/mob/living/silicon/ai/malf.dm b/code/modules/mob/living/silicon/ai/malf.dm index d86faeb3ea3..adafb233fb5 100644 --- a/code/modules/mob/living/silicon/ai/malf.dm +++ b/code/modules/mob/living/silicon/ai/malf.dm @@ -136,6 +136,5 @@ // Cleaner proc for creating powersupply for an AI. /mob/living/silicon/ai/proc/create_powersupply() if(psupply) - del(psupply) + qdel(psupply) psupply = new/obj/machinery/ai_powersupply(src) - diff --git a/code/modules/mob/living/simple_animal/borer/borer_captive.dm b/code/modules/mob/living/simple_animal/borer/borer_captive.dm index e666f7ac716..45132f588eb 100644 --- a/code/modules/mob/living/simple_animal/borer/borer_captive.dm +++ b/code/modules/mob/living/simple_animal/borer/borer_captive.dm @@ -34,9 +34,6 @@ /mob/living/captive_brain/emote(var/message) return -/mob/living/captive_brain/can_resist() - return !(stat || !canClick()) - /mob/living/captive_brain/process_resist() //Resisting control by an alien mind. if(istype(src.loc,/mob/living/simple_animal/borer)) diff --git a/code/modules/mob/mob_grab_specials.dm b/code/modules/mob/mob_grab_specials.dm index a151b97aae3..4f8bd02a13e 100644 --- a/code/modules/mob/mob_grab_specials.dm +++ b/code/modules/mob/mob_grab_specials.dm @@ -91,15 +91,15 @@ var/damage = 20 var/obj/item/clothing/hat = attacker.head if(istype(hat)) - damage += hat.force * 10 + damage += hat.force * 3 var/armor = target.run_armor_check("head", "melee") - target.apply_damage(damage*rand(90, 110)/100, BRUTE, "head", armor) - attacker.apply_damage(10*rand(90, 110)/100, BRUTE, "head", attacker.run_armor_check("head", "melee")) + target.apply_damage(damage, BRUTE, "head", armor) + attacker.apply_damage(10, BRUTE, "head", attacker.run_armor_check("head", "melee")) - if(!armor && prob(damage)) + if(!armor && target.headcheck("head") && prob(damage)) target.apply_effect(20, PARALYZE) - target.visible_message("[target] has been knocked unconscious!") + target.visible_message("[target] [target.species.knockout_message]") playsound(attacker.loc, "swing_hit", 25, 1, -1) attacker.attack_log += text("\[[time_stamp()]\] Headbutted [target.name] ([target.ckey])") diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index e87e486ff37..647875ca4b9 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -626,6 +626,12 @@ proc/is_blind(A) return 0 +/mob/living/carbon/assess_perp(var/obj/access_obj, var/check_access, var/auth_weapons, var/check_records, var/check_arrest) + if(handcuffed) + return SAFE_PERP + + return ..() + /mob/living/carbon/human/assess_perp(var/obj/access_obj, var/check_access, var/auth_weapons, var/check_records, var/check_arrest) var/threatcount = ..() if(. == SAFE_PERP) diff --git a/code/modules/organs/organ_external.dm b/code/modules/organs/organ_external.dm index fd8e9a78338..1e2f7d1e52a 100644 --- a/code/modules/organs/organ_external.dm +++ b/code/modules/organs/organ_external.dm @@ -270,7 +270,7 @@ owner.updatehealth() //droplimb will call updatehealth() again if it does end up being called //If limb took enough damage, try to cut or tear it off - if(owner && loc == owner) + if(owner && loc == owner && !is_stump()) if(!cannot_amputate && config.limbs_can_break && (brute_dam + burn_dam) >= (max_damage * config.organ_health_multiplier)) //organs can come off in three cases //1. If the damage source is edge_eligible and the brute damage dealt exceeds the edge threshold, then the organ is cut off. diff --git a/code/modules/organs/organ_stump.dm b/code/modules/organs/organ_stump.dm index 0ab0e145a0e..d59e7470337 100644 --- a/code/modules/organs/organ_stump.dm +++ b/code/modules/organs/organ_stump.dm @@ -25,4 +25,4 @@ qdel(src) /obj/item/organ/external/stump/is_usable() - return 0 \ No newline at end of file + return 0 diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 8b57003325b..6d2e232eef0 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -1148,7 +1148,7 @@ obj/machinery/power/apc/proc/autoset(var/val, var/on) switch(severity) if(1.0) - //set_broken() //now Del() do what we need + //set_broken() //now qdel() do what we need if (cell) cell.ex_act(1.0) // more lags woohoo qdel(src) diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm index 0d817d16b2b..ba86ba1bb2a 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Food-Drinks.dm @@ -32,17 +32,17 @@ return ..() -/datum/reagent/nutriment/egg // Also bad for skrell. Not a child of protein because it might mess up, not sure. +/datum/reagent/nutriment/protein/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + if(alien && alien == IS_SKRELL) + M.adjustToxLoss(2 * removed) + return + ..() + +/datum/reagent/nutriment/protein/egg // Also bad for skrell. name = "egg yolk" id = "egg" color = "#FFFFAA" -/datum/reagent/nutriment/egg/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) - if(alien && alien == IS_SKRELL) - M.adjustToxLoss(0.5 * removed) - return - ..() - /datum/reagent/nutriment/honey name = "Honey" id = "honey" @@ -570,19 +570,36 @@ adj_drowsy = -3 adj_sleepy = -2 adj_temp = 25 + overdose = 45 glass_icon_state = "hot_coffee" glass_name = "cup of coffee" glass_desc = "Don't drop it, or you'll send scalding liquid and glass shards everywhere." /datum/reagent/drink/coffee/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) - ..() if(alien == IS_DIONA) return + ..() + if(alien == IS_TAJARA) + M.adjustToxLoss(0.5 * removed) + M.make_jittery(4) //extra sensitive to caffine if(adj_temp > 0) holder.remove_reagent("frostoil", 10 * removed) - if(dose > 45) - M.make_jittery(5) + +/datum/reagent/nutriment/coffee/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + ..() + if(alien == IS_TAJARA) + M.adjustToxLoss(2 * removed) + M.make_jittery(4) + return + +/datum/reagent/drink/coffee/overdose(var/mob/living/carbon/M, var/alien) + if(alien == IS_DIONA) + return + if(alien == IS_TAJARA) + M.adjustToxLoss(4 * REM) + M.apply_effect(3, STUTTER) + M.make_jittery(5) /datum/reagent/drink/coffee/icecoffee name = "Iced Coffee" @@ -1010,7 +1027,39 @@ glass_desc = "A crystal clear glass of Griffeater gin." glass_center_of_mass = list("x"=16, "y"=12) -/datum/reagent/ethanol/kahlua +//Base type for alchoholic drinks containing coffee +/datum/reagent/ethanol/coffee + overdose = 45 + +/datum/reagent/ethanol/coffee/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) + if(alien == IS_DIONA) + return + ..() + M.dizziness = max(0, M.dizziness - 5) + M.drowsyness = max(0, M.drowsyness - 3) + M.sleeping = max(0, M.sleeping - 2) + if(M.bodytemperature > 310) + M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT)) + if(alien == IS_TAJARA) + M.adjustToxLoss(0.5 * removed) + M.make_jittery(4) //extra sensitive to caffine + +/datum/reagent/ethanol/coffee/affect_blood(var/mob/living/carbon/M, var/alien, var/removed) + if(alien == IS_TAJARA) + M.adjustToxLoss(2 * removed) + M.make_jittery(4) + return + ..() + +/datum/reagent/ethanol/coffee/overdose(var/mob/living/carbon/M, var/alien) + if(alien == IS_DIONA) + return + if(alien == IS_TAJARA) + M.adjustToxLoss(4 * REM) + M.apply_effect(3, STUTTER) + M.make_jittery(5) + +/datum/reagent/ethanol/coffee/kahlua name = "Kahlua" id = "kahlua" description = "A widely known, Mexican coffee-flavoured liqueur. In production since 1936!" @@ -1022,17 +1071,6 @@ glass_desc = "DAMN, THIS THING LOOKS ROBUST" glass_center_of_mass = list("x"=15, "y"=7) -/datum/reagent/ethanol/kahlua/affect_ingest(var/mob/living/carbon/M, var/alien, var/removed) - ..() - if(alien == IS_DIONA) - return - M.dizziness = max(0, M.dizziness - 5) - M.drowsyness = max(0, M.drowsyness - 3) - M.sleeping = max(0, M.sleeping - 2) - if(M.bodytemperature > 310) - M.bodytemperature = max(310, M.bodytemperature - (5 * TEMPERATURE_DAMAGE_COEFFICIENT)) - M.make_jittery(5) - /datum/reagent/ethanol/melonliquor name = "Melon Liquor" id = "melonliquor" @@ -1246,7 +1284,7 @@ glass_desc = "We cannot take legal responsibility for your actions after imbibing." glass_center_of_mass = list("x"=15, "y"=7) -/datum/reagent/ethanol/b52 +/datum/reagent/ethanol/coffee/b52 name = "B-52" id = "b52" description = "Coffee, Irish Cream, and cognac. You will get bombed." @@ -1357,7 +1395,7 @@ glass_name = "glass of Booger" glass_desc = "Ewww..." -/datum/reagent/ethanol/brave_bull +/datum/reagent/ethanol/coffee/brave_bull name = "Brave Bull" id = "bravebull" description = "It's just as effective as Dutch-Courage!" @@ -1566,7 +1604,7 @@ glass_desc = "An irish car bomb." glass_center_of_mass = list("x"=16, "y"=8) -/datum/reagent/ethanol/irishcoffee +/datum/reagent/ethanol/coffee/irishcoffee name = "Irish Coffee" id = "irishcoffee" description = "Coffee, and alcohol. More fun than a Mimosa to drink in the morning." diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm index 8817db3618b..f55eb57f587 100644 --- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm +++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Toxins.dm @@ -420,19 +420,19 @@ return M.druggy = max(M.druggy, 30) if(dose < 1) - M.stuttering = max(M.stuttering, 3) + M.apply_effect(3, STUTTER) M.make_dizzy(5) if(prob(10)) M.emote(pick("twitch", "giggle")) else if(dose < 2) - M.stuttering = max(M.stuttering, 3) + M.apply_effect(3, STUTTER) M.make_jittery(10) M.make_dizzy(10) M.druggy = max(M.druggy, 35) if(prob(20)) M.emote(pick("twitch","giggle")) else - M.stuttering = max(M.stuttering, 3) + M.apply_effect(3, STUTTER) M.make_jittery(20) M.make_dizzy(20) M.druggy = max(M.druggy, 40) diff --git a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm index 8e0f26dce3b..ef2b5ca1d31 100644 --- a/code/modules/reagents/reagent_containers/food/drinks/bottle.dm +++ b/code/modules/reagents/reagent_containers/food/drinks/bottle.dm @@ -130,8 +130,10 @@ if(blocked < 2) weaken_duration = smash_duration + min(0, force - target.getarmor(hit_zone, "melee") + 10) - if(hit_zone == "head" && istype(target, /mob/living/carbon/)) - user.visible_message("\The [user] smashes [src] over [target]'s head!") + var/mob/living/carbon/human/H = target + if(istype(H) && H.headcheck(hit_zone)) + var/obj/item/organ/affecting = H.get_organ(hit_zone) //headcheck should ensure that affecting is not null + user.visible_message("[user] smashes [src] into [H]'s [affecting.name]!") if(weaken_duration) target.apply_effect(min(weaken_duration, 5), WEAKEN, blocked) // Never weaken more than a flash! else @@ -428,5 +430,3 @@ New() ..() reagents.add_reagent("ale", 30) - - diff --git a/code/modules/virus2/admin.dm b/code/modules/virus2/admin.dm index cbcb5ed2ba1..dad0a309255 100644 --- a/code/modules/virus2/admin.dm +++ b/code/modules/virus2/admin.dm @@ -15,6 +15,20 @@ return 1 +/datum/disease2/disease/get_view_variables_header() + . = list() + for(var/datum/disease2/effectholder/E in effects) + . += "[E.stage]: [E.effect.name]" + return {" + [name()]
    + [list2text(., "
    ")]
    + "} + +/datum/disease2/disease/get_view_variables_options() + return ..() + {" + + "} + /datum/admins/var/datum/virus2_editor/virus2_editor_datum = new /client/proc/virus2_editor() set name = "Virus Editor" diff --git a/html/changelog.html b/html/changelog.html index afa21cd997e..8e9a697fd41 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,11 +56,23 @@ -->
    +

    11 September 2015

    +

    HarpyEagle updated:

    + +

    08 September 2015

    Soadreqm updated:

    +

    Zuhayr updated:

    +

    07 September 2015

    GinjaNinja32 updated:

    diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index e720f6f04c9..6bbef3faa17 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -2299,3 +2299,11 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. 2015-09-08: Soadreqm: - tweak: Increased changeling starting genetic points to 25. + Zuhayr: + - bugfix: Auto-traitor should now be fixed. + - bugfix: The Secret game mode should now be fixed. +2015-09-11: + HarpyEagle: + - tweak: Made flares brighter. + - rscadd: Coffee is now poisonous to tajaran, much like how animal protein is poisonous + to skrell.