diff --git a/.travis.yml b/.travis.yml index 9d86d85229..81b8487f48 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,4 +19,6 @@ install: script: - shopt -s globstar - (! grep 'step_[xy]' maps/**/*.dmm) + - (! find nano/templates/ -type f -exec md5sum {} + | sort | uniq -D -w 32 | grep nano) + - ( md5sum -c - <<< "0af969f671fba6cf9696c78cd175a14a *baystation12.int") - DreamMaker baystation12.dme diff --git a/code/controllers/Processes/machinery.dm b/code/controllers/Processes/machinery.dm index c796afa1f9..b84dfaf943 100644 --- a/code/controllers/Processes/machinery.dm +++ b/code/controllers/Processes/machinery.dm @@ -59,4 +59,4 @@ /datum/controller/process/machinery/getStatName() - return ..()+"([machines.len])" \ No newline at end of file + return ..()+"([machines.len])" diff --git a/code/controllers/Processes/turf.dm b/code/controllers/Processes/turf.dm index c1efac52f9..2ac33f48ba 100644 --- a/code/controllers/Processes/turf.dm +++ b/code/controllers/Processes/turf.dm @@ -1,9 +1,14 @@ -var/global/list/processing_turfs = list() +var/global/list/turf/processing_turfs = list() /datum/controller/process/turf/setup() name = "turf" schedule_interval = 20 // every 2 seconds /datum/controller/process/turf/doWork() - for(var/turf/unsimulated/wall/supermatter/SM in processing_turfs) - SM.process() + for(var/turf/T in processing_turfs) + if(T.process() == PROCESS_KILL) + processing_turfs.Remove(T) + scheck() + +/datum/controller/process/turf/getStatName() + return ..()+"([processing_turfs.len])" diff --git a/code/controllers/configuration.dm b/code/controllers/configuration.dm index 171080fb32..98d56d3d23 100644 --- a/code/controllers/configuration.dm +++ b/code/controllers/configuration.dm @@ -114,6 +114,10 @@ var/list/gamemode_cache = list() var/organ_health_multiplier = 1 var/organ_regeneration_multiplier = 1 + + //Paincrit knocks someone down once they hit 60 shock_stage, so by default make it so that close to 100 additional damage needs to be dealt, + //so that it's similar to HALLOSS. Lowered it a bit since hitting paincrit takes much longer to wear off than a halloss stun. + var/organ_damage_spillover_multiplier = 0.5 var/bones_can_break = 0 var/limbs_can_break = 0 @@ -670,6 +674,8 @@ var/list/gamemode_cache = list() config.organ_health_multiplier = value / 100 if("organ_regeneration_multiplier") config.organ_regeneration_multiplier = value / 100 + if("organ_damage_spillover_multiplier") + config.organ_damage_spillover_multiplier = value / 100 if("bones_can_break") config.bones_can_break = value if("limbs_can_break") diff --git a/code/controllers/master_controller.dm b/code/controllers/master_controller.dm index d698454cab..0152af8b13 100644 --- a/code/controllers/master_controller.dm +++ b/code/controllers/master_controller.dm @@ -39,7 +39,6 @@ datum/controller/game_controller/proc/setup() setup_objects() setupgenetics() - setup_economy() SetupXenoarch() transfer_controller = new diff --git a/code/controllers/voting.dm b/code/controllers/voting.dm index 7db31c6fa6..68bfdab74b 100644 --- a/code/controllers/voting.dm +++ b/code/controllers/voting.dm @@ -257,7 +257,7 @@ datum/controller/vote text += "\n[question]" log_vote(text) - world << "[text]\nType vote to place your votes.\nYou have [config.vote_period/10] seconds to vote." + world << "[text]\nType vote or click here to place your votes.\nYou have [config.vote_period/10] seconds to vote." switch(vote_type) if("crew_transfer") world << sound('sound/ambience/alarm4.ogg', repeat = 0, wait = 0, volume = 50, channel = 3) diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 97e1f59582..8bc6cc0580 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -2,10 +2,8 @@ data_core = new /obj/effect/datacore() return 1 -/obj/effect/datacore/proc/manifest(var/nosleep = 0) +/obj/effect/datacore/proc/manifest() spawn() - if(!nosleep) - sleep(40) for(var/mob/living/carbon/human/H in player_list) manifest_inject(H) return diff --git a/code/datums/wires/airlock.dm b/code/datums/wires/airlock.dm index 7e8c8779cf..a0f1f9c7f1 100644 --- a/code/datums/wires/airlock.dm +++ b/code/datums/wires/airlock.dm @@ -37,10 +37,11 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 var/haspower = A.arePowerSystemsOn() //If there's no power, then no lights will be on. . += ..() - . += text("
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]", + . += text("
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]
\n[]", (A.locked ? "The door bolts have fallen!" : "The door bolts look up."), ((A.lights && haspower) ? "The door bolt lights are on." : "The door bolt lights are off!"), ((haspower) ? "The test light is on." : "The test light is off!"), + ((A.backupPowerCablesCut()) ? "The backup power light is off!" : "The backup power light is on."), ((A.aiControlDisabled==0 && !A.emagged && haspower)? "The 'AI control allowed' light is on." : "The 'AI control allowed' light is off."), ((A.safe==0 && haspower)? "The 'Check Wiring' light is on." : "The 'Check Wiring' light is off."), ((A.normalspeed==0 && haspower)? "The 'Check Timing Mechanism' light is on." : "The 'Check Timing Mechanism' light is off."), @@ -124,7 +125,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 //Sending a pulse through flashes the red light on the door (if the door has power). if(A.arePowerSystemsOn() && A.density) A.do_animate("deny") - if(AIRLOCK_WIRE_MAIN_POWER1 || AIRLOCK_WIRE_MAIN_POWER2) + if(AIRLOCK_WIRE_MAIN_POWER1, AIRLOCK_WIRE_MAIN_POWER2) //Sending a pulse through either one causes a breaker to trip, disabling the door for 10 seconds if backup power is connected, or 1 minute if not (or until backup power comes back on, whichever is shorter). A.loseMainPower() if(AIRLOCK_WIRE_DOOR_BOLTS) @@ -135,7 +136,7 @@ var/const/AIRLOCK_WIRE_LIGHT = 2048 else A.unlock() - if(AIRLOCK_WIRE_BACKUP_POWER1 || AIRLOCK_WIRE_BACKUP_POWER2) + if(AIRLOCK_WIRE_BACKUP_POWER1, AIRLOCK_WIRE_BACKUP_POWER2) //two wires for backup power. Sending a pulse through either one causes a breaker to trip, but this does not disable it unless main power is down too (in which case it is disabled for 1 minute or however long it takes main power to come back, whichever is shorter). A.loseBackupPower() if(AIRLOCK_WIRE_AI_CONTROL) diff --git a/code/datums/wires/wires.dm b/code/datums/wires/wires.dm index 3b0b54942f..0555a140bd 100644 --- a/code/datums/wires/wires.dm +++ b/code/datums/wires/wires.dm @@ -278,6 +278,11 @@ var/const/POWER = 8 var/r = rand(1, wires.len) CutWireIndex(r) +/datum/wires/proc/RandomCutAll(var/probability = 10) + for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i) + if(prob(probability)) + CutWireIndex(i) + /datum/wires/proc/CutAll() for(var/i = 1; i < MAX_FLAG && i < (1 << wire_count); i += i) CutWireIndex(i) diff --git a/code/defines/obj/weapon.dm b/code/defines/obj/weapon.dm index 99ff26c89a..4d564bbf83 100644 --- a/code/defines/obj/weapon.dm +++ b/code/defines/obj/weapon.dm @@ -175,47 +175,91 @@ origin_tech = "materials=1" var/breakouttime = 300 //Deciseconds = 30s = 0.5 minute -/obj/item/weapon/legcuffs/beartrap +/obj/item/weapon/beartrap name = "bear trap" throw_speed = 2 throw_range = 1 + gender = PLURAL + icon = 'icons/obj/items.dmi' icon_state = "beartrap0" desc = "A trap used to catch bears and other legged creatures." - var/armed = 0 + throwforce = 0 + w_class = 3.0 + origin_tech = "materials=1" + var/deployed = 0 suicide_act(mob/user) - viewers(user) << "\red [user] is putting the [src.name] on \his head! It looks like \he's trying to commit suicide." + viewers(user) << "[user] is putting the [src.name] on \his head! It looks like \he's trying to commit suicide." return (BRUTELOSS) -/obj/item/weapon/legcuffs/beartrap/attack_self(mob/user as mob) +/obj/item/weapon/beartrap/attack_self(mob/user as mob) ..() if(ishuman(user) && !user.stat && !user.restrained()) - armed = !armed - icon_state = "beartrap[armed]" - user << "[src] is now [armed ? "armed" : "disarmed"]" + if(deployed==0) + user.visible_message("[user] is deploying \the [src]", "You are deploying \the [src]!") + if (do_after(user, 60)) + user.visible_message("[user] has deployed \the [src]", "You have deployed \the [src]!") + deployed = 1 + user.drop_from_inventory(src, user.loc) + update_icon() + anchored = 1 -/obj/item/weapon/legcuffs/beartrap/Crossed(AM as mob|obj) - if(armed) +/obj/item/weapon/beartrap/attack_hand(mob/user as mob) + if(ishuman(user) && !user.stat && !user.restrained()) + if(deployed==1) + user.visible_message("[user] is disarming \the [src]", "You are disarming \the [src]!") + if (do_after(user, 60)) + user.visible_message("[user] has disarmed \the [src]", "You have disarmed \the [src]!") + deployed = 0 + anchored = 0 + update_icon() + + if(deployed==0) + ..() + +/obj/item/weapon/beartrap/Crossed(AM as mob|obj) + if(deployed) if(ishuman(AM)) if(isturf(src.loc)) - var/mob/living/carbon/H = AM + var/mob/living/carbon/human/H = AM if(H.m_intent == "run") - armed = 0 - H.legcuffed = src - src.loc = H - H.update_inv_legcuffed() - H << "\red You step on \the [src]!" - feedback_add_details("handcuffs","B") //Yes, I know they're legcuffs. Don't change this, no need for an extra variable. The "B" is used to tell them apart. + deployed = 0 + update_icon() + H << "You step on \the [src]!" for(var/mob/O in viewers(H, null)) if(O == H) continue - O.show_message("\red [H] steps on \the [src].", 1) + O.show_message("[H] steps on \the [src].", 1) + if(H.lying) + var/obj/item/organ/external/affecting = pick(H.organs) + if(affecting.take_damage(30, 0)) + H.UpdateDamageIcon() + affecting.embed(src) + else + var/list/potentialorgans = list() + for(var/organ in list("l_leg", "r_leg", "l_foot", "r_foot")) + var/obj/item/organ/external/R = H.get_organ(organ) + if(R && !(R.status & ORGAN_DESTROYED)) + potentialorgans += R + var/obj/item/organ/external/affecting = pick(potentialorgans) + if(affecting.take_damage(30, 0)) + H.UpdateDamageIcon() + affecting.embed(src) + + if(isanimal(AM) && !istype(AM, /mob/living/simple_animal/parrot) && !istype(AM, /mob/living/simple_animal/construct) && !istype(AM, /mob/living/simple_animal/shade) && !istype(AM, /mob/living/simple_animal/hostile/viscerator)) - armed = 0 + deployed = 0 var/mob/living/simple_animal/SA = AM SA.health -= 20 ..() +/obj/item/weapon/beartrap/update_icon() + ..() + + if(deployed == 0) + icon_state = "beartrap0" + else + icon_state = "beartrap1" /obj/item/weapon/caution diff --git a/code/defines/procs/statistics.dm b/code/defines/procs/statistics.dm index 07856d9251..6025457758 100644 --- a/code/defines/procs/statistics.dm +++ b/code/defines/procs/statistics.dm @@ -98,7 +98,7 @@ proc/statistic_cycle() return while(1) sql_poll_population() - sleep(600) + sleep(6000) //This proc is used for feedback. It is executed at round end. proc/sql_commit_feedback() diff --git a/code/game/gamemodes/endgame/supermatter_cascade/blob.dm b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm index d71ff249d1..dc315ac510 100644 --- a/code/game/gamemodes/endgame/supermatter_cascade/blob.dm +++ b/code/game/gamemodes/endgame/supermatter_cascade/blob.dm @@ -23,7 +23,7 @@ processing_turfs.Remove(src) ..() -/turf/unsimulated/wall/supermatter/proc/process() +/turf/unsimulated/wall/supermatter/process() // Only check infrequently. if(next_check>world.time) return diff --git a/code/game/gamemodes/gameticker.dm b/code/game/gamemodes/gameticker.dm index 08ad7e7253..34a57a0768 100644 --- a/code/game/gamemodes/gameticker.dm +++ b/code/game/gamemodes/gameticker.dm @@ -110,11 +110,11 @@ var/global/datum/controller/gameticker/ticker else src.mode.announce() + current_state = GAME_STATE_PLAYING create_characters() //Create player characters and transfer them collect_minds() equip_characters() data_core.manifest() - current_state = GAME_STATE_PLAYING callHook("roundstart") @@ -155,7 +155,6 @@ var/global/datum/controller/gameticker/ticker for(var/obj/multiz/ladder/L in world) L.connect() //Lazy hackfix for ladders. TODO: move this to an actual controller. ~ Z if(config.sql_enabled) - spawn(3000) statistic_cycle() // Polls population totals regularly and stores them in an SQL DB -- TLE return 1 diff --git a/code/game/jobs/access.dm b/code/game/jobs/access.dm index 33dcee54a2..449e5f68ba 100644 --- a/code/game/jobs/access.dm +++ b/code/game/jobs/access.dm @@ -160,7 +160,7 @@ access_hydroponics, access_library, access_lawyer, access_virology, access_psychiatrist, access_cmo, access_qm, access_clown, access_mime, access_surgery, access_theatre, access_research, access_mining, access_mailsorting, access_heads_vault, access_mining_station, access_xenobiology, access_ce, access_hop, access_hos, access_RC_announce, - access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch) + access_keycard_auth, access_tcomsat, access_gateway, access_xenoarch, access_medical_equip) /proc/get_all_centcom_access() return list(access_cent_general, access_cent_thunder, access_cent_specops, access_cent_medical, access_cent_living, access_cent_storage, access_cent_teleporter, access_cent_creed, access_cent_captain) diff --git a/code/game/jobs/job/civilian.dm b/code/game/jobs/job/civilian.dm index 073e663a4b..c1ca46da14 100644 --- a/code/game/jobs/job/civilian.dm +++ b/code/game/jobs/job/civilian.dm @@ -305,15 +305,15 @@ faction = "Station" total_positions = 2 spawn_positions = 2 - supervisors = "the captain" + supervisors = "Nanotrasen officials and Corporate Regulations" selection_color = "#dddddd" - access = list(access_lawyer, access_court, access_sec_doors, access_maint_tunnels) - minimal_access = list(access_lawyer, access_court, access_sec_doors) + access = list(access_lawyer, access_court, access_sec_doors, access_maint_tunnels, access_heads) + minimal_access = list(access_lawyer, access_court, access_sec_doors, access_heads) equip(var/mob/living/carbon/human/H) if(!H) return 0 - H.equip_to_slot_or_del(new /obj/item/device/radio/headset/headset_sec(H), slot_l_ear) + H.equip_to_slot_or_del(new /obj/item/device/radio/headset/ia(H), slot_l_ear) switch(H.backbag) if(2) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack(H), slot_back) if(3) H.equip_to_slot_or_del(new /obj/item/weapon/storage/backpack/satchel_norm(H), slot_back) diff --git a/code/game/machinery/atmoalter/portable_atmospherics.dm b/code/game/machinery/atmoalter/portable_atmospherics.dm index 5e8817359f..9ba8c2de49 100644 --- a/code/game/machinery/atmoalter/portable_atmospherics.dm +++ b/code/game/machinery/atmoalter/portable_atmospherics.dm @@ -68,6 +68,7 @@ //Perform the connection connected_port = new_port connected_port.connected_device = src + connected_port.on = 1 //Activate port updates anchored = 1 //Prevent movement diff --git a/code/game/machinery/bots/mulebot.dm b/code/game/machinery/bots/mulebot.dm index 125345c518..3e6f0d8e33 100644 --- a/code/game/machinery/bots/mulebot.dm +++ b/code/game/machinery/bots/mulebot.dm @@ -305,7 +305,14 @@ if("destination") refresh=0 - var/new_dest = input("Enter new destination tag", "Mulebot [suffix ? "([suffix])" : ""]", destination) as text|null + var/new_dest + var/list/beaconlist = new() + for(var/obj/machinery/navbeacon/N in navbeacons) + beaconlist.Add(N.location) + if(beaconlist.len) + new_dest = input("Select new destination tag", "Mulebot [suffix ? "([suffix])" : ""]", destination) in beaconlist + else + alert("No destination beacons available.") refresh=1 if(new_dest) set_destination(new_dest) @@ -741,11 +748,6 @@ if(!on) return - /* - world << "rec signal: [signal.source]" - for(var/x in signal.data) - world << "* [x] = [signal.data[x]]" - */ var/recv = signal.data["command"] // process all-bot input if(recv=="bot_status" && wires.RemoteRX()) diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index ec9c17f241..43e26a7d46 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -226,6 +226,8 @@ //Used when someone breaks a camera /obj/machinery/camera/proc/destroy() stat |= BROKEN + wires.RandomCutAll() + kick_viewers() triggerCameraAlarm() update_icon() diff --git a/code/game/machinery/navbeacon.dm b/code/game/machinery/navbeacon.dm index d7224f2212..c9228000e2 100644 --- a/code/game/machinery/navbeacon.dm +++ b/code/game/machinery/navbeacon.dm @@ -1,6 +1,9 @@ // Navigation beacon for AI robots // Functions as a transponder: looks for incoming signal matching + +var/global/list/navbeacons // no I don't like putting this in, but it will do for now + /obj/machinery/navbeacon icon = 'icons/obj/objects.dmi' @@ -27,6 +30,13 @@ var/turf/T = loc hide(T.intact) + + // add beacon to MULE bot beacon list + if(freq == 1400) + if(!navbeacons) + navbeacons = new() + navbeacons += src + spawn(5) // must wait for map loading to finish if(radio_controller) @@ -241,6 +251,7 @@ Transponder Codes: