From 883e6709a1f40ccd93642b417f961919f257d18e Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Fri, 18 Dec 2020 21:44:49 +0000 Subject: [PATCH 01/48] Update gibs.dm --- code/game/objects/effects/gibs.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/game/objects/effects/gibs.dm b/code/game/objects/effects/gibs.dm index 5503ac91dd1..39f3f250e00 100644 --- a/code/game/objects/effects/gibs.dm +++ b/code/game/objects/effects/gibs.dm @@ -41,6 +41,7 @@ gib.blood_DNA = list() if(MobDNA) + gib.color = MobDNA.species.blood_color gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.blood_type else if(istype(src, /obj/effect/gibspawner/xeno)) gib.blood_DNA["UNKNOWN DNA"] = "X*" From fb2e7c6ecdcd8197b5fb7ab8734b426de37730e9 Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Sat, 19 Dec 2020 15:38:26 +0000 Subject: [PATCH 02/48] Slime People Colours --- code/game/objects/effects/gibs.dm | 46 ++++++++++++++++--------------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/code/game/objects/effects/gibs.dm b/code/game/objects/effects/gibs.dm index 39f3f250e00..3b56364babf 100644 --- a/code/game/objects/effects/gibs.dm +++ b/code/game/objects/effects/gibs.dm @@ -18,37 +18,39 @@ /obj/effect/gibspawner/New(location, datum/dna/MobDNA) ..() + ASSERT(length(gibtypes) == length(gibamounts)) + ASSERT(length(gibamounts) == length(gibdirections)) - if(istype(loc,/turf)) //basically if a badmin spawns it + if(istype(loc, /turf)) //basically if a badmin spawns it Gib(loc, MobDNA) /obj/effect/gibspawner/proc/Gib(atom/location, datum/dna/MobDNA = null) - if(gibtypes.len != gibamounts.len || gibamounts.len != gibdirections.len) - to_chat(world, "Gib list length mismatch!") - return - var/obj/effect/decal/cleanable/blood/gibs/gib = null if(sparks) do_sparks(2, 1, location) - for(var/i = 1, i<= gibtypes.len, i++) - if(gibamounts[i]) - for(var/j = 1, j<= gibamounts[i], j++) - var/gibType = gibtypes[i] - gib = new gibType(location) + for(var/I in 1 to length(gibtypes)) + if(!gibamounts[I]) + continue + for(var/J in 1 to gibamounts[I]) + var/gib_type = gibtypes[I] + gib = new gib_type(location) + gib.blood_DNA = list() + if(MobDNA) + gib.basecolor = MobDNA.species.blood_color + gib.update_icon() + gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.blood_type - gib.blood_DNA = list() - if(MobDNA) - gib.color = MobDNA.species.blood_color - gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.blood_type - else if(istype(src, /obj/effect/gibspawner/xeno)) - gib.blood_DNA["UNKNOWN DNA"] = "X*" - else if(istype(src, /obj/effect/gibspawner/human)) // Probably a monkey - gib.blood_DNA["Non-human DNA"] = "A+" - var/list/directions = gibdirections[i] - if(directions.len) - gib.streak(directions) + else if(istype(src, /obj/effect/gibspawner/xeno)) + gib.blood_DNA["UNKNOWN DNA"] = "X*" - qdel(src) + else if(istype(src, /obj/effect/gibspawner/human)) // Probably a monkey + gib.blood_DNA["Non-human DNA"] = "A+" + + var/list/directions = gibdirections[I] + if(length(directions)) + gib.streak(directions) + + qdel(src) // qdel once done From b7aa7265e9706cf18175b10a648f624d8f1b0132 Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Tue, 22 Dec 2020 19:14:27 +0000 Subject: [PATCH 03/48] Desnowflakeification V1 --- code/game/objects/effects/gibs.dm | 21 +++++++++---------- .../objects/effects/spawners/gibspawner.dm | 8 +++++++ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/code/game/objects/effects/gibs.dm b/code/game/objects/effects/gibs.dm index 3b56364babf..015163c2639 100644 --- a/code/game/objects/effects/gibs.dm +++ b/code/game/objects/effects/gibs.dm @@ -24,7 +24,7 @@ if(istype(loc, /turf)) //basically if a badmin spawns it Gib(loc, MobDNA) -/obj/effect/gibspawner/proc/Gib(atom/location, datum/dna/MobDNA = null) +/obj/effect/gibspawner/proc/Gib(atom/location, datum/dna/MobDNA) var/obj/effect/decal/cleanable/blood/gibs/gib = null if(sparks) @@ -38,19 +38,18 @@ gib = new gib_type(location) gib.blood_DNA = list() - if(MobDNA) - gib.basecolor = MobDNA.species.blood_color - gib.update_icon() - gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.blood_type - - else if(istype(src, /obj/effect/gibspawner/xeno)) - gib.blood_DNA["UNKNOWN DNA"] = "X*" - - else if(istype(src, /obj/effect/gibspawner/human)) // Probably a monkey - gib.blood_DNA["Non-human DNA"] = "A+" + gib_dna(gib, MobDNA) var/list/directions = gibdirections[I] if(length(directions)) gib.streak(directions) qdel(src) // qdel once done + +/obj/effect/gibspawner/proc/gib_dna(obj/effect/decal/cleanable/blood/gibs/gib, datum/dna/MobDNA) + if(!MobDNA) + return TRUE + + gib.basecolor = MobDNA.species.blood_color + gib.update_icon() + gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.blood_type diff --git a/code/game/objects/effects/spawners/gibspawner.dm b/code/game/objects/effects/spawners/gibspawner.dm index 998fb4a2868..e0bf0edb307 100644 --- a/code/game/objects/effects/spawners/gibspawner.dm +++ b/code/game/objects/effects/spawners/gibspawner.dm @@ -15,6 +15,10 @@ gibamounts[6] = pick(0,1,2) ..() +/obj/effect/gibspawner/human/gib_dna(obj/effect/decal/cleanable/blood/gibs/gib, datum/dna/MobDNA) + if(..()) // Probably a monkey + gib.blood_DNA["Non-human DNA"] = "A+" + /obj/effect/gibspawner/xeno gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/xeno/up,/obj/effect/decal/cleanable/blood/gibs/xeno/down,/obj/effect/decal/cleanable/blood/gibs/xeno,/obj/effect/decal/cleanable/blood/gibs/xeno,/obj/effect/decal/cleanable/blood/gibs/xeno/body,/obj/effect/decal/cleanable/blood/gibs/xeno/limb,/obj/effect/decal/cleanable/blood/gibs/xeno/core) gibamounts = list(1,1,1,1,1,1,1) @@ -24,6 +28,10 @@ gibamounts[6] = pick(0,1,2) ..() +/obj/effect/gibspawner/xeno/gib_dna(obj/effect/decal/cleanable/blood/gibs/gib, datum/dna/MobDNA) + if(..()) + gib.blood_DNA["UNKNOWN DNA"] = "X*" + /obj/effect/gibspawner/robot sparks = 1 gibtypes = list(/obj/effect/decal/cleanable/blood/gibs/robot/up,/obj/effect/decal/cleanable/blood/gibs/robot/down,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot,/obj/effect/decal/cleanable/blood/gibs/robot/limb) From bb87e70d6c67ee7ab47351857f6178b69b6722b0 Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Mon, 28 Dec 2020 00:40:18 +0000 Subject: [PATCH 04/48] Face structures while pulling --- code/modules/mob/mob_movement.dm | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index e0f88a53b2b..8b2ba3ff5d3 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -169,7 +169,10 @@ n = get_step(mob, direct) . = mob.SelfMove(n, direct, delay) - mob.setDir(direct) + if(mob.pulling && isstructure(mob.pulling)) + mob.setDir(get_dir(mob, mob.pulling)) // Face welding tanks and stuff when pulling + else + mob.setDir(direct) if((direct & (direct - 1)) && mob.loc == n) //moved diagonally successfully delay = mob.movement_delay() * 2 //Will prevent mob diagonal moves from smoothing accurately, sadly From 52e278cc355ba5ef67240fc7fd921d5dc5a228aa Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Mon, 28 Dec 2020 01:32:52 +0000 Subject: [PATCH 05/48] Variable --- code/game/atoms_movable.dm | 12 +++++++----- code/game/objects/structures.dm | 1 + code/modules/mob/mob_movement.dm | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index d5b3443cc01..d60959706d3 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -3,7 +3,7 @@ appearance_flags = TILE_BOUND glide_size = 8 // Default, adjusted when mobs move based on their movement delays var/last_move = null - var/anchored = 0 + var/anchored = FALSE var/move_resist = MOVE_RESIST_DEFAULT var/move_force = MOVE_FORCE_DEFAULT var/pull_force = PULL_FORCE_DEFAULT @@ -13,13 +13,15 @@ var/datum/thrownthing/throwing = null var/throw_speed = 2 //How many tiles to move per ds when being thrown. Float values are fully supported var/throw_range = 7 - var/no_spin = 0 - var/no_spin_thrown = 0 - var/moved_recently = 0 + var/no_spin = FALSE + var/no_spin_thrown = FALSE + var/moved_recently = FALSE var/mob/pulledby = null var/atom/movable/pulling + /// Face towards the atom while pulling it + var/face_while_pulling = FALSE var/throwforce = 0 - var/canmove = 1 + var/canmove = TRUE var/inertia_dir = 0 var/atom/inertia_last_loc diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index bd8ca8c024b..0ded1e60ced 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -2,6 +2,7 @@ icon = 'icons/obj/structures.dmi' pressure_resistance = 8 max_integrity = 300 + face_while_pulling = TRUE var/climbable var/mob/climber var/broken = FALSE diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 8b2ba3ff5d3..ed75caa8f39 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -169,7 +169,7 @@ n = get_step(mob, direct) . = mob.SelfMove(n, direct, delay) - if(mob.pulling && isstructure(mob.pulling)) + if(mob.pulling?.face_while_pulling) mob.setDir(get_dir(mob, mob.pulling)) // Face welding tanks and stuff when pulling else mob.setDir(direct) From c4ebe82ea7b14e95c83bf922c6cdadebd0d2322d Mon Sep 17 00:00:00 2001 From: SabreML <57483089+SabreML@users.noreply.github.com> Date: Mon, 28 Dec 2020 06:22:30 +0000 Subject: [PATCH 06/48] Exceptions part 1 Curtains, Jani/Engi/Food Cart, Roller Beds, Chairs/Wheelchairs --- code/game/objects/structures/curtains.dm | 1 + code/game/objects/structures/engicart.dm | 1 + code/game/objects/structures/foodcart.dm | 1 + code/game/objects/structures/janicart.dm | 1 + code/game/objects/structures/stool_bed_chair_nest/bed.dm | 1 + code/game/objects/structures/stool_bed_chair_nest/chairs.dm | 1 + 6 files changed, 6 insertions(+) diff --git a/code/game/objects/structures/curtains.dm b/code/game/objects/structures/curtains.dm index 029b0a761ad..da8b0f48476 100644 --- a/code/game/objects/structures/curtains.dm +++ b/code/game/objects/structures/curtains.dm @@ -5,6 +5,7 @@ icon = 'icons/obj/curtain.dmi' name = "curtain" icon_state = "closed" + face_while_pulling = FALSE layer = SHOWER_CLOSED_LAYER opacity = 1 density = 0 diff --git a/code/game/objects/structures/engicart.dm b/code/game/objects/structures/engicart.dm index a77dc35b909..52e1d0ca8e1 100644 --- a/code/game/objects/structures/engicart.dm +++ b/code/game/objects/structures/engicart.dm @@ -3,6 +3,7 @@ desc = "A cart for storing engineering items." icon = 'icons/obj/engicart.dmi' icon_state = "cart" + face_while_pulling = FALSE anchored = 0 density = 1 var/obj/item/stack/sheet/glass/myglass = null diff --git a/code/game/objects/structures/foodcart.dm b/code/game/objects/structures/foodcart.dm index 3a9a3414986..0253ad66952 100644 --- a/code/game/objects/structures/foodcart.dm +++ b/code/game/objects/structures/foodcart.dm @@ -3,6 +3,7 @@ desc = "A cart for transporting food and drinks." icon = 'icons/obj/foodcart.dmi' icon_state = "cart" + face_while_pulling = FALSE anchored = 0 density = 1 //Food slots diff --git a/code/game/objects/structures/janicart.dm b/code/game/objects/structures/janicart.dm index 58120ca4ed5..75a2d288a9e 100644 --- a/code/game/objects/structures/janicart.dm +++ b/code/game/objects/structures/janicart.dm @@ -7,6 +7,7 @@ icon_state = "cart" anchored = 0 density = 1 + face_while_pulling = FALSE container_type = OPENCONTAINER //copypaste sorry var/amount_per_transfer_from_this = 5 //shit I dunno, adding this so syringes stop runtime erroring. --NeoFite 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 d91caa4244f..7d02e861fb2 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/bed.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/bed.dm @@ -64,6 +64,7 @@ name = "roller bed" icon = 'icons/obj/rollerbed.dmi' icon_state = "down" + face_while_pulling = FALSE resistance_flags = NONE anchored = FALSE comfort = 1 diff --git a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm index c1fe7dd7013..0c40c15d539 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/chairs.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/chairs.dm @@ -11,6 +11,7 @@ max_integrity = 250 integrity_failure = 25 buckle_offset = 0 + face_while_pulling = FALSE var/buildstacktype = /obj/item/stack/sheet/metal var/buildstackamount = 1 var/item_chair = /obj/item/chair // if null it can't be picked up From 7297f815193f7e6c2fd8e3d3d92b66bdcd7dc515 Mon Sep 17 00:00:00 2001 From: S34NW <06sean@gmail.com> Date: Sat, 6 Mar 2021 11:57:51 +0000 Subject: [PATCH 07/48] Alert does not equate to armory --- code/modules/admin/admin.dm | 8 ++++++++ code/modules/admin/secrets.dm | 3 +++ code/modules/admin/topic.dm | 6 ++++++ code/modules/security_levels/security_levels.dm | 9 +-------- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index 10417e2b937..b40b73825dd 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -787,9 +787,17 @@ GLOBAL_VAR_INIT(gamma_ship_location, 1) // 0 = station , 1 = space if(GLOB.gamma_ship_location == 1) fromArea = locate(/area/shuttle/gamma/space) toArea = locate(/area/shuttle/gamma/station) + for(var/obj/machinery/door/airlock/hatch/gamma/H in GLOB.airlocks) + H.locked = 0 + H.update_icon() + GLOB.event_announcement.Announce("Centcomm has deployed the Gamma Armory shuttle.", new_sound = 'sound/AI/commandreport.ogg') else fromArea = locate(/area/shuttle/gamma/station) toArea = locate(/area/shuttle/gamma/space) + for(var/obj/machinery/door/airlock/hatch/gamma/H in GLOB.airlocks) + H.locked = 1 + H.update_icon() + GLOB.event_announcement.Announce("Centcomm has recalled the Gamma Armory shuttle.", new_sound = 'sound/AI/commandreport.ogg') fromArea.move_contents_to(toArea) for(var/obj/machinery/mech_bay_recharge_port/P in toArea) diff --git a/code/modules/admin/secrets.dm b/code/modules/admin/secrets.dm index 5cfd50a5ce9..50119d5b24b 100644 --- a/code/modules/admin/secrets.dm +++ b/code/modules/admin/secrets.dm @@ -82,6 +82,9 @@ Create Weather
Weather - Ash Storm  
+ Reinforce Station
+ Move the Gamma Armory   +
"} if(2) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index aa10d51ce1d..c1e1fd3d8ab 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -3218,6 +3218,12 @@ if(!SSshuttle.toggleShuttle("ferry","ferry_home","ferry_away")) message_admins("[key_name_admin(usr)] moved the centcom ferry") log_admin("[key_name(usr)] moved the centcom ferry") + + if("gammashuttle") + SSblackbox.record_feedback("tally", "admin_secrets_fun_used", 1, "Send Gamma Armory") + message_admins("[key_name_admin(usr)] moved the gamma armory") + log_admin("[key_name(usr)] moved the gamma armory") + move_gamma_ship() if(usr) log_admin("[key_name(usr)] used secret [href_list["secretsfun"]]") diff --git a/code/modules/security_levels/security_levels.dm b/code/modules/security_levels/security_levels.dm index bacf982b595..24deabde6a1 100644 --- a/code/modules/security_levels/security_levels.dm +++ b/code/modules/security_levels/security_levels.dm @@ -77,22 +77,15 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur FA.overlays += image('icons/obj/monitors.dmi', "overlay_red") if(SEC_LEVEL_GAMMA) - GLOB.security_announcement_up.Announce("Central Command has ordered the Gamma security level on the station. Security is to have weapons equipped at all times, and all civilians are to immediately seek their nearest head for transportation to a secure location. The station's Gamma armory has been unlocked and is ready for use.","Attention! Gamma security level activated!", new_sound = sound('sound/effects/new_siren.ogg')) + GLOB.security_announcement_up.Announce("Central Command has ordered the Gamma security level on the station. Security is to have weapons equipped at all times, and all civilians are to immediately seek their nearest head for transportation to a secure location.","Attention! Gamma security level activated!", new_sound = sound('sound/effects/new_siren.ogg')) GLOB.security_level = SEC_LEVEL_GAMMA - move_gamma_ship() - if(GLOB.security_level < SEC_LEVEL_RED) for(var/obj/machinery/door/airlock/highsecurity/red/R in GLOB.airlocks) if(is_station_level(R.z)) R.locked = 0 R.update_icon() - for(var/obj/machinery/door/airlock/hatch/gamma/H in GLOB.airlocks) - if(is_station_level(H.z)) - H.locked = 0 - H.update_icon() - post_status("alert", "gammaalert") for(var/obj/machinery/firealarm/FA in GLOB.machines) From 352d3983423cbfd91ad05ba9bb3f04f69b8bcf29 Mon Sep 17 00:00:00 2001 From: Sean Williams <06sean@gmail.com> Date: Sun, 7 Mar 2021 14:38:19 +0000 Subject: [PATCH 08/48] Apply suggestions from AA code review Co-authored-by: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> --- code/modules/admin/admin.dm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index b40b73825dd..f0b5f3c8653 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -788,14 +788,14 @@ GLOBAL_VAR_INIT(gamma_ship_location, 1) // 0 = station , 1 = space fromArea = locate(/area/shuttle/gamma/space) toArea = locate(/area/shuttle/gamma/station) for(var/obj/machinery/door/airlock/hatch/gamma/H in GLOB.airlocks) - H.locked = 0 + H.locked = FALSE H.update_icon() GLOB.event_announcement.Announce("Centcomm has deployed the Gamma Armory shuttle.", new_sound = 'sound/AI/commandreport.ogg') else fromArea = locate(/area/shuttle/gamma/station) toArea = locate(/area/shuttle/gamma/space) for(var/obj/machinery/door/airlock/hatch/gamma/H in GLOB.airlocks) - H.locked = 1 + H.locked = TRUE H.update_icon() GLOB.event_announcement.Announce("Centcomm has recalled the Gamma Armory shuttle.", new_sound = 'sound/AI/commandreport.ogg') fromArea.move_contents_to(toArea) @@ -925,4 +925,3 @@ GLOBAL_VAR_INIT(gamma_ship_location, 1) // 0 = station , 1 = space continue result[1]++ return result - From 7e989b6b7ac005424a06afd59ec44beef174e7e0 Mon Sep 17 00:00:00 2001 From: Sean Williams <06sean@gmail.com> Date: Sun, 7 Mar 2021 22:26:29 +0000 Subject: [PATCH 09/48] Apply suggestions from farie code review Co-authored-by: Farie82 --- code/modules/admin/admin.dm | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index f0b5f3c8653..f4f2bb3170e 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -788,15 +788,13 @@ GLOBAL_VAR_INIT(gamma_ship_location, 1) // 0 = station , 1 = space fromArea = locate(/area/shuttle/gamma/space) toArea = locate(/area/shuttle/gamma/station) for(var/obj/machinery/door/airlock/hatch/gamma/H in GLOB.airlocks) - H.locked = FALSE - H.update_icon() + H.unlock(TRUE) GLOB.event_announcement.Announce("Centcomm has deployed the Gamma Armory shuttle.", new_sound = 'sound/AI/commandreport.ogg') else fromArea = locate(/area/shuttle/gamma/station) toArea = locate(/area/shuttle/gamma/space) for(var/obj/machinery/door/airlock/hatch/gamma/H in GLOB.airlocks) - H.locked = TRUE - H.update_icon() + H.lock(TRUE) GLOB.event_announcement.Announce("Centcomm has recalled the Gamma Armory shuttle.", new_sound = 'sound/AI/commandreport.ogg') fromArea.move_contents_to(toArea) From 8926877d29e379b4420c1435152b4a125c531d0b Mon Sep 17 00:00:00 2001 From: Sean Williams <06sean@gmail.com> Date: Wed, 10 Mar 2021 23:51:23 +0000 Subject: [PATCH 10/48] =?UTF-8?q?Centcomm=20=E2=89=A0=20Central=20Command?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: SabreML <57483089+SabreML@users.noreply.github.com> --- code/modules/admin/admin.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/admin/admin.dm b/code/modules/admin/admin.dm index f4f2bb3170e..59975082aca 100644 --- a/code/modules/admin/admin.dm +++ b/code/modules/admin/admin.dm @@ -789,13 +789,13 @@ GLOBAL_VAR_INIT(gamma_ship_location, 1) // 0 = station , 1 = space toArea = locate(/area/shuttle/gamma/station) for(var/obj/machinery/door/airlock/hatch/gamma/H in GLOB.airlocks) H.unlock(TRUE) - GLOB.event_announcement.Announce("Centcomm has deployed the Gamma Armory shuttle.", new_sound = 'sound/AI/commandreport.ogg') + GLOB.event_announcement.Announce("Central Command has deployed the Gamma Armory shuttle.", new_sound = 'sound/AI/commandreport.ogg') else fromArea = locate(/area/shuttle/gamma/station) toArea = locate(/area/shuttle/gamma/space) for(var/obj/machinery/door/airlock/hatch/gamma/H in GLOB.airlocks) H.lock(TRUE) - GLOB.event_announcement.Announce("Centcomm has recalled the Gamma Armory shuttle.", new_sound = 'sound/AI/commandreport.ogg') + GLOB.event_announcement.Announce("Central Command has recalled the Gamma Armory shuttle.", new_sound = 'sound/AI/commandreport.ogg') fromArea.move_contents_to(toArea) for(var/obj/machinery/mech_bay_recharge_port/P in toArea) From f54b7e5f710f294856bf207725305345dd00067d Mon Sep 17 00:00:00 2001 From: SabreML Date: Tue, 30 Mar 2021 16:06:37 +0100 Subject: [PATCH 11/48] Mochi Review And a couple of other things too. --- code/game/objects/effects/gibs.dm | 59 ++++++++++++------- .../objects/effects/spawners/gibspawner.dm | 8 +-- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/code/game/objects/effects/gibs.dm b/code/game/objects/effects/gibs.dm index 015163c2639..f97b15c1112 100644 --- a/code/game/objects/effects/gibs.dm +++ b/code/game/objects/effects/gibs.dm @@ -1,8 +1,8 @@ -/proc/gibs(atom/location, datum/dna/MobDNA) //CARN MARKER - new /obj/effect/gibspawner/generic(get_turf(location), MobDNA) +/proc/gibs(atom/location, datum/dna/mob_dna) //CARN MARKER + new /obj/effect/gibspawner/generic(get_turf(location), mob_dna) -/proc/hgibs(atom/location, datum/dna/MobDNA) - new /obj/effect/gibspawner/human(get_turf(location), MobDNA) +/proc/hgibs(atom/location, datum/dna/mob_dna) + new /obj/effect/gibspawner/human(get_turf(location), mob_dna) /proc/xgibs(atom/location) new /obj/effect/gibspawner/xeno(get_turf(location)) @@ -16,40 +16,55 @@ var/list/gibamounts = list() var/list/gibdirections = list() //of lists -/obj/effect/gibspawner/New(location, datum/dna/MobDNA) +/obj/effect/gibspawner/Initialize(mapload, datum/dna/mob_dna) ..() ASSERT(length(gibtypes) == length(gibamounts)) ASSERT(length(gibamounts) == length(gibdirections)) - if(istype(loc, /turf)) //basically if a badmin spawns it - Gib(loc, MobDNA) + if(isturf(loc)) + spawn_gibs(loc, mob_dna) -/obj/effect/gibspawner/proc/Gib(atom/location, datum/dna/MobDNA) + return INITIALIZE_HINT_QDEL // qdel once done + +/** + * Spawns the gibs (and sparks if applicable) from the gib spawner. + * + * Arguments: + * * location - The position to spawn the gibs on. + * * mob_dna - The [/datum/dna] controlling the blood DNA and colour of the gibs. + */ +/obj/effect/gibspawner/proc/spawn_gibs(atom/location, datum/dna/mob_dna) var/obj/effect/decal/cleanable/blood/gibs/gib = null if(sparks) do_sparks(2, 1, location) - for(var/I in 1 to length(gibtypes)) - if(!gibamounts[I]) + for(var/gibtype in 1 to length(gibtypes)) + if(!gibamounts[gibtype]) continue - for(var/J in 1 to gibamounts[I]) - var/gib_type = gibtypes[I] + for(var/I in 1 to gibamounts[gibtype]) + var/gib_type = gibtypes[gibtype] gib = new gib_type(location) - gib.blood_DNA = list() - gib_dna(gib, MobDNA) + gib_dna(gib, mob_dna) - var/list/directions = gibdirections[I] + var/list/directions = gibdirections[gibtype] if(length(directions)) gib.streak(directions) - qdel(src) // qdel once done +/** + * Assigns DNA and blood colour to mob gibs. + * + * Returns FALSE if there was no DNA data to transfer to the gibs, and TRUE if there was. + * Arguments: + * * gib - The [/obj/effect/decal/cleanable/blood/gibs] that is being edited. + * * mob_dna - The [/datum/dna] which is being transferred onto the gib. + */ +/obj/effect/gibspawner/proc/gib_dna(obj/effect/decal/cleanable/blood/gibs/gib, datum/dna/mob_dna) + if(!mob_dna) + return FALSE -/obj/effect/gibspawner/proc/gib_dna(obj/effect/decal/cleanable/blood/gibs/gib, datum/dna/MobDNA) - if(!MobDNA) - return TRUE - - gib.basecolor = MobDNA.species.blood_color + gib.basecolor = mob_dna.species.blood_color gib.update_icon() - gib.blood_DNA[MobDNA.unique_enzymes] = MobDNA.blood_type + gib.blood_DNA[mob_dna.unique_enzymes] = mob_dna.blood_type + return TRUE diff --git a/code/game/objects/effects/spawners/gibspawner.dm b/code/game/objects/effects/spawners/gibspawner.dm index e0bf0edb307..3ca1b7d5ae5 100644 --- a/code/game/objects/effects/spawners/gibspawner.dm +++ b/code/game/objects/effects/spawners/gibspawner.dm @@ -15,8 +15,8 @@ gibamounts[6] = pick(0,1,2) ..() -/obj/effect/gibspawner/human/gib_dna(obj/effect/decal/cleanable/blood/gibs/gib, datum/dna/MobDNA) - if(..()) // Probably a monkey +/obj/effect/gibspawner/human/gib_dna(obj/effect/decal/cleanable/blood/gibs/gib, datum/dna/mob_dna) + if(!..()) // Probably admin spawned gib.blood_DNA["Non-human DNA"] = "A+" /obj/effect/gibspawner/xeno @@ -28,8 +28,8 @@ gibamounts[6] = pick(0,1,2) ..() -/obj/effect/gibspawner/xeno/gib_dna(obj/effect/decal/cleanable/blood/gibs/gib, datum/dna/MobDNA) - if(..()) +/obj/effect/gibspawner/xeno/gib_dna(obj/effect/decal/cleanable/blood/gibs/gib, datum/dna/mob_dna) + if(!..()) gib.blood_DNA["UNKNOWN DNA"] = "X*" /obj/effect/gibspawner/robot From 34c8756f1e778723650a55d470fb2357172ea280 Mon Sep 17 00:00:00 2001 From: Pidgey <35320204+PidgeyThePirate@users.noreply.github.com> Date: Tue, 20 Apr 2021 20:25:32 +1000 Subject: [PATCH 12/48] Added *spin to humans and cyborgs, gave the dog's tail chase verb a 5 second cooldown. --- code/modules/mob/living/carbon/human/emote.dm | 20 +++++++++++++++---- .../modules/mob/living/silicon/robot/emote.dm | 6 ++++++ .../mob/living/simple_animal/friendly/dog.dm | 7 +++++-- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index d80ab50e0b0..a5c78ed6766 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -128,12 +128,14 @@ on_CD = handle_emote_CD(50) //longer cooldown if("fart", "farts", "flip", "flips", "snap", "snaps") on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm - if("cough", "coughs", "highfive") + if("cough", "coughs", "slap", "slaps", "highfive") on_CD = handle_emote_CD() if("gasp", "gasps") on_CD = handle_emote_CD() if("deathgasp", "deathgasps") on_CD = handle_emote_CD(50) + if("spin", "spins") + on_CD = handle_emote_CD(50) if("sneeze", "sneezes") on_CD = handle_emote_CD() if("clap", "claps") @@ -443,6 +445,17 @@ message = "[src] does a flip!" SpinAnimation(5,1) + if("spin", "spins") + if(!restrained() && !lying) + if(prob(5)) + INVOKE_ASYNC(src, .proc/spin, 30, 1) + message = "[src] spins too much!" + Dizzy(12) + Confused(12) + else + INVOKE_ASYNC(src, .proc/spin, 20, 1) + message = "[src] spins!" + if("aflap", "aflaps") if(!restrained()) message = "[src] flaps [p_their()] wings ANGRILY!" @@ -870,7 +883,7 @@ var/obj/item/slapper/N = new(src) if(put_in_hands(N)) to_chat(src, "You ready your slapping hand.") - else + else qdel(N) to_chat(src, "You're incapable of slapping in your current state.") @@ -956,8 +969,7 @@ if("help") var/emotelist = "aflap(s), airguitar, blink(s), blink(s)_r, blush(es), bow(s)-none/mob, burp(s), choke(s), chuckle(s), clap(s), collapse(s), cough(s), cry, cries, custom, dance, dap(s)-none/mob," \ + " deathgasp(s), drool(s), eyebrow, fart(s), faint(s), flap(s), flip(s), frown(s), gasp(s), giggle(s), glare(s)-none/mob, grin(s), groan(s), grumble(s), grin(s)," \ - + " handshake-mob, hug(s)-none/mob, hem, highfive, johnny, jump, kiss(es), laugh(s), look(s)-none/mob, moan(s), mumble(s), nod(s), pale(s), point(s)-atom, quiver(s), raise(s), salute(s)-none/mob, scream(s), shake(s)," \ - + " shiver(s), shrug(s), sigh(s), signal(s)-#1-10, slap(s), smile(s),snap(s), sneeze(s), sniff(s), snore(s), stare(s)-none/mob, tremble(s), twitch(es), twitch(es)_s," \ + + " shiver(s), shrug(s), sigh(s), signal(s)-#1-10,slap(s)-none/mob, smile(s),snap(s), sneeze(s), sniff(s), snore(s), spin(s) stare(s)-none/mob, tremble(s), twitch(es), twitch(es)_s," \ + " wave(s), whimper(s), wink(s), yawn(s)" switch(dna.species.name) diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm index bec1e1ae668..5c066213978 100644 --- a/code/modules/mob/living/silicon/robot/emote.dm +++ b/code/modules/mob/living/silicon/robot/emote.dm @@ -13,6 +13,8 @@ //Cooldown-inducing emotes if("law","flip","flips","halt") //halt is exempt because it's used to stop criminal scum //WHOEVER THOUGHT THAT WAS A GOOD IDEA IS GOING TO GET SHOT. on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm + if("spin","spins") + on_CD = handle_emote_CD(5 SECONDS) //Everything else, including typos of the above emotes else on_CD = 0 //If it doesn't induce the cooldown, we won't check for the cooldown @@ -157,6 +159,10 @@ message = "[src] does a flip!" src.SpinAnimation(5,1) + if("spin","spins") + INVOKE_ASYNC(src, .proc/spin, 20, 1) + message = "[src] spins!" + if("help") to_chat(src, "salute, bow-(none)/mob, clap, flap, aflap, twitch, twitches, nod, deathgasp, glare-(none)/mob, stare-(none)/mob, look,\n law, halt") diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 415d012b402..9092ffb8992 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -21,14 +21,17 @@ var/yelp_sound = 'sound/creatures/dog_yelp.ogg' //Used on death. var/last_eaten = 0 footstep_type = FOOTSTEP_MOB_CLAW + var/next_spin = 0 /mob/living/simple_animal/pet/dog/verb/chasetail() set name = "Chase your tail" set desc = "d'awwww." set category = "Dog" - visible_message("[src] [pick("dances around", "chases [p_their()] tail")].", "[pick("You dance around", "You chase your tail")].") - spin(20, 1) + if(next_spin <= world.time) + visible_message("[src] [pick("dances around", "chases [p_their()] tail")].", "[pick("You dance around", "You chase your tail")].") + spin(20, 1) + next_spin = world.time + 5 SECONDS /mob/living/simple_animal/pet/dog/death(gibbed) // Only execute the below if we successfully died From d8e68cb445d332218e187e0eb0e690279f145595 Mon Sep 17 00:00:00 2001 From: Pidgey <35320204+PidgeyThePirate@users.noreply.github.com> Date: Tue, 20 Apr 2021 20:28:37 +1000 Subject: [PATCH 13/48] forgot to add spin to robot *help --- code/modules/mob/living/silicon/robot/emote.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm index 5c066213978..635783ee241 100644 --- a/code/modules/mob/living/silicon/robot/emote.dm +++ b/code/modules/mob/living/silicon/robot/emote.dm @@ -164,7 +164,7 @@ message = "[src] spins!" if("help") - to_chat(src, "salute, bow-(none)/mob, clap, flap, aflap, twitch, twitches, nod, deathgasp, glare-(none)/mob, stare-(none)/mob, look,\n law, halt") + to_chat(src, "salute, bow-(none)/mob, clap, flap, aflap, twitch, twitches, nod, deathgasp, glare-(none)/mob, stare-(none)/mob, look,\n law, halt, flip, spin") ..() From ba3536a20c07d5a05191d6736c9c8b7695d4382f Mon Sep 17 00:00:00 2001 From: Pidgey <35320204+PidgeyThePirate@users.noreply.github.com> Date: Tue, 20 Apr 2021 20:45:15 +1000 Subject: [PATCH 14/48] Okay, done being a dumbo now... I hope --- code/modules/mob/living/carbon/human/emote.dm | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index a5c78ed6766..3684014baa1 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -128,7 +128,7 @@ on_CD = handle_emote_CD(50) //longer cooldown if("fart", "farts", "flip", "flips", "snap", "snaps") on_CD = handle_emote_CD() //proc located in code\modules\mob\emote.dm - if("cough", "coughs", "slap", "slaps", "highfive") + if("cough", "coughs", "highfive") on_CD = handle_emote_CD() if("gasp", "gasps") on_CD = handle_emote_CD() @@ -883,7 +883,7 @@ var/obj/item/slapper/N = new(src) if(put_in_hands(N)) to_chat(src, "You ready your slapping hand.") - else + else qdel(N) to_chat(src, "You're incapable of slapping in your current state.") @@ -969,7 +969,8 @@ if("help") var/emotelist = "aflap(s), airguitar, blink(s), blink(s)_r, blush(es), bow(s)-none/mob, burp(s), choke(s), chuckle(s), clap(s), collapse(s), cough(s), cry, cries, custom, dance, dap(s)-none/mob," \ + " deathgasp(s), drool(s), eyebrow, fart(s), faint(s), flap(s), flip(s), frown(s), gasp(s), giggle(s), glare(s)-none/mob, grin(s), groan(s), grumble(s), grin(s)," \ - + " shiver(s), shrug(s), sigh(s), signal(s)-#1-10,slap(s)-none/mob, smile(s),snap(s), sneeze(s), sniff(s), snore(s), spin(s) stare(s)-none/mob, tremble(s), twitch(es), twitch(es)_s," \ + + " handshake-mob, hug(s)-none/mob, hem, highfive, johnny, jump, kiss(es), laugh(s), look(s)-none/mob, moan(s), mumble(s), nod(s), pale(s), point(s)-atom, quiver(s), raise(s), salute(s)-none/mob, scream(s), shake(s)," \ + + " shiver(s), shrug(s), sigh(s), signal(s)-#1-10, slap(s), smile(s),snap(s), sneeze(s), sniff(s), snore(s), spin(s) stare(s)-none/mob, tremble(s), twitch(es), twitch(es)_s," \ + " wave(s), whimper(s), wink(s), yawn(s)" switch(dna.species.name) From a15a20b8e17616f1fe6cd3c8a2817d752d02de50 Mon Sep 17 00:00:00 2001 From: Pidgey <35320204+PidgeyThePirate@users.noreply.github.com> Date: Tue, 20 Apr 2021 22:04:37 +1000 Subject: [PATCH 15/48] Now look what you've done. Hope I did this right. --- code/modules/mob/living/carbon/human/emote.dm | 4 +- .../modules/mob/living/silicon/robot/emote.dm | 2 +- code/modules/mob/mob.dm | 56 ++++++++++++++----- 3 files changed, 45 insertions(+), 17 deletions(-) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 3684014baa1..8881832eade 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -448,12 +448,12 @@ if("spin", "spins") if(!restrained() && !lying) if(prob(5)) - INVOKE_ASYNC(src, .proc/spin, 30, 1) + spin(30, 1, spin_direction = 2) message = "[src] spins too much!" Dizzy(12) Confused(12) else - INVOKE_ASYNC(src, .proc/spin, 20, 1) + spin(20, 1, spin_direction = 2) message = "[src] spins!" if("aflap", "aflaps") diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm index 635783ee241..fc874889fc0 100644 --- a/code/modules/mob/living/silicon/robot/emote.dm +++ b/code/modules/mob/living/silicon/robot/emote.dm @@ -160,7 +160,7 @@ src.SpinAnimation(5,1) if("spin","spins") - INVOKE_ASYNC(src, .proc/spin, 20, 1) + spin(20, 1, spin_direction = 2) message = "[src] spins!" if("help") diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 95538b18995..6907a2d26c8 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1343,24 +1343,52 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \ /mob/proc/can_resist() return FALSE //overridden in living.dm -/mob/proc/spin(spintime, speed) +#define SPIN_DIRECTION_CLOCKWISE 0 +#define SPIN_DIRECTION_COUNTERCLOCKWISE 1 +#define SPIN_DIRECTION_RANDOM 2 + +/mob/proc/spin(spintime, speed, spin_direction = SPIN_DIRECTION_CLOCKWISE) set waitfor = 0 if(!spintime || !speed || spintime > 100) CRASH("Aborted attempted call of /mob/proc/spin with invalid args ([spintime],[speed]) which could have frozen the server.") var/D = dir - while(spintime >= speed) - sleep(speed) - switch(D) - if(NORTH) - D = EAST - if(SOUTH) - D = WEST - if(EAST) - D = SOUTH - if(WEST) - D = NORTH - setDir(D) - spintime -= speed + var/S + if(spin_direction == SPIN_DIRECTION_CLOCKWISE || spin_direction == SPIN_DIRECTION_COUNTERCLOCKWISE) + S = spin_direction + else + S = pick(SPIN_DIRECTION_CLOCKWISE,SPIN_DIRECTION_COUNTERCLOCKWISE) + if(S == SPIN_DIRECTION_CLOCKWISE) + while(spintime >= speed) + sleep(speed) + switch(D) + if(NORTH) + D = EAST + if(SOUTH) + D = WEST + if(EAST) + D = SOUTH + if(WEST) + D = NORTH + setDir(D) + spintime -= speed + else + while(spintime >= speed) + sleep(speed) + switch(D) + if(NORTH) + D = WEST + if(SOUTH) + D = EAST + if(EAST) + D = NORTH + if(WEST) + D = SOUTH + setDir(D) + spintime -= speed + +#undef SPIN_DIRECTION_CLOCKWISE +#undef SPIN_DIRECTION_COUNTERCLOCKWISE +#undef SPIN_DIRECTION_RANDOM /mob/proc/is_literate() return FALSE From 150d0e4f3b38e27703434a25afcb4022bc84e27c Mon Sep 17 00:00:00 2001 From: Pidgey <35320204+PidgeyThePirate@users.noreply.github.com> Date: Tue, 20 Apr 2021 22:41:45 +1000 Subject: [PATCH 16/48] Implemented Flatty Patty's nicer spin() function. Works great! Also makes the dog cooldown the message rather than the action. --- code/modules/mob/living/carbon/human/emote.dm | 4 +- .../modules/mob/living/silicon/robot/emote.dm | 2 +- .../mob/living/simple_animal/friendly/dog.dm | 8 ++-- code/modules/mob/mob.dm | 44 ++++--------------- 4 files changed, 16 insertions(+), 42 deletions(-) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 8881832eade..875d184775c 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -448,12 +448,12 @@ if("spin", "spins") if(!restrained() && !lying) if(prob(5)) - spin(30, 1, spin_direction = 2) + spin(30, 1) message = "[src] spins too much!" Dizzy(12) Confused(12) else - spin(20, 1, spin_direction = 2) + spin(20, 1) message = "[src] spins!" if("aflap", "aflaps") diff --git a/code/modules/mob/living/silicon/robot/emote.dm b/code/modules/mob/living/silicon/robot/emote.dm index fc874889fc0..36dea666cc5 100644 --- a/code/modules/mob/living/silicon/robot/emote.dm +++ b/code/modules/mob/living/silicon/robot/emote.dm @@ -160,7 +160,7 @@ src.SpinAnimation(5,1) if("spin","spins") - spin(20, 1, spin_direction = 2) + spin(20, 1) message = "[src] spins!" if("help") diff --git a/code/modules/mob/living/simple_animal/friendly/dog.dm b/code/modules/mob/living/simple_animal/friendly/dog.dm index 9092ffb8992..726798c0392 100644 --- a/code/modules/mob/living/simple_animal/friendly/dog.dm +++ b/code/modules/mob/living/simple_animal/friendly/dog.dm @@ -21,17 +21,17 @@ var/yelp_sound = 'sound/creatures/dog_yelp.ogg' //Used on death. var/last_eaten = 0 footstep_type = FOOTSTEP_MOB_CLAW - var/next_spin = 0 + var/next_spin_message = 0 /mob/living/simple_animal/pet/dog/verb/chasetail() set name = "Chase your tail" set desc = "d'awwww." set category = "Dog" - if(next_spin <= world.time) + if(next_spin_message <= world.time) visible_message("[src] [pick("dances around", "chases [p_their()] tail")].", "[pick("You dance around", "You chase your tail")].") - spin(20, 1) - next_spin = world.time + 5 SECONDS + next_spin_message = world.time + 5 SECONDS + spin(20, 1) /mob/living/simple_animal/pet/dog/death(gibbed) // Only execute the below if we successfully died diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 6907a2d26c8..41d0d9aa8af 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1347,44 +1347,18 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \ #define SPIN_DIRECTION_COUNTERCLOCKWISE 1 #define SPIN_DIRECTION_RANDOM 2 -/mob/proc/spin(spintime, speed, spin_direction = SPIN_DIRECTION_CLOCKWISE) +/mob/proc/spin(spintime, speed) set waitfor = 0 if(!spintime || !speed || spintime > 100) CRASH("Aborted attempted call of /mob/proc/spin with invalid args ([spintime],[speed]) which could have frozen the server.") - var/D = dir - var/S - if(spin_direction == SPIN_DIRECTION_CLOCKWISE || spin_direction == SPIN_DIRECTION_COUNTERCLOCKWISE) - S = spin_direction - else - S = pick(SPIN_DIRECTION_CLOCKWISE,SPIN_DIRECTION_COUNTERCLOCKWISE) - if(S == SPIN_DIRECTION_CLOCKWISE) - while(spintime >= speed) - sleep(speed) - switch(D) - if(NORTH) - D = EAST - if(SOUTH) - D = WEST - if(EAST) - D = SOUTH - if(WEST) - D = NORTH - setDir(D) - spintime -= speed - else - while(spintime >= speed) - sleep(speed) - switch(D) - if(NORTH) - D = WEST - if(SOUTH) - D = EAST - if(EAST) - D = NORTH - if(WEST) - D = SOUTH - setDir(D) - spintime -= speed + var/end_time = world.time + spintime + var/spin_dir = prob(50) + while(world.time <= end_time) + sleep(speed) + if(spin_dir) + dir = turn(dir, 90) + else + dir = turn(dir, -90) #undef SPIN_DIRECTION_CLOCKWISE #undef SPIN_DIRECTION_COUNTERCLOCKWISE From 5c7e8cc3a00bc5fda145b3501ba2a5a89c511d34 Mon Sep 17 00:00:00 2001 From: Pidgey <35320204+PidgeyThePirate@users.noreply.github.com> Date: Wed, 21 Apr 2021 01:44:02 +1000 Subject: [PATCH 17/48] forgot to remove some unused defs --- code/modules/mob/mob.dm | 8 -------- 1 file changed, 8 deletions(-) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 41d0d9aa8af..8eb59b8ad5a 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1343,10 +1343,6 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \ /mob/proc/can_resist() return FALSE //overridden in living.dm -#define SPIN_DIRECTION_CLOCKWISE 0 -#define SPIN_DIRECTION_COUNTERCLOCKWISE 1 -#define SPIN_DIRECTION_RANDOM 2 - /mob/proc/spin(spintime, speed) set waitfor = 0 if(!spintime || !speed || spintime > 100) @@ -1360,10 +1356,6 @@ GLOBAL_LIST_INIT(slot_equipment_priority, list( \ else dir = turn(dir, -90) -#undef SPIN_DIRECTION_CLOCKWISE -#undef SPIN_DIRECTION_COUNTERCLOCKWISE -#undef SPIN_DIRECTION_RANDOM - /mob/proc/is_literate() return FALSE From b1549ae272bb5054bb47b148ac4b667dd0df35b8 Mon Sep 17 00:00:00 2001 From: Pidgey <35320204+PidgeyThePirate@users.noreply.github.com> Date: Sat, 24 Apr 2021 16:32:11 +1000 Subject: [PATCH 18/48] Fireballs from the fireflash and fireflash_s procs have the body temperature increase resisted by heat resistance. --- .../atmospherics/environmental/LINDA_fire.dm | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/code/modules/atmospherics/environmental/LINDA_fire.dm b/code/modules/atmospherics/environmental/LINDA_fire.dm index 9c91d72b65c..612dfe4fe1c 100644 --- a/code/modules/atmospherics/environmental/LINDA_fire.dm +++ b/code/modules/atmospherics/environmental/LINDA_fire.dm @@ -228,7 +228,12 @@ for(var/mob/living/L in T) L.adjust_fire_stacks(3) L.IgniteMob() - L.bodytemperature = max(temp / 3, L.bodytemperature) + if(ishuman(L)) + var/mob/living/carbon/human/M = L + var/heatBlockPercent = 1 - M.get_heat_protection(temp) + M.bodytemperature += (temp - M.bodytemperature) * heatBlockPercent / 2 + else + L.bodytemperature = (2 * L.bodytemperature + temp) / 3 /proc/fireflash_s(atom/center, radius, temp, falloff) if(temp < T0C + 60) @@ -291,7 +296,12 @@ for(var/mob/living/L in T) L.adjust_fire_stacks(3) L.IgniteMob() - L.bodytemperature = (2 * L.bodytemperature + temp) / 3 + if(ishuman(L)) + var/mob/living/carbon/human/M = L + var/heatBlockPercent = 1 - M.get_heat_protection(temp) + M.bodytemperature += (temp - M.bodytemperature) * heatBlockPercent / 2 + else + L.bodytemperature = (2 * L.bodytemperature + temp) / 3 if(T.density) continue From 8a64f1bec1bb29661117a97b78f26495c1ab38e1 Mon Sep 17 00:00:00 2001 From: Pidgey <35320204+PidgeyThePirate@users.noreply.github.com> Date: Sat, 24 Apr 2021 16:59:35 +1000 Subject: [PATCH 19/48] Accidentally made the explosions MORE powerful against unarmored individuals. Fixed that. --- code/modules/atmospherics/environmental/LINDA_fire.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/atmospherics/environmental/LINDA_fire.dm b/code/modules/atmospherics/environmental/LINDA_fire.dm index 612dfe4fe1c..ab690676308 100644 --- a/code/modules/atmospherics/environmental/LINDA_fire.dm +++ b/code/modules/atmospherics/environmental/LINDA_fire.dm @@ -231,7 +231,7 @@ if(ishuman(L)) var/mob/living/carbon/human/M = L var/heatBlockPercent = 1 - M.get_heat_protection(temp) - M.bodytemperature += (temp - M.bodytemperature) * heatBlockPercent / 2 + M.bodytemperature += (temp - M.bodytemperature) * heatBlockPercent / 3 else L.bodytemperature = (2 * L.bodytemperature + temp) / 3 @@ -299,7 +299,7 @@ if(ishuman(L)) var/mob/living/carbon/human/M = L var/heatBlockPercent = 1 - M.get_heat_protection(temp) - M.bodytemperature += (temp - M.bodytemperature) * heatBlockPercent / 2 + M.bodytemperature += (temp - M.bodytemperature) * heatBlockPercent / 3 else L.bodytemperature = (2 * L.bodytemperature + temp) / 3 From 7ee3b8548c3f36658a02bcd51b50466c65d426ab Mon Sep 17 00:00:00 2001 From: Onyxarias Date: Mon, 17 May 2021 15:20:58 -0700 Subject: [PATCH 20/48] Flashproofs sleek, adds species restrictions to others. --- .../client/preference/loadout/loadout_racial.dm | 16 ++++++++-------- code/modules/clothing/glasses/glasses.dm | 4 ++++ code/modules/clothing/glasses/hud.dm | 2 ++ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/code/modules/client/preference/loadout/loadout_racial.dm b/code/modules/client/preference/loadout/loadout_racial.dm index 0d7b945bb78..c3d4c0d50bc 100644 --- a/code/modules/client/preference/loadout/loadout_racial.dm +++ b/code/modules/client/preference/loadout/loadout_racial.dm @@ -5,42 +5,42 @@ /datum/gear/racial/taj display_name = "embroidered veil" - description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races." + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. Cannot be worn by non-Tajaran" path = /obj/item/clothing/glasses/tajblind slot = slot_glasses /datum/gear/racial/taj/sec display_name = "sleek veil" - description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. This one has an in-built security HUD." + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. This one has an in-built security HUD. Cannot be worn by non-Tajaran" path = /obj/item/clothing/glasses/hud/security/tajblind allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot", "Internal Affairs Agent", "Magistrate") cost = 2 /datum/gear/racial/taj/med display_name = "lightweight veil" - description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. This one has an in-built medical HUD." + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. This one has an in-built medical HUD. Cannot be worn by non-Tajaran" path = /obj/item/clothing/glasses/hud/health/tajblind allowed_roles = list("Chief Medical Officer", "Medical Doctor", "Chemist", "Psychiatrist", "Paramedic", "Virologist", "Brig Physician" , "Coroner") cost = 2 /datum/gear/racial/taj/sci display_name = "hi-tech veil" - description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races." + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. Cannot be worn by non-Tajaran" path = /obj/item/clothing/glasses/tajblind/sci cost = 2 /datum/gear/racial/taj/eng display_name = "industrial veil" - description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races." + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. Cannot be worn by non-Tajaran" path = /obj/item/clothing/glasses/tajblind/eng cost = 2 - + /datum/gear/racial/taj/cargo display_name = "khaki veil" - description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. It is light and comfy!" + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. It is light and comfy! Cannot be worn by non-Tajaran" path = /obj/item/clothing/glasses/tajblind/cargo cost = 2 - + /datum/gear/racial/footwraps display_name = "cloth footwraps" path = /obj/item/clothing/shoes/footwraps diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index d07b95d18eb..f5f0e8bd3e2 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -487,6 +487,7 @@ desc = "An Ahdominian made veil that allows the user to see while obscuring their eyes." icon_state = "tajblind" item_state = "tajblind" + species_restricted = list("Tajaran") flags_cover = GLASSESCOVERSEYES actions_types = list(/datum/action/item_action/toggle) up = 0 @@ -502,16 +503,19 @@ name = "industrial veil" icon_state = "tajblind_engi" item_state = "tajblind_engi" + species_restricted = list("Tajaran") /obj/item/clothing/glasses/tajblind/sci name = "hi-tech veil" icon_state = "tajblind_sci" item_state = "tajblind_sci" + species_restricted = list("Tajaran") /obj/item/clothing/glasses/tajblind/cargo name = "khaki veil" icon_state = "tajblind_cargo" item_state = "tajblind_cargo" + species_restricted = list("Tajaran") /obj/item/clothing/glasses/tajblind/attack_self() toggle_veil() diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index f0dce270fb6..a6d85f1e9ae 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -171,6 +171,8 @@ desc = "An Ahdominian made veil that allows the user to see while obscuring their eyes. This one has an in-built security HUD." icon_state = "tajblind_sec" item_state = "tajblind_sec" + flash_protect = 1 + species_restricted = list("Tajaran") flags_cover = GLASSESCOVERSEYES actions_types = list(/datum/action/item_action/toggle) up = 0 From 10fd2da8c854bc48a9f171605eee8835919f985b Mon Sep 17 00:00:00 2001 From: Onyxarias Date: Wed, 19 May 2021 09:11:53 -0700 Subject: [PATCH 21/48] Removed taj racial restrictions. --- Paradise | 1 + .../client/preference/loadout/loadout_racial.dm | 12 ++++++------ code/modules/clothing/glasses/glasses.dm | 4 ---- code/modules/clothing/glasses/hud.dm | 1 - 4 files changed, 7 insertions(+), 11 deletions(-) create mode 160000 Paradise diff --git a/Paradise b/Paradise new file mode 160000 index 00000000000..7ee3b8548c3 --- /dev/null +++ b/Paradise @@ -0,0 +1 @@ +Subproject commit 7ee3b8548c3f36658a02bcd51b50466c65d426ab diff --git a/code/modules/client/preference/loadout/loadout_racial.dm b/code/modules/client/preference/loadout/loadout_racial.dm index c3d4c0d50bc..78d38cf87b5 100644 --- a/code/modules/client/preference/loadout/loadout_racial.dm +++ b/code/modules/client/preference/loadout/loadout_racial.dm @@ -5,39 +5,39 @@ /datum/gear/racial/taj display_name = "embroidered veil" - description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. Cannot be worn by non-Tajaran" + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races." path = /obj/item/clothing/glasses/tajblind slot = slot_glasses /datum/gear/racial/taj/sec display_name = "sleek veil" - description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. This one has an in-built security HUD. Cannot be worn by non-Tajaran" + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. This one has an in-built security HUD." path = /obj/item/clothing/glasses/hud/security/tajblind allowed_roles = list("Head of Security", "Warden", "Security Officer", "Security Pod Pilot", "Internal Affairs Agent", "Magistrate") cost = 2 /datum/gear/racial/taj/med display_name = "lightweight veil" - description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. This one has an in-built medical HUD. Cannot be worn by non-Tajaran" + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. This one has an in-built medical HUD." path = /obj/item/clothing/glasses/hud/health/tajblind allowed_roles = list("Chief Medical Officer", "Medical Doctor", "Chemist", "Psychiatrist", "Paramedic", "Virologist", "Brig Physician" , "Coroner") cost = 2 /datum/gear/racial/taj/sci display_name = "hi-tech veil" - description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. Cannot be worn by non-Tajaran" + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races." path = /obj/item/clothing/glasses/tajblind/sci cost = 2 /datum/gear/racial/taj/eng display_name = "industrial veil" - description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. Cannot be worn by non-Tajaran" + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races." path = /obj/item/clothing/glasses/tajblind/eng cost = 2 /datum/gear/racial/taj/cargo display_name = "khaki veil" - description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. It is light and comfy! Cannot be worn by non-Tajaran" + description = "A common traditional nano-fiber veil worn by many Tajaran, It is rare and offensive to see it on other races. It is light and comfy!" path = /obj/item/clothing/glasses/tajblind/cargo cost = 2 diff --git a/code/modules/clothing/glasses/glasses.dm b/code/modules/clothing/glasses/glasses.dm index f5f0e8bd3e2..d07b95d18eb 100644 --- a/code/modules/clothing/glasses/glasses.dm +++ b/code/modules/clothing/glasses/glasses.dm @@ -487,7 +487,6 @@ desc = "An Ahdominian made veil that allows the user to see while obscuring their eyes." icon_state = "tajblind" item_state = "tajblind" - species_restricted = list("Tajaran") flags_cover = GLASSESCOVERSEYES actions_types = list(/datum/action/item_action/toggle) up = 0 @@ -503,19 +502,16 @@ name = "industrial veil" icon_state = "tajblind_engi" item_state = "tajblind_engi" - species_restricted = list("Tajaran") /obj/item/clothing/glasses/tajblind/sci name = "hi-tech veil" icon_state = "tajblind_sci" item_state = "tajblind_sci" - species_restricted = list("Tajaran") /obj/item/clothing/glasses/tajblind/cargo name = "khaki veil" icon_state = "tajblind_cargo" item_state = "tajblind_cargo" - species_restricted = list("Tajaran") /obj/item/clothing/glasses/tajblind/attack_self() toggle_veil() diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index a6d85f1e9ae..8bc9efb0be1 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -172,7 +172,6 @@ icon_state = "tajblind_sec" item_state = "tajblind_sec" flash_protect = 1 - species_restricted = list("Tajaran") flags_cover = GLASSESCOVERSEYES actions_types = list(/datum/action/item_action/toggle) up = 0 From 1202954e092c1ff581fdf5be18f99462efc250ae Mon Sep 17 00:00:00 2001 From: Arvenius169 <56715097+Arvenius169@users.noreply.github.com> Date: Wed, 2 Jun 2021 17:31:05 -0400 Subject: [PATCH 22/48] Replaces all occurrences of the between() proc with the native clamp() proc --- code/game/machinery/computer/atmos_control.dm | 2 +- .../modules/admin/verbs/infiltratorteam_syndicate.dm | 2 +- .../components/binary_devices/dp_vent_pump.dm | 12 ++++++------ .../components/binary_devices/passive_gate.dm | 4 ++-- .../machinery/components/binary_devices/pump.dm | 4 ++-- .../components/binary_devices/volume_pump.dm | 4 ++-- .../components/unary_devices/outlet_injector.dm | 2 +- code/modules/power/port_gen.dm | 4 ++-- code/modules/surgery/organs/organ.dm | 4 ++-- 9 files changed, 19 insertions(+), 19 deletions(-) diff --git a/code/game/machinery/computer/atmos_control.dm b/code/game/machinery/computer/atmos_control.dm index db28dd16dc6..e514e493cb9 100644 --- a/code/game/machinery/computer/atmos_control.dm +++ b/code/game/machinery/computer/atmos_control.dm @@ -549,7 +549,7 @@ if(href_list["out_set_pressure"]) var/response=input(usr,"Set new pressure, in kPa. \[0-[50*ONE_ATMOSPHERE]\]") as num pressure_setting = text2num(response) - pressure_setting = between(0, pressure_setting, 50*ONE_ATMOSPHERE) + pressure_setting = clamp(pressure_setting, 0, 50*ONE_ATMOSPHERE) if(!radio_connection) return 0 diff --git a/code/modules/admin/verbs/infiltratorteam_syndicate.dm b/code/modules/admin/verbs/infiltratorteam_syndicate.dm index 1ed13ac8ed0..1199a8e5ea5 100644 --- a/code/modules/admin/verbs/infiltratorteam_syndicate.dm +++ b/code/modules/admin/verbs/infiltratorteam_syndicate.dm @@ -34,7 +34,7 @@ GLOBAL_VAR_INIT(sent_syndicate_infiltration_team, 0) return var/tctext = input(src, "How much TC do you want to give each team member? Suggested: 20-30. They cannot trade TC.") as num var/tcamount = text2num(tctext) - tcamount = between(0, tcamount, 1000) + tcamount = clamp(tcamount, 0, 1000) if(GLOB.sent_syndicate_infiltration_team == 1) if(alert("A Syndicate Infiltration Team has already been sent. Sure you want to send another?",,"Yes","No")=="No") return diff --git a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm index 0ff312806e9..7f2cae91027 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm @@ -206,23 +206,23 @@ pump_direction = 1 if(signal.data["set_input_pressure"] != null) - input_pressure_min = between( - 0, + input_pressure_min = clamp( text2num(signal.data["set_input_pressure"]), + 0, ONE_ATMOSPHERE*50 ) if(signal.data["set_output_pressure"] != null) - output_pressure_max = between( - 0, + output_pressure_max = clamp( text2num(signal.data["set_output_pressure"]), + 0, ONE_ATMOSPHERE*50 ) if(signal.data["set_external_pressure"] != null) - external_pressure_bound = between( - 0, + external_pressure_bound = clamp( text2num(signal.data["set_external_pressure"]), + 0, ONE_ATMOSPHERE*50 ) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm index 2c12b3fa6a6..d3c03b0fb1d 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm @@ -100,9 +100,9 @@ on = !on if("set_output_pressure" in signal.data) - target_pressure = between( - 0, + target_pressure = clamp( text2num(signal.data["set_output_pressure"]), + 0, ONE_ATMOSPHERE*50 ) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index fec536ad0c9..8b7d930b7d7 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -155,9 +155,9 @@ Thus, the two variables affect pump operation are set in New(): on = !on if(signal.data["set_output_pressure"]) - target_pressure = between( - 0, + target_pressure = clamp( text2num(signal.data["set_output_pressure"]), + 0, ONE_ATMOSPHERE*50 ) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm index 83d01cb20aa..05918fa1226 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -153,9 +153,9 @@ Thus, the two variables affect pump operation are set in New(): on = !on if(signal.data["set_transfer_rate"]) - transfer_rate = between( - 0, + transfer_rate = clamp( text2num(signal.data["set_transfer_rate"]), + 0, air1.volume ) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm index 11c032a522d..986b6727e64 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm @@ -135,7 +135,7 @@ if(signal.data["set_volume_rate"] != null) var/number = text2num(signal.data["set_volume_rate"]) - volume_rate = between(0, number, air_contents.volume) + volume_rate = clamp(number, 0, air_contents.volume) if(signal.data["status"]) broadcast_status() diff --git a/code/modules/power/port_gen.dm b/code/modules/power/port_gen.dm index 38df561727d..461a4580789 100644 --- a/code/modules/power/port_gen.dm +++ b/code/modules/power/port_gen.dm @@ -222,7 +222,7 @@ //or if it is already above upper_limit, limit the increase to 0. var/inc_limit = max(upper_limit - temperature, 0) var/dec_limit = min(temperature - lower_limit, 0) - temperature += between(dec_limit, rand(-7 + bias, 7 + bias), inc_limit) + temperature += clamp(rand(-7 + bias, 7 + bias), dec_limit, inc_limit) if(temperature > max_temperature) overheat() @@ -239,7 +239,7 @@ if(temperature > cooling_temperature) var/temp_loss = (temperature - cooling_temperature)/TEMPERATURE_DIVISOR - temp_loss = between(2, round(temp_loss, 1), TEMPERATURE_CHANGE_MAX) + temp_loss = clamp(round(temp_loss, 1), 2, TEMPERATURE_CHANGE_MAX) temperature = max(temperature - temp_loss, cooling_temperature) SStgui.update_uis(src) diff --git a/code/modules/surgery/organs/organ.dm b/code/modules/surgery/organs/organ.dm index f4916716efb..4d6979de069 100644 --- a/code/modules/surgery/organs/organ.dm +++ b/code/modules/surgery/organs/organ.dm @@ -164,7 +164,7 @@ if(germ_level >= INFECTION_LEVEL_ONE) var/fever_temperature = (owner.dna.species.heat_level_1 - owner.dna.species.body_temperature - 5) * min(germ_level / INFECTION_LEVEL_TWO, 1) + owner.dna.species.body_temperature - owner.bodytemperature += between(0, (fever_temperature - T20C) / BODYTEMP_COLD_DIVISOR + 1, fever_temperature - owner.bodytemperature) + owner.bodytemperature += clamp((fever_temperature - T20C) / BODYTEMP_COLD_DIVISOR + 1, 0, fever_temperature - owner.bodytemperature) if(germ_level >= INFECTION_LEVEL_TWO) var/obj/item/organ/external/parent = owner.get_organ(parent_organ) @@ -208,7 +208,7 @@ /obj/item/organ/proc/receive_damage(amount, silent = 0) if(tough) return - damage = between(0, damage + amount, max_damage) + damage = clamp(damage + amount, 0, max_damage) //only show this if the organ is not robotic if(owner && parent_organ && amount > 0) From b4466b4f7490e6841798c1239025bb17cba2f6f0 Mon Sep 17 00:00:00 2001 From: Arvenius169 <56715097+Arvenius169@users.noreply.github.com> Date: Wed, 2 Jun 2021 17:31:25 -0400 Subject: [PATCH 23/48] Removes the between() proc --- code/__HELPERS/unsorted.dm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 5f95d44efc4..349254fb29a 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -538,10 +538,6 @@ Returns 1 if the chain up to the area contains the given typepath var/y = min(world.maxy, max(1, A.y + dy)) return locate(x,y,A.z) -//Makes sure MIDDLE is between LOW and HIGH. If not, it adjusts it. Returns the adjusted value. -/proc/between(low, middle, high) - return max(min(middle, high), low) - //returns random gauss number /proc/GaussRand(sigma) var/x,y,rsq From 8a3a2cc25ff2ba55447789f6373fe384577733f9 Mon Sep 17 00:00:00 2001 From: Froststahr Date: Thu, 17 Jun 2021 06:46:24 -0500 Subject: [PATCH 24/48] https://www.youtube.com/watch?v=q93VsIb4Pzg --- .../sprite_accessories/sprite_accessories.dm | 32 ++++++++++++++++++ icons/mob/underwear.dmi | Bin 48851 -> 50440 bytes 2 files changed, 32 insertions(+) diff --git a/code/modules/mob/new_player/sprite_accessories/sprite_accessories.dm b/code/modules/mob/new_player/sprite_accessories/sprite_accessories.dm index 44fa9cfbd3b..6e618dba0d0 100644 --- a/code/modules/mob/new_player/sprite_accessories/sprite_accessories.dm +++ b/code/modules/mob/new_player/sprite_accessories/sprite_accessories.dm @@ -616,3 +616,35 @@ /datum/sprite_accessory/socks/black_fishnet name = "Black Fishnet" icon_state = "black_fishnet" + +/datum/sprite_accessory/socks/stockings_lpink + name = "Stockings (Programmer)" + icon_state = "stockings_lpink" + +/datum/sprite_accessory/socks/stockings_purple + name = "Stockings (Purple)" + icon_state = "stockings_purple" + +/datum/sprite_accessory/socks/stockings_green + name = "Stockings (Green)" + icon_state = "stockings_green" + +/datum/sprite_accessory/socks/stockings_cyan + name = "Stockings (Cyan)" + icon_state = "stockings_cyan" + +/datum/sprite_accessory/socks/stockings_orange + name = "Stockings (Orange)" + icon_state = "stockings_orange" + +/datum/sprite_accessory/socks/stockings_yellow + name = "Stockings (Yellow)" + icon_state = "stockings_yellow" + +/datum/sprite_accessory/socks/stockings_dpink + name = "Stockings (Dark Pink)" + icon_state = "stockings_dpink" + +/datum/sprite_accessory/socks/stockings_blue + name = "Stockings (Blue)" + icon_state = "stockings_blue" diff --git a/icons/mob/underwear.dmi b/icons/mob/underwear.dmi index ab1879132dedd6041e9f7b7e8343166d27967a93..2a4e63a035c17baabb5c15fe6b7866b786110abc 100644 GIT binary patch literal 50440 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 literal 48851 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≠4JC}DsKb|`7aU6C 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 Date: Thu, 17 Jun 2021 08:08:18 -0500 Subject: [PATCH 25/48] revisionism --- icons/mob/underwear.dmi | Bin 50440 -> 50419 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/icons/mob/underwear.dmi b/icons/mob/underwear.dmi index 2a4e63a035c17baabb5c15fe6b7866b786110abc..a7027e86232146058dcf3fa240c5eee54aabc69a 100644 GIT binary patch delta 45283 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 delta 45476 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 Date: Mon, 5 Jul 2021 00:26:12 +0200 Subject: [PATCH 26/48] blur thy screen take two --- code/__DEFINES/misc.dm | 3 --- code/_onclick/hud/fullscreen.dm | 5 ----- code/_onclick/hud/plane_master.dm | 17 ++++++++++++++++- code/game/atoms.dm | 2 +- code/modules/mob/living/update_status.dm | 9 +++++++-- 5 files changed, 24 insertions(+), 12 deletions(-) diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index ad182c9f9c4..32c4f44cdee 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -432,9 +432,6 @@ /// Prepares a text to be used for maptext. Use this so it doesn't look hideous. #define MAPTEXT(text) {"[##text]"} -// Filters -#define FILTER_AMBIENT_OCCLUSION filter(type="drop_shadow", x=0, y=-2, size=4, color="#04080FAA") - //Fullscreen overlay resolution in tiles. #define FULLSCREEN_OVERLAY_RESOLUTION_X 15 #define FULLSCREEN_OVERLAY_RESOLUTION_Y 15 diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm index 9d00f216eac..f6c8880a485 100644 --- a/code/_onclick/hud/fullscreen.dm +++ b/code/_onclick/hud/fullscreen.dm @@ -99,11 +99,6 @@ /obj/screen/fullscreen/impaired icon_state = "impairedoverlay" -/obj/screen/fullscreen/blurry - icon = 'icons/mob/screen_gen.dmi' - screen_loc = "WEST,SOUTH to EAST,NORTH" - icon_state = "blurry" - /obj/screen/fullscreen/flash icon = 'icons/mob/screen_gen.dmi' screen_loc = "WEST,SOUTH to EAST,NORTH" diff --git a/code/_onclick/hud/plane_master.dm b/code/_onclick/hud/plane_master.dm index d49722e79ee..ec8e67bc08e 100644 --- a/code/_onclick/hud/plane_master.dm +++ b/code/_onclick/hud/plane_master.dm @@ -1,3 +1,7 @@ +#define BLUR_FILTER_NAME "blur" +#define AMBIENT_OCCLUSION_FILTER_NAME "ambient_occlusion" +#define BLUR_ANIMATION_TIME 5 + /obj/screen/plane_master screen_loc = "CENTER" icon_state = "blank" @@ -16,6 +20,17 @@ //Trust me, you need one. Period. If you don't think you do, you're doing something extremely wrong. /obj/screen/plane_master/proc/backdrop(mob/mymob) +/obj/screen/plane_master/proc/add_blur() + add_filter(BLUR_FILTER_NAME, 7, gauss_blur_filter(0)) + transition_filter(BLUR_FILTER_NAME, BLUR_ANIMATION_TIME, list("size" = 1)) + +/obj/screen/plane_master/proc/animate_remove_blur() + transition_filter(BLUR_FILTER_NAME, BLUR_ANIMATION_TIME, list("size" = 0)) + addtimer(CALLBACK(src, .proc/remove_blur), BLUR_ANIMATION_TIME) + +/obj/screen/plane_master/proc/remove_blur() + remove_filter(BLUR_FILTER_NAME) + /obj/screen/plane_master/floor name = "floor plane master" plane = FLOOR_PLANE @@ -31,7 +46,7 @@ /obj/screen/plane_master/game_world/backdrop(mob/mymob) clear_filters() if(istype(mymob) && mymob.client && mymob.client.prefs && (mymob.client.prefs.toggles & PREFTOGGLE_AMBIENT_OCCLUSION)) - add_filter("AO", 1, drop_shadow_filter(x = 0, y = -2, size = 4, color = "#04080FAA")) + add_filter(AMBIENT_OCCLUSION_FILTER_NAME, 1, drop_shadow_filter(x = 0, y = -2, size = 4, color = "#04080FAA")) /obj/screen/plane_master/lighting name = "lighting plane master" diff --git a/code/game/atoms.dm b/code/game/atoms.dm index fc5e1d8eb5f..d7223c1209d 100644 --- a/code/game/atoms.dm +++ b/code/game/atoms.dm @@ -460,7 +460,7 @@ filters += filter(arglist(arguments)) UNSETEMPTY(filter_data) -/atom/proc/transition_filter(name, time, list/new_params, easing, loop) +/atom/proc/transition_filter(name, time, list/new_params, easing = LINEAR_EASING, loop = 1) var/filter = get_filter(name) if(!filter) return diff --git a/code/modules/mob/living/update_status.dm b/code/modules/mob/living/update_status.dm index b942b0cabe7..eec2cfb5d76 100644 --- a/code/modules/mob/living/update_status.dm +++ b/code/modules/mob/living/update_status.dm @@ -9,11 +9,16 @@ return 0 /mob/living/update_blurry_effects() + var/obj/screen/plane_master/game_world/GW = locate(/obj/screen/plane_master/game_world) in client.screen + var/obj/screen/plane_master/floor/F = locate(/obj/screen/plane_master/floor) in client.screen + if(eyes_blurred()) - overlay_fullscreen("blurry", /obj/screen/fullscreen/blurry) + GW.add_blur() + F.add_blur() return 1 else - clear_fullscreen("blurry") + GW.animate_remove_blur() + F.animate_remove_blur() return 0 /mob/living/update_druggy_effects() From 116c4e70045d7cabe70fad86c65b7e3c7a2508d8 Mon Sep 17 00:00:00 2001 From: theo-3 <85434590+theo-3@users.noreply.github.com> Date: Tue, 6 Jul 2021 03:48:27 +0300 Subject: [PATCH 27/48] Make cryo start with auto eject --- .../atmospherics/machinery/components/unary_devices/cryo.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index 01d18336b5c..156a92ce37d 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -18,7 +18,7 @@ var/mob/living/carbon/occupant = null var/obj/item/reagent_containers/glass/beaker = null /// Holds two bitflags, AUTO_EJECT_DEAD and AUTO_EJECT_HEALTHY. Used to determine if the cryo cell will auto-eject dead and/or completely health patients. - var/auto_eject_prefs = NONE + var/auto_eject_prefs = AUTO_EJECT_HEALTHY | AUTO_EJECT_DEAD var/next_trans = 0 var/current_heat_capacity = 50 From 4b22d5b2dcdf46423ec68aeb52011393e924feb7 Mon Sep 17 00:00:00 2001 From: S34N <12197162+S34NW@users.noreply.github.com> Date: Sat, 10 Jul 2021 14:11:21 +0100 Subject: [PATCH 28/48] Update code/modules/security_levels/security_levels.dm Co-authored-by: SabreML <57483089+SabreML@users.noreply.github.com> --- code/modules/security_levels/security_levels.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/security_levels/security_levels.dm b/code/modules/security_levels/security_levels.dm index 24deabde6a1..bc47267a98c 100644 --- a/code/modules/security_levels/security_levels.dm +++ b/code/modules/security_levels/security_levels.dm @@ -77,7 +77,7 @@ GLOBAL_DATUM_INIT(security_announcement_down, /datum/announcement/priority/secur FA.overlays += image('icons/obj/monitors.dmi', "overlay_red") if(SEC_LEVEL_GAMMA) - GLOB.security_announcement_up.Announce("Central Command has ordered the Gamma security level on the station. Security is to have weapons equipped at all times, and all civilians are to immediately seek their nearest head for transportation to a secure location.","Attention! Gamma security level activated!", new_sound = sound('sound/effects/new_siren.ogg')) + GLOB.security_announcement_up.Announce("Central Command has ordered the Gamma security level on the station. Security is to have weapons equipped at all times, and all civilians are to immediately seek their nearest head for transportation to a secure location.", "Attention! Gamma security level activated!", sound('sound/effects/new_siren.ogg')) GLOB.security_level = SEC_LEVEL_GAMMA if(GLOB.security_level < SEC_LEVEL_RED) From 4109628e05470e2541400f83dec3e6806302ae20 Mon Sep 17 00:00:00 2001 From: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com> Date: Sun, 11 Jul 2021 11:51:25 -0400 Subject: [PATCH 29/48] Makes goats female. --- code/modules/mob/living/simple_animal/friendly/farm_animals.dm | 1 + 1 file changed, 1 insertion(+) 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 245dcf26f70..c99545e7ed6 100644 --- a/code/modules/mob/living/simple_animal/friendly/farm_animals.dm +++ b/code/modules/mob/living/simple_animal/friendly/farm_animals.dm @@ -29,6 +29,7 @@ can_collar = 1 blood_volume = BLOOD_VOLUME_NORMAL var/obj/item/udder/udder = null + gender = FEMALE footstep_type = FOOTSTEP_MOB_SHOE /mob/living/simple_animal/hostile/retaliate/goat/New() From e4f4dc51d4a8a2b1171abc48a15f4aacb231f608 Mon Sep 17 00:00:00 2001 From: theo-3 <85434590+theo-3@users.noreply.github.com> Date: Mon, 12 Jul 2021 19:07:33 +0300 Subject: [PATCH 30/48] Fix typo --- .../atmospherics/machinery/components/unary_devices/cryo.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index 156a92ce37d..5acb9f9cc73 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -17,7 +17,7 @@ var/temperature_archived var/mob/living/carbon/occupant = null var/obj/item/reagent_containers/glass/beaker = null - /// Holds two bitflags, AUTO_EJECT_DEAD and AUTO_EJECT_HEALTHY. Used to determine if the cryo cell will auto-eject dead and/or completely health patients. + /// Holds two bitflags, AUTO_EJECT_DEAD and AUTO_EJECT_HEALTHY. Used to determine if the cryo cell will auto-eject dead and/or completely healthy patients. var/auto_eject_prefs = AUTO_EJECT_HEALTHY | AUTO_EJECT_DEAD var/next_trans = 0 From 8f24160317e0691869a84c137b3bcae5b947ab80 Mon Sep 17 00:00:00 2001 From: Mieszko Jedrzejczak Date: Tue, 13 Jul 2021 17:48:58 +0200 Subject: [PATCH 31/48] revert initial eyeblur, add tg's plane master controllers --- code/__DEFINES/layers.dm | 3 + code/__DEFINES/mobs.dm | 3 + code/_onclick/hud/hud.dm | 7 ++ code/_onclick/hud/plane_master.dm | 17 +--- code/_onclick/hud/plane_master_controller.dm | 77 +++++++++++++++++++ code/modules/mob/living/status_procs.dm | 5 +- code/modules/mob/living/update_status.dm | 14 +--- .../reagents/chemistry/reagents/drugs.dm | 14 ++-- paradise.dme | 1 + 9 files changed, 106 insertions(+), 35 deletions(-) create mode 100644 code/_onclick/hud/plane_master_controller.dm diff --git a/code/__DEFINES/layers.dm b/code/__DEFINES/layers.dm index 9286ea2726d..a633ddab5eb 100644 --- a/code/__DEFINES/layers.dm +++ b/code/__DEFINES/layers.dm @@ -117,3 +117,6 @@ #define SPLASHSCREEN_LAYER 23 #define SPLASHSCREEN_PLANE 23 + +///Plane master controller keys +#define PLANE_MASTERS_GAME "plane_masters_game" diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index a023063ca7f..1978f1e9e34 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -282,3 +282,6 @@ #define FLASH_PROTECTION_NONE 0 #define FLASH_PROTECTION_FLASH 1 #define FLASH_PROTECTION_WELDER 2 + +#define MAX_EYE_BLURRY_FILTER_SIZE 2 +#define EYE_BLUR_TO_FILTER_SIZE_MULTIPLIER 0.1 diff --git a/code/_onclick/hud/hud.dm b/code/_onclick/hud/hud.dm index 0cfb6985b8e..9779e306939 100644 --- a/code/_onclick/hud/hud.dm +++ b/code/_onclick/hud/hud.dm @@ -37,6 +37,8 @@ var/action_buttons_hidden = FALSE var/list/obj/screen/plane_master/plane_masters = list() // see "appearance_flags" in the ref, assoc list of "[plane]" = object + ///Assoc list of controller groups, associated with key string group name with value of the plane master controller ref + var/list/atom/movable/plane_master_controller/plane_master_controllers = list() /mob/proc/create_mob_hud() if(client && !hud_used) @@ -53,6 +55,10 @@ plane_masters["[instance.plane]"] = instance instance.backdrop(mymob) + for(var/mytype in subtypesof(/atom/movable/plane_master_controller)) + var/atom/movable/plane_master_controller/controller_instance = new mytype(src) + plane_master_controllers[controller_instance.name] = controller_instance + /datum/hud/Destroy() if(mymob.hud_used == src) mymob.hud_used = null @@ -89,6 +95,7 @@ nightvisionicon = null QDEL_LIST_ASSOC_VAL(plane_masters) + QDEL_LIST_ASSOC_VAL(plane_master_controllers) mymob = null return ..() diff --git a/code/_onclick/hud/plane_master.dm b/code/_onclick/hud/plane_master.dm index ec8e67bc08e..d49722e79ee 100644 --- a/code/_onclick/hud/plane_master.dm +++ b/code/_onclick/hud/plane_master.dm @@ -1,7 +1,3 @@ -#define BLUR_FILTER_NAME "blur" -#define AMBIENT_OCCLUSION_FILTER_NAME "ambient_occlusion" -#define BLUR_ANIMATION_TIME 5 - /obj/screen/plane_master screen_loc = "CENTER" icon_state = "blank" @@ -20,17 +16,6 @@ //Trust me, you need one. Period. If you don't think you do, you're doing something extremely wrong. /obj/screen/plane_master/proc/backdrop(mob/mymob) -/obj/screen/plane_master/proc/add_blur() - add_filter(BLUR_FILTER_NAME, 7, gauss_blur_filter(0)) - transition_filter(BLUR_FILTER_NAME, BLUR_ANIMATION_TIME, list("size" = 1)) - -/obj/screen/plane_master/proc/animate_remove_blur() - transition_filter(BLUR_FILTER_NAME, BLUR_ANIMATION_TIME, list("size" = 0)) - addtimer(CALLBACK(src, .proc/remove_blur), BLUR_ANIMATION_TIME) - -/obj/screen/plane_master/proc/remove_blur() - remove_filter(BLUR_FILTER_NAME) - /obj/screen/plane_master/floor name = "floor plane master" plane = FLOOR_PLANE @@ -46,7 +31,7 @@ /obj/screen/plane_master/game_world/backdrop(mob/mymob) clear_filters() if(istype(mymob) && mymob.client && mymob.client.prefs && (mymob.client.prefs.toggles & PREFTOGGLE_AMBIENT_OCCLUSION)) - add_filter(AMBIENT_OCCLUSION_FILTER_NAME, 1, drop_shadow_filter(x = 0, y = -2, size = 4, color = "#04080FAA")) + add_filter("AO", 1, drop_shadow_filter(x = 0, y = -2, size = 4, color = "#04080FAA")) /obj/screen/plane_master/lighting name = "lighting plane master" diff --git a/code/_onclick/hud/plane_master_controller.dm b/code/_onclick/hud/plane_master_controller.dm new file mode 100644 index 00000000000..b525dfc0ef3 --- /dev/null +++ b/code/_onclick/hud/plane_master_controller.dm @@ -0,0 +1,77 @@ +///Atom that manages and controls multiple planes. It's an atom so we can hook into add_filter etc. Multiple controllers can control one plane. +/atom/movable/plane_master_controller + ///List of planes in this controllers control. Initially this is a normal list, but becomes an assoc list of plane numbers as strings | plane instance + var/list/controlled_planes = list() + ///hud that owns this controller + var/datum/hud/owner_hud + +///Ensures that all the planes are correctly in the controlled_planes list. +/atom/movable/plane_master_controller/New(hud) + . = ..() + owner_hud = hud + var/assoc_controlled_planes = list() + for(var/i in controlled_planes) + var/obj/screen/plane_master/instance = owner_hud.plane_masters["[i]"] + assoc_controlled_planes["[i]"] = instance + controlled_planes = assoc_controlled_planes + +///Full override so we can just use filterrific +/atom/movable/plane_master_controller/add_filter(name, priority, list/params) + . = ..() + for(var/i in controlled_planes) + var/obj/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.add_filter(name, priority, params) + +///Full override so we can just use filterrific +/atom/movable/plane_master_controller/remove_filter(name_or_names) + . = ..() + for(var/i in controlled_planes) + var/obj/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.remove_filter(name_or_names) + +/atom/movable/plane_master_controller/update_filters() + . = ..() + for(var/i in controlled_planes) + var/obj/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.update_filters() + +///Gets all filters for this controllers plane masters +/atom/movable/plane_master_controller/proc/get_filters(name) + . = list() + for(var/i in controlled_planes) + var/obj/screen/plane_master/pm_iterator = controlled_planes[i] + . += pm_iterator.get_filter(name) + +///Transitions all filters owned by this plane master controller +/atom/movable/plane_master_controller/transition_filter(name, time, list/new_params, easing, loop) + . = ..() + for(var/i in controlled_planes) + var/obj/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.transition_filter(name, time, new_params, easing, loop) + +///Full override so we can just use filterrific +/atom/movable/plane_master_controller/add_atom_colour(coloration, colour_priority) + . = ..() + for(var/i in controlled_planes) + var/obj/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.add_atom_colour(coloration, colour_priority) + + +///Removes an instance of colour_type from the atom's atom_colours list +/atom/movable/plane_master_controller/remove_atom_colour(colour_priority, coloration) + . = ..() + for(var/i in controlled_planes) + var/obj/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.remove_atom_colour(colour_priority, coloration) + + +///Resets the atom's color to null, and then sets it to the highest priority colour available +/atom/movable/plane_master_controller/update_atom_colour() + for(var/i in controlled_planes) + var/obj/screen/plane_master/pm_iterator = controlled_planes[i] + pm_iterator.update_atom_colour() + + +/atom/movable/plane_master_controller/game + name = PLANE_MASTERS_GAME + controlled_planes = list(FLOOR_PLANE, GAME_PLANE, LIGHTING_PLANE) diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index fceffecbffc..fab75c91507 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -211,11 +211,12 @@ /mob/living/SetEyeBlurry(amount, updating = TRUE) . = STATUS_UPDATE_BLURRY - if((!!amount) == (!!eye_blurry)) // We're not changing from + to 0 or vice versa + //if they're both above max or equal that means we won't change the blur filter + if(amount > MAX_EYE_BLURRY_FILTER_SIZE / EYE_BLUR_TO_FILTER_SIZE_MULTIPLIER && eye_blurry > MAX_EYE_BLURRY_FILTER_SIZE / EYE_BLUR_TO_FILTER_SIZE_MULTIPLIER || eye_blurry == amount) updating = FALSE . = STATUS_UPDATE_NONE + eye_blurry = max(amount, 0) - // We transitioned to/from 0, so update the eye blur overlays if(updating) update_blurry_effects() diff --git a/code/modules/mob/living/update_status.dm b/code/modules/mob/living/update_status.dm index eec2cfb5d76..73231403d9a 100644 --- a/code/modules/mob/living/update_status.dm +++ b/code/modules/mob/living/update_status.dm @@ -9,17 +9,11 @@ return 0 /mob/living/update_blurry_effects() - var/obj/screen/plane_master/game_world/GW = locate(/obj/screen/plane_master/game_world) in client.screen - var/obj/screen/plane_master/floor/F = locate(/obj/screen/plane_master/floor) in client.screen - - if(eyes_blurred()) - GW.add_blur() - F.add_blur() - return 1 + var/atom/movable/plane_master_controller/game_plane_master_controller = hud_used.plane_master_controllers[PLANE_MASTERS_GAME] + if(eye_blurry) + game_plane_master_controller.add_filter("eye_blur", 1, gauss_blur_filter(clamp(eye_blurry * EYE_BLUR_TO_FILTER_SIZE_MULTIPLIER, 0.6, MAX_EYE_BLURRY_FILTER_SIZE))) else - GW.animate_remove_blur() - F.animate_remove_blur() - return 0 + game_plane_master_controller.remove_filter("eye_blur") /mob/living/update_druggy_effects() if(druggy) diff --git a/code/modules/reagents/chemistry/reagents/drugs.dm b/code/modules/reagents/chemistry/reagents/drugs.dm index 201071745a8..89362dc9166 100644 --- a/code/modules/reagents/chemistry/reagents/drugs.dm +++ b/code/modules/reagents/chemistry/reagents/drugs.dm @@ -640,18 +640,18 @@ /datum/reagent/rotatium/on_mob_life(mob/living/carbon/M) if(M.hud_used) if(current_cycle >= 20 && current_cycle % 20 == 0) - var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"]) + var/atom/movable/plane_master_controller/pm_controller = M.hud_used.plane_master_controllers[PLANE_MASTERS_GAME] var/rotation = min(round(current_cycle / 20), 89) // By this point the player is probably puking and quitting anyway - for(var/whole_screen in screens) - animate(whole_screen, transform = matrix(rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING, loop = -1) + for(var/key in pm_controller.controlled_planes) + animate(pm_controller.controlled_planes[key], transform = matrix(rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING, loop = -1) animate(transform = matrix(-rotation, MATRIX_ROTATE), time = 5, easing = QUAD_EASING) return ..() /datum/reagent/rotatium/on_mob_delete(mob/living/M) - if(M && M.hud_used) - var/list/screens = list(M.hud_used.plane_masters["[FLOOR_PLANE]"], M.hud_used.plane_masters["[GAME_PLANE]"], M.hud_used.plane_masters["[LIGHTING_PLANE]"]) - for(var/whole_screen in screens) - animate(whole_screen, transform = matrix(), time = 5, easing = QUAD_EASING) + if(M?.hud_used) + var/atom/movable/plane_master_controller/pm_controller = M.hud_used.plane_master_controllers[PLANE_MASTERS_GAME] + for(var/key in pm_controller.controlled_planes) + animate(pm_controller.controlled_planes[key], transform = matrix(), time = 5, easing = QUAD_EASING) ..() ////////////////////////////// diff --git a/paradise.dme b/paradise.dme index a6b2a53c467..02507d1b917 100644 --- a/paradise.dme +++ b/paradise.dme @@ -173,6 +173,7 @@ #include "code\_onclick\hud\parallax.dm" #include "code\_onclick\hud\picture_in_picture.dm" #include "code\_onclick\hud\plane_master.dm" +#include "code\_onclick\hud\plane_master_controller.dm" #include "code\_onclick\hud\radial.dm" #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" From e81cfee52a2856f626652a37ea837931eb27eccb Mon Sep 17 00:00:00 2001 From: Edan52 <29551695+Edan52@users.noreply.github.com> Date: Wed, 14 Jul 2021 01:00:27 +0100 Subject: [PATCH 32/48] gc tweaks --- code/modules/mining/minebot.dm | 4 ++++ .../simple_animal/hostile/terror_spiders/terror_spiders.dm | 2 ++ code/modules/mob/living/simple_animal/simple_animal.dm | 1 + code/modules/mob/mob.dm | 1 + 4 files changed, 8 insertions(+) diff --git a/code/modules/mining/minebot.dm b/code/modules/mining/minebot.dm index 889f2012d1e..0f11bd0e665 100644 --- a/code/modules/mining/minebot.dm +++ b/code/modules/mining/minebot.dm @@ -59,6 +59,10 @@ SetCollectBehavior() +/mob/living/simple_animal/hostile/mining_drone/Destroy() + QDEL_NULL(stored_gun) + return ..() + /mob/living/simple_animal/hostile/mining_drone/emp_act(severity) adjustHealth(100 / severity) to_chat(src, "NOTICE: EMP detected, systems damaged!") diff --git a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm index eed323d9ebe..d910903c009 100644 --- a/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm +++ b/code/modules/mob/living/simple_animal/hostile/terror_spiders/terror_spiders.dm @@ -312,6 +312,8 @@ GLOBAL_LIST_EMPTY(ts_spiderling_list) /mob/living/simple_animal/hostile/poison/terror_spider/Destroy() GLOB.ts_spiderlist -= src + var/datum/atom_hud/U = GLOB.huds[DATA_HUD_MEDICAL_ADVANCED] + U.remove_hud_from(src) handle_dying() return ..() diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 7a34f746728..356cca68b25 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -140,6 +140,7 @@ if (T && AIStatus == AI_Z_OFF) SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src + QDEL_LIST(actions) return ..() /mob/living/simple_animal/handle_atom_del(atom/A) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 9d4a22b73cc..87c133b89b3 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -20,6 +20,7 @@ AA.viewers -= src viewing_alternate_appearances = null LAssailant = null + runechat_msg_location = null return ..() /mob/Initialize(mapload) From 5d22adde6d5de9eb916c64e9147446af37be845c Mon Sep 17 00:00:00 2001 From: Edan52 <29551695+Edan52@users.noreply.github.com> Date: Wed, 14 Jul 2021 13:46:59 +0100 Subject: [PATCH 33/48] moves actions qdel to mob level --- code/modules/mob/living/simple_animal/simple_animal.dm | 1 - code/modules/mob/mob.dm | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 356cca68b25..7a34f746728 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -140,7 +140,6 @@ if (T && AIStatus == AI_Z_OFF) SSidlenpcpool.idle_mobs_by_zlevel[T.z] -= src - QDEL_LIST(actions) return ..() /mob/living/simple_animal/handle_atom_del(atom/A) diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 87c133b89b3..06c05739d22 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -8,6 +8,7 @@ spellremove(src) mobspellremove(src) QDEL_LIST(viruses) + QDEL_LIST(actions) ghostize() QDEL_LIST_ASSOC_VAL(tkgrabbed_objects) for(var/I in tkgrabbed_objects) From 216e80303b414f48783f713f18b41bcfc3901678 Mon Sep 17 00:00:00 2001 From: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com> Date: Sun, 18 Jul 2021 10:37:13 -0400 Subject: [PATCH 34/48] Lets revivers potentially heal you out of shock --- code/modules/surgery/organs/augments_internal.dm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/code/modules/surgery/organs/augments_internal.dm b/code/modules/surgery/organs/augments_internal.dm index 319f044f449..00abe28ff71 100644 --- a/code/modules/surgery/organs/augments_internal.dm +++ b/code/modules/surgery/organs/augments_internal.dm @@ -336,7 +336,7 @@ /obj/item/organ/internal/cyberimp/chest/reviver name = "Reviver implant" - desc = "This implant will attempt to revive you if you lose consciousness. For the faint of heart!" + desc = "This implant will attempt to heal you out of critical condition. For the faint of heart!" icon_state = "chest_implant" implant_color = "#AD0000" origin_tech = "materials=5;programming=4;biotech=4" @@ -361,6 +361,11 @@ addtimer(CALLBACK(src, .proc/heal), 30) else reviving = FALSE + if(owner.HasDisease(new /datum/disease/critical/shock(0)) && prob(15)) //If they are no longer in crit, but have shock, and pass a 15% chance: + for(var/datum/disease/critical/shock/S in owner.viruses) + S.cure() + revive_cost += 150 + to_chat(owner, "You feel better.") return cooldown = revive_cost + world.time revive_cost = 0 From f9d00d8df3cef70e7e7f21812c9e55dfa39b1a16 Mon Sep 17 00:00:00 2001 From: Qwertytoforty <52090703+Qwertytoforty@users.noreply.github.com> Date: Mon, 19 Jul 2021 11:19:12 -0400 Subject: [PATCH 35/48] Better equips med ERT for the basics --- code/modules/response_team/ert_outfits.dm | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/code/modules/response_team/ert_outfits.dm b/code/modules/response_team/ert_outfits.dm index 8c3fbda5e57..b4c333ee5d7 100644 --- a/code/modules/response_team/ert_outfits.dm +++ b/code/modules/response_team/ert_outfits.dm @@ -321,12 +321,11 @@ /obj/item/clothing/head/helmet/ert/medical = 1, /obj/item/clothing/mask/surgical = 1, /obj/item/storage/firstaid/adv = 1, - /obj/item/storage/firstaid/regular = 1, + /obj/item/storage/firstaid/doctor = 1, /obj/item/storage/box/autoinjectors = 1, /obj/item/roller = 1, /obj/item/storage/pill_bottle/ert = 1, /obj/item/flashlight = 1, - /obj/item/healthupgrade = 1, /obj/item/handheld_defibrillator = 1 ) @@ -349,13 +348,12 @@ backpack_contents = list( /obj/item/clothing/mask/surgical = 1, /obj/item/storage/firstaid/toxin = 1, - /obj/item/storage/firstaid/brute = 1, - /obj/item/storage/firstaid/fire = 1, + /obj/item/storage/firstaid/doctor = 1, + /obj/item/storage/firstaid/adv = 1, /obj/item/storage/box/autoinjectors = 1, /obj/item/roller = 1, /obj/item/clothing/shoes/magboots = 1, /obj/item/bodyanalyzer = 1, - /obj/item/healthupgrade = 1, /obj/item/handheld_defibrillator = 1 ) @@ -378,9 +376,10 @@ backpack_contents = list( /obj/item/bodyanalyzer/advanced = 1, + /obj/item/storage/firstaid/doctor = 1, + /obj/item/storage/firstaid/adv = 1, /obj/item/extinguisher/mini = 1, /obj/item/roller = 1, - /obj/item/healthanalyzer/advanced = 1, /obj/item/handheld_defibrillator = 1 ) From 6b6b9a68da7e6128fdf99247996e93a3ea3c9637 Mon Sep 17 00:00:00 2001 From: Sirryan2002 <80364400+Sirryan2002@users.noreply.github.com> Date: Mon, 19 Jul 2021 16:28:31 -0400 Subject: [PATCH 36/48] Jani ERT Equipment Tweak --- code/game/objects/items/weapons/storage/belt.dm | 1 - code/modules/response_team/ert_outfits.dm | 15 ++++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/code/game/objects/items/weapons/storage/belt.dm b/code/game/objects/items/weapons/storage/belt.dm index 870ebe470cd..9fb4684f3ff 100644 --- a/code/game/objects/items/weapons/storage/belt.dm +++ b/code/game/objects/items/weapons/storage/belt.dm @@ -409,7 +409,6 @@ new /obj/item/soap(src) new /obj/item/grenade/chem_grenade/cleaner(src) new /obj/item/grenade/chem_grenade/cleaner(src) - new /obj/item/melee/flyswatter(src) update_icon() /obj/item/storage/belt/lazarus diff --git a/code/modules/response_team/ert_outfits.dm b/code/modules/response_team/ert_outfits.dm index 8c3fbda5e57..bf18ffac91c 100644 --- a/code/modules/response_team/ert_outfits.dm +++ b/code/modules/response_team/ert_outfits.dm @@ -483,16 +483,15 @@ /obj/item/reagent_containers/spray/cleaner = 1, /obj/item/storage/bag/trash = 1, /obj/item/storage/box/lights/mixed = 1, - /obj/item/holosign_creator = 1, - /obj/item/flashlight = 1) + /obj/item/melee/flyswatter = 1) /datum/outfit/job/centcom/response_team/janitorial/amber name = "RT Janitor (Amber)" suit = /obj/item/clothing/suit/armor/vest/ert/janitor head = /obj/item/clothing/head/helmet/ert/janitor glasses = /obj/item/clothing/glasses/sunglasses - - r_hand = /obj/item/gun/energy/disabler + r_pocket = /obj/item/flashlight + suit_store = /obj/item/gun/energy/disabler cybernetic_implants = list( /obj/item/organ/internal/cyberimp/arm/advmop) @@ -503,7 +502,7 @@ glasses = /obj/item/clothing/glasses/hud/security/sunglasses r_pocket = /obj/item/scythe/tele - l_pocket = /obj/item/gun/energy/gun/mini + suit_store = /obj/item/gun/energy/gun/mini cybernetic_implants = list( /obj/item/organ/internal/cyberimp/arm/janitorial, @@ -515,18 +514,20 @@ suit = /obj/item/clothing/suit/space/hardsuit/ert/janitor/gamma glasses = /obj/item/clothing/glasses/hud/security/sunglasses suit_store = /obj/item/gun/energy/gun - l_pocket = /obj/item/grenade/clusterbuster/cleaner r_pocket = /obj/item/scythe/tele shoes = /obj/item/clothing/shoes/magboots/advance backpack_contents = list( /obj/item/grenade/chem_grenade/antiweed = 2, + /obj/item/grenade/clusterbuster/cleaner = 1, /obj/item/storage/box/lights/mixed = 1, /obj/item/storage/bag/trash/bluespace = 1, - /obj/item/reagent_containers/spray/cleaner = 1 + /obj/item/reagent_containers/spray/cleaner = 1, + /obj/item/melee/flyswatter = 1 ) cybernetic_implants = list( + /obj/item/organ/internal/cyberimp/chest/nutriment/plus, /obj/item/organ/internal/cyberimp/arm/advmop, /obj/item/organ/internal/cyberimp/brain/anti_stun/hardened ) From 850ce3f12cc1d3614de3572e1a6513ca1f7c625d Mon Sep 17 00:00:00 2001 From: Sirryan2002 <80364400+Sirryan2002@users.noreply.github.com> Date: Tue, 20 Jul 2021 14:36:15 -0400 Subject: [PATCH 37/48] adds nv to jani gamma --- code/modules/response_team/ert_outfits.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/response_team/ert_outfits.dm b/code/modules/response_team/ert_outfits.dm index bf18ffac91c..e2fec68cc6d 100644 --- a/code/modules/response_team/ert_outfits.dm +++ b/code/modules/response_team/ert_outfits.dm @@ -512,7 +512,7 @@ /datum/outfit/job/centcom/response_team/janitorial/gamma name = "RT Janitor (Gamma)" suit = /obj/item/clothing/suit/space/hardsuit/ert/janitor/gamma - glasses = /obj/item/clothing/glasses/hud/security/sunglasses + glasses = /obj/item/clothing/glasses/night suit_store = /obj/item/gun/energy/gun r_pocket = /obj/item/scythe/tele shoes = /obj/item/clothing/shoes/magboots/advance From ca5bedcbdd5653203dacb35cd7ac39706a764582 Mon Sep 17 00:00:00 2001 From: PacifistDalek <32213277+PacifistDalek@users.noreply.github.com> Date: Wed, 21 Jul 2021 21:09:23 -0400 Subject: [PATCH 38/48] Update vending.dm --- code/game/machinery/vending.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/game/machinery/vending.dm b/code/game/machinery/vending.dm index 375cb4b8628..babae081e9d 100644 --- a/code/game/machinery/vending.dm +++ b/code/game/machinery/vending.dm @@ -1177,7 +1177,7 @@ /obj/item/stack/medical/splint = 4, /obj/item/reagent_containers/glass/beaker = 4, /obj/item/reagent_containers/dropper = 4, /obj/item/healthanalyzer = 4, /obj/item/healthupgrade = 4, /obj/item/reagent_containers/hypospray/safety = 2, /obj/item/sensor_device = 2, /obj/item/pinpointer/crew = 2) contraband = list(/obj/item/reagent_containers/glass/bottle/sulfonal = 1, /obj/item/reagent_containers/glass/bottle/pancuronium = 1) - armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) + armor = list(melee = 50, bullet = 20, laser = 20, energy = 20, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 70) resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/medical @@ -1203,7 +1203,7 @@ density = FALSE //It is wall-mounted, and thus, not dense. --Superxpdude products = list(/obj/item/stack/medical/bruise_pack = 2, /obj/item/stack/medical/ointment = 2, /obj/item/reagent_containers/hypospray/autoinjector = 4, /obj/item/healthanalyzer = 1) contraband = list(/obj/item/reagent_containers/syringe/charcoal = 4, /obj/item/reagent_containers/syringe/antiviral = 4, /obj/item/reagent_containers/food/pill/tox = 1) - armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50) + armor = list(melee = 50, bullet = 20, laser = 20, energy = 20, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 70) resistance_flags = FIRE_PROOF refill_canister = /obj/item/vending_refill/wallmed @@ -1522,7 +1522,7 @@ contraband = list(/obj/item/weldingtool/hugetank = 2,/obj/item/clothing/gloves/color/fyellow = 2) premium = list(/obj/item/clothing/gloves/color/yellow = 1) refill_canister = /obj/item/vending_refill/youtool - armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 70) + armor = list(melee = 50, bullet = 20, laser = 20, energy = 20, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 70) resistance_flags = FIRE_PROOF From a78048534728e091861163aade704440dd12e9ca Mon Sep 17 00:00:00 2001 From: Onyxarias Date: Sun, 25 Jul 2021 06:52:51 -0700 Subject: [PATCH 39/48] Deletes Paradise Removes the second Repository folder from inside the main one, that was there for some reason. --- Paradise | 1 - 1 file changed, 1 deletion(-) delete mode 160000 Paradise diff --git a/Paradise b/Paradise deleted file mode 160000 index 7ee3b8548c3..00000000000 --- a/Paradise +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7ee3b8548c3f36658a02bcd51b50466c65d426ab From d7a313791acde3056d6ae7ed9d1981be6b871eec Mon Sep 17 00:00:00 2001 From: Onyxarias Date: Sun, 25 Jul 2021 07:23:14 -0700 Subject: [PATCH 40/48] Replaces "flash_protect = 1" with the proper define Replaces "flash_protect = 1" with the proper define --- code/modules/clothing/glasses/hud.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 8bc9efb0be1..9f4b4f4c834 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -171,7 +171,7 @@ desc = "An Ahdominian made veil that allows the user to see while obscuring their eyes. This one has an in-built security HUD." icon_state = "tajblind_sec" item_state = "tajblind_sec" - flash_protect = 1 + flash_protect = FLASH_PROTECTION_FLASH flags_cover = GLASSESCOVERSEYES actions_types = list(/datum/action/item_action/toggle) up = 0 From c852290246285647c98fc28217f39f537c416525 Mon Sep 17 00:00:00 2001 From: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> Date: Sun, 25 Jul 2021 15:47:44 +0100 Subject: [PATCH 41/48] Updates some documentation --- .github/DOWNLOADING.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/DOWNLOADING.md b/.github/DOWNLOADING.md index 27731066cae..39e671cff78 100644 --- a/.github/DOWNLOADING.md +++ b/.github/DOWNLOADING.md @@ -42,24 +42,28 @@ or a code issue on the main repo. Feel free to ask on Discord. Once that's done, open up the config folder. Firstly, you will want to copy `config.toml` from the example folder into the regular config folder. -You'll want to edit the url configuration section of `config.toml` to set your server location, +You'll want to edit the `url_configuration` section of `config.toml` to set `reboot_url` to your server location, so that all your players don't get disconnected at the end of each round. It's recommended you don't turn on the gamemodes with probability 0, as they have various issues and aren't currently being tested, so they may have unknown and bizarre bugs. -You'll also want to edit the admin configuration of `config.toml` to remove the default admins and add your own. +You'll also want to edit the `admin_configuration` section of `config.toml` to remove the default admins and add your own. If you are connecting from localhost to your own test server, you should automatically be admin. -"Host" is the highest level of access, and the other recommended admin levels for now are -"Game Admin" and "Moderator". The format is: +"Head of Staff" is the highest level of access, and the other recommended admin levels for now are +"Game Admin". The format is: -```cfg - byondkey - Rank +```toml +# Note that your ranks must be cased properly, usernames can be normal keys or ckey +admin_assignments = [ + {ckey = "Admin1", rank = "Hosting Provider"}, + {ckey = "Admin2", rank = "Game Admin"}, +] ``` -where the BYOND key must be in lowercase and the admin rank must be properly capitalised. -There are a bunch more admin ranks, but these two should be enough for most servers, -assuming you have trustworthy admins. You can define your own ranks in the admin section of `config.toml` +You can define your own ranks in the admin section of `config.toml`. + +If you want to run a production scale server, we highly recommend using database administrators. Finally, to start the server, run Dream Daemon and enter the path to your compiled paradise.dmb file. @@ -93,7 +97,7 @@ When you have done this, you'll need to recompile the code, but then it should w The SQL backend is required for storing character saves, preferences, administrative data, and many other things. We recommend running a database if your server is going to be used as more than just a local test server. -Your SQL server details go in `config/dbconfig.txt`, +Your SQL server details go in the `database_configuration` section of `config.toml`, and the SQL schema is in `SQL/paradise_schema.sql` or `SQL/paradise_schema_prefix.sql`, depending on if you want table prefixes. More detailed setup instructions are located on our wiki: From bede78aeff3a41637ab13326190741fc752b99e6 Mon Sep 17 00:00:00 2001 From: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> Date: Mon, 26 Jul 2021 17:21:24 +0100 Subject: [PATCH 42/48] Removes table prefixes --- SQL/paradise_schema.sql | 4 +- SQL/paradise_schema_prefixed.sql | 597 ------------------ SQL/updates/10-11.sql | 58 +- SQL/updates/17-18.py | 2 +- code/__HELPERS/text.dm | 4 - code/__HELPERS/unsorted.dm | 2 +- .../sections/database_configuration.dm | 5 +- code/controllers/subsystem/blackbox.dm | 4 +- code/controllers/subsystem/changelog.dm | 4 +- code/controllers/subsystem/dbcore.dm | 8 +- code/controllers/subsystem/jobs.dm | 6 +- code/controllers/subsystem/mapping.dm | 2 +- code/controllers/subsystem/statistics.dm | 2 +- code/game/gamemodes/game_mode.dm | 2 +- code/game/jobs/whitelist.dm | 4 +- code/modules/admin/IsBanned.dm | 6 +- code/modules/admin/admin_memo.dm | 16 +- code/modules/admin/admin_ranks.dm | 2 +- code/modules/admin/admin_verbs.dm | 4 +- code/modules/admin/banappearance.dm | 2 +- code/modules/admin/banjob.dm | 6 +- code/modules/admin/cookielog.dm | 4 +- code/modules/admin/db_ban/functions.dm | 22 +- code/modules/admin/ipintel.dm | 12 +- .../admin/permissionverbs/permissionedit.dm | 22 +- code/modules/admin/sql_notes.dm | 16 +- code/modules/admin/topic.dm | 16 +- code/modules/admin/watchlist.dm | 14 +- code/modules/client/2fa.dm | 6 +- code/modules/client/client_procs.dm | 38 +- code/modules/client/preference/preferences.dm | 2 +- .../client/preference/preferences_mysql.dm | 22 +- code/modules/customitems/item_spawning.dm | 2 +- code/modules/karma/karma.dm | 36 +- code/modules/library/admin.dm | 4 +- code/modules/library/computers/base.dm | 4 +- code/modules/library/computers/checkout.dm | 6 +- code/modules/library/lib_machines.dm | 6 +- code/modules/library/random_books.dm | 2 +- code/modules/mob/new_player/new_player.dm | 4 +- config/example/config.toml | 6 +- tools/ci/generate_sql_scripts.py | 12 +- tools/ci/sql_v0.sql | 98 +-- tools/githubChangelogProcessor.php | 2 +- 44 files changed, 244 insertions(+), 852 deletions(-) delete mode 100644 SQL/paradise_schema_prefixed.sql diff --git a/SQL/paradise_schema.sql b/SQL/paradise_schema.sql index b6030beea09..3ed1cbca688 100644 --- a/SQL/paradise_schema.sql +++ b/SQL/paradise_schema.sql @@ -1,5 +1,5 @@ -CREATE DATABASE IF NOT EXISTS `feedback` /*!40100 DEFAULT CHARACTER SET utf8 */; -USE `feedback`; +CREATE DATABASE IF NOT EXISTS `paradise_gamedb` /*!40100 DEFAULT CHARACTER SET utf8 */; +USE `paradise_gamedb`; /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; diff --git a/SQL/paradise_schema_prefixed.sql b/SQL/paradise_schema_prefixed.sql deleted file mode 100644 index 345711e357e..00000000000 --- a/SQL/paradise_schema_prefixed.sql +++ /dev/null @@ -1,597 +0,0 @@ -CREATE DATABASE IF NOT EXISTS `feedback` /*!40100 DEFAULT CHARACTER SET utf8 */; -USE `feedback`; - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; - --- --- Table structure for table `SS13_characters` --- - -DROP TABLE IF EXISTS `SS13_characters`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_characters` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `ckey` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `slot` int(2) NOT NULL, - `OOC_Notes` longtext COLLATE utf8mb4_unicode_ci NOT NULL, - `real_name` varchar(55) COLLATE utf8mb4_unicode_ci NOT NULL, - `name_is_always_random` tinyint(1) NOT NULL, - `gender` varchar(11) COLLATE utf8mb4_unicode_ci NOT NULL, - `age` smallint(4) NOT NULL, - `species` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL, - `language` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL, - `hair_colour` varchar(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '#000000', - `secondary_hair_colour` varchar(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '#000000', - `facial_hair_colour` varchar(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '#000000', - `secondary_facial_hair_colour` varchar(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '#000000', - `skin_tone` smallint(4) NOT NULL, - `skin_colour` varchar(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '#000000', - `marking_colours` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'head=%23000000&body=%23000000&tail=%23000000', - `head_accessory_colour` varchar(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '#000000', - `hair_style_name` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL, - `facial_style_name` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL, - `marking_styles` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'head=None&body=None&tail=None', - `head_accessory_style_name` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL, - `alt_head_name` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL, - `eye_colour` varchar(7) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '#000000', - `underwear` longtext COLLATE utf8mb4_unicode_ci NOT NULL, - `undershirt` longtext COLLATE utf8mb4_unicode_ci NOT NULL, - `backbag` longtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `b_type` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL, - `alternate_option` smallint(4) NOT NULL, - `job_support_high` mediumint(8) NOT NULL, - `job_support_med` mediumint(8) NOT NULL, - `job_support_low` mediumint(8) NOT NULL, - `job_medsci_high` mediumint(8) NOT NULL, - `job_medsci_med` mediumint(8) NOT NULL, - `job_medsci_low` mediumint(8) NOT NULL, - `job_engsec_high` mediumint(8) NOT NULL, - `job_engsec_med` mediumint(8) NOT NULL, - `job_engsec_low` mediumint(8) NOT NULL, - `job_karma_high` mediumint(8) NOT NULL, - `job_karma_med` mediumint(8) NOT NULL, - `job_karma_low` mediumint(8) NOT NULL, - `flavor_text` longtext COLLATE utf8mb4_unicode_ci NOT NULL, - `med_record` longtext COLLATE utf8mb4_unicode_ci NOT NULL, - `sec_record` longtext COLLATE utf8mb4_unicode_ci NOT NULL, - `gen_record` longtext COLLATE utf8mb4_unicode_ci NOT NULL, - `disabilities` mediumint(8) NOT NULL, - `player_alt_titles` longtext COLLATE utf8mb4_unicode_ci NOT NULL, - `organ_data` longtext COLLATE utf8mb4_unicode_ci NOT NULL, - `rlimb_data` longtext COLLATE utf8mb4_unicode_ci NOT NULL, - `nanotrasen_relation` varchar(45) COLLATE utf8mb4_unicode_ci NOT NULL, - `speciesprefs` int(1) NOT NULL, - `socks` longtext COLLATE utf8mb4_unicode_ci NOT NULL, - `body_accessory` longtext COLLATE utf8mb4_unicode_ci NOT NULL, - `gear` longtext COLLATE utf8mb4_unicode_ci NOT NULL, - `autohiss` tinyint(1) NOT NULL, - PRIMARY KEY (`id`), - KEY `ckey` (`ckey`) -) ENGINE=InnoDB AUTO_INCREMENT=125467 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_customuseritems` --- - -DROP TABLE IF EXISTS `SS13_customuseritems`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_customuseritems` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `cuiCKey` varchar(36) NOT NULL, - `cuiRealName` varchar(60) NOT NULL, - `cuiPath` varchar(255) NOT NULL, - `cuiItemName` text, - `cuiDescription` text, - `cuiReason` text, - `cuiPropAdjust` text, - `cuiJobMask` text NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=56 DEFAULT CHARSET=utf8mb4; -ALTER TABLE `SS13_customuseritems` ADD INDEX(`cuiCKey`); -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_death` --- - -DROP TABLE IF EXISTS `SS13_death`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_death` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `pod` text NOT NULL COMMENT 'Place of death', - `coord` text NOT NULL COMMENT 'X, Y, Z POD', - `tod` datetime NOT NULL COMMENT 'Time of death', - `job` text NOT NULL, - `special` text NOT NULL, - `name` text NOT NULL, - `byondkey` text NOT NULL, - `laname` text NOT NULL COMMENT 'Last attacker name', - `lakey` text NOT NULL COMMENT 'Last attacker key', - `gender` text NOT NULL, - `bruteloss` int(11) NOT NULL, - `brainloss` int(11) NOT NULL, - `fireloss` int(11) NOT NULL, - `oxyloss` int(11) NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=166546 DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `donators` --- - -DROP TABLE IF EXISTS `SS13_donators`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_donators` ( - `patreon_name` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `tier` int(2), - `ckey` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Manual Field', - `start_date` datetime, - `end_date` datetime, - `active` boolean, - PRIMARY KEY (`patreon_name`), - KEY `ckey` (`ckey`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_admin` --- - -DROP TABLE IF EXISTS `SS13_admin`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_admin` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `ckey` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `admin_rank` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'Administrator', - `level` int(2) NOT NULL DEFAULT '0', - `flags` int(16) NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - KEY `ckey` (`ckey`) -) ENGINE=InnoDB AUTO_INCREMENT=99 DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_admin_log` --- - -DROP TABLE IF EXISTS `SS13_admin_log`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_admin_log` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `datetime` datetime NOT NULL, - `adminckey` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `adminip` varchar(18) COLLATE utf8mb4_unicode_ci NOT NULL, - `log` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL, - PRIMARY KEY (`id`), - KEY `adminckey` (`adminckey`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_ban` --- - -DROP TABLE IF EXISTS `SS13_ban`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_ban` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `bantime` datetime NOT NULL, - `ban_round_id` INT(11) NULL DEFAULT NULL, - `serverip` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `bantype` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `reason` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL, - `job` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `duration` int(11) NOT NULL, - `rounds` int(11) DEFAULT NULL, - `expiration_time` datetime NOT NULL, - `ckey` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `computerid` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `ip` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `a_ckey` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `a_computerid` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `a_ip` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `who` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL, - `adminwho` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL, - `edits` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `unbanned` tinyint(1) DEFAULT NULL, - `unbanned_datetime` datetime DEFAULT NULL, - `unbanned_round_id` INT(11) NULL DEFAULT NULL, - `unbanned_ckey` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `unbanned_computerid` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `unbanned_ip` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `ckey` (`ckey`), - KEY `computerid` (`computerid`), - KEY `ip` (`ip`) -) ENGINE=InnoDB AUTO_INCREMENT=58903 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_feedback` --- - -DROP TABLE IF EXISTS `SS13_feedback`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_feedback` ( - `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, - `datetime` datetime NOT NULL, - `round_id` int(8) NOT NULL, - `key_name` varchar(32) NOT NULL, - `key_type` enum('text', 'amount', 'tally', 'nested tally', 'associative') NOT NULL, - `version` tinyint(3) UNSIGNED NOT NULL, - `json` LONGTEXT NOT NULL COLLATE 'utf8mb4_general_ci', - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=257638 DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_player` --- - -DROP TABLE IF EXISTS `SS13_player`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_player` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `ckey` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `firstseen` datetime NOT NULL, - `lastseen` datetime NOT NULL, - `ip` varchar(18) COLLATE utf8mb4_unicode_ci NOT NULL, - `computerid` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `lastadminrank` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'Player', - `ooccolor` varchar(7) COLLATE utf8mb4_unicode_ci DEFAULT '#b82e00', - `UI_style` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT 'Midnight', - `UI_style_color` varchar(7) COLLATE utf8mb4_unicode_ci DEFAULT '#ffffff', - `UI_style_alpha` smallint(4) DEFAULT '255', - `be_role` longtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `default_slot` smallint(4) DEFAULT '1', - `toggles` int(11) DEFAULT NULL, - `toggles_2` int(11) DEFAULT '0', - `sound` mediumint(8) DEFAULT '31', - `volume_mixer` longtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `lastchangelog` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0', - `exp` longtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `clientfps` smallint(4) DEFAULT '0', - `atklog` smallint(4) DEFAULT '0', - `fuid` bigint(20) DEFAULT NULL, - `fupdate` smallint(4) DEFAULT '0', - `parallax` tinyint(1) DEFAULT '8', - `byond_date` DATE DEFAULT NULL, - `2fa_status` ENUM('DISABLED','ENABLED_IP','ENABLED_ALWAYS') NOT NULL DEFAULT 'DISABLED' COLLATE 'utf8mb4_general_ci', - PRIMARY KEY (`id`), - UNIQUE KEY `ckey` (`ckey`), - KEY `lastseen` (`lastseen`), - KEY `computerid` (`computerid`), - KEY `ip` (`ip`), - KEY `fuid` (`fuid`), - KEY `fupdate` (`fupdate`) -) ENGINE=InnoDB AUTO_INCREMENT=135298 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_privacy` --- - -DROP TABLE IF EXISTS `SS13_privacy`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `ss13_privacy` ( - `ckey` varchar(32) NOT NULL, - `datetime` datetime NOT NULL, - `consent` bit(1) NOT NULL, - PRIMARY KEY (`ckey`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_karma` --- - -DROP TABLE IF EXISTS `SS13_karma`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_karma` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `spendername` text NOT NULL, - `spenderkey` text NOT NULL, - `receivername` text NOT NULL, - `receiverkey` text NOT NULL, - `receiverrole` text, - `receiverspecial` text, - `isnegative` tinyint(1) DEFAULT NULL, - `spenderip` text NOT NULL, - `time` datetime NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=73614 DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_karmatotals` --- - -DROP TABLE IF EXISTS `SS13_karmatotals`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_karmatotals` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `byondkey` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL, - `karma` int(11) NOT NULL, - `karmaspent` int(11) NOT NULL DEFAULT 0, - PRIMARY KEY (`id`), - KEY `byondkey` (`byondkey`) -) ENGINE=InnoDB AUTO_INCREMENT=25715 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_library` --- - -DROP TABLE IF EXISTS `SS13_library`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_library` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `author` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL, - `title` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL, - `content` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL, - `category` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL, - `ckey` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `flagged` int(11) NOT NULL, - PRIMARY KEY (`id`), - KEY `ckey` (`ckey`), - KEY `flagged` (`flagged`) -) ENGINE=InnoDB AUTO_INCREMENT=4537 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_legacy_population` --- - -DROP TABLE IF EXISTS `SS13_legacy_population`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_legacy_population` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `playercount` int(11) DEFAULT NULL, - `admincount` int(11) DEFAULT NULL, - `time` datetime NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=2550 DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_whitelist` --- - -DROP TABLE IF EXISTS `SS13_whitelist`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_whitelist` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `ckey` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `job` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `species` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `ckey` (`ckey`) -) ENGINE=InnoDB AUTO_INCREMENT=4080 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!40101 SET character_set_client = @saved_cs_client */; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; - --- --- Table structure for table `SS13_watch` --- - -DROP TABLE IF EXISTS `SS13_watch`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_watch` ( - `ckey` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `reason` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL, - `timestamp` datetime NOT NULL, - `adminckey` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL, - `last_editor` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL, - `edits` mediumtext COLLATE utf8mb4_unicode_ci DEFAULT NULL, - PRIMARY KEY (`ckey`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -/*!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, - `round_id` INT(11) NULL DEFAULT NULL, - `adminckey` varchar(32) NOT NULL, - `last_editor` varchar(32), - `edits` text, - `server` varchar(50) NOT NULL, - `crew_playtime` mediumint(8) UNSIGNED DEFAULT '0', - `automated` TINYINT(3) UNSIGNED NULL DEFAULT '0', - PRIMARY KEY (`id`), - KEY `ckey` (`ckey`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_memo` --- - -DROP TABLE IF EXISTS `SS13_memo`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_memo` ( - `ckey` varchar(32) NOT NULL, - `memotext` text NOT NULL, - `timestamp` datetime NOT NULL, - `last_editor` varchar(32), - `edits` text, - PRIMARY KEY (`ckey`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_ipintel` --- -DROP TABLE IF EXISTS `SS13_ipintel`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_ipintel` ( - `ip` int UNSIGNED NOT NULL, - `date` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL, - `intel` real NOT NULL DEFAULT '0', - PRIMARY key (`ip`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_vpn_whitelist` --- -DROP TABLE IF EXISTS `SS13_vpn_whitelist`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_vpn_whitelist` ( - `ckey` varchar(32) NOT NULL, - `reason` text, - PRIMARY KEY (`ckey`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_oauth_tokens` --- -DROP TABLE IF EXISTS `SS13_oauth_tokens`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_oauth_tokens` ( - `ckey` varchar(32) NOT NULL, - `token` varchar(32) NOT NULL, - PRIMARY KEY (`token`), - KEY `ckey` (`ckey`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Table structure for table `SS13_playtime_history` --- -DROP TABLE IF EXISTS `SS13_playtime_history`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8 */; -CREATE TABLE `SS13_playtime_history` ( - `ckey` varchar(32) NOT NULL, - `date` DATE NOT NULL, - `time_living` SMALLINT NOT NULL, - `time_ghost` SMALLINT NOT NULL, - PRIMARY KEY (`ckey`, `date`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; - --- --- Table structure for table `SS13_connection_log` --- -DROP TABLE IF EXISTS `SS13_connection_log`; -CREATE TABLE `SS13_connection_log` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `datetime` datetime NOT NULL, - `ckey` varchar(32) NOT NULL, - `ip` varchar(32) NOT NULL, - `computerid` varchar(32) NOT NULL, - `result` ENUM('ESTABLISHED','DROPPED - IPINTEL','DROPPED - BANNED','DROPPED - INVALID') NOT NULL DEFAULT 'ESTABLISHED' COLLATE 'utf8mb4_general_ci', - PRIMARY KEY (`id`), - KEY `ckey` (`ckey`), - KEY `ip` (`ip`), - KEY `computerid` (`computerid`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; - --- --- Table structure for table `SS13_changelog` --- -DROP TABLE IF EXISTS `SS13_changelog`; -CREATE TABLE `SS13_changelog` ( - `id` INT(11) NOT NULL AUTO_INCREMENT, - `pr_number` INT(11) NOT NULL, - `date_merged` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, - `author` VARCHAR(32) NOT NULL, - `cl_type` ENUM('FIX','WIP','TWEAK','SOUNDADD','SOUNDDEL','CODEADD','CODEDEL','IMAGEADD','IMAGEDEL','SPELLCHECK','EXPERIMENT') NOT NULL, - `cl_entry` TEXT NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; - --- --- Table structure for table `ip2group` --- -DROP TABLE IF EXISTS `SS13_ip2group`; -CREATE TABLE `SS13_ip2group` ( - `ip` varchar (18) COLLATE utf8mb4_unicode_ci NOT NULL, - `date` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL, - `groupstr` varchar (32) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '', - PRIMARY KEY (`ip`), - KEY `groupstr` (`groupstr`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; - --- --- Table structure for table `round` --- -DROP TABLE IF EXISTS `SS13_round`; -CREATE TABLE `SS13_round` ( - `id` INT(11) NOT NULL AUTO_INCREMENT, - `initialize_datetime` DATETIME NOT NULL, - `start_datetime` DATETIME NULL, - `shutdown_datetime` DATETIME NULL, - `end_datetime` DATETIME NULL, - `server_ip` INT(10) UNSIGNED NOT NULL, - `server_port` SMALLINT(5) UNSIGNED NOT NULL, - `commit_hash` CHAR(40) NULL, - `game_mode` VARCHAR(32) NULL, - `game_mode_result` VARCHAR(64) NULL, - `end_state` VARCHAR(64) NULL, - `shuttle_name` VARCHAR(64) NULL, - `map_name` VARCHAR(32) NULL, - `station_name` VARCHAR(80) NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; - --- --- Table structure for table `2fa_secrets` --- -CREATE TABLE `SS13_2fa_secrets` ( - `ckey` VARCHAR(50) NOT NULL COLLATE 'utf8mb4_general_ci', - `secret` VARCHAR(64) NOT NULL COLLATE 'utf8mb4_general_ci', - `date_setup` DATETIME NOT NULL DEFAULT current_timestamp(), - `last_time` DATETIME NULL DEFAULT NULL, - PRIMARY KEY (`ckey`) USING BTREE -) -COLLATE='utf8mb4_general_ci' ENGINE=InnoDB; diff --git a/SQL/updates/10-11.sql b/SQL/updates/10-11.sql index 843eb9d9982..7102170a9ff 100644 --- a/SQL/updates/10-11.sql +++ b/SQL/updates/10-11.sql @@ -6,35 +6,35 @@ # Generation (not necessary to run unless your DB has extra tables) SELECT CONCAT("ALTER TABLE ", TABLE_SCHEMA, '.', TABLE_NAME," CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;") AS ExecuteTheString FROM INFORMATION_SCHEMA.TABLES -WHERE TABLE_SCHEMA="feedback" +WHERE TABLE_SCHEMA="paradise_gamedb" AND TABLE_TYPE="BASE TABLE"; # Actual table conversion stuff -ALTER TABLE feedback.admin CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.admin_log CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.ban CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.characters CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.connection_log CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.customuseritems CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.death CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.donators CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.privacy CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.feedback CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.ipintel CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.karma CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.karmatotals CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.legacy_population CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.library CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.memo CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.notes CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.oauth_tokens CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.player CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.playtime_history CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.poll_option CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.poll_question CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.poll_textreply CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.poll_vote CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.privacy CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.vpn_whitelist CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.watch CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -ALTER TABLE feedback.whitelist CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE admin CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE admin_log CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE ban CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE characters CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE connection_log CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE customuseritems CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE death CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE donators CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE privacy CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE feedback CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE ipintel CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE karma CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE karmatotals CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE legacy_population CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE library CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE memo CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE notes CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE oauth_tokens CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE player CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE playtime_history CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE poll_option CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE poll_question CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE poll_textreply CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE poll_vote CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE privacy CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE vpn_whitelist CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE watch CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +ALTER TABLE whitelist CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; diff --git a/SQL/updates/17-18.py b/SQL/updates/17-18.py index 61d4fe39674..389722fa7d9 100644 --- a/SQL/updates/17-18.py +++ b/SQL/updates/17-18.py @@ -8,7 +8,7 @@ #To view the parameters for this script, execute it with the argument --help #All the positional arguments are required, remember to include prefixes in your table names if you use them #An example of the command used to execute this script from powershell: -#python feedback_conversion_2017-11-12.py "localhost" "root" "password" "feedback" "feedback" "feedback_2" +#python feedback_conversion_2017-11-12.py "localhost" "root" "password" "paradise_gamedb" "feedback" "feedback_2" #I found that this script would complete conversion of 10000 rows approximately every 2-3 seconds #Depending on the size of your feedback table and the computer used it may take several minutes for the script to finish # diff --git a/code/__HELPERS/text.dm b/code/__HELPERS/text.dm index 437765a0a6f..fa357006723 100644 --- a/code/__HELPERS/text.dm +++ b/code/__HELPERS/text.dm @@ -8,10 +8,6 @@ * Misc */ - -/proc/format_table_name(table as text) - return GLOB.configuration.database.table_prefix + table - /* * Text sanitization */ diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 8478d8c0c91..d343a60bcc9 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -2082,7 +2082,7 @@ GLOBAL_DATUM_INIT(dview_mob, /mob/dview, new) /proc/log_connection(ckey, ip, cid, connection_type) ASSERT(connection_type in list(CONNECTION_TYPE_ESTABLISHED, CONNECTION_TYPE_DROPPED_IPINTEL, CONNECTION_TYPE_DROPPED_BANNED, CONNECTION_TYPE_DROPPED_INVALID)) - var/datum/db_query/query_accesslog = SSdbcore.NewQuery("INSERT INTO `[format_table_name("connection_log")]`(`datetime`, `ckey`, `ip`, `computerid`, `result`) VALUES(Now(), :ckey, :ip, :cid, :result)", list( + var/datum/db_query/query_accesslog = SSdbcore.NewQuery("INSERT INTO connection_log (`datetime`, `ckey`, `ip`, `computerid`, `result`) VALUES(Now(), :ckey, :ip, :cid, :result)", list( "ckey" = ckey, "ip" = "[ip ? ip : ""]", // This is important. NULL is not the same as "", and if you directly open the `.dmb` file, you get a NULL IP. "cid" = cid, diff --git a/code/controllers/configuration/sections/database_configuration.dm b/code/controllers/configuration/sections/database_configuration.dm index d95aedcf193..1e75d7af3f4 100644 --- a/code/controllers/configuration/sections/database_configuration.dm +++ b/code/controllers/configuration/sections/database_configuration.dm @@ -14,9 +14,7 @@ /// SQL password var/password = "root" // Dont do this in prod. Please...... /// Database name - var/db = "feedback" // AA TODO: Rename to paradise_gamedb - /// Table prefix - var/table_prefix = "erro_" // AA TODO: Remove table prefixes + var/db = "paradise_gamedb" /// Time in seconds for async queries to time out var/async_query_timeout = 10 /// Thread limit for async queries @@ -41,7 +39,6 @@ CONFIG_LOAD_STR(username, data["sql_username"]) CONFIG_LOAD_STR(password, data["sql_password"]) CONFIG_LOAD_STR(db, data["sql_database"]) - CONFIG_LOAD_STR(table_prefix, data["sql_table_prefix"]) CONFIG_LOAD_NUM(async_query_timeout, data["async_query_timeout"]) CONFIG_LOAD_NUM(async_thread_limit, data["async_thread_limit"]) #endif diff --git a/code/controllers/subsystem/blackbox.dm b/code/controllers/subsystem/blackbox.dm index acfb7444323..37e4299b06d 100644 --- a/code/controllers/subsystem/blackbox.dm +++ b/code/controllers/subsystem/blackbox.dm @@ -65,7 +65,7 @@ SUBSYSTEM_DEF(blackbox) sqlversion = versions[FV.key] var/datum/db_query/query_feedback_save = SSdbcore.NewQuery({" - INSERT IGNORE INTO [format_table_name("feedback")] (datetime, round_id, key_name, key_type, version, json) + INSERT IGNORE INTO feedback (datetime, round_id, key_name, key_type, version, json) VALUES (NOW(), :rid, :keyname, :keytype, :version, :json)"}, list( "rid" = text2num(GLOB.round_id), "keyname" = FV.key, @@ -287,7 +287,7 @@ SUBSYSTEM_DEF(blackbox) lakey = L.lastattackerckey var/datum/db_query/deathquery = SSdbcore.NewQuery({" - INSERT INTO [format_table_name("death")] (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) + INSERT INTO death (name, byondkey, job, special, pod, tod, laname, lakey, gender, bruteloss, fireloss, brainloss, oxyloss, coord) VALUES (:name, :key, :job, :special, :pod, NOW(), :laname, :lakey, :gender, :bruteloss, :fireloss, :brainloss, :oxyloss, :coord)"}, list( "name" = L.real_name, diff --git a/code/controllers/subsystem/changelog.dm b/code/controllers/subsystem/changelog.dm index 3a35488e562..55221263033 100644 --- a/code/controllers/subsystem/changelog.dm +++ b/code/controllers/subsystem/changelog.dm @@ -24,7 +24,7 @@ SUBSYSTEM_DEF(changelog) if(!SSdbcore.IsConnected()) return ..() - var/datum/db_query/latest_cl_date = SSdbcore.NewQuery("SELECT CAST(UNIX_TIMESTAMP(date_merged) AS CHAR) AS ut FROM [format_table_name("changelog")] ORDER BY date_merged DESC LIMIT 1") + var/datum/db_query/latest_cl_date = SSdbcore.NewQuery("SELECT CAST(UNIX_TIMESTAMP(date_merged) AS CHAR) AS ut FROM changelog ORDER BY date_merged DESC LIMIT 1") if(!latest_cl_date.warn_execute()) qdel(latest_cl_date) // Abort if we cant do this @@ -63,7 +63,7 @@ SUBSYSTEM_DEF(changelog) C.prefs.lastchangelog = current_cl_timestamp var/datum/db_query/updatePlayerCLTime = SSdbcore.NewQuery( - "UPDATE [format_table_name("player")] SET lastchangelog=:lastchangelog WHERE ckey=:ckey", + "UPDATE player SET lastchangelog=:lastchangelog WHERE ckey=:ckey", list( "lastchangelog" = current_cl_timestamp, "ckey" = C.ckey diff --git a/code/controllers/subsystem/dbcore.dm b/code/controllers/subsystem/dbcore.dm index 4a845c375ea..f6974a2fb17 100644 --- a/code/controllers/subsystem/dbcore.dm +++ b/code/controllers/subsystem/dbcore.dm @@ -142,7 +142,7 @@ SUBSYSTEM_DEF(dbcore) //This is as close as we can get to the true round end before Disconnect() without changing where it's called, defeating the reason this is a subsystem if(SSdbcore.Connect()) var/datum/db_query/query_round_shutdown = SSdbcore.NewQuery( - "UPDATE [format_table_name("round")] SET shutdown_datetime = Now(), end_state = :end_state WHERE id = :round_id", + "UPDATE round SET shutdown_datetime = Now(), end_state = :end_state WHERE id = :round_id", list("end_state" = SSticker.end_state, "round_id" = GLOB.round_id) ) query_round_shutdown.Execute() @@ -160,7 +160,7 @@ SUBSYSTEM_DEF(dbcore) if(!IsConnected()) return var/datum/db_query/query_round_initialize = SSdbcore.NewQuery( - "INSERT INTO [format_table_name("round")] (initialize_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(:internet_address), :port)", + "INSERT INTO round (initialize_datetime, server_ip, server_port) VALUES (Now(), INET_ATON(:internet_address), :port)", list("internet_address" = world.internet_address || "0", "port" = "[world.port]") ) query_round_initialize.Execute(async = FALSE) @@ -177,7 +177,7 @@ SUBSYSTEM_DEF(dbcore) if(!IsConnected()) return var/datum/db_query/query_round_start = SSdbcore.NewQuery( - "UPDATE [format_table_name("round")] SET start_datetime=NOW(), commit_hash=:hash WHERE id=:round_id", + "UPDATE round SET start_datetime=NOW(), commit_hash=:hash WHERE id=:round_id", list("hash" = GLOB.revision_info.commit_hash, "round_id" = GLOB.round_id) ) query_round_start.Execute(async = FALSE) // This happens during a time of intense server lag, so should be non-async @@ -193,7 +193,7 @@ SUBSYSTEM_DEF(dbcore) if(!IsConnected()) return var/datum/db_query/query_round_end = SSdbcore.NewQuery( - "UPDATE [format_table_name("round")] SET end_datetime = Now(), game_mode_result = :game_mode_result WHERE id = :round_id", + "UPDATE round SET end_datetime = Now(), game_mode_result = :game_mode_result WHERE id = :round_id", list("game_mode_result" = SSticker.mode_result, "station_name" = station_name(), "round_id" = GLOB.round_id) ) query_round_end.Execute() diff --git a/code/controllers/subsystem/jobs.dm b/code/controllers/subsystem/jobs.dm index 415e04e8611..f7660f4d75a 100644 --- a/code/controllers/subsystem/jobs.dm +++ b/code/controllers/subsystem/jobs.dm @@ -740,7 +740,7 @@ SUBSYSTEM_DEF(jobs) continue // If a client logs out in the middle of this var/datum/db_query/exp_read = SSdbcore.NewQuery( - "SELECT exp FROM [format_table_name("player")] WHERE ckey=:ckey", + "SELECT exp FROM player WHERE ckey=:ckey", list("ckey" = C.ckey) ) @@ -824,7 +824,7 @@ SUBSYSTEM_DEF(jobs) C.prefs.exp = new_exp var/datum/db_query/update_query = SSdbcore.NewQuery( - "UPDATE [format_table_name("player")] SET exp =:newexp, lastseen=NOW() WHERE ckey=:ckey", + "UPDATE player SET exp =:newexp, lastseen=NOW() WHERE ckey=:ckey", list( "newexp" = new_exp, "ckey" = C.ckey @@ -834,7 +834,7 @@ SUBSYSTEM_DEF(jobs) player_update_queries += update_query var/datum/db_query/update_query_history = SSdbcore.NewQuery({" - INSERT INTO [format_table_name("playtime_history")] (ckey, date, time_living, time_ghost) + INSERT INTO playtime_history (ckey, date, time_living, time_ghost) VALUES (:ckey, CURDATE(), :addedliving, :addedghost) ON DUPLICATE KEY UPDATE time_living=time_living + VALUES(time_living), time_ghost=time_ghost + VALUES(time_ghost)"}, list( diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index a816c18d0c5..044913acb89 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -128,7 +128,7 @@ SUBSYSTEM_DEF(mapping) if(!SSdbcore.IsConnected()) return var/datum/db_query/query_set_map = SSdbcore.NewQuery( - "UPDATE [format_table_name("round")] SET start_datetime=NOW(), map_name=:mapname, station_name=:stationname WHERE id=:round_id", + "UPDATE round SET start_datetime=NOW(), map_name=:mapname, station_name=:stationname WHERE id=:round_id", list("mapname" = map_datum.technical_name, "stationname" = map_datum.fluff_name, "round_id" = GLOB.round_id) ) query_set_map.Execute(async = FALSE) // This happens during a time of intense server lag, so should be non-async diff --git a/code/controllers/subsystem/statistics.dm b/code/controllers/subsystem/statistics.dm index 375bb47486f..63c20742904 100644 --- a/code/controllers/subsystem/statistics.dm +++ b/code/controllers/subsystem/statistics.dm @@ -18,7 +18,7 @@ SUBSYSTEM_DEF(statistics) return else var/datum/db_query/statquery = SSdbcore.NewQuery( - "INSERT INTO [format_table_name("legacy_population")] (playercount, admincount, time) VALUES (:playercount, :admincount, NOW())", + "INSERT INTO legacy_population (playercount, admincount, time) VALUES (:playercount, :admincount, NOW())", list( "playercount" = length(GLOB.clients), "admincount" = length(GLOB.admins) diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 2b0000d9c38..88a287efc02 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -92,7 +92,7 @@ // I wonder what this could do guessing by the name /datum/game_mode/proc/set_mode_in_db() if(SSticker?.mode && SSdbcore.IsConnected()) - var/datum/db_query/query_round_game_mode = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET game_mode=:gm WHERE id=:rid", list( + var/datum/db_query/query_round_game_mode = SSdbcore.NewQuery("UPDATE round SET game_mode=:gm WHERE id=:rid", list( "gm" = SSticker.mode.name, "rid" = GLOB.round_id )) diff --git a/code/game/jobs/whitelist.dm b/code/game/jobs/whitelist.dm index b327da6390f..b459576d960 100644 --- a/code/game/jobs/whitelist.dm +++ b/code/game/jobs/whitelist.dm @@ -8,7 +8,7 @@ return FALSE else var/datum/db_query/job_read = SSdbcore.NewQuery( - "SELECT job FROM [format_table_name("whitelist")] WHERE ckey=:ckey", + "SELECT job FROM whitelist WHERE ckey=:ckey", list("ckey" = M.ckey) ) @@ -43,7 +43,7 @@ return FALSE else var/datum/db_query/species_read = SSdbcore.NewQuery( - "SELECT species FROM [format_table_name("whitelist")] WHERE ckey=:ckey", + "SELECT species FROM whitelist WHERE ckey=:ckey", list("ckey" = M.ckey) ) diff --git a/code/modules/admin/IsBanned.dm b/code/modules/admin/IsBanned.dm index 5e5f8c07343..8e1ee44ac21 100644 --- a/code/modules/admin/IsBanned.dm +++ b/code/modules/admin/IsBanned.dm @@ -47,7 +47,7 @@ // If 2FA is enabled, makes sure they were authed within the last minute if(check_2fa && GLOB.configuration.system._2fa_auth_host) // First see if they exist at all - var/datum/db_query/check_query = SSdbcore.NewQuery("SELECT 2fa_status, ip FROM [format_table_name("player")] WHERE ckey=:ckey", list("ckey" = ckey(key))) + var/datum/db_query/check_query = SSdbcore.NewQuery("SELECT 2fa_status, ip FROM player WHERE ckey=:ckey", list("ckey" = ckey(key))) if(!check_query.warn_execute()) message_admins("Failed to do a DB 2FA check for [key]. You have been warned.") @@ -71,7 +71,7 @@ // Have it set to always check, or their IP is different if(_2fa_enabled && (always_check || (address != last_ip))) // They have 2FA enabled, lets make sure they have authed within the last minute - var/datum/db_query/verify_query = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("2fa_secrets")] WHERE (last_time BETWEEN NOW() - INTERVAL 1 MINUTE AND NOW()) AND ckey=:ckey LIMIT 1", list( + var/datum/db_query/verify_query = SSdbcore.NewQuery("SELECT ckey FROM 2fa_secrets WHERE (last_time BETWEEN NOW() - INTERVAL 1 MINUTE AND NOW()) AND ckey=:ckey LIMIT 1", list( "ckey" = ckey(key) )) @@ -120,7 +120,7 @@ sql_query_params["cid"] = computer_id var/datum/db_query/query = SSdbcore.NewQuery({" - SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype, ban_round_id FROM [format_table_name("ban")] + SELECT ckey, ip, computerid, a_ckey, reason, expiration_time, duration, bantime, bantype, ban_round_id FROM ban WHERE (ckey=:ckeytext [ipquery] [cidquery]) AND (bantype = 'PERMABAN' OR bantype = 'ADMIN_PERMABAN' OR ((bantype = 'TEMPBAN' OR bantype = 'ADMIN_TEMPBAN') AND expiration_time > Now())) AND isnull(unbanned)"}, sql_query_params) diff --git a/code/modules/admin/admin_memo.dm b/code/modules/admin/admin_memo.dm index 71d96715a09..cda97437097 100644 --- a/code/modules/admin/admin_memo.dm +++ b/code/modules/admin/admin_memo.dm @@ -22,7 +22,7 @@ switch(task) if("Write") var/datum/db_query/query_memocheck = SSdbcore.NewQuery( - "SELECT ckey FROM [format_table_name("memo")] WHERE ckey=:ckey", + "SELECT ckey FROM memo WHERE ckey=:ckey", list("ckey" = ckey) ) @@ -41,7 +41,7 @@ return var/datum/db_query/query_memoadd = SSdbcore.NewQuery( - "INSERT INTO [format_table_name("memo")] (ckey, memotext, timestamp) VALUES (:ckey, :memotext, NOW())", + "INSERT INTO memo (ckey, memotext, timestamp) VALUES (:ckey, :memotext, NOW())", list( "ckey" = ckey, "memotext" = memotext @@ -57,7 +57,7 @@ qdel(query_memoadd) if("Edit") - var/datum/db_query/query_memolist = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("memo")]") + var/datum/db_query/query_memolist = SSdbcore.NewQuery("SELECT ckey FROM memo") if(!query_memolist.warn_execute()) qdel(query_memolist) @@ -78,7 +78,7 @@ return var/datum/db_query/query_memofind = SSdbcore.NewQuery( - "SELECT memotext FROM [format_table_name("memo")] WHERE ckey=:ckey", + "SELECT memotext FROM memo WHERE ckey=:ckey", list("ckey" = target_ckey) ) @@ -96,7 +96,7 @@ var/edit_text = "Edited by [target_ckey] on [SQLtime()] from
[old_memo]
to
[new_memo]
" var/datum/db_query/update_query = SSdbcore.NewQuery( - "UPDATE [format_table_name("memo")] SET memotext=:newmemo, last_editor=:lasteditor, edits=CONCAT(IFNULL(edits,''),:edittext) WHERE ckey=:targetckey", + "UPDATE memo SET memotext=:newmemo, last_editor=:lasteditor, edits=CONCAT(IFNULL(edits,''),:edittext) WHERE ckey=:targetckey", list( "newmemo" = new_memo, "lasteditor" = ckey, @@ -120,7 +120,7 @@ qdel(query_memofind) if("Show") - var/datum/db_query/query_memoshow = SSdbcore.NewQuery("SELECT ckey, memotext, timestamp, last_editor FROM [format_table_name("memo")]") + var/datum/db_query/query_memoshow = SSdbcore.NewQuery("SELECT ckey, memotext, timestamp, last_editor FROM memo") if(!query_memoshow.warn_execute()) qdel(query_memoshow) return @@ -141,7 +141,7 @@ qdel(query_memoshow) if("Remove") - var/datum/db_query/query_memodellist = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("memo")]") + var/datum/db_query/query_memodellist = SSdbcore.NewQuery("SELECT ckey FROM memo") if(!query_memodellist.warn_execute()) qdel(query_memodellist) return @@ -161,7 +161,7 @@ return var/datum/db_query/query_memodel = SSdbcore.NewQuery( - "DELETE FROM [format_table_name("memo")] WHERE ckey=:ckey", + "DELETE FROM memo WHERE ckey=:ckey", list("ckey" = target_ckey) ) diff --git a/code/modules/admin/admin_ranks.dm b/code/modules/admin/admin_ranks.dm index 9f0f37df719..3fd0df9c4d7 100644 --- a/code/modules/admin/admin_ranks.dm +++ b/code/modules/admin/admin_ranks.dm @@ -91,7 +91,7 @@ GLOBAL_PROTECT(admin_ranks) // this shit is being protected for obvious reasons load_admins() return - var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey, admin_rank, level, flags FROM [format_table_name("admin")]") + var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey, admin_rank, level, flags FROM admin") if(!query.warn_execute(async=run_async)) qdel(query) return diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 62b2a01e3eb..598705668ae 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -691,7 +691,7 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list( return var/datum/db_query/rank_read = SSdbcore.NewQuery( - "SELECT admin_rank FROM [format_table_name("admin")] WHERE ckey=:ckey", + "SELECT admin_rank FROM admin WHERE ckey=:ckey", list("ckey" = ckey) ) @@ -717,7 +717,7 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list( return var/datum/db_query/admin_read = SSdbcore.NewQuery( - "SELECT ckey, admin_rank, flags FROM [format_table_name("admin")] WHERE ckey=:ckey", + "SELECT ckey, admin_rank, flags FROM admin WHERE ckey=:ckey", list("ckey" = ckey) ) diff --git a/code/modules/admin/banappearance.dm b/code/modules/admin/banappearance.dm index 75816c22c43..4544edba3f8 100644 --- a/code/modules/admin/banappearance.dm +++ b/code/modules/admin/banappearance.dm @@ -59,7 +59,7 @@ DEBUG return //appearance bans - var/datum/db_query/appearanceban_query = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("ban")] WHERE bantype = 'APPEARANCE_BAN' AND NOT unbanned = 1") + var/datum/db_query/appearanceban_query = SSdbcore.NewQuery("SELECT ckey FROM ban WHERE bantype = 'APPEARANCE_BAN' AND NOT unbanned = 1") if(!appearanceban_query.warn_execute()) qdel(appearanceban_query) diff --git a/code/modules/admin/banjob.dm b/code/modules/admin/banjob.dm index 024b264fbb1..29e615c8932 100644 --- a/code/modules/admin/banjob.dm +++ b/code/modules/admin/banjob.dm @@ -79,7 +79,7 @@ GLOBAL_DATUM_INIT(jobban_regex, /regex, regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ## return //Job permabans - var/datum/db_query/permabans = SSdbcore.NewQuery("SELECT ckey, job FROM [format_table_name("ban")] WHERE bantype = 'JOB_PERMABAN' AND isnull(unbanned)") + var/datum/db_query/permabans = SSdbcore.NewQuery("SELECT ckey, job FROM ban WHERE bantype = 'JOB_PERMABAN' AND isnull(unbanned)") if(!permabans.warn_execute(async=FALSE)) qdel(permabans) @@ -94,7 +94,7 @@ GLOBAL_DATUM_INIT(jobban_regex, /regex, regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ## qdel(permabans) // Job tempbans - var/datum/db_query/tempbans = SSdbcore.NewQuery("SELECT ckey, job FROM [format_table_name("ban")] WHERE bantype = 'JOB_TEMPBAN' AND isnull(unbanned) AND expiration_time > Now()") + var/datum/db_query/tempbans = SSdbcore.NewQuery("SELECT ckey, job FROM ban WHERE bantype = 'JOB_TEMPBAN' AND isnull(unbanned) AND expiration_time > Now()") if(!tempbans.warn_execute(async=FALSE)) qdel(tempbans) @@ -152,7 +152,7 @@ GLOBAL_DATUM_INIT(jobban_regex, /regex, regex("(\[\\S]+) - (\[^#]+\[^# ])(?: ## //using the SQL ban system var/is_actually_banned = FALSE var/datum/db_query/select_query = SSdbcore.NewQuery({" - SELECT bantime, bantype, reason, job, duration, expiration_time, a_ckey FROM [format_table_name("ban")] + SELECT bantime, bantype, reason, job, duration, expiration_time, a_ckey FROM ban WHERE ckey LIKE :ckey AND ((bantype like 'JOB_TEMPBAN' AND expiration_time > Now()) OR (bantype like 'JOB_PERMABAN')) AND isnull(unbanned) ORDER BY bantime DESC LIMIT 100"}, list("ckey" = ckey) diff --git a/code/modules/admin/cookielog.dm b/code/modules/admin/cookielog.dm index a2de0c126fe..3f00fb40b36 100644 --- a/code/modules/admin/cookielog.dm +++ b/code/modules/admin/cookielog.dm @@ -35,7 +35,7 @@ var/has_note = FALSE var/raw_text = "" // Now lets see if we have a note logging the infraction in the past - var/datum/db_query/check_existing_note = SSdbcore.NewQuery("SELECT notetext FROM [format_table_name("notes")] WHERE ckey=:ckey AND adminckey=:ackey", list( + var/datum/db_query/check_existing_note = SSdbcore.NewQuery("SELECT notetext FROM notes WHERE ckey=:ckey AND adminckey=:ackey", list( "ckey" = cookie_holder_ckey, "ackey" = COOKIERECORD_PSUEDO_CKEY )) @@ -99,7 +99,7 @@ serialized_text = serialized_list.Join("
") if(has_note) // They have a note. Update. - var/datum/db_query/update_existing_note = SSdbcore.NewQuery("UPDATE [format_table_name("notes")] SET notetext=:nt, timestamp=NOW(), round_id=:rid WHERE ckey=:ckey AND adminckey=:ackey", list( + var/datum/db_query/update_existing_note = SSdbcore.NewQuery("UPDATE notes SET notetext=:nt, timestamp=NOW(), round_id=:rid WHERE ckey=:ckey AND adminckey=:ackey", list( "nt" = serialized_text, "rid" = GLOB.round_id, "ckey" = cookie_holder_ckey, diff --git a/code/modules/admin/db_ban/functions.dm b/code/modules/admin/db_ban/functions.dm index 9d0be1f83b5..d16b61ae690 100644 --- a/code/modules/admin/db_ban/functions.dm +++ b/code/modules/admin/db_ban/functions.dm @@ -86,7 +86,7 @@ message_admins("[key_name_admin(usr)] attempted to add a ban based on a non-existent mob, with no ckey provided. Report this bug.",1) return - var/datum/db_query/query = SSdbcore.NewQuery("SELECT id FROM [format_table_name("player")] WHERE ckey=:ckey", list( + var/datum/db_query/query = SSdbcore.NewQuery("SELECT id FROM player WHERE ckey=:ckey", list( "ckey" = ckey )) if(!query.warn_execute()) @@ -131,7 +131,7 @@ adminwho += ", [C]" if(maxadminbancheck) - var/datum/db_query/adm_query = SSdbcore.NewQuery("SELECT count(id) AS num FROM [format_table_name("ban")] WHERE (a_ckey=:a_ckey) AND (bantype = 'ADMIN_PERMABAN' OR (bantype = 'ADMIN_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)", list( + var/datum/db_query/adm_query = SSdbcore.NewQuery("SELECT count(id) AS num FROM ban WHERE (a_ckey=:a_ckey) AND (bantype = 'ADMIN_PERMABAN' OR (bantype = 'ADMIN_TEMPBAN' AND expiration_time > Now())) AND isnull(unbanned)", list( "a_ckey" = a_ckey )) if(!adm_query.warn_execute()) @@ -146,7 +146,7 @@ qdel(adm_query) var/datum/db_query/query_insert = SSdbcore.NewQuery({" - INSERT INTO [format_table_name("ban")] (`id`,`bantime`,`serverip`,`bantype`,`reason`,`job`,`duration`,`rounds`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`,`edits`,`unbanned`,`unbanned_datetime`,`unbanned_ckey`,`unbanned_computerid`,`unbanned_ip`,`ban_round_id`,`unbanned_round_id`) + INSERT INTO ban (`id`,`bantime`,`serverip`,`bantype`,`reason`,`job`,`duration`,`rounds`,`expiration_time`,`ckey`,`computerid`,`ip`,`a_ckey`,`a_computerid`,`a_ip`,`who`,`adminwho`,`edits`,`unbanned`,`unbanned_datetime`,`unbanned_ckey`,`unbanned_computerid`,`unbanned_ip`,`ban_round_id`,`unbanned_round_id`) VALUES (null, Now(), :serverip, :bantype_str, :reason, :job, :duration, :rounds, Now() + INTERVAL :duration MINUTE, :ckey, :computerid, :ip, :a_ckey, :a_computerid, :a_ip, :who, :adminwho, '', null, null, null, null, null, :roundid, null) "}, list( // Get ready for parameters @@ -233,7 +233,7 @@ else bantype_sql = "bantype = '[bantype_str]'" - var/sql = "SELECT id FROM [format_table_name("ban")] WHERE ckey=:ckey AND [bantype_sql] AND (unbanned is null OR unbanned = false)" + var/sql = "SELECT id FROM ban WHERE ckey=:ckey AND [bantype_sql] AND (unbanned is null OR unbanned = false)" var/list/sql_params = list( "ckey" = ckey ) @@ -283,7 +283,7 @@ to_chat(usr, "Cancelled") return - var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey, duration, reason, job FROM [format_table_name("ban")] WHERE id=:banid", list( + var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey, duration, reason, job FROM ban WHERE id=:banid", list( "banid" = banid )) if(!query.warn_execute()) @@ -318,7 +318,7 @@ return var/edit_reason = "- [eckey] changed ban reason from \\\"[reason]\\\" to \\\"[value]\\\"
" - var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE [format_table_name("ban")] SET reason=:value, edits = CONCAT(IFNULL(edits,''), :edittext) WHERE id=:banid", list( + var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE ban SET reason=:value, edits = CONCAT(IFNULL(edits,''), :edittext) WHERE id=:banid", list( "edittext" = edit_reason, "banid" = banid, "value" = value @@ -337,7 +337,7 @@ return var/edittext = "- [eckey] changed ban duration from [duration] to [value]
" - var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE [format_table_name("ban")] SET duration=:value, edits = CONCAT(IFNULL(edits, ''), :edittext), expiration_time = DATE_ADD(bantime, INTERVAL :value MINUTE) WHERE id=:banid", list( + var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE ban SET duration=:value, edits = CONCAT(IFNULL(edits, ''), :edittext), expiration_time = DATE_ADD(bantime, INTERVAL :value MINUTE) WHERE id=:banid", list( "edittext" = edittext, "banid" = banid, "value" = value @@ -373,7 +373,7 @@ var/ban_number = 0 //failsafe var/pckey - var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("ban")] WHERE id=:banid", list( + var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey FROM ban WHERE id=:banid", list( "banid" = id )) if(!query.warn_execute()) @@ -400,7 +400,7 @@ var/unban_computerid = src.owner:computer_id var/unban_ip = src.owner:address - var/datum/db_query/query_update = SSdbcore.NewQuery("UPDATE [format_table_name("ban")] SET unbanned = 1, unbanned_datetime = Now(), unbanned_ckey=:unban_ckey, unbanned_computerid=:unban_computerid, unbanned_ip=:unban_ip, unbanned_round_id=:roundid WHERE id=:id", list( + var/datum/db_query/query_update = SSdbcore.NewQuery("UPDATE ban SET unbanned = 1, unbanned_datetime = Now(), unbanned_ckey=:unban_ckey, unbanned_computerid=:unban_computerid, unbanned_ip=:unban_ip, unbanned_round_id=:roundid WHERE id=:id", list( "unban_ckey" = unban_ckey, "unban_computerid" = unban_computerid, "unban_ip" = unban_ip, @@ -587,7 +587,7 @@ var/datum/db_query/select_query = SSdbcore.NewQuery({" SELECT id, bantime, bantype, reason, job, duration, expiration_time, ckey, a_ckey, unbanned, unbanned_ckey, unbanned_datetime, edits, ip, computerid, ban_round_id, unbanned_round_id - FROM [format_table_name("ban")] WHERE 1 [playersearch] [adminsearch] [ipsearch] [cidsearch] [bantypesearch] ORDER BY bantime DESC LIMIT 100"}, sql_params) + FROM ban WHERE 1 [playersearch] [adminsearch] [ipsearch] [cidsearch] [bantypesearch] ORDER BY bantime DESC LIMIT 100"}, sql_params) if(!select_query.warn_execute()) qdel(select_query) @@ -673,7 +673,7 @@ /proc/flag_account_for_forum_sync(ckey) if(!SSdbcore.IsConnected()) return - var/datum/db_query/adm_query = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET fupdate = 1 WHERE ckey=:ckey", list( + var/datum/db_query/adm_query = SSdbcore.NewQuery("UPDATE player SET fupdate = 1 WHERE ckey=:ckey", list( "ckey" = ckey )) // We do nothing with output here so we dont need to wrap the warn_execute() inside an if statement diff --git a/code/modules/admin/ipintel.dm b/code/modules/admin/ipintel.dm index e9079d1d289..e85b8a6787a 100644 --- a/code/modules/admin/ipintel.dm +++ b/code/modules/admin/ipintel.dm @@ -37,7 +37,7 @@ if(SSdbcore.IsConnected()) var/datum/db_query/query_get_ip_intel = SSdbcore.NewQuery({" SELECT date, intel, TIMESTAMPDIFF(MINUTE,date,NOW()) - FROM [format_table_name("ipintel")] + FROM ipintel WHERE ip = INET_ATON(:ip) AND (( @@ -73,7 +73,7 @@ SSipintel.cache[ip] = res if(SSdbcore.IsConnected()) var/datum/db_query/query_add_ip_intel = SSdbcore.NewQuery({" - INSERT INTO [format_table_name("ipintel")] (ip, intel) VALUES (INET_ATON(:ip), :intel) + INSERT INTO ipintel (ip, intel) VALUES (INET_ATON(:ip), :intel) ON DUPLICATE KEY UPDATE intel = VALUES(intel), date = NOW()"}, list( "ip" = ip, @@ -171,7 +171,7 @@ log_debug("ipintel_badip_check reports misconfigured ipintel_save_bad directive") return FALSE var/datum/db_query/query_get_ip_intel = SSdbcore.NewQuery({" - SELECT * FROM [format_table_name("ipintel")] WHERE ip = INET_ATON(:target_ip) + SELECT * FROM ipintel WHERE ip = INET_ATON(:target_ip) AND intel >= :rating_bad AND (date + INTERVAL :valid_hours HOUR) > NOW()"}, list( "target_ip" = target_ip, @@ -192,7 +192,7 @@ /proc/vpn_whitelist_check(target_ckey) if(!GLOB.configuration.ipintel.whitelist_mode) return FALSE - var/datum/db_query/query_whitelist_check = SSdbcore.NewQuery("SELECT * FROM [format_table_name("vpn_whitelist")] WHERE ckey=:ckey", list( + var/datum/db_query/query_whitelist_check = SSdbcore.NewQuery("SELECT * FROM vpn_whitelist WHERE ckey=:ckey", list( "ckey" = target_ckey )) if(!query_whitelist_check.warn_execute()) @@ -208,7 +208,7 @@ var/reason_string = input(usr, "Enter link to the URL of their whitelist request on the forum.","Reason required") as message|null if(!reason_string) return FALSE - var/datum/db_query/query_whitelist_add = SSdbcore.NewQuery("INSERT INTO [format_table_name("vpn_whitelist")] (ckey,reason) VALUES (:targetckey, :reason)", list( + var/datum/db_query/query_whitelist_add = SSdbcore.NewQuery("INSERT INTO vpn_whitelist (ckey,reason) VALUES (:targetckey, :reason)", list( "targetckey" = target_ckey, "reason" = reason_string )) @@ -219,7 +219,7 @@ return TRUE /proc/vpn_whitelist_remove(target_ckey) - var/datum/db_query/query_whitelist_remove = SSdbcore.NewQuery("DELETE FROM [format_table_name("vpn_whitelist")] WHERE ckey=:targetckey", list( + var/datum/db_query/query_whitelist_remove = SSdbcore.NewQuery("DELETE FROM vpn_whitelist WHERE ckey=:targetckey", list( "targetckey" = target_ckey )) if(!query_whitelist_remove.warn_execute()) diff --git a/code/modules/admin/permissionverbs/permissionedit.dm b/code/modules/admin/permissionverbs/permissionedit.dm index 86491bce349..a9cf399a259 100644 --- a/code/modules/admin/permissionverbs/permissionedit.dm +++ b/code/modules/admin/permissionverbs/permissionedit.dm @@ -76,7 +76,7 @@ if(!istext(adm_ckey) || !istext(new_rank)) return - var/datum/db_query/select_query = SSdbcore.NewQuery("SELECT id FROM [format_table_name("admin")] WHERE ckey=:adm_ckey", list( + var/datum/db_query/select_query = SSdbcore.NewQuery("SELECT id FROM admin WHERE ckey=:adm_ckey", list( "adm_ckey" = adm_ckey )) if(!select_query.warn_execute()) @@ -91,7 +91,7 @@ qdel(select_query) flag_account_for_forum_sync(adm_ckey) if(new_admin) - var/datum/db_query/insert_query = SSdbcore.NewQuery("INSERT INTO [format_table_name("admin")] (`id`, `ckey`, `admin_rank`, `level`, `flags`) VALUES (null, :adm_ckey, :new_rank, -1, 0)", list( + var/datum/db_query/insert_query = SSdbcore.NewQuery("INSERT INTO admin (`id`, `ckey`, `admin_rank`, `level`, `flags`) VALUES (null, :adm_ckey, :new_rank, -1, 0)", list( "adm_ckey" = adm_ckey, "new_rank" = new_rank )) @@ -101,7 +101,7 @@ qdel(insert_query) var/logtxt = "Added new admin [adm_ckey] to rank [new_rank]" - var/datum/db_query/log_query = SSdbcore.NewQuery("INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , :uckey, :uip, :logtxt)", list( + var/datum/db_query/log_query = SSdbcore.NewQuery("INSERT INTO admin_log (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , :uckey, :uip, :logtxt)", list( "uckey" = usr.ckey, "uip" = usr.client.address, "logtxt" = logtxt @@ -114,7 +114,7 @@ to_chat(usr, "New admin added.") else if(!isnull(admin_id) && isnum(admin_id)) - var/datum/db_query/insert_query = SSdbcore.NewQuery("UPDATE [format_table_name("admin")] SET admin_rank=:new_rank WHERE id=:admin_id", list( + var/datum/db_query/insert_query = SSdbcore.NewQuery("UPDATE admin SET admin_rank=:new_rank WHERE id=:admin_id", list( "new_rank" = new_rank, "admin_id" = admin_id, )) @@ -124,7 +124,7 @@ qdel(insert_query) var/logtxt = "Edited the rank of [adm_ckey] to [new_rank]" - var/datum/db_query/log_query = SSdbcore.NewQuery("INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , :uckey, :uip, :logtxt)", list( + var/datum/db_query/log_query = SSdbcore.NewQuery("INSERT INTO admin_log (`datetime` ,`adminckey` ,`adminip` ,`log` ) VALUES (Now() , :uckey, :uip, :logtxt)", list( "uckey" = usr.ckey, "uip" = usr.client.address, "logtxt" = logtxt, @@ -168,7 +168,7 @@ if(!istext(adm_ckey) || !isnum(new_permission)) return - var/datum/db_query/select_query = SSdbcore.NewQuery("SELECT id, flags FROM [format_table_name("admin")] WHERE ckey=:adm_ckey", list( + var/datum/db_query/select_query = SSdbcore.NewQuery("SELECT id, flags FROM admin WHERE ckey=:adm_ckey", list( "adm_ckey" = adm_ckey )) if(!select_query.warn_execute()) @@ -187,7 +187,7 @@ flag_account_for_forum_sync(adm_ckey) if(admin_rights & new_permission) //This admin already has this permission, so we are removing it. - var/datum/db_query/insert_query = SSdbcore.NewQuery("UPDATE [format_table_name("admin")] SET flags=:newflags WHERE id=:admin_id", list( + var/datum/db_query/insert_query = SSdbcore.NewQuery("UPDATE admin SET flags=:newflags WHERE id=:admin_id", list( "newflags" = (admin_rights & ~new_permission), "admin_id" = admin_id )) @@ -198,7 +198,7 @@ var/logtxt = "Removed permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]" var/datum/db_query/log_query = SSdbcore.NewQuery({" - INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log`) + INSERT INTO admin_log (`datetime` ,`adminckey` ,`adminip` ,`log`) VALUES (Now() , :uckey, :uip, :logtxt)"}, list( "uckey" = usr.ckey, "uip" = usr.client.address, @@ -210,7 +210,7 @@ qdel(log_query) to_chat(usr, "Permission removed.") else //This admin doesn't have this permission, so we are adding it. - var/datum/db_query/insert_query = SSdbcore.NewQuery("UPDATE [format_table_name("admin")] SET flags=:newflags WHERE id=:admin_id", list( + var/datum/db_query/insert_query = SSdbcore.NewQuery("UPDATE admin SET flags=:newflags WHERE id=:admin_id", list( "newflags" = (admin_rights | new_permission), "admin_id" = admin_id )) @@ -221,7 +221,7 @@ var/logtxt = "Added permission [rights2text(new_permission)] (flag = [new_permission]) to admin [adm_ckey]" var/datum/db_query/log_query = SSdbcore.NewQuery({" - INSERT INTO [format_table_name("admin_log")] (`datetime` ,`adminckey` ,`adminip` ,`log`) + INSERT INTO admin_log (`datetime` ,`adminckey` ,`adminip` ,`log`) VALUES (Now() , :uckey, :uip, :logtxt)"}, list( "uckey" = usr.ckey, "uip" = usr.client.address, @@ -240,7 +240,7 @@ if(!check_rights(R_PERMISSIONS)) return - var/datum/db_query/query_update = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET lastadminrank=:admin_rank WHERE ckey=:ckey", list( + var/datum/db_query/query_update = SSdbcore.NewQuery("UPDATE player SET lastadminrank=:admin_rank WHERE ckey=:ckey", list( "admin_rank" = newrank, "ckey" = ckey )) diff --git a/code/modules/admin/sql_notes.dm b/code/modules/admin/sql_notes.dm index 4bbef9829ec..af7a7150d92 100644 --- a/code/modules/admin/sql_notes.dm +++ b/code/modules/admin/sql_notes.dm @@ -15,7 +15,7 @@ else target_ckey = ckey(target_ckey) - var/datum/db_query/query_find_ckey = SSdbcore.NewQuery("SELECT ckey, exp FROM [format_table_name("player")] WHERE ckey=:ckey", list( + var/datum/db_query/query_find_ckey = SSdbcore.NewQuery("SELECT ckey, exp FROM player WHERE ckey=:ckey", list( "ckey" = target_ckey )) @@ -61,7 +61,7 @@ automated = !!automated var/datum/db_query/query_noteadd = SSdbcore.NewQuery({" - INSERT INTO [format_table_name("notes")] (ckey, timestamp, notetext, adminckey, server, crew_playtime, round_id, automated) + INSERT INTO notes (ckey, timestamp, notetext, adminckey, server, crew_playtime, round_id, automated) VALUES (:targetckey, NOW(), :notetext, :adminkey, :server, :crewnum, :roundid, :automated) "}, list( "targetckey" = target_ckey, @@ -95,7 +95,7 @@ if(!note_id) return note_id = text2num(note_id) - var/datum/db_query/query_find_note_del = SSdbcore.NewQuery("SELECT ckey, notetext, adminckey FROM [format_table_name("notes")] WHERE id=:note_id", list( + var/datum/db_query/query_find_note_del = SSdbcore.NewQuery("SELECT ckey, notetext, adminckey FROM notes WHERE id=:note_id", list( "note_id" = note_id )) if(!query_find_note_del.warn_execute()) @@ -107,7 +107,7 @@ adminckey = query_find_note_del.item[3] qdel(query_find_note_del) - var/datum/db_query/query_del_note = SSdbcore.NewQuery("DELETE FROM [format_table_name("notes")] WHERE id=:note_id", list( + var/datum/db_query/query_del_note = SSdbcore.NewQuery("DELETE FROM notes WHERE id=:note_id", list( "note_id" = note_id )) if(!query_del_note.warn_execute()) @@ -130,7 +130,7 @@ return note_id = text2num(note_id) var/target_ckey - var/datum/db_query/query_find_note_edit = SSdbcore.NewQuery("SELECT ckey, notetext, adminckey, automated FROM [format_table_name("notes")] WHERE id=:note_id", list( + var/datum/db_query/query_find_note_edit = SSdbcore.NewQuery("SELECT ckey, notetext, adminckey, automated FROM notes WHERE id=:note_id", list( "note_id" = note_id )) if(!query_find_note_edit.warn_execute()) @@ -148,7 +148,7 @@ if(!new_note) return var/edit_text = "Edited by [usr.ckey] on [SQLtime()] from \"[old_note]\" to \"[new_note]\"
" - var/datum/db_query/query_update_note = SSdbcore.NewQuery("UPDATE [format_table_name("notes")] SET notetext=:new_note, last_editor=:akey, edits = CONCAT(IFNULL(edits,''),:edit_text) WHERE id=:note_id", list( + var/datum/db_query/query_update_note = SSdbcore.NewQuery("UPDATE notes SET notetext=:new_note, last_editor=:akey, edits = CONCAT(IFNULL(edits,''),:edit_text) WHERE id=:note_id", list( "new_note" = new_note, "akey" = usr.ckey, "edit_text" = edit_text, @@ -182,7 +182,7 @@ var/target_sql_ckey = ckey(target_ckey) var/datum/db_query/query_get_notes = SSdbcore.NewQuery({" SELECT id, timestamp, notetext, adminckey, last_editor, server, crew_playtime, round_id, automated - FROM [format_table_name("notes")] WHERE ckey=:targetkey ORDER BY timestamp"}, list( + FROM notes WHERE ckey=:targetkey ORDER BY timestamp"}, list( "targetkey" = target_sql_ckey )) if(!query_get_notes.warn_execute()) @@ -226,7 +226,7 @@ search = "^\[^\[:alpha:\]\]" else search = "^[index]" - var/datum/db_query/query_list_notes = SSdbcore.NewQuery("SELECT DISTINCT ckey FROM [format_table_name("notes")] WHERE ckey REGEXP :search ORDER BY ckey", list( + var/datum/db_query/query_list_notes = SSdbcore.NewQuery("SELECT DISTINCT ckey FROM notes WHERE ckey REGEXP :search ORDER BY ckey", list( "search" = search )) if(!query_list_notes.warn_execute()) diff --git a/code/modules/admin/topic.dm b/code/modules/admin/topic.dm index f0232622f8e..eea32e43bcb 100644 --- a/code/modules/admin/topic.dm +++ b/code/modules/admin/topic.dm @@ -1017,7 +1017,7 @@ else if(href_list["noteedits"]) var/note_id = text2num(href_list["noteedits"]) - var/datum/db_query/query_noteedits = SSdbcore.NewQuery("SELECT edits FROM [format_table_name("notes")] WHERE id=:note_id", list( + var/datum/db_query/query_noteedits = SSdbcore.NewQuery("SELECT edits FROM notes WHERE id=:note_id", list( "note_id" = note_id )) if(!query_noteedits.warn_execute()) @@ -1132,7 +1132,7 @@ else if(href_list["watcheditlog"]) var/target_ckey = href_list["watcheditlog"] - var/datum/db_query/query_watchedits = SSdbcore.NewQuery("SELECT edits FROM [format_table_name("watch")] WHERE ckey=:targetkey", list( + var/datum/db_query/query_watchedits = SSdbcore.NewQuery("SELECT edits FROM watch WHERE ckey=:targetkey", list( "targetkey" = target_ckey )) if(!query_watchedits.warn_execute()) @@ -2840,7 +2840,7 @@ else if(href_list["memoeditlist"]) if(!check_rights(R_SERVER)) return var/sql_key = href_list["memoeditlist"] - var/datum/db_query/query_memoedits = SSdbcore.NewQuery("SELECT edits FROM [format_table_name("memo")] WHERE (ckey=:sql_key)", list( + var/datum/db_query/query_memoedits = SSdbcore.NewQuery("SELECT edits FROM memo WHERE (ckey=:sql_key)", list( "sql_key" = sql_key )) if(!query_memoedits.warn_execute()) @@ -3393,7 +3393,7 @@ var/isbn = text2num(href_list["library_book_id"]) if(href_list["view_library_book"]) - var/datum/db_query/query_view_book = SSdbcore.NewQuery("SELECT content, title FROM [format_table_name("library")] WHERE id=:isbn", list( + var/datum/db_query/query_view_book = SSdbcore.NewQuery("SELECT content, title FROM library WHERE id=:isbn", list( "isbn" = isbn )) if(!query_view_book.warn_execute()) @@ -3420,7 +3420,7 @@ return else if(href_list["unflag_library_book"]) - var/datum/db_query/query_unflag_book = SSdbcore.NewQuery("UPDATE [format_table_name("library")] SET flagged = 0 WHERE id=:isbn", list( + var/datum/db_query/query_unflag_book = SSdbcore.NewQuery("UPDATE library SET flagged = 0 WHERE id=:isbn", list( "isbn" = isbn )) if(!query_unflag_book.warn_execute()) @@ -3432,7 +3432,7 @@ message_admins("[key_name_admin(usr)] has unflagged the book [isbn].") else if(href_list["delete_library_book"]) - var/datum/db_query/query_delbook = SSdbcore.NewQuery("DELETE FROM [format_table_name("library")] WHERE id=:isbn", list( + var/datum/db_query/query_delbook = SSdbcore.NewQuery("DELETE FROM library WHERE id=:isbn", list( "isbn" = isbn )) if(!query_delbook.warn_execute()) @@ -3500,7 +3500,7 @@ var/unlocked_jobs = "" var/unlocked_species = "" // Get their totals - var/datum/db_query/query_get_totals = SSdbcore.NewQuery("SELECT karma, karmaspent FROM [format_table_name("karmatotals")] WHERE byondkey=:ckey", list( + var/datum/db_query/query_get_totals = SSdbcore.NewQuery("SELECT karma, karmaspent FROM karmatotals WHERE byondkey=:ckey", list( "ckey" = target_ckey )) if(!query_get_totals.warn_execute()) @@ -3514,7 +3514,7 @@ qdel(query_get_totals) // Now get their unlocks - var/datum/db_query/query_get_unlocks = SSdbcore.NewQuery("SELECT job, species FROM [format_table_name("whitelist")] WHERE ckey=:ckey", list( + var/datum/db_query/query_get_unlocks = SSdbcore.NewQuery("SELECT job, species FROM whitelist WHERE ckey=:ckey", list( "ckey" = target_ckey )) if(!query_get_unlocks.warn_execute()) diff --git a/code/modules/admin/watchlist.dm b/code/modules/admin/watchlist.dm index df6a56933f4..89288bd13ab 100644 --- a/code/modules/admin/watchlist.dm +++ b/code/modules/admin/watchlist.dm @@ -5,7 +5,7 @@ var/new_ckey = ckey(clean_input("Who would you like to add to the watchlist?","Enter a ckey",null)) if(!new_ckey) return - var/datum/db_query/query_watchfind = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ckey=:new_ckey", list( + var/datum/db_query/query_watchfind = SSdbcore.NewQuery("SELECT ckey FROM player WHERE ckey=:new_ckey", list( "new_ckey" = new_ckey )) if(!query_watchfind.warn_execute()) @@ -27,7 +27,7 @@ if(!adminckey) return var/datum/db_query/query_watchadd = SSdbcore.NewQuery({" - INSERT INTO [format_table_name("watch")] (ckey, reason, adminckey, timestamp) + INSERT INTO watch (ckey, reason, adminckey, timestamp) VALUES (:targetkey, :reason, :adminkey, NOW())"}, list( "targetkey" = target_ckey, @@ -50,7 +50,7 @@ /client/proc/watchlist_remove(target_ckey, browse = 0) if(!check_rights(R_ADMIN)) return - var/datum/db_query/query_watchdel = SSdbcore.NewQuery("DELETE FROM [format_table_name("watch")] WHERE ckey=:target_ckey", list( + var/datum/db_query/query_watchdel = SSdbcore.NewQuery("DELETE FROM watch WHERE ckey=:target_ckey", list( "target_ckey" = target_ckey )) if(!query_watchdel.warn_execute()) @@ -68,7 +68,7 @@ /client/proc/watchlist_edit(target_ckey, browse = 0) if(!check_rights(R_ADMIN)) return - var/datum/db_query/query_watchreason = SSdbcore.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey=:target_ckey", list( + var/datum/db_query/query_watchreason = SSdbcore.NewQuery("SELECT reason FROM watch WHERE ckey=:target_ckey", list( "target_ckey" = target_ckey )) if(!query_watchreason.warn_execute()) @@ -82,7 +82,7 @@ var/sql_ckey = usr.ckey var/edit_text = "Edited by [sql_ckey] on [SQLtime()] from \"[watch_reason]\" to \"[new_reason]\"" - var/datum/db_query/query_watchupdate = SSdbcore.NewQuery("UPDATE [format_table_name("watch")] SET reason=:new_reason, last_editor=:sql_ckey, edits = CONCAT(IFNULL(edits,''), :edit_text) WHERE ckey=:target_ckey", list( + var/datum/db_query/query_watchupdate = SSdbcore.NewQuery("UPDATE watch SET reason=:new_reason, last_editor=:sql_ckey, edits = CONCAT(IFNULL(edits,''), :edit_text) WHERE ckey=:target_ckey", list( "new_reason" = new_reason, "sql_ckey" = sql_ckey, "edit_text" = edit_text, @@ -114,7 +114,7 @@ else search = "^." - var/datum/db_query/query_watchlist = SSdbcore.NewQuery("SELECT ckey, reason, adminckey, timestamp, last_editor FROM [format_table_name("watch")] WHERE ckey REGEXP :search ORDER BY ckey", list( + var/datum/db_query/query_watchlist = SSdbcore.NewQuery("SELECT ckey, reason, adminckey, timestamp, last_editor FROM watch WHERE ckey REGEXP :search ORDER BY ckey", list( "search" = search )) if(!query_watchlist.warn_execute()) @@ -134,7 +134,7 @@ qdel(query_watchlist) /proc/check_watchlist(target_ckey) - var/datum/db_query/query_watch = SSdbcore.NewQuery("SELECT reason FROM [format_table_name("watch")] WHERE ckey=:target_ckey", list( + var/datum/db_query/query_watch = SSdbcore.NewQuery("SELECT reason FROM watch WHERE ckey=:target_ckey", list( "target_ckey" = target_ckey )) if(!query_watch.warn_execute()) diff --git a/code/modules/client/2fa.dm b/code/modules/client/2fa.dm index d51d41e13d6..930670d1867 100644 --- a/code/modules/client/2fa.dm +++ b/code/modules/client/2fa.dm @@ -27,7 +27,7 @@ var/entered_code = input(usr, "Please enter a code from your auth app. Failure to enter the code correctly will abort 2FA setup.", "2FA Validation") if(!entered_code) // Cleanup so they can start again - var/datum/db_query/dbq = SSdbcore.NewQuery("DELETE FROM [format_table_name("2fa_secrets")] WHERE ckey=:ckey", list("ckey" = ckey)) + var/datum/db_query/dbq = SSdbcore.NewQuery("DELETE FROM 2fa_secrets WHERE ckey=:ckey", list("ckey" = ckey)) dbq.warn_execute() alert(usr, "2FA Setup aborted!") B.close() @@ -42,7 +42,7 @@ if(vr.status_code != 200) // Cleanup so they can start again - var/datum/db_query/dbq = SSdbcore.NewQuery("DELETE FROM [format_table_name("2fa_secrets")] WHERE ckey=:ckey", list("ckey" = ckey)) + var/datum/db_query/dbq = SSdbcore.NewQuery("DELETE FROM 2fa_secrets WHERE ckey=:ckey", list("ckey" = ckey)) dbq.warn_execute() // See if its unauthorised. I used 400 for that dont at me @@ -101,7 +101,7 @@ return // If we are here, they authed properly - var/datum/db_query/dbq = SSdbcore.NewQuery("DELETE FROM [format_table_name("2fa_secrets")] WHERE ckey=:ckey", list("ckey" = ckey)) + var/datum/db_query/dbq = SSdbcore.NewQuery("DELETE FROM 2fa_secrets WHERE ckey=:ckey", list("ckey" = ckey)) dbq.warn_execute() prefs._2fa_status = _2FA_DISABLED prefs.save_preferences(src) diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm index 5622cbc5b95..1415f0b1c01 100644 --- a/code/modules/client/client_procs.dm +++ b/code/modules/client/client_procs.dm @@ -442,7 +442,7 @@ return //Donator stuff. - var/datum/db_query/query_donor_select = SSdbcore.NewQuery("SELECT ckey, tier, active FROM `[format_table_name("donators")]` WHERE ckey=:ckey", list( + var/datum/db_query/query_donor_select = SSdbcore.NewQuery("SELECT ckey, tier, active FROM donators WHERE ckey=:ckey", list( "ckey" = ckey )) @@ -473,7 +473,7 @@ if(!SSdbcore.IsConnected()) return - var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, datediff(Now(),firstseen) as age FROM [format_table_name("player")] WHERE ckey=:ckey", list( + var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, datediff(Now(),firstseen) as age FROM player WHERE ckey=:ckey", list( "ckey" = ckey )) if(!query.warn_execute()) @@ -488,7 +488,7 @@ break qdel(query) - var/datum/db_query/query_ip = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE ip=:address", list( + var/datum/db_query/query_ip = SSdbcore.NewQuery("SELECT ckey FROM player WHERE ip=:address", list( "address" = address )) if(!query_ip.warn_execute()) @@ -501,7 +501,7 @@ qdel(query_ip) - var/datum/db_query/query_cid = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("player")] WHERE computerid=:cid", list( + var/datum/db_query/query_cid = SSdbcore.NewQuery("SELECT ckey FROM player WHERE computerid=:cid", list( "cid" = computer_id )) if(!query_cid.warn_execute()) @@ -548,7 +548,7 @@ if(!client_address) // Localhost can sometimes have no address set client_address = "127.0.0.1" //Player already identified previously, we need to just update the 'lastseen', 'ip' and 'computer_id' variables - var/datum/db_query/query_update = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET lastseen = Now(), ip=:sql_ip, computerid=:sql_cid, lastadminrank=:sql_ar WHERE id=:sql_id", list( + var/datum/db_query/query_update = SSdbcore.NewQuery("UPDATE player SET lastseen = Now(), ip=:sql_ip, computerid=:sql_cid, lastadminrank=:sql_ar WHERE id=:sql_id", list( "sql_ip" = client_address, "sql_cid" = computer_id, "sql_ar" = admin_rank, @@ -572,7 +572,7 @@ qdel(src) return // Dont insert or they can just go in again - var/datum/db_query/query_insert = SSdbcore.NewQuery("INSERT INTO [format_table_name("player")] (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank) VALUES (null, :ckey, Now(), Now(), :ip, :cid, :rank)", list( + var/datum/db_query/query_insert = SSdbcore.NewQuery("INSERT INTO player (id, ckey, firstseen, lastseen, ip, computerid, lastadminrank) VALUES (null, :ckey, Now(), Now(), :ip, :cid, :rank)", list( "ckey" = ckey, "ip" = address, "cid" = computer_id, @@ -635,7 +635,7 @@ to_chat(src, "You have no verified forum account.
VERIFY FORUM ACCOUNT") /client/proc/create_oauth_token() - var/datum/db_query/query_find_token = SSdbcore.NewQuery("SELECT token FROM [format_table_name("oauth_tokens")] WHERE ckey=:ckey limit 1", list( + var/datum/db_query/query_find_token = SSdbcore.NewQuery("SELECT token FROM oauth_tokens WHERE ckey=:ckey limit 1", list( "ckey" = ckey )) // These queries have log_error=FALSE to avoid auth tokens being in plaintext logs @@ -650,7 +650,7 @@ var/tokenstr = md5("[rand(0,9999)][world.time][rand(0,9999)][ckey][rand(0,9999)][address][rand(0,9999)][computer_id][rand(0,9999)]") - var/datum/db_query/query_insert_token = SSdbcore.NewQuery("INSERT INTO [format_table_name("oauth_tokens")] (ckey, token) VALUES(:ckey, :tokenstr)", list( + var/datum/db_query/query_insert_token = SSdbcore.NewQuery("INSERT INTO oauth_tokens (ckey, token) VALUES(:ckey, :tokenstr)", list( "ckey" = ckey, "tokenstr" = tokenstr, )) @@ -671,7 +671,7 @@ if(!fromban) to_chat(src, "Your forum account is already set.") return - var/datum/db_query/query_find_link = SSdbcore.NewQuery("SELECT fuid FROM [format_table_name("player")] WHERE ckey=:ckey LIMIT 1", list( + var/datum/db_query/query_find_link = SSdbcore.NewQuery("SELECT fuid FROM player WHERE ckey=:ckey LIMIT 1", list( "ckey" = ckey )) if(!query_find_link.warn_execute()) @@ -720,7 +720,7 @@ var/oldcid = cidcheck[ckey] if(!oldcid) - var/datum/db_query/query_cidcheck = SSdbcore.NewQuery("SELECT computerid FROM [format_table_name("player")] WHERE ckey=:ckey", list( + var/datum/db_query/query_cidcheck = SSdbcore.NewQuery("SELECT computerid FROM player WHERE ckey=:ckey", list( "ckey" = ckey )) if(!query_cidcheck.warn_execute()) @@ -790,7 +790,7 @@ var/const/adminckey = "CID-Error" // Check for notes in the last day - only 1 note per 24 hours - var/datum/db_query/query_get_notes = SSdbcore.NewQuery("SELECT id from [format_table_name("notes")] WHERE ckey=:ckey AND adminckey=:adminckey AND timestamp + INTERVAL 1 DAY < NOW()", list( + var/datum/db_query/query_get_notes = SSdbcore.NewQuery("SELECT id from notes WHERE ckey=:ckey AND adminckey=:adminckey AND timestamp + INTERVAL 1 DAY < NOW()", list( "ckey" = ckey, "adminckey" = adminckey )) @@ -803,7 +803,7 @@ qdel(query_get_notes) // Only add a note if their most recent note isn't from the randomizer blocker, either - var/datum/db_query/query_get_note = SSdbcore.NewQuery("SELECT adminckey FROM [format_table_name("notes")] WHERE ckey=:ckey ORDER BY timestamp DESC LIMIT 1", list( + var/datum/db_query/query_get_note = SSdbcore.NewQuery("SELECT adminckey FROM notes WHERE ckey=:ckey ORDER BY timestamp DESC LIMIT 1", list( "ckey" = ckey )) if(!query_get_note.warn_execute()) @@ -1053,7 +1053,7 @@ */ /client/proc/get_byond_account_date(notify = FALSE) // First we see if the client has a saved date in the DB - var/datum/db_query/query_date = SSdbcore.NewQuery("SELECT byond_date, DATEDIFF(Now(), byond_date) FROM [format_table_name("player")] WHERE ckey=:ckey", list( + var/datum/db_query/query_date = SSdbcore.NewQuery("SELECT byond_date, DATEDIFF(Now(), byond_date) FROM player WHERE ckey=:ckey", list( "ckey" = ckey )) if(!query_date.warn_execute()) @@ -1079,7 +1079,7 @@ byondacc_date = byond_data["general"]["joined"] // Now save it - var/datum/db_query/query_update = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET byond_date=:date WHERE ckey=:ckey", list( + var/datum/db_query/query_update = SSdbcore.NewQuery("UPDATE player SET byond_date=:date WHERE ckey=:ckey", list( "date" = byondacc_date, "ckey" = ckey )) @@ -1089,7 +1089,7 @@ qdel(query_update) // Now retrieve the age again because BYOND doesnt have native methods for this - var/datum/db_query/query_age = SSdbcore.NewQuery("SELECT DATEDIFF(Now(), byond_date) FROM [format_table_name("player")] WHERE ckey=:ckey", list( + var/datum/db_query/query_age = SSdbcore.NewQuery("SELECT DATEDIFF(Now(), byond_date) FROM player WHERE ckey=:ckey", list( "ckey" = ckey )) if(!query_age.warn_execute()) @@ -1124,7 +1124,7 @@ tos_consent = TRUE return TRUE - var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey FROM [format_table_name("privacy")] WHERE ckey=:ckey AND consent=1", list( + var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey FROM privacy WHERE ckey=:ckey AND consent=1", list( "ckey" = ckey )) if(!query.warn_execute()) @@ -1172,7 +1172,7 @@ // Check their notes for CID tracking in the past var/has_note = FALSE var/note_text = "" - var/datum/db_query/query_find_track_note = SSdbcore.NewQuery("SELECT notetext FROM [format_table_name("notes")] WHERE ckey=:ckey AND adminckey=:ackey", list( + var/datum/db_query/query_find_track_note = SSdbcore.NewQuery("SELECT notetext FROM notes WHERE ckey=:ckey AND adminckey=:ackey", list( "ckey" = ckey, "ackey" = CIDTRACKING_PSUEDO_CKEY )) @@ -1189,7 +1189,7 @@ var/new_text = "Connected on the date of this note with unique CID #[cidcount]" // Only update the note if the text is different. Otherwise it bumps the timestamp when it shouldnt if(note_text != new_text) - var/datum/db_query/query_update_track_note = SSdbcore.NewQuery("UPDATE [format_table_name("notes")] SET notetext=:notetext, timestamp=NOW(), round_id=:rid WHERE ckey=:ckey AND adminckey=:ackey", list( + var/datum/db_query/query_update_track_note = SSdbcore.NewQuery("UPDATE notes SET notetext=:notetext, timestamp=NOW(), round_id=:rid WHERE ckey=:ckey AND adminckey=:ackey", list( "notetext" = new_text, "ckey" = ckey, "ackey" = CIDTRACKING_PSUEDO_CKEY, @@ -1207,7 +1207,7 @@ var/show_warning = TRUE // Check if they have a note that matches the warning suppressor - var/datum/db_query/query_find_note = SSdbcore.NewQuery("SELECT id FROM [format_table_name("notes")] WHERE ckey=:ckey AND notetext=:notetext", list( + var/datum/db_query/query_find_note = SSdbcore.NewQuery("SELECT id FROM notes WHERE ckey=:ckey AND notetext=:notetext", list( "ckey" = ckey, "notetext" = CIDWARNING_SUPPRESSED_NOTETEXT )) diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 66fff042534..1979be243fa 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -2299,7 +2299,7 @@ GLOBAL_LIST_INIT(special_role_times, list( //minimum age (in days) for accounts /datum/preferences/proc/open_load_dialog(mob/user) - var/datum/db_query/query = SSdbcore.NewQuery("SELECT slot, real_name FROM [format_table_name("characters")] WHERE ckey=:ckey ORDER BY slot", list( + var/datum/db_query/query = SSdbcore.NewQuery("SELECT slot, real_name FROM characters WHERE ckey=:ckey ORDER BY slot", list( "ckey" = user.ckey )) var/list/slotnames[max_save_slots] diff --git a/code/modules/client/preference/preferences_mysql.dm b/code/modules/client/preference/preferences_mysql.dm index bcb5823af6a..77f11729293 100644 --- a/code/modules/client/preference/preferences_mysql.dm +++ b/code/modules/client/preference/preferences_mysql.dm @@ -18,7 +18,7 @@ fuid, parallax, 2fa_status - FROM [format_table_name("player")] + FROM player WHERE ckey=:ckey"}, list( "ckey" = C.ckey )) @@ -80,7 +80,7 @@ deltimer(volume_mixer_saving) volume_mixer_saving = null - var/datum/db_query/query = SSdbcore.NewQuery({"UPDATE [format_table_name("player")] + var/datum/db_query/query = SSdbcore.NewQuery({"UPDATE player SET ooccolor=:ooccolour, UI_style=:ui_style, @@ -133,7 +133,7 @@ slot = sanitize_integer(slot, 1, max_save_slots, initial(default_slot)) if(slot != default_slot) default_slot = slot - var/datum/db_query/firstquery = SSdbcore.NewQuery("UPDATE [format_table_name("player")] SET default_slot=:slot WHERE ckey=:ckey", list( + var/datum/db_query/firstquery = SSdbcore.NewQuery("UPDATE player SET default_slot=:slot WHERE ckey=:ckey", list( "slot" = slot, "ckey" = C.ckey )) @@ -196,7 +196,7 @@ body_accessory, gear, autohiss - FROM [format_table_name("characters")] WHERE ckey=:ckey AND slot=:slot"}, list( + FROM characters WHERE ckey=:ckey AND slot=:slot"}, list( "ckey" = C.ckey, "slot" = slot )) @@ -360,7 +360,7 @@ if(!isemptylist(loadout_gear)) gearlist = list2params(loadout_gear) - var/datum/db_query/firstquery = SSdbcore.NewQuery("SELECT slot FROM [format_table_name("characters")] WHERE ckey=:ckey ORDER BY slot", list( + var/datum/db_query/firstquery = SSdbcore.NewQuery("SELECT slot FROM characters WHERE ckey=:ckey ORDER BY slot", list( "ckey" = C.ckey )) if(!firstquery.warn_execute()) @@ -368,7 +368,7 @@ return while(firstquery.NextRow()) if(text2num(firstquery.item[1]) == default_slot) - var/datum/db_query/query = SSdbcore.NewQuery({"UPDATE [format_table_name("characters")] + var/datum/db_query/query = SSdbcore.NewQuery({"UPDATE characters SET OOC_Notes=:metadata, real_name=:real_name, @@ -493,7 +493,7 @@ qdel(firstquery) var/datum/db_query/query = SSdbcore.NewQuery({" - INSERT INTO [format_table_name("characters")] (ckey, slot, OOC_Notes, real_name, name_is_always_random, gender, + INSERT INTO characters (ckey, slot, OOC_Notes, real_name, name_is_always_random, gender, age, species, language, hair_colour, secondary_hair_colour, facial_hair_colour, secondary_facial_hair_colour, @@ -615,7 +615,7 @@ return 1 /datum/preferences/proc/load_random_character_slot(client/C) - var/datum/db_query/query = SSdbcore.NewQuery("SELECT slot FROM [format_table_name("characters")] WHERE ckey=:ckey ORDER BY slot", list( + var/datum/db_query/query = SSdbcore.NewQuery("SELECT slot FROM characters WHERE ckey=:ckey ORDER BY slot", list( "ckey" = C.ckey )) var/list/saves = list() @@ -637,7 +637,7 @@ /datum/preferences/proc/clear_character_slot(client/C) . = FALSE // Is there a character in that slot? - var/datum/db_query/query = SSdbcore.NewQuery("SELECT slot FROM [format_table_name("characters")] WHERE ckey=:ckey AND slot=:slot", list( + var/datum/db_query/query = SSdbcore.NewQuery("SELECT slot FROM characters WHERE ckey=:ckey AND slot=:slot", list( "ckey" = C.ckey, "slot" = default_slot )) @@ -652,7 +652,7 @@ qdel(query) - var/datum/db_query/delete_query = SSdbcore.NewQuery("DELETE FROM [format_table_name("characters")] WHERE ckey=:ckey AND slot=:slot", list( + var/datum/db_query/delete_query = SSdbcore.NewQuery("DELETE FROM characters WHERE ckey=:ckey AND slot=:slot", list( "ckey" = C.ckey, "slot" = default_slot )) @@ -673,7 +673,7 @@ volume_mixer_saving = null var/datum/db_query/update_query = SSdbcore.NewQuery( - "UPDATE [format_table_name("player")] SET volume_mixer=:volume_mixer WHERE ckey=:ckey", + "UPDATE player SET volume_mixer=:volume_mixer WHERE ckey=:ckey", list( "volume_mixer" = serialize_volume_mixer(volume_mixer), "ckey" = parent.ckey diff --git a/code/modules/customitems/item_spawning.dm b/code/modules/customitems/item_spawning.dm index 33566ddfef8..5f998861cf6 100644 --- a/code/modules/customitems/item_spawning.dm +++ b/code/modules/customitems/item_spawning.dm @@ -4,7 +4,7 @@ // Grab the info we want. var/datum/db_query/query = SSdbcore.NewQuery({" - SELECT cuiPath, cuiPropAdjust, cuiJobMask, cuiDescription, cuiItemName FROM [format_table_name("customuseritems")] + SELECT cuiPath, cuiPropAdjust, cuiJobMask, cuiDescription, cuiItemName FROM customuseritems WHERE cuiCKey=:ckey AND (cuiRealName=:realname OR cuiRealName='*')"}, list( "ckey" = M.ckey, "realname" = M.real_name diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm index 6c011da5b2f..02d0f4edb0f 100644 --- a/code/modules/karma/karma.dm +++ b/code/modules/karma/karma.dm @@ -16,7 +16,7 @@ return var/datum/db_query/log_query = SSdbcore.NewQuery({" - INSERT INTO [format_table_name("karma")] (spendername, spenderkey, receivername, receiverkey, receiverrole, receiverspecial, spenderip, time) + INSERT INTO karma (spendername, spenderkey, receivername, receiverkey, receiverrole, receiverspecial, spenderip, time) VALUES (:sname, :skey, :rname, :rkey, :rrole, :rspecial, :sip, Now())"}, list( "sname" = spender.name, "skey" = spender.ckey, @@ -33,7 +33,7 @@ qdel(log_query) - var/datum/db_query/select_spender = SSdbcore.NewQuery("SELECT id, karma FROM [format_table_name("karmatotals")] WHERE byondkey=:rkey", list( + var/datum/db_query/select_spender = SSdbcore.NewQuery("SELECT id, karma FROM karmatotals WHERE byondkey=:rkey", list( "rkey" = receiver.ckey )) @@ -52,7 +52,7 @@ if(karma == null) karma = 1 - var/datum/db_query/insert_query = SSdbcore.NewQuery("INSERT INTO [format_table_name("karmatotals")] (byondkey, karma) VALUES (:rkey, :karma)", list( + var/datum/db_query/insert_query = SSdbcore.NewQuery("INSERT INTO karmatotals (byondkey, karma) VALUES (:rkey, :karma)", list( "rkey" = receiver.ckey, "karma" = karma )) @@ -62,7 +62,7 @@ qdel(insert_query) else karma++ - var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE [format_table_name("karmatotals")] SET karma=:karma WHERE id=:id", list( + var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE karmatotals SET karma=:karma WHERE id=:id", list( "karma" = karma, "id" = id )) @@ -197,7 +197,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) to_chat(usr, "Unable to connect to karma database. Please try again later.
") return - var/datum/db_query/query = SSdbcore.NewQuery("SELECT karma, karmaspent FROM [format_table_name("karmatotals")] WHERE byondkey=:ckey", list( + var/datum/db_query/query = SSdbcore.NewQuery("SELECT karma, karmaspent FROM karmatotals WHERE byondkey=:ckey", list( "ckey" = ckey )) if(!query.warn_execute()) @@ -225,7 +225,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) karmashopmenu() /client/proc/karmashopmenu() - var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey, job, species FROM [format_table_name("whitelist")] WHERE ckey=:ckey", list( + var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey, job, species FROM whitelist WHERE ckey=:ckey", list( "ckey" = ckey )) if(!query.warn_execute()) @@ -383,7 +383,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) karmashopmenu() /client/proc/DB_job_unlock(job, cost) - var/datum/db_query/select_query = SSdbcore.NewQuery("SELECT ckey, job FROM [format_table_name("whitelist")] WHERE ckey=:ckey", list( + var/datum/db_query/select_query = SSdbcore.NewQuery("SELECT ckey, job FROM whitelist WHERE ckey=:ckey", list( "ckey" = ckey )) if(!select_query.warn_execute()) @@ -398,7 +398,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) qdel(select_query) if(!dbckey) - var/datum/db_query/insert_query = SSdbcore.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, job) VALUES (:ckey, :job)", list( + var/datum/db_query/insert_query = SSdbcore.NewQuery("INSERT INTO whitelist (ckey, job) VALUES (:ckey, :job)", list( "ckey" = ckey, "job" = job )) @@ -417,7 +417,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) if(!(job in joblist)) joblist += job var/newjoblist = jointext(joblist,",") - var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE [format_table_name("whitelist")] SET job=:newjoblist WHERE ckey=:ckey", list( + var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE whitelist SET job=:newjoblist WHERE ckey=:ckey", list( "newjoblist" = newjoblist, "ckey" = ckey )) @@ -434,7 +434,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) return /client/proc/DB_species_unlock(species, cost) - var/datum/db_query/select_query = SSdbcore.NewQuery("SELECT ckey, species FROM [format_table_name("whitelist")] WHERE ckey=:ckey", list( + var/datum/db_query/select_query = SSdbcore.NewQuery("SELECT ckey, species FROM whitelist WHERE ckey=:ckey", list( "ckey" = ckey )) if(!select_query.warn_execute()) @@ -448,7 +448,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) dbspecies = select_query.item[2] qdel(select_query) if(!dbckey) - var/datum/db_query/insert_query = SSdbcore.NewQuery("INSERT INTO [format_table_name("whitelist")] (ckey, species) VALUES (:ckey, :species)", list( + var/datum/db_query/insert_query = SSdbcore.NewQuery("INSERT INTO whitelist (ckey, species) VALUES (:ckey, :species)", list( "ckey" = ckey, "species" = species )) @@ -466,7 +466,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) if(!(species in specieslist)) specieslist += species var/newspecieslist = jointext(specieslist,",") - var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE [format_table_name("whitelist")] SET species=:newspecieslist WHERE ckey=:ckey", list( + var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE whitelist SET species=:newspecieslist WHERE ckey=:ckey", list( "newspecieslist" = newspecieslist, "ckey" = ckey )) @@ -483,7 +483,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) return /client/proc/karmacharge(cost, refund = FALSE) - var/datum/db_query/select_query = SSdbcore.NewQuery("SELECT karmaspent FROM [format_table_name("karmatotals")] WHERE byondkey=:ckey", list( + var/datum/db_query/select_query = SSdbcore.NewQuery("SELECT karmaspent FROM karmatotals WHERE byondkey=:ckey", list( "ckey" = ckey )) if(!select_query.warn_execute()) @@ -496,7 +496,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) spent -= cost else spent += cost - var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE [format_table_name("karmatotals")] SET karmaspent=:spent WHERE byondkey=:ckey", list( + var/datum/db_query/update_query = SSdbcore.NewQuery("UPDATE karmatotals SET karmaspent=:spent WHERE byondkey=:ckey", list( "spent" = spent, "ckey" = ckey )) @@ -522,7 +522,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) to_chat(usr, "That job is not refundable.") return - var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey, job, species FROM [format_table_name("whitelist")] WHERE ckey=:ckey", list( + var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey, job, species FROM whitelist WHERE ckey=:ckey", list( "ckey" = ckey )) if(!query.warn_execute()) @@ -545,10 +545,10 @@ GLOBAL_LIST_EMPTY(karma_spenders) switch(type) if("job") typelist = splittext(dbjob,",") - statement = "UPDATE [format_table_name("whitelist")] SET job=:newtypelist WHERE ckey=:ckey" + statement = "UPDATE whitelist SET job=:newtypelist WHERE ckey=:ckey" if("species") typelist = splittext(dbspecies,",") - statement = "UPDATE [format_table_name("whitelist")] SET species=:newtypelist WHERE ckey=:ckey" + statement = "UPDATE whitelist SET species=:newtypelist WHERE ckey=:ckey" else to_chat(usr, "Type [type] is not a valid column.") @@ -574,7 +574,7 @@ GLOBAL_LIST_EMPTY(karma_spenders) to_chat(usr, "Your ckey ([dbckey]) was not found.") /client/proc/checkpurchased(name = null) // If the first parameter is null, return a full list of purchases - var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey, job, species FROM [format_table_name("whitelist")] WHERE ckey=:ckey", list( + var/datum/db_query/query = SSdbcore.NewQuery("SELECT ckey, job, species FROM whitelist WHERE ckey=:ckey", list( "ckey" = ckey )) if(!query.warn_execute()) diff --git a/code/modules/library/admin.dm b/code/modules/library/admin.dm index 4d45a724ad5..2f1c1e101fc 100644 --- a/code/modules/library/admin.dm +++ b/code/modules/library/admin.dm @@ -10,7 +10,7 @@ if(!isbn) return - var/datum/db_query/query_delbook = SSdbcore.NewQuery("DELETE FROM [format_table_name("library")] WHERE id=:isbn", list( + var/datum/db_query/query_delbook = SSdbcore.NewQuery("DELETE FROM library WHERE id=:isbn", list( "isbn" = text2num(isbn) // just to be sure )) if(!query_delbook.warn_execute()) @@ -37,7 +37,7 @@ var/dat = "" - var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, title, flagged FROM [format_table_name("library")] WHERE flagged > 0 ORDER BY flagged DESC") + var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, title, flagged FROM library WHERE flagged > 0 ORDER BY flagged DESC") if(!query.warn_execute()) qdel(query) return diff --git a/code/modules/library/computers/base.dm b/code/modules/library/computers/base.dm index 660ada20c31..c0f2d473afa 100644 --- a/code/modules/library/computers/base.dm +++ b/code/modules/library/computers/base.dm @@ -51,7 +51,7 @@ // This one doesnt take player input directly, so it doesnt require params searchquery += " [!where ? "WHERE" : "AND"] flagged < [MAX_BOOK_FLAGS]" // This does though - var/sql = "SELECT id, author, title, category, ckey, flagged FROM [format_table_name("library")] [searchquery] LIMIT :lowerlimit, :upperlimit" + var/sql = "SELECT id, author, title, category, ckey, flagged FROM library [searchquery] LIMIT :lowerlimit, :upperlimit" sql_params["lowerlimit"] = text2num((page_num - 1) * LIBRARY_BOOKS_PER_PAGE) sql_params["upperlimit"] = LIBRARY_BOOKS_PER_PAGE @@ -78,7 +78,7 @@ return results /obj/machinery/computer/library/proc/get_num_results() - var/sql = "SELECT COUNT(id) FROM [format_table_name("library")]" + var/sql = "SELECT COUNT(id) FROM library" var/datum/db_query/count_query = SSdbcore.NewQuery(sql) if(!count_query.warn_execute()) diff --git a/code/modules/library/computers/checkout.dm b/code/modules/library/computers/checkout.dm index 065608b7b3d..67fe4a2315e 100644 --- a/code/modules/library/computers/checkout.dm +++ b/code/modules/library/computers/checkout.dm @@ -262,7 +262,7 @@ var/datum/cachedbook/target = getBookByID(href_list["del"]) // Sanitized in getBookByID var/ans = alert(usr, "Are you sure you wish to delete \"[target.title]\", by [target.author]? This cannot be undone.", "Library System", "Yes", "No") if(ans=="Yes") - var/datum/db_query/query = SSdbcore.NewQuery("DELETE FROM [format_table_name("library")] WHERE id=:id", list( + var/datum/db_query/query = SSdbcore.NewQuery("DELETE FROM library WHERE id=:id", list( "id" = text2num(target.id) )) if(!query.warn_execute()) @@ -280,7 +280,7 @@ var/tckey = ckey(href_list["delbyckey"]) var/ans = alert(usr,"Are you sure you wish to delete all books by [tckey]? This cannot be undone.", "Library System", "Yes", "No") if(ans=="Yes") - var/datum/db_query/query = SSdbcore.NewQuery("DELETE FROM [format_table_name("library")] WHERE ckey=:ckey", list( + var/datum/db_query/query = SSdbcore.NewQuery("DELETE FROM library WHERE ckey=:ckey", list( "ckey" = tckey )) if(!query.warn_execute()) @@ -387,7 +387,7 @@ alert("Connection to Archive has been severed. Aborting.") else var/datum/db_query/query = SSdbcore.NewQuery({" - INSERT INTO [format_table_name("library")] (author, title, content, category, ckey, flagged) + INSERT INTO library (author, title, content, category, ckey, flagged) VALUES (:author, :title, :content, :category, :ckey, 0)"}, list( "author" = scanner.cache.author, "title" = scanner.cache.name, diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index ad3e7008396..d76c1f3ef1f 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -78,7 +78,7 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A books_flagged_this_round["[id]"] = 1 message_admins("[key_name_admin(user)] has flagged book #[id] as inappropriate.") - var/datum/db_query/query = SSdbcore.NewQuery("UPDATE [format_table_name("library")] SET flagged = flagged + 1 WHERE id=:id", list( + var/datum/db_query/query = SSdbcore.NewQuery("UPDATE library SET flagged = flagged + 1 WHERE id=:id", list( "id" = text2num(id) )) if(!query.warn_execute()) @@ -93,7 +93,7 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A to_chat(user, "That book cannot be removed from the system, as it does not actually exist in the database.") return - var/datum/db_query/query = SSdbcore.NewQuery("DELETE FROM [format_table_name("library")] WHERE id=:id", list( + var/datum/db_query/query = SSdbcore.NewQuery("DELETE FROM library WHERE id=:id", list( "id" = text2num(id) )) if(!query.warn_execute()) @@ -105,7 +105,7 @@ GLOBAL_LIST_INIT(library_section_names, list("Any", "Fiction", "Non-Fiction", "A if("[id]" in cached_books) return cached_books["[id]"] - var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, author, title, category, content, ckey, flagged FROM [format_table_name("library")] WHERE id=:id", list( + var/datum/db_query/query = SSdbcore.NewQuery("SELECT id, author, title, category, content, ckey, flagged FROM library WHERE id=:id", list( "id" = text2num(id) )) if(!query.warn_execute()) diff --git a/code/modules/library/random_books.dm b/code/modules/library/random_books.dm index 062b531a261..a43f0cc4b18 100644 --- a/code/modules/library/random_books.dm +++ b/code/modules/library/random_books.dm @@ -56,7 +56,7 @@ sql_params["category"] = category sql_params["amount"] = amount - var/datum/db_query/query_get_random_books = SSdbcore.NewQuery("SELECT author, title, content FROM [format_table_name("library")] WHERE (isnull(flagged) OR flagged = 0)[c] GROUP BY title ORDER BY rand() LIMIT :amount", sql_params) + var/datum/db_query/query_get_random_books = SSdbcore.NewQuery("SELECT author, title, content FROM library WHERE (isnull(flagged) OR flagged = 0)[c] GROUP BY title ORDER BY rand() LIMIT :amount", sql_params) if(!query_get_random_books.warn_execute()) qdel(query_get_random_books) return diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm index 5d7d5caa919..30a26a7af6e 100644 --- a/code/modules/mob/new_player/new_player.dm +++ b/code/modules/mob/new_player/new_player.dm @@ -115,7 +115,7 @@ return FALSE if(href_list["consent_signed"]) - var/datum/db_query/query = SSdbcore.NewQuery("REPLACE INTO [format_table_name("privacy")] (ckey, datetime, consent) VALUES (:ckey, Now(), 1)", list( + var/datum/db_query/query = SSdbcore.NewQuery("REPLACE INTO privacy (ckey, datetime, consent) VALUES (:ckey, Now(), 1)", list( "ckey" = ckey )) // If the query fails we dont want them permenantly stuck on being unable to accept TOS @@ -129,7 +129,7 @@ if(href_list["consent_rejected"]) client.tos_consent = FALSE to_chat(usr, "You must consent to the terms of service before you can join!") - var/datum/db_query/query = SSdbcore.NewQuery("REPLACE INTO [format_table_name("privacy")] (ckey, datetime, consent) VALUES (:ckey, Now(), 0)", list( + var/datum/db_query/query = SSdbcore.NewQuery("REPLACE INTO privacy (ckey, datetime, consent) VALUES (:ckey, Now(), 0)", list( "ckey" = ckey )) // If the query fails we dont want them permenantly stuck on being unable to accept TOS diff --git a/config/example/config.toml b/config/example/config.toml index 59a752a2b45..0f46fcf6d7f 100644 --- a/config/example/config.toml +++ b/config/example/config.toml @@ -146,13 +146,11 @@ sql_address = "127.0.0.1" # SQL server port sql_port = 3306 # SQL server database name -sql_database = "feedback" # TODO: Convert into `paradise_db` -# SQL server table prefix, if applicable. SET TO EMPTY STRING IF NOT. -sql_table_prefix = "" # TODO: Deprecate table prefixes +sql_database = "paradise_gamedb" # SQL server username sql_username = "root" # SQL server password -sql_password = "please use something secure in a prod environment" +sql_password = "please use something secure in a production environment" # Time in seconds for async queries to time out async_query_timeout = 10 # How many threads is the async SQL engine allowed to open. 50 is normal. Trust me. diff --git a/tools/ci/generate_sql_scripts.py b/tools/ci/generate_sql_scripts.py index 5c7cf97230b..3b2687a733a 100644 --- a/tools/ci/generate_sql_scripts.py +++ b/tools/ci/generate_sql_scripts.py @@ -54,9 +54,9 @@ for file in orderedSqlFiles: if file.endswith(".py"): # Begin snowflakery if file == "16-17.py": - scriptLines.append("python3 SQL/updates/" + str(file) + " 127.0.0.1 root root feedback feedback round\n") + scriptLines.append("python3 SQL/updates/" + str(file) + " 127.0.0.1 root root paradise_gamedb feedback round\n") elif file == "17-18.py": - scriptLines.append("python3 SQL/updates/" + str(file) + " 127.0.0.1 root root feedback feedback feedback_2\n") + scriptLines.append("python3 SQL/updates/" + str(file) + " 127.0.0.1 root root paradise_gamedb feedback feedback_2\n") else: print("ERROR: CI failed due to invalid python file in SQL/updates") exit(1) @@ -64,8 +64,8 @@ for file in orderedSqlFiles: inFile = open("SQL/updates/" + file, "r") fileLines = inFile.readlines() inFile.close() - # Add in a line which tells it to use the feedback DB - fileLines.insert(0, "USE `feedback`;\n") + # Add in a line which tells it to use the paradise DB + fileLines.insert(0, "USE `paradise_gamedb`;\n") # Write new files to be used by the testing script outFile = open("tools/ci/sql_tmp/" + file, "w+") @@ -75,9 +75,7 @@ for file in orderedSqlFiles: # Add a line to the script being made that tells it to use this SQL file scriptLines.append("mysql -u root -proot < tools/ci/sql_tmp/" + str(file) + "\n") -scriptLines.append("mysql -u root -proot -e 'DROP DATABASE feedback;'\n") -scriptLines.append("mysql -u root -proot < SQL/paradise_schema_prefixed.sql\n") -scriptLines.append("mysql -u root -proot -e 'DROP DATABASE feedback;'\n") +scriptLines.append("mysql -u root -proot -e 'DROP DATABASE paradise_gamedb;'\n") scriptLines.append("mysql -u root -proot < SQL/paradise_schema.sql\n") outputScript = open("tools/ci/validate_sql.sh", "w+") diff --git a/tools/ci/sql_v0.sql b/tools/ci/sql_v0.sql index 201347a2f1e..d9c5d235fc2 100644 --- a/tools/ci/sql_v0.sql +++ b/tools/ci/sql_v0.sql @@ -16,12 +16,12 @@ /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; --- Dumping database structure for feedback -DROP DATABASE IF EXISTS `feedback`; -CREATE DATABASE IF NOT EXISTS `feedback` /*!40100 DEFAULT CHARACTER SET utf8 */; -USE `feedback`; +-- Dumping database structure for paradise_gamedb +DROP DATABASE IF EXISTS `paradise_gamedb`; +CREATE DATABASE IF NOT EXISTS `paradise_gamedb` /*!40100 DEFAULT CHARACTER SET utf8 */; +USE `paradise_gamedb`; --- Dumping structure for table feedback.admin +-- Dumping structure for table paradise_gamedb.admin DROP TABLE IF EXISTS `admin`; CREATE TABLE IF NOT EXISTS `admin` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -32,13 +32,13 @@ CREATE TABLE IF NOT EXISTS `admin` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.admin: ~0 rows (approximately) +-- Dumping data for table paradise_gamedb.admin: ~0 rows (approximately) /*!40000 ALTER TABLE `admin` DISABLE KEYS */; INSERT INTO `admin` (`id`, `ckey`, `rank`, `level`, `flags`) VALUES (1, 'AffectedArc07', 'Administrator', 0, 131071); /*!40000 ALTER TABLE `admin` ENABLE KEYS */; --- Dumping structure for table feedback.admin_log +-- Dumping structure for table paradise_gamedb.admin_log DROP TABLE IF EXISTS `admin_log`; CREATE TABLE IF NOT EXISTS `admin_log` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -49,13 +49,13 @@ CREATE TABLE IF NOT EXISTS `admin_log` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.admin_log: ~0 rows (approximately) +-- Dumping data for table paradise_gamedb.admin_log: ~0 rows (approximately) /*!40000 ALTER TABLE `admin_log` DISABLE KEYS */; INSERT INTO `admin_log` (`id`, `datetime`, `adminckey`, `adminip`, `log`) VALUES (1, '2020-04-24 17:36:49', 'AffectedArc07', '127.0.0.1', 'Created this row'); /*!40000 ALTER TABLE `admin_log` ENABLE KEYS */; --- Dumping structure for table feedback.ban +-- Dumping structure for table paradise_gamedb.ban DROP TABLE IF EXISTS `ban`; CREATE TABLE IF NOT EXISTS `ban` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -84,13 +84,13 @@ CREATE TABLE IF NOT EXISTS `ban` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.ban: ~0 rows (approximately) +-- Dumping data for table paradise_gamedb.ban: ~0 rows (approximately) /*!40000 ALTER TABLE `ban` DISABLE KEYS */; INSERT INTO `ban` (`id`, `bantime`, `serverip`, `bantype`, `reason`, `job`, `duration`, `rounds`, `expiration_time`, `ckey`, `computerid`, `ip`, `a_ckey`, `a_computerid`, `a_ip`, `who`, `adminwho`, `edits`, `unbanned`, `unbanned_datetime`, `unbanned_ckey`, `unbanned_computerid`, `unbanned_ip`) VALUES (1, '2020-04-24 17:40:05', '127.0.0.1', 'PERMABAN', 'Breaking it all', NULL, -1, NULL, '2020-04-24 17:40:20', 'AffectedArc07', '1111111111', '127.0.0.1', 'AffectedArc07', '1111111111', '127.0.0.1', 'Player1, Player2, Whoever', 'SomeAdmin', NULL, NULL, NULL, NULL, NULL, NULL); /*!40000 ALTER TABLE `ban` ENABLE KEYS */; --- Dumping structure for table feedback.characters +-- Dumping structure for table paradise_gamedb.characters DROP TABLE IF EXISTS `characters`; CREATE TABLE IF NOT EXISTS `characters` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -165,13 +165,13 @@ CREATE TABLE IF NOT EXISTS `characters` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; --- Dumping data for table feedback.characters: ~0 rows (approximately) +-- Dumping data for table paradise_gamedb.characters: ~0 rows (approximately) /*!40000 ALTER TABLE `characters` DISABLE KEYS */; INSERT INTO `characters` (`id`, `ckey`, `slot`, `OOC_Notes`, `real_name`, `name_is_always_random`, `gender`, `age`, `species`, `language`, `hair_red`, `hair_green`, `hair_blue`, `secondary_hair_red`, `secondary_hair_green`, `secondary_hair_blue`, `facial_red`, `facial_green`, `facial_blue`, `secondary_facial_red`, `secondary_facial_green`, `secondary_facial_blue`, `skin_tone`, `skin_red`, `skin_green`, `skin_blue`, `marking_colours`, `head_accessory_red`, `head_accessory_green`, `head_accessory_blue`, `hair_style_name`, `facial_style_name`, `marking_styles`, `head_accessory_style_name`, `alt_head_name`, `eyes_red`, `eyes_green`, `eyes_blue`, `underwear`, `undershirt`, `backbag`, `b_type`, `alternate_option`, `job_support_high`, `job_support_med`, `job_support_low`, `job_medsci_high`, `job_medsci_med`, `job_medsci_low`, `job_engsec_high`, `job_engsec_med`, `job_engsec_low`, `job_karma_high`, `job_karma_med`, `job_karma_low`, `flavor_text`, `med_record`, `sec_record`, `gen_record`, `disabilities`, `player_alt_titles`, `organ_data`, `rlimb_data`, `nanotrasen_relation`, `speciesprefs`, `socks`, `body_accessory`, `gear`, `autohiss`) VALUES (1, 'AffectedArc07', 1, 'Some notes', 'John Smith', 0, 'male', 25, 'Human', 'None', 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 25, 10, 10, 10, 'head=%23000000&body=%23000000&tail=%23000000', 10, 10, 10, 'Bald', 'Shaved', 'head=None&body=None&tail=None', 'None', 'None', 10, 10, 10, 'Nude', 'Nude', 'Grey Backpack', 'A+', 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 'He is short', 'Yes', 'Yes', 'Yes', 0, ' ', ' ', ' ', 'Neutral', 0, 'Nude', ' ', ' ', 0); /*!40000 ALTER TABLE `characters` ENABLE KEYS */; --- Dumping structure for table feedback.customuseritems +-- Dumping structure for table paradise_gamedb.customuseritems DROP TABLE IF EXISTS `customuseritems`; CREATE TABLE IF NOT EXISTS `customuseritems` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -186,13 +186,13 @@ CREATE TABLE IF NOT EXISTS `customuseritems` ( PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.customuseritems: 0 rows +-- Dumping data for table paradise_gamedb.customuseritems: 0 rows /*!40000 ALTER TABLE `customuseritems` DISABLE KEYS */; INSERT INTO `customuseritems` (`id`, `cuiCKey`, `cuiRealName`, `cuiPath`, `cuiItemName`, `cuiDescription`, `cuiReason`, `cuiPropAdjust`, `cuiJobMask`) VALUES (1, 'AffectedArc07', 'Character Name', '/obj/item/multitool', NULL, NULL, NULL, NULL, '*'); /*!40000 ALTER TABLE `customuseritems` ENABLE KEYS */; --- Dumping structure for table feedback.death +-- Dumping structure for table paradise_gamedb.death DROP TABLE IF EXISTS `death`; CREATE TABLE IF NOT EXISTS `death` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -213,13 +213,13 @@ CREATE TABLE IF NOT EXISTS `death` ( PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.death: 0 rows +-- Dumping data for table paradise_gamedb.death: 0 rows /*!40000 ALTER TABLE `death` DISABLE KEYS */; INSERT INTO `death` (`id`, `pod`, `coord`, `tod`, `job`, `special`, `name`, `byondkey`, `laname`, `lakey`, `gender`, `bruteloss`, `brainloss`, `fireloss`, `oxyloss`) VALUES (1, 'Central Primary Hallway', '1,1,1', '2020-04-24 17:58:41', 'Captain', 'Traitor', 'John Smith', 'AffectedArc07', 'Bad Man', 'BadGuyCkey', 'Male', 12, 12, 12, 12); /*!40000 ALTER TABLE `death` ENABLE KEYS */; --- Dumping structure for table feedback.donators +-- Dumping structure for table paradise_gamedb.donators DROP TABLE IF EXISTS `donators`; CREATE TABLE IF NOT EXISTS `donators` ( `patreon_name` varchar(32) NOT NULL, @@ -231,13 +231,13 @@ CREATE TABLE IF NOT EXISTS `donators` ( PRIMARY KEY (`patreon_name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; --- Dumping data for table feedback.donators: ~0 rows (approximately) +-- Dumping data for table paradise_gamedb.donators: ~0 rows (approximately) /*!40000 ALTER TABLE `donators` DISABLE KEYS */; INSERT INTO `donators` (`patreon_name`, `tier`, `ckey`, `start_date`, `end_date`, `active`) VALUES ('AffectedArc07', 3, 'AffectedArc07', '2020-04-24 18:00:47', '2020-04-24 18:00:48', 1); /*!40000 ALTER TABLE `donators` ENABLE KEYS */; --- Dumping structure for table feedback.feedback +-- Dumping structure for table paradise_gamedb.feedback DROP TABLE IF EXISTS `feedback`; CREATE TABLE IF NOT EXISTS `feedback` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -249,13 +249,13 @@ CREATE TABLE IF NOT EXISTS `feedback` ( PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.feedback: 0 rows +-- Dumping data for table paradise_gamedb.feedback: 0 rows /*!40000 ALTER TABLE `feedback` DISABLE KEYS */; INSERT INTO `feedback` (`id`, `time`, `round_id`, `var_name`, `var_value`, `details`) VALUES (1, '2020-04-24 18:01:08', 1, 'yes', 1, 'feedback scares me'); /*!40000 ALTER TABLE `feedback` ENABLE KEYS */; --- Dumping structure for table feedback.karma +-- Dumping structure for table paradise_gamedb.karma DROP TABLE IF EXISTS `karma`; CREATE TABLE IF NOT EXISTS `karma` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -271,13 +271,13 @@ CREATE TABLE IF NOT EXISTS `karma` ( PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.karma: 0 rows +-- Dumping data for table paradise_gamedb.karma: 0 rows /*!40000 ALTER TABLE `karma` DISABLE KEYS */; INSERT INTO `karma` (`id`, `spendername`, `spenderkey`, `receivername`, `receiverkey`, `receiverrole`, `receiverspecial`, `isnegative`, `spenderip`, `time`) VALUES (1, 'John Smith', 'AffectedArc07', 'Other Man', 'OtherCkey', 'Captain', 'Special', 0, '127.0.0.1', '2020-04-24 18:02:00'); /*!40000 ALTER TABLE `karma` ENABLE KEYS */; --- Dumping structure for table feedback.karmatotals +-- Dumping structure for table paradise_gamedb.karmatotals DROP TABLE IF EXISTS `karmatotals`; CREATE TABLE IF NOT EXISTS `karmatotals` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -287,13 +287,13 @@ CREATE TABLE IF NOT EXISTS `karmatotals` ( PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.karmatotals: 0 rows +-- Dumping data for table paradise_gamedb.karmatotals: 0 rows /*!40000 ALTER TABLE `karmatotals` DISABLE KEYS */; INSERT INTO `karmatotals` (`id`, `byondkey`, `karma`, `karmaspent`) VALUES (1, 'AffectedArc07', 1000, 100); /*!40000 ALTER TABLE `karmatotals` ENABLE KEYS */; --- Dumping structure for table feedback.legacy_population +-- Dumping structure for table paradise_gamedb.legacy_population DROP TABLE IF EXISTS `legacy_population`; CREATE TABLE IF NOT EXISTS `legacy_population` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -303,13 +303,13 @@ CREATE TABLE IF NOT EXISTS `legacy_population` ( PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.legacy_population: 0 rows +-- Dumping data for table paradise_gamedb.legacy_population: 0 rows /*!40000 ALTER TABLE `legacy_population` DISABLE KEYS */; INSERT INTO `legacy_population` (`id`, `playercount`, `admincount`, `time`) VALUES (1, 233, 23, '2020-04-24 18:02:19'); /*!40000 ALTER TABLE `legacy_population` ENABLE KEYS */; --- Dumping structure for table feedback.library +-- Dumping structure for table paradise_gamedb.library DROP TABLE IF EXISTS `library`; CREATE TABLE IF NOT EXISTS `library` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -322,13 +322,13 @@ CREATE TABLE IF NOT EXISTS `library` ( PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.library: 0 rows +-- Dumping data for table paradise_gamedb.library: 0 rows /*!40000 ALTER TABLE `library` DISABLE KEYS */; INSERT INTO `library` (`id`, `author`, `title`, `content`, `category`, `ckey`, `flagged`) VALUES (1, 'John Smith', 'A book', 'WOW WHAT A BOOK', 'Fiction', 'AffectedArc07', 0); /*!40000 ALTER TABLE `library` ENABLE KEYS */; --- Dumping structure for table feedback.memo +-- Dumping structure for table paradise_gamedb.memo DROP TABLE IF EXISTS `memo`; CREATE TABLE IF NOT EXISTS `memo` ( `ckey` varchar(32) NOT NULL, @@ -339,13 +339,13 @@ CREATE TABLE IF NOT EXISTS `memo` ( PRIMARY KEY (`ckey`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; --- Dumping data for table feedback.memo: ~0 rows (approximately) +-- Dumping data for table paradise_gamedb.memo: ~0 rows (approximately) /*!40000 ALTER TABLE `memo` DISABLE KEYS */; INSERT INTO `memo` (`ckey`, `memotext`, `timestamp`, `last_editor`, `edits`) VALUES ('AffectedArc07', 'Remember to test your PRs', '2020-04-24 18:04:00', NULL, NULL); /*!40000 ALTER TABLE `memo` ENABLE KEYS */; --- Dumping structure for table feedback.notes +-- Dumping structure for table paradise_gamedb.notes DROP TABLE IF EXISTS `notes`; CREATE TABLE IF NOT EXISTS `notes` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -359,13 +359,13 @@ CREATE TABLE IF NOT EXISTS `notes` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.notes: ~0 rows (approximately) +-- Dumping data for table paradise_gamedb.notes: ~0 rows (approximately) /*!40000 ALTER TABLE `notes` DISABLE KEYS */; INSERT INTO `notes` (`id`, `ckey`, `notetext`, `timestamp`, `adminckey`, `last_editor`, `edits`, `server`) VALUES (1, 'AffectedArc07', 'Cant behave', '2020-04-24 18:04:14', 'AffectedArc07', NULL, NULL, 'SS13'); /*!40000 ALTER TABLE `notes` ENABLE KEYS */; --- Dumping structure for table feedback.player +-- Dumping structure for table paradise_gamedb.player DROP TABLE IF EXISTS `player`; CREATE TABLE IF NOT EXISTS `player` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -395,13 +395,13 @@ CREATE TABLE IF NOT EXISTS `player` ( UNIQUE KEY `ckey` (`ckey`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.player: ~0 rows (approximately) +-- Dumping data for table paradise_gamedb.player: ~0 rows (approximately) /*!40000 ALTER TABLE `player` DISABLE KEYS */; INSERT INTO `player` (`id`, `ckey`, `firstseen`, `lastseen`, `ip`, `computerid`, `lastadminrank`, `ooccolor`, `UI_style`, `UI_style_color`, `UI_style_alpha`, `be_role`, `default_slot`, `toggles`, `sound`, `randomslot`, `volume`, `nanoui_fancy`, `show_ghostitem_attack`, `lastchangelog`, `windowflashing`, `ghost_anonsay`, `exp`) VALUES (1, 'AffectedArc07', '2020-04-24 18:04:44', '2020-04-24 18:04:45', '127.0.0.1', '1111111111', 'Player', '#b82e00', 'Midnight', '#ffffff', 10, NULL, 1, 1024, 16, 0, 100, 1, 1, '0', 1, 1, NULL); /*!40000 ALTER TABLE `player` ENABLE KEYS */; --- Dumping structure for table feedback.poll_option +-- Dumping structure for table paradise_gamedb.poll_option DROP TABLE IF EXISTS `poll_option`; CREATE TABLE IF NOT EXISTS `poll_option` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -416,13 +416,13 @@ CREATE TABLE IF NOT EXISTS `poll_option` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.poll_option: ~0 rows (approximately) +-- Dumping data for table paradise_gamedb.poll_option: ~0 rows (approximately) /*!40000 ALTER TABLE `poll_option` DISABLE KEYS */; INSERT INTO `poll_option` (`id`, `pollid`, `text`, `percentagecalc`, `minval`, `maxval`, `descmin`, `descmid`, `descmax`) VALUES (1, 1, 'What is this', 12, NULL, NULL, NULL, NULL, NULL); /*!40000 ALTER TABLE `poll_option` ENABLE KEYS */; --- Dumping structure for table feedback.poll_question +-- Dumping structure for table paradise_gamedb.poll_question DROP TABLE IF EXISTS `poll_question`; CREATE TABLE IF NOT EXISTS `poll_question` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -437,13 +437,13 @@ CREATE TABLE IF NOT EXISTS `poll_question` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.poll_question: ~0 rows (approximately) +-- Dumping data for table paradise_gamedb.poll_question: ~0 rows (approximately) /*!40000 ALTER TABLE `poll_question` DISABLE KEYS */; INSERT INTO `poll_question` (`id`, `polltype`, `starttime`, `endtime`, `question`, `adminonly`, `multiplechoiceoptions`, `createdby_ckey`, `createdby_ip`) VALUES (1, 'OPTION', '2020-04-24 18:05:31', '2020-04-24 18:05:33', 'Is this a good idea', 0, NULL, NULL, NULL); /*!40000 ALTER TABLE `poll_question` ENABLE KEYS */; --- Dumping structure for table feedback.poll_textreply +-- Dumping structure for table paradise_gamedb.poll_textreply DROP TABLE IF EXISTS `poll_textreply`; CREATE TABLE IF NOT EXISTS `poll_textreply` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -456,13 +456,13 @@ CREATE TABLE IF NOT EXISTS `poll_textreply` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.poll_textreply: ~0 rows (approximately) +-- Dumping data for table paradise_gamedb.poll_textreply: ~0 rows (approximately) /*!40000 ALTER TABLE `poll_textreply` DISABLE KEYS */; INSERT INTO `poll_textreply` (`id`, `datetime`, `pollid`, `ckey`, `ip`, `replytext`, `adminrank`) VALUES (1, '2020-04-24 18:05:42', 1, 'AffectedArc07', '127.0.0.1', 'This is far too much work for a CI rework', 'Player'); /*!40000 ALTER TABLE `poll_textreply` ENABLE KEYS */; --- Dumping structure for table feedback.poll_vote +-- Dumping structure for table paradise_gamedb.poll_vote DROP TABLE IF EXISTS `poll_vote`; CREATE TABLE IF NOT EXISTS `poll_vote` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -476,13 +476,13 @@ CREATE TABLE IF NOT EXISTS `poll_vote` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.poll_vote: ~0 rows (approximately) +-- Dumping data for table paradise_gamedb.poll_vote: ~0 rows (approximately) /*!40000 ALTER TABLE `poll_vote` DISABLE KEYS */; INSERT INTO `poll_vote` (`id`, `datetime`, `pollid`, `optionid`, `ckey`, `ip`, `adminrank`, `rating`) VALUES (1, '2020-04-24 18:06:02', 1, 1, 'AffectedArc07', '127.0.0.1', 'Administrator', NULL); /*!40000 ALTER TABLE `poll_vote` ENABLE KEYS */; --- Dumping structure for table feedback.privacy +-- Dumping structure for table paradise_gamedb.privacy DROP TABLE IF EXISTS `privacy`; CREATE TABLE IF NOT EXISTS `privacy` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -492,13 +492,13 @@ CREATE TABLE IF NOT EXISTS `privacy` ( PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.privacy: ~0 rows (approximately) +-- Dumping data for table paradise_gamedb.privacy: ~0 rows (approximately) /*!40000 ALTER TABLE `privacy` DISABLE KEYS */; INSERT INTO `privacy` (`id`, `datetime`, `ckey`, `option`) VALUES (1, '2020-04-24 18:06:20', 'AffectedArc07', '1'); /*!40000 ALTER TABLE `privacy` ENABLE KEYS */; --- Dumping structure for table feedback.watch +-- Dumping structure for table paradise_gamedb.watch DROP TABLE IF EXISTS `watch`; CREATE TABLE IF NOT EXISTS `watch` ( `ckey` varchar(32) NOT NULL, @@ -510,13 +510,13 @@ CREATE TABLE IF NOT EXISTS `watch` ( PRIMARY KEY (`ckey`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; --- Dumping data for table feedback.watch: ~0 rows (approximately) +-- Dumping data for table paradise_gamedb.watch: ~0 rows (approximately) /*!40000 ALTER TABLE `watch` DISABLE KEYS */; INSERT INTO `watch` (`ckey`, `reason`, `timestamp`, `adminckey`, `last_editor`, `edits`) VALUES ('AffectedArc07', 'Cant behave', '2020-04-24 18:06:33', 'AffectedArc07', NULL, NULL); /*!40000 ALTER TABLE `watch` ENABLE KEYS */; --- Dumping structure for table feedback.whitelist +-- Dumping structure for table paradise_gamedb.whitelist DROP TABLE IF EXISTS `whitelist`; CREATE TABLE IF NOT EXISTS `whitelist` ( `id` int(11) NOT NULL AUTO_INCREMENT, @@ -526,7 +526,7 @@ CREATE TABLE IF NOT EXISTS `whitelist` ( PRIMARY KEY (`id`) ) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1; --- Dumping data for table feedback.whitelist: 0 rows +-- Dumping data for table paradise_gamedb.whitelist: 0 rows /*!40000 ALTER TABLE `whitelist` DISABLE KEYS */; INSERT INTO `whitelist` (`id`, `ckey`, `job`, `species`) VALUES (1, 'AffectedArc07', 'Captain', 'Machine'); @@ -535,4 +535,4 @@ INSERT INTO `whitelist` (`id`, `ckey`, `job`, `species`) VALUES /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; /*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); \ No newline at end of file +SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); diff --git a/tools/githubChangelogProcessor.php b/tools/githubChangelogProcessor.php index 6e8c4094699..a88cd99580c 100644 --- a/tools/githubChangelogProcessor.php +++ b/tools/githubChangelogProcessor.php @@ -32,7 +32,7 @@ $dbServer = "localhost"; // Hostname of the database server (default localhost) $dbPort = "3306"; // Port of the database server (default 3306) | MUST BE A STRING $dbUser = "root"; // Database username (default root) $dbPassword = ""; // Database password (default blank) -$dbDatabase = "feedback"; // Database name (default feedback) +$dbDatabase = "paradise_gamedb"; // Database name (default paradise_gamedb) //servers to announce PRs to. $servers = array(); From 7f76dafd794cfd9c511dcdadc126e79db06351d2 Mon Sep 17 00:00:00 2001 From: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> Date: Mon, 26 Jul 2021 17:33:30 +0100 Subject: [PATCH 43/48] I FELL VICTIM TO MY OWN CI --- .../controllers/configuration/sections/database_configuration.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/controllers/configuration/sections/database_configuration.dm b/code/controllers/configuration/sections/database_configuration.dm index 1e75d7af3f4..e7ed707f573 100644 --- a/code/controllers/configuration/sections/database_configuration.dm +++ b/code/controllers/configuration/sections/database_configuration.dm @@ -25,7 +25,6 @@ #ifdef UNIT_TESTS enabled = TRUE - table_prefix = "" // This needs to happen in the CI environment to ensure the example SQL version gets updated. CONFIG_LOAD_NUM(version, data["sql_version"]) From 9659fbd0f8e3493f2f2d9510a13d6a1c5c131741 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sun, 31 Jan 2021 10:12:14 -0600 Subject: [PATCH 44/48] atmos-alt-control-click --- code/game/machinery/machinery.dm | 16 +++++++ .../atmospherics/machinery/atmospherics.dm | 35 +++++++++++++++- .../components/binary_devices/dp_vent_pump.dm | 1 - .../components/binary_devices/passive_gate.dm | 8 +--- .../components/binary_devices/pump.dm | 41 +++++------------- .../components/binary_devices/volume_pump.dm | 39 +++++------------ .../components/trinary_devices/filter.dm | 42 ++++++------------- .../components/trinary_devices/mixer.dm | 42 ++++++------------- .../trinary_devices/trinary_base.dm | 1 - .../components/unary_devices/cryo.dm | 1 - .../unary_devices/outlet_injector.dm | 1 - .../unary_devices/oxygen_generator.dm | 2 - .../unary_devices/portables_connector.dm | 2 - .../components/unary_devices/thermomachine.dm | 3 -- .../components/unary_devices/vent_pump.dm | 1 - .../components/unary_devices/vent_scrubber.dm | 1 - 16 files changed, 96 insertions(+), 140 deletions(-) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 901844c0c14..0d1c6ada2d0 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -650,3 +650,19 @@ Class Procs: . = . % 9 AM.pixel_x = -8 + ((.%3)*8) AM.pixel_y = -8 + (round( . / 3)*8) + +/** + * Makes sure the user is allowed to interact with the machine when they use a shortcut, like Control or Alt-clicking. + * + * Arguments: + * * user - the mob who is trying to interact with the machine. + */ +/obj/machinery/proc/can_use_shortcut(mob/living/user) + if(!ishuman(user) && !issilicon(user)) + return FALSE + if(!in_range(src, user) && !issilicon(user)) + return FALSE + if(user.incapacitated()) + to_chat(user, "You can't do that right now!") + return FALSE + return TRUE diff --git a/code/modules/atmospherics/machinery/atmospherics.dm b/code/modules/atmospherics/machinery/atmospherics.dm index 8a77e3908f1..1a877ce857a 100644 --- a/code/modules/atmospherics/machinery/atmospherics.dm +++ b/code/modules/atmospherics/machinery/atmospherics.dm @@ -20,7 +20,10 @@ Pipelines + Other Objects -> Pipe network on_blueprints = TRUE var/nodealert = 0 var/can_unwrench = 0 - + /// If the machine is currently operating or not. + var/on = FALSE + /// The amount of pressure the machine wants to operate at. + var/target_pressure = 0 var/connect_types[] = list(1) //1=regular, 2=supply, 3=scrubber var/connected_to = 1 //same as above, currently not used for anything var/icon_connect_type = "" //"-supply" or "-scrubbers" @@ -353,3 +356,33 @@ Pipelines + Other Objects -> Pipe network //Used for certain children of obj/machinery/atmospherics to not show pipe vision when mob is inside it. /obj/machinery/atmospherics/proc/can_see_pipes() return TRUE + +/** + * Turns the machine either on, or off. If this is done by a user, display a message to them. + * + * NOTE: Only applies to atmospherics machines which can be toggled on or off, such as pumps, or other devices. + * + * Arguments: + * * user - the mob who is toggling the machine. + */ +/obj/machinery/atmospherics/proc/toggle(mob/living/user) + if(powered()) + on = !on + update_icon() + if(user) + to_chat(user, "You toggle [src] [on ? "on" : "off"].") + +/** + * Maxes the output pressure of the machine. If this is done by a user, display a message to them. + * + * NOTE: Only applies to atmospherics machines which allow a `target_pressure` to be set, such as pumps, or other devices. + * + * Arguments: + * * user - the mob who is setting the output pressure to maximum. + */ +/obj/machinery/atmospherics/proc/set_max(mob/living/user) + if(powered()) + target_pressure = MAX_OUTPUT_PRESSURE + update_icon() + if(user) + to_chat(user, "You set the target pressure of [src] to maximum.") diff --git a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm index 7f2cae91027..b81fb88ee67 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/dp_vent_pump.dm @@ -16,7 +16,6 @@ connect_types = list(1,2,3) //connects to regular, supply and scrubbers pipes - var/on = 0 var/pump_direction = 1 //0 = siphoning, 1 = releasing var/external_pressure_bound = ONE_ATMOSPHERE diff --git a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm index 087172d74e9..1b1443f7853 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/passive_gate.dm @@ -9,8 +9,7 @@ can_unwrench = 1 - var/on = 0 - var/target_pressure = ONE_ATMOSPHERE + target_pressure = ONE_ATMOSPHERE var/id = null @@ -174,11 +173,6 @@ if(.) investigate_log("was set to [target_pressure] kPa by [key_name(usr)]", "atmos") -/obj/machinery/atmospherics/binary/passive_gate/proc/toggle() - if(powered()) - on = !on - update_icon() - /obj/machinery/atmospherics/binary/passive_gate/attackby(obj/item/W, mob/user, params) if(!istype(W, /obj/item/wrench)) return ..() diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index 2527bec07da..9303dee01d9 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -21,54 +21,35 @@ Thus, the two variables affect pump operation are set in New(): can_unwrench = 1 - var/on = 0 - var/target_pressure = ONE_ATMOSPHERE + target_pressure = ONE_ATMOSPHERE var/id = null /obj/machinery/atmospherics/binary/pump/detailed_examine() return "This moves gas from one pipe to another. A higher target pressure demands more energy. The side with the red end is the output." +// So we can CtrlClick without triggering the anchored message. +/obj/machinery/atmospherics/binary/pump/can_be_pulled(user, grab_state, force, show_message) + return FALSE + /obj/machinery/atmospherics/binary/pump/CtrlClick(mob/living/user) - if(!istype(user) || user.incapacitated()) - to_chat(user, "You can't do that right now!") - return - if(!in_range(src, user) && !issilicon(usr)) - return - if(!ishuman(usr) && !issilicon(usr)) - return - toggle() + if(can_use_shortcut(user)) + toggle(user) return ..() -/obj/machinery/atmospherics/binary/pump/AICtrlClick() - toggle() +/obj/machinery/atmospherics/binary/pump/AICtrlClick(mob/living/silicon/user) + toggle(user) return ..() /obj/machinery/atmospherics/binary/pump/AltClick(mob/living/user) - if(!istype(user) || user.incapacitated()) - to_chat(user, "You can't do that right now!") - return - if(!in_range(src, user) && !issilicon(usr)) - return - if(!ishuman(usr) && !issilicon(usr)) - return - set_max() + if(can_use_shortcut(user)) + set_max(user) return /obj/machinery/atmospherics/binary/pump/AIAltClick() set_max() return ..() -/obj/machinery/atmospherics/binary/pump/proc/toggle() - if(powered()) - on = !on - update_icon() - -/obj/machinery/atmospherics/binary/pump/proc/set_max() - if(powered()) - target_pressure = MAX_OUTPUT_PRESSURE - update_icon() - /obj/machinery/atmospherics/binary/pump/Destroy() if(SSradio) SSradio.remove_object(src, frequency) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm index 05918fa1226..21225229738 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -21,51 +21,32 @@ Thus, the two variables affect pump operation are set in New(): can_unwrench = 1 - var/on = 0 var/transfer_rate = 200 var/id = null +// So we can CtrlClick without triggering the anchored message. +/obj/machinery/atmospherics/binary/volume_pump/can_be_pulled(user, grab_state, force, show_message) + return FALSE + /obj/machinery/atmospherics/binary/volume_pump/CtrlClick(mob/living/user) - if(!istype(user) || user.incapacitated()) - to_chat(user, "You can't do that right now!") - return - if(!in_range(src, user) && !issilicon(usr)) - return - if(!ishuman(usr) && !issilicon(usr)) - return - toggle() + if(can_use_shortcut(user)) + toggle(user) return ..() -/obj/machinery/atmospherics/binary/volume_pump/AICtrlClick() - toggle() +/obj/machinery/atmospherics/binary/volume_pump/AICtrlClick(mob/living/silicon/user) + toggle(user) return ..() /obj/machinery/atmospherics/binary/volume_pump/AltClick(mob/living/user) - if(!istype(user) || user.incapacitated()) - to_chat(user, "You can't do that right now!") - return - if(!in_range(src, user) && !issilicon(usr)) - return - if(!ishuman(usr) && !issilicon(usr)) - return - set_max() + if(can_use_shortcut(user)) + set_max(user) return /obj/machinery/atmospherics/binary/volume_pump/AIAltClick() set_max() return ..() -/obj/machinery/atmospherics/binary/volume_pump/proc/toggle() - if(powered()) - on = !on - update_icon() - -/obj/machinery/atmospherics/binary/volume_pump/proc/set_max() - if(powered()) - transfer_rate = MAX_TRANSFER_RATE - update_icon() - /obj/machinery/atmospherics/binary/volume_pump/Destroy() if(SSradio) SSradio.remove_object(src, frequency) diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index ff2b3a485a4..2043220ef77 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -17,8 +17,8 @@ icon = 'icons/atmos/filter.dmi' icon_state = "map" can_unwrench = TRUE - /// The amount of pressure the filter wants to operate at. - var/target_pressure = ONE_ATMOSPHERE + + target_pressure = ONE_ATMOSPHERE /// The type of gas we want to filter. Valid values that go here are from the `FILTER` defines at the top of the file. var/filter_type = FILTER_TOXINS /// A list of available filter options. Used with `ui_data`. @@ -31,46 +31,28 @@ "N2O" = FILTER_N2O ) +// So we can CtrlClick without triggering the anchored message. +/obj/machinery/atmospherics/trinary/filter/can_be_pulled(user, grab_state, force, show_message) + return FALSE + /obj/machinery/atmospherics/trinary/filter/CtrlClick(mob/living/user) - if(!istype(user) || user.incapacitated()) - to_chat(user, "You can't do that right now!") - return - if(!in_range(src, user) && !issilicon(usr)) - return - if(!ishuman(usr) && !issilicon(usr)) - return - toggle() + if(can_use_shortcut(user)) + toggle(user) return ..() -/obj/machinery/atmospherics/trinary/filter/AICtrlClick() - toggle() +/obj/machinery/atmospherics/trinary/filter/AICtrlClick(mob/living/silicon/user) + toggle(user) return ..() /obj/machinery/atmospherics/trinary/filter/AltClick(mob/living/user) - if(!istype(user) || user.incapacitated()) - to_chat(user, "You can't do that right now!") - return - if(!in_range(src, user) && !issilicon(usr)) - return - if(!ishuman(usr) && !issilicon(usr)) - return - set_max() + if(can_use_shortcut(user)) + set_max(user) return /obj/machinery/atmospherics/trinary/filter/AIAltClick() set_max() return ..() -/obj/machinery/atmospherics/trinary/filter/proc/toggle() - if(powered()) - on = !on - update_icon() - -/obj/machinery/atmospherics/trinary/filter/proc/set_max() - if(powered()) - target_pressure = MAX_OUTPUT_PRESSURE - update_icon() - /obj/machinery/atmospherics/trinary/filter/Destroy() if(SSradio) SSradio.remove_object(src, frequency) diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm index 5db62c29b7f..39c7c73aba1 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm @@ -6,37 +6,29 @@ name = "gas mixer" - var/target_pressure = ONE_ATMOSPHERE + target_pressure = ONE_ATMOSPHERE var/node1_concentration = 0.5 var/node2_concentration = 0.5 //node 3 is the outlet, nodes 1 & 2 are intakes +// So we can CtrlClick without triggering the anchored message. +/obj/machinery/atmospherics/trinary/mixer/can_be_pulled(user, grab_state, force, show_message) + return FALSE + /obj/machinery/atmospherics/trinary/mixer/CtrlClick(mob/living/user) - if(!istype(user) || user.incapacitated()) - to_chat(user, "You can't do that right now!") - return - if(!in_range(src, user) && !issilicon(usr)) - return - if(!ishuman(usr) && !issilicon(usr)) - return - toggle() + if(can_use_shortcut(user)) + toggle(user) return ..() -/obj/machinery/atmospherics/trinary/mixer/AICtrlClick() - toggle() +/obj/machinery/atmospherics/trinary/mixer/AICtrlClick(mob/living/silicon/user) + toggle(user) return ..() /obj/machinery/atmospherics/trinary/mixer/AltClick(mob/living/user) - if(!istype(user) || user.incapacitated()) - to_chat(user, "You can't do that right now!") - return - if(!in_range(src, user) && !issilicon(usr)) - return - if(!ishuman(usr) && !issilicon(usr)) - return - set_max() - return + if(can_use_shortcut(user)) + set_max(user) + return ..() /obj/machinery/atmospherics/trinary/mixer/AIAltClick() set_max() @@ -46,16 +38,6 @@ icon_state = "mmap" flipped = 1 -/obj/machinery/atmospherics/trinary/mixer/proc/toggle() - if(powered()) - on = !on - update_icon() - -/obj/machinery/atmospherics/trinary/mixer/proc/set_max() - if(powered()) - target_pressure = MAX_OUTPUT_PRESSURE - update_icon() - /obj/machinery/atmospherics/trinary/mixer/update_icon(safety = 0) ..() diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/trinary_base.dm b/code/modules/atmospherics/machinery/components/trinary_devices/trinary_base.dm index 5b54f0ff91c..86b1aa74699 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/trinary_base.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/trinary_base.dm @@ -3,7 +3,6 @@ initialize_directions = SOUTH|NORTH|WEST use_power = IDLE_POWER_USE - var/on = 0 layer = GAS_FILTER_LAYER var/datum/gas_mixture/air1 diff --git a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm index 1452ab48b2f..b227fc64c70 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/cryo.dm @@ -13,7 +13,6 @@ interact_offline = 1 max_integrity = 350 armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 30, "acid" = 30) - var/on = FALSE var/temperature_archived var/mob/living/carbon/occupant = null var/obj/item/reagent_containers/glass/beaker = null diff --git a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm index 29e3db67ca2..f1bf25957d8 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/outlet_injector.dm @@ -13,7 +13,6 @@ req_one_access_txt = "24;10" - var/on = 0 var/injecting = 0 var/volume_rate = 50 diff --git a/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm b/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm index 9b06019e49e..fdeb02b7b83 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/oxygen_generator.dm @@ -9,8 +9,6 @@ dir = SOUTH initialize_directions = SOUTH - var/on = 0 - var/oxygen_content = 10 /obj/machinery/atmospherics/unary/oxygen_generator/update_icon() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm b/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm index eadd1bac280..64aaa045c8f 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/portables_connector.dm @@ -10,8 +10,6 @@ var/obj/machinery/portable_atmospherics/connected_device - var/on = 0 - /obj/machinery/atmospherics/unary/portables_connector/Destroy() if(connected_device) connected_device.disconnect() diff --git a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm index 7a3bedf9271..aca2e02aff0 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/thermomachine.dm @@ -10,9 +10,6 @@ armor = list("melee" = 0, "bullet" = 0, "laser" = 0, "energy" = 100, "bomb" = 0, "bio" = 100, "rad" = 100, "fire" = 80, "acid" = 30) layer = OBJ_LAYER - ///Check if the device should be on or off - var/on = FALSE - var/icon_state_off = "freezer" var/icon_state_on = "freezer_1" var/icon_state_open = "freezer-o" diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm index 74c8be45b1b..35e9a84e932 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_pump.dm @@ -20,7 +20,6 @@ req_one_access_txt = "24;10" - var/on = 0 var/pump_direction = 1 //0 = siphoning, 1 = releasing var/external_pressure_bound = EXTERNAL_PRESSURE_BOUND diff --git a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm index 618dd1bc355..d006ae874f3 100644 --- a/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm +++ b/code/modules/atmospherics/machinery/components/unary_devices/vent_scrubber.dm @@ -20,7 +20,6 @@ var/list/turf/simulated/adjacent_turfs = list() - var/on = 0 var/scrubbing = 1 //0 = siphoning, 1 = scrubbing var/scrub_O2 = 0 var/scrub_N2 = 0 From c18c177002c174e54b1c2b4fea60020b41f0d767 Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sun, 31 Jan 2021 17:21:49 -0600 Subject: [PATCH 45/48] remove useless returns --- .../atmospherics/machinery/components/binary_devices/pump.dm | 1 - .../machinery/components/binary_devices/volume_pump.dm | 1 - .../atmospherics/machinery/components/trinary_devices/filter.dm | 1 - .../atmospherics/machinery/components/trinary_devices/mixer.dm | 1 - 4 files changed, 4 deletions(-) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index 9303dee01d9..63cc657dfb6 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -44,7 +44,6 @@ Thus, the two variables affect pump operation are set in New(): /obj/machinery/atmospherics/binary/pump/AltClick(mob/living/user) if(can_use_shortcut(user)) set_max(user) - return /obj/machinery/atmospherics/binary/pump/AIAltClick() set_max() diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm index 21225229738..641b492f009 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -41,7 +41,6 @@ Thus, the two variables affect pump operation are set in New(): /obj/machinery/atmospherics/binary/volume_pump/AltClick(mob/living/user) if(can_use_shortcut(user)) set_max(user) - return /obj/machinery/atmospherics/binary/volume_pump/AIAltClick() set_max() diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index 2043220ef77..14b802ec19c 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -47,7 +47,6 @@ /obj/machinery/atmospherics/trinary/filter/AltClick(mob/living/user) if(can_use_shortcut(user)) set_max(user) - return /obj/machinery/atmospherics/trinary/filter/AIAltClick() set_max() diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm index 39c7c73aba1..3e42cf411cd 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm @@ -28,7 +28,6 @@ /obj/machinery/atmospherics/trinary/mixer/AltClick(mob/living/user) if(can_use_shortcut(user)) set_max(user) - return ..() /obj/machinery/atmospherics/trinary/mixer/AIAltClick() set_max() From d5ecfc3ae4dcd252e639fe3383dbe4ad72d66ead Mon Sep 17 00:00:00 2001 From: SteelSlayer Date: Sat, 24 Jul 2021 14:59:19 -0500 Subject: [PATCH 46/48] sabre changes --- code/game/machinery/machinery.dm | 10 +++++----- .../modules/atmospherics/machinery/atmospherics.dm | 14 ++++++++------ .../machinery/components/binary_devices/pump.dm | 6 ++---- .../components/binary_devices/volume_pump.dm | 6 ++---- .../machinery/components/trinary_devices/filter.dm | 6 ++---- .../machinery/components/trinary_devices/mixer.dm | 6 ++---- 6 files changed, 21 insertions(+), 27 deletions(-) diff --git a/code/game/machinery/machinery.dm b/code/game/machinery/machinery.dm index 0d1c6ada2d0..154f094d941 100644 --- a/code/game/machinery/machinery.dm +++ b/code/game/machinery/machinery.dm @@ -658,11 +658,11 @@ Class Procs: * * user - the mob who is trying to interact with the machine. */ /obj/machinery/proc/can_use_shortcut(mob/living/user) - if(!ishuman(user) && !issilicon(user)) - return FALSE - if(!in_range(src, user) && !issilicon(user)) - return FALSE if(user.incapacitated()) to_chat(user, "You can't do that right now!") return FALSE - return TRUE + if(ishuman(user) && in_range(src, user)) + return TRUE + if(issilicon(user)) + return TRUE + return FALSE diff --git a/code/modules/atmospherics/machinery/atmospherics.dm b/code/modules/atmospherics/machinery/atmospherics.dm index 1a877ce857a..bb255692633 100644 --- a/code/modules/atmospherics/machinery/atmospherics.dm +++ b/code/modules/atmospherics/machinery/atmospherics.dm @@ -366,9 +366,10 @@ Pipelines + Other Objects -> Pipe network * * user - the mob who is toggling the machine. */ /obj/machinery/atmospherics/proc/toggle(mob/living/user) - if(powered()) - on = !on - update_icon() + if(!powered()) + return + on = !on + update_icon() if(user) to_chat(user, "You toggle [src] [on ? "on" : "off"].") @@ -381,8 +382,9 @@ Pipelines + Other Objects -> Pipe network * * user - the mob who is setting the output pressure to maximum. */ /obj/machinery/atmospherics/proc/set_max(mob/living/user) - if(powered()) - target_pressure = MAX_OUTPUT_PRESSURE - update_icon() + if(!powered()) + return + target_pressure = MAX_OUTPUT_PRESSURE + update_icon() if(user) to_chat(user, "You set the target pressure of [src] to maximum.") diff --git a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm index 63cc657dfb6..e6fb4f66f8c 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/pump.dm @@ -39,15 +39,13 @@ Thus, the two variables affect pump operation are set in New(): /obj/machinery/atmospherics/binary/pump/AICtrlClick(mob/living/silicon/user) toggle(user) - return ..() /obj/machinery/atmospherics/binary/pump/AltClick(mob/living/user) if(can_use_shortcut(user)) set_max(user) -/obj/machinery/atmospherics/binary/pump/AIAltClick() - set_max() - return ..() +/obj/machinery/atmospherics/binary/pump/AIAltClick(mob/living/silicon/user) + set_max(user) /obj/machinery/atmospherics/binary/pump/Destroy() if(SSradio) diff --git a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm index 641b492f009..f7e50707cdb 100644 --- a/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm +++ b/code/modules/atmospherics/machinery/components/binary_devices/volume_pump.dm @@ -36,15 +36,13 @@ Thus, the two variables affect pump operation are set in New(): /obj/machinery/atmospherics/binary/volume_pump/AICtrlClick(mob/living/silicon/user) toggle(user) - return ..() /obj/machinery/atmospherics/binary/volume_pump/AltClick(mob/living/user) if(can_use_shortcut(user)) set_max(user) -/obj/machinery/atmospherics/binary/volume_pump/AIAltClick() - set_max() - return ..() +/obj/machinery/atmospherics/binary/volume_pump/AIAltClick(mob/living/silicon/user) + set_max(user) /obj/machinery/atmospherics/binary/volume_pump/Destroy() if(SSradio) diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm index 14b802ec19c..f40ecda9147 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/filter.dm @@ -42,15 +42,13 @@ /obj/machinery/atmospherics/trinary/filter/AICtrlClick(mob/living/silicon/user) toggle(user) - return ..() /obj/machinery/atmospherics/trinary/filter/AltClick(mob/living/user) if(can_use_shortcut(user)) set_max(user) -/obj/machinery/atmospherics/trinary/filter/AIAltClick() - set_max() - return ..() +/obj/machinery/atmospherics/trinary/filter/AIAltClick(mob/living/silicon/user) + set_max(user) /obj/machinery/atmospherics/trinary/filter/Destroy() if(SSradio) diff --git a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm index 3e42cf411cd..3b34a95c1ba 100644 --- a/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm +++ b/code/modules/atmospherics/machinery/components/trinary_devices/mixer.dm @@ -23,15 +23,13 @@ /obj/machinery/atmospherics/trinary/mixer/AICtrlClick(mob/living/silicon/user) toggle(user) - return ..() /obj/machinery/atmospherics/trinary/mixer/AltClick(mob/living/user) if(can_use_shortcut(user)) set_max(user) -/obj/machinery/atmospherics/trinary/mixer/AIAltClick() - set_max() - return ..() +/obj/machinery/atmospherics/trinary/mixer/AIAltClick(mob/living/silicon/user) + set_max(user) /obj/machinery/atmospherics/trinary/mixer/flipped icon_state = "mmap" From 076e807731dded5beffd7877cb83ecca3e601235 Mon Sep 17 00:00:00 2001 From: S34N <12197162+S34NW@users.noreply.github.com> Date: Tue, 27 Jul 2021 10:46:26 +0100 Subject: [PATCH 47/48] uh oh that guy is glowing green (#16435) --- code/datums/radiation_wave.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/datums/radiation_wave.dm b/code/datums/radiation_wave.dm index 0c6f32c4555..648cc7284e4 100644 --- a/code/datums/radiation_wave.dm +++ b/code/datums/radiation_wave.dm @@ -109,6 +109,7 @@ var/atom/thing = k if(QDELETED(thing)) continue + strength = strength / RAD_DOSAGE_MULTIPLIER //We don't want contamination murdering everyone instantly thing.rad_act(strength) // This list should only be for types which don't get contaminated but you want to look in their contents From fad93ed2e49896f75a2fa5c35758f2d153e3fe88 Mon Sep 17 00:00:00 2001 From: AffectedArc07 <25063394+AffectedArc07@users.noreply.github.com> Date: Tue, 27 Jul 2021 12:54:33 +0100 Subject: [PATCH 48/48] Revert "uh oh that guy is glowing green (#16435)" This reverts commit 076e807731dded5beffd7877cb83ecca3e601235. --- code/datums/radiation_wave.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/datums/radiation_wave.dm b/code/datums/radiation_wave.dm index 648cc7284e4..0c6f32c4555 100644 --- a/code/datums/radiation_wave.dm +++ b/code/datums/radiation_wave.dm @@ -109,7 +109,6 @@ var/atom/thing = k if(QDELETED(thing)) continue - strength = strength / RAD_DOSAGE_MULTIPLIER //We don't want contamination murdering everyone instantly thing.rad_act(strength) // This list should only be for types which don't get contaminated but you want to look in their contents
ISBNTitleTotal FlagsOptions