diff --git a/code/game/gamemodes/clock_cult/__clock_defines.dm b/code/game/gamemodes/clock_cult/__clock_defines.dm index 5b24c15f731..fc2eb1b1b56 100644 --- a/code/game/gamemodes/clock_cult/__clock_defines.dm +++ b/code/game/gamemodes/clock_cult/__clock_defines.dm @@ -14,7 +14,13 @@ var/global/ratvar_awakens = FALSE //If Ratvar has been summoned #define SCRIPTURE_REVENANT 4 #define SCRIPTURE_JUDGEMENT 5 -#define SLAB_PRODUCTION_THRESHOLD 60 //How many cycles slabs require to produce a single component; defaults to one minute +#define SLAB_PRODUCTION_TIME 400 //how long(deciseconds) slabs require to produce a single component; defaults to 40 seconds + +#define CACHE_PRODUCTION_TIME 300 //how long(deciseconds) caches require to produce a component; defaults to 30 seconds + +#define LOWER_PROB_PER_COMPONENT 10 //how much each component in the cache reduces the weight of getting another of that component type + +#define MAX_COMPONENTS_BEFORE_RAND 10*LOWER_PROB_PER_COMPONENT //the number of each component, times LOWER_PROB_PER_COMPONENT, you need to have before component generation will become random #define GATEWAY_SUMMON_RATE 3 //The speed multiplier used by the Gateway to the Celestial Derelict; defaults to 3x speed diff --git a/code/game/gamemodes/clock_cult/clock_items.dm b/code/game/gamemodes/clock_cult/clock_items.dm index e90f9e48e82..9bdc7086aad 100644 --- a/code/game/gamemodes/clock_cult/clock_items.dm +++ b/code/game/gamemodes/clock_cult/clock_items.dm @@ -28,7 +28,7 @@ w_class = 3 var/list/stored_components = list("belligerent_eye" = 0, "vanguard_cogwheel" = 0, "guvax_capacitor" = 0, "replicant_alloy" = 0, "hierophant_ansible" = 0) var/busy //If the slab is currently being used by something - var/production_cycle = 0 + var/production_time = 0 var/no_cost = FALSE //If the slab is admin-only and needs no components and has no scripture locks /obj/item/clockwork/slab/starter @@ -45,36 +45,39 @@ /obj/item/clockwork/slab/New() ..() SSobj.processing += src + production_time = world.time + SLAB_PRODUCTION_TIME /obj/item/clockwork/slab/Destroy() SSobj.processing -= src - ..() + return ..() /obj/item/clockwork/slab/process() - production_cycle++ - if(production_cycle < SLAB_PRODUCTION_THRESHOLD) - return 0 - var/component_to_generate = pick("belligerent_eye", "vanguard_cogwheel", "guvax_capacitor", "replicant_alloy", "hierophant_ansible") //Possible todo: Generate based on the lowest amount? - stored_components[component_to_generate]++ + if(production_time > world.time) + return + production_time = world.time + SLAB_PRODUCTION_TIME var/mob/living/L if(isliving(loc)) L = loc else if(istype(loc, /obj/item/weapon/storage)) var/obj/item/weapon/storage/W = loc - if(isliving(W.loc)) //Only goes one level down - otherwise it just doesn't tell you + if(isliving(W.loc)) //Only goes one level down - otherwise it won't produce components L = W.loc if(L) - L << "Your slab clunks as it produces a new component." - production_cycle = 0 - return 1 + var/component_to_generate = get_weighted_component_id(src) //more likely to generate components that we have less of + stored_components[component_to_generate]++ + for(var/obj/item/clockwork/slab/S in L.GetAllContents()) //prevent slab abuse today + if(L == src) + continue + S.production_time = world.time + SLAB_PRODUCTION_TIME + L << "Your slab clunks as it produces a new component." /obj/item/clockwork/slab/attackby(obj/item/I, mob/user, params) if(istype(I, /obj/item/clockwork/component) && is_servant_of_ratvar(user)) var/obj/item/clockwork/component/C = I if(!C.component_id) return 0 - user.visible_message("[user] inserts [C] into [src]'s compartments.", "You insert [C] into [src].") - stored_components[C.component_id]++ + user.visible_message("[user] inserts [C] into [src].", "You insert [C] into [src], where it is added to the global cache.") + clockwork_component_cache[C.component_id]++ user.drop_item() qdel(C) return 1 @@ -93,7 +96,8 @@ return 0 if(!is_servant_of_ratvar(user)) user << "The information on [src]'s display shifts rapidly. After a moment, your head begins to pound, and you tear your eyes away." - user.confused = max(0, user.confused + 3) + user.confused += 5 + user.dizziness += 5 return 0 if(busy) user << "[src] refuses to work, displaying the message: \"[busy]!\"" @@ -103,7 +107,7 @@ /obj/item/clockwork/slab/proc/access_display(mob/living/user) if(!is_servant_of_ratvar(user)) return 0 - var/action = input(user, "Among the swathes of information, you see...", "[src]") as null|anything in list("Recital", "Records", "Recollection", "Repository", "Report") + var/action = input(user, "Among the swathes of information, you see...", "[src]") as null|anything in list("Recital", "Records", "Recollection", "Report") if(!action || !user.canUseTopic(src)) return 0 switch(action) @@ -113,9 +117,6 @@ show_stats(user) if("Recollection") show_guide(user) - if("Repository") - show_components(user) - access_display(user) if("Report") show_hierophant(user) access_display(user) @@ -329,14 +330,16 @@ popup.open() return 1 -/obj/item/clockwork/slab/proc/show_components(mob/living/user) - user << "Stored components:" - user << "Belligerent Eyes: [stored_components["belligerent_eye"]]" - user << "Vanguard Cogwheels: [stored_components["vanguard_cogwheel"]]" - user << "Guvax Capacitors: [stored_components["guvax_capacitor"]]" - user << "Replicant Alloys: [stored_components["replicant_alloy"]]" - user << "Hierophant Ansibles: [stored_components["hierophant_ansible"]]" - return 1 +/obj/item/clockwork/slab/examine(mob/user) + ..() + if(is_servant_of_ratvar(user) || isobserver(user)) + user << "Clockwork slabs will only generate components if held by a human or if inside a storage item held by a human, and when generating a component will prevent all other slabs held from generating components." + user << "Stored components (with global cache):" + user << "Belligerent Eyes: [stored_components["belligerent_eye"]] ([stored_components["belligerent_eye"] + clockwork_component_cache["belligerent_eye"]])" + user << "Vanguard Cogwheels: [stored_components["vanguard_cogwheel"]] ([stored_components["vanguard_cogwheel"] + clockwork_component_cache["vanguard_cogwheel"]])" + user << "Guvax Capacitors: [stored_components["guvax_capacitor"]] ([stored_components["guvax_capacitor"] + clockwork_component_cache["guvax_capacitor"]])" + user << "Replicant Alloys: [stored_components["replicant_alloy"]] ([stored_components["replicant_alloy"] + clockwork_component_cache["replicant_alloy"]])" + user << "Hierophant Ansibles: [stored_components["hierophant_ansible"]] ([stored_components["hierophant_ansible"] + clockwork_component_cache["hierophant_ansible"]])" /obj/item/clockwork/slab/proc/show_hierophant(mob/living/user) var/message = stripped_input(user, "Enter a message to send to your fellow servants.", "Hierophant") @@ -676,8 +679,8 @@ w_class = 3 var/specific_component //The type of component that the daemon is set to produce in particular, if any var/obj/structure/clockwork/cache/cache //The cache the daemon is feeding - var/production_progress = 0 //Progress towards production of the next component in seconds - var/production_interval = 30 //How many seconds it takes to produce a new component + var/production_time = 0 //Progress towards production of the next component in seconds + var/production_cooldown = 200 //How many deciseconds it takes to produce a new component /obj/item/clockwork/tinkerers_daemon/New() ..() @@ -687,7 +690,7 @@ /obj/item/clockwork/tinkerers_daemon/Destroy() SSobj.processing -= src clockwork_daemons-- - ..() + return ..() /obj/item/clockwork/tinkerers_daemon/process() if(!cache) @@ -699,16 +702,12 @@ for(var/mob/living/L in living_mob_list) if(is_servant_of_ratvar(L)) servants++ - if(servants / 5 < clockwork_daemons) + if(servants * 0.2 < clockwork_daemons) return 0 - production_progress = min(production_progress + 1, production_interval) - if(production_progress >= production_interval) - production_progress = 0 //Start it over - if(specific_component) - clockwork_component_cache[specific_component]++ - else - clockwork_component_cache[pick("belligerent_eye", "vanguard_cogwheel", "guvax_capacitor", "replicant_alloy", "hierophant_ansible")]++ - cache.visible_message("Something clunks around inside of [cache].") + if(production_time <= world.time) + production_time = world.time + production_cooldown //Start it over + generate_cache_component(specific_component) + cache.visible_message("[cache] hums as the tinkerer's daemon within it produces a component.") /obj/item/clockwork/tinkerers_daemon/attack_hand(mob/user) return 0 diff --git a/code/game/gamemodes/clock_cult/clock_scripture.dm b/code/game/gamemodes/clock_cult/clock_scripture.dm index f50971dc89a..71895772f7c 100644 --- a/code/game/gamemodes/clock_cult/clock_scripture.dm +++ b/code/game/gamemodes/clock_cult/clock_scripture.dm @@ -26,17 +26,35 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed var/multiple_invokers_optional = FALSE //If scripture can have multiple invokers to bolster its effects var/tier = SCRIPTURE_PERIPHERAL //The scripture's tier +//components the scripture used from a slab + var/list/used_slab_components = list("belligerent_eye" = 0, "vanguard_cogwheel" = 0, "guvax_capacitor" = 0, "replicant_alloy" = 0, "hierophant_ansible" = 0) +//components the scripture used from the global cache + var/list/used_cache_components = list("belligerent_eye" = 0, "vanguard_cogwheel" = 0, "guvax_capacitor" = 0, "replicant_alloy" = 0, "hierophant_ansible" = 0) + /datum/clockwork_scripture/proc/run_scripture() if(can_recite() && check_special_requirements()) + if(slab.busy) + invoker << "[slab] refuses to work, displaying the message: \"[slab.busy]!\"" + return 0 slab.busy = "Invocation ([name]) in progress" - if(check_special_requirements() && recital()) - slab.busy = null - if(check_special_requirements() && scripture_effects() && (!ratvar_awakens || !slab.no_cost)) - for(var/i in required_components) - if(clockwork_component_cache[i] >= consumed_components[i]) //Draw components from the global cache first - clockwork_component_cache[i] -= consumed_components[i] - else - slab.stored_components[i] -= consumed_components[i] + if(!ratvar_awakens && !slab.no_cost) + for(var/i in consumed_components) + if(slab.stored_components[i] >= consumed_components[i]) //Draw components from the slab first + slab.stored_components[i] -= consumed_components[i] + used_slab_components[i]++ + else + clockwork_component_cache[i] -= consumed_components[i] + used_cache_components[i]++ + if(!check_special_requirements() || !recital() || !check_special_requirements() || !scripture_effects()) //if we fail any of these, refund components used + for(var/i in used_slab_components) + if(used_slab_components[i]) + if(slab) + slab.stored_components[i] += consumed_components[i] + else //if we can't find a slab add to the global cache + clockwork_component_cache[i] += consumed_components[i] + for(var/i in used_cache_components) + if(used_cache_components[i]) + clockwork_component_cache[i] += consumed_components[i] if(slab) slab.busy = null qdel(src) @@ -337,7 +355,6 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed invocations = list("Z`rgny, orpbzr terngre!") channel_time = 0 required_components = list("replicant_alloy" = 1) - consumed_components = list("replicant_alloy" = 1) //People were spamming slabs to get infinite components. You chose this. whispered = TRUE usage_tip = "This is inefficient as a way to produce components, as it consumes them in the first place." tier = SCRIPTURE_DRIVER @@ -911,7 +928,7 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed for(var/obj/item/clockwork/clockwork_proselytizer/P in all_clockwork_objects) //Proselytizers no longer require alloy P.uses_alloy = FALSE for(var/obj/item/clockwork/tinkerers_daemon/D in all_clockwork_objects) //Daemons produce components twice as quickly - D.production_interval /= 2 + D.production_time *= 0.5 for(var/obj/structure/clockwork/powered/M in all_clockwork_objects) //Powered clockwork structures no longer need power M.needs_power = FALSE spawn(600) @@ -919,11 +936,11 @@ Judgement: 10 servants, 100 CV, and any existing AIs are converted or destroyed W.damage_per_tick = initial(W.damage_per_tick) W.sight_range = initial(W.sight_range) for(var/obj/item/clockwork/clockwork_proselytizer/P in all_clockwork_objects) - P.uses_alloy = TRUE + P.uses_alloy = initial(P.uses_alloy) for(var/obj/item/clockwork/tinkerers_daemon/D in all_clockwork_objects) - D.production_interval = initial(D.production_interval) + D.production_time = initial(D.production_time) for(var/obj/structure/clockwork/powered/M in all_clockwork_objects) - M.needs_power = TRUE + M.needs_power = initial(M.needs_power) return 1 diff --git a/code/game/gamemodes/clock_cult/clock_structures.dm b/code/game/gamemodes/clock_cult/clock_structures.dm index 384f2c9b232..d2da171b022 100644 --- a/code/game/gamemodes/clock_cult/clock_structures.dm +++ b/code/game/gamemodes/clock_cult/clock_structures.dm @@ -28,7 +28,7 @@ /obj/structure/clockwork/Destroy() clockwork_construction_value -= construction_value all_clockwork_objects -= src - ..() + return ..() /obj/structure/clockwork/proc/destroyed() if(!takes_damage) @@ -122,6 +122,8 @@ icon_state = "tinkerers_cache" construction_value = 10 break_message = "The cache's fire winks out before it falls in on itself!" + var/wall_generation_cooldown + var/wall_found = FALSE //if we've found a wall and finished our windup delay /obj/structure/clockwork/cache/New() ..() @@ -133,13 +135,26 @@ SSobj.processing -= src return ..() +/obj/structure/clockwork/cache/destroyed() + if(takes_damage) + for(var/I in src) + var/atom/movable/A = I + A.forceMove(get_turf(src)) //drop any daemons we have + return ..() + /obj/structure/clockwork/cache/process() - if(prob(2)) - playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', rand(1, 5), 1, -4, 1, 1) - for(var/turf/closed/wall/clockwork/C in orange(1, get_turf(src))) - if(prob(5)) - clockwork_component_cache[pick("belligerent_eye", "vanguard_cogwheel", "guvax_capacitor", "replicant_alloy", "hierophant_ansible")]++ - playsound(src, 'sound/magic/clockwork/fellowship_armory.ogg', rand(15, 20), 1, -3, 1, 1) + for(var/turf/closed/wall/clockwork/C in orange(1, src)) + if(!wall_found) + wall_found = TRUE + wall_generation_cooldown = world.time + CACHE_PRODUCTION_TIME + visible_message("[src] starts to whirr in the presence of [C]...") + break + if(wall_generation_cooldown <= world.time) + wall_generation_cooldown = world.time + CACHE_PRODUCTION_TIME + generate_cache_component() + playsound(C, 'sound/magic/clockwork/fellowship_armory.ogg', rand(15, 20), 1, -3, 1, 1) + visible_message("Something clunks around inside of [src]...") + break /obj/structure/clockwork/cache/attackby(obj/item/I, mob/living/user, params) if(!is_servant_of_ratvar(user)) @@ -186,7 +201,7 @@ D.cache = src D.specific_component = component_type user.visible_message("[user] spins the cogwheel on [I] and puts it into [src].", \ - "You activate the daemon and put it into [src]. It will now produce a component every thirty seconds.") + "You activate the daemon and put it into [src]. It will now produce a component every twenty seconds.") user.drop_item() qdel(I) return 1 @@ -216,20 +231,25 @@ var/obj/item/clockwork/component/the_component switch(component_to_withdraw) if("Belligerent Eye") - the_component = new/obj/item/clockwork/component/belligerent_eye(get_turf(src)) - clockwork_component_cache["belligerent_eye"]-- + if(clockwork_component_cache["belligerent_eye"]) + the_component = new/obj/item/clockwork/component/belligerent_eye(get_turf(src)) + clockwork_component_cache["belligerent_eye"]-- if("Vanguard Cogwheel") - the_component = new/obj/item/clockwork/component/vanguard_cogwheel(get_turf(src)) - clockwork_component_cache["vanguard_cogwheel"]-- + if(clockwork_component_cache["vanguard_cogwheel"]) + the_component = new/obj/item/clockwork/component/vanguard_cogwheel(get_turf(src)) + clockwork_component_cache["vanguard_cogwheel"]-- if("Guvax Capacitor") - the_component = new/obj/item/clockwork/component/guvax_capacitor(get_turf(src)) - clockwork_component_cache["guvax_capacitor"]-- + if(clockwork_component_cache["guvax_capacitor"]) + the_component = new/obj/item/clockwork/component/guvax_capacitor(get_turf(src)) + clockwork_component_cache["guvax_capacitor"]-- if("Replicant Alloy") - the_component = new/obj/item/clockwork/component/replicant_alloy(get_turf(src)) - clockwork_component_cache["replicant_alloy"]-- + if(clockwork_component_cache["replicant_alloy"]) + the_component = new/obj/item/clockwork/component/replicant_alloy(get_turf(src)) + clockwork_component_cache["replicant_alloy"]-- if("Hierophant Ansible") - the_component = new/obj/item/clockwork/component/hierophant_ansible(get_turf(src)) - clockwork_component_cache["hierophant_ansible"]-- + if(clockwork_component_cache["hierophant_ansible"]) + the_component = new/obj/item/clockwork/component/hierophant_ansible(get_turf(src)) + clockwork_component_cache["hierophant_ansible"]-- if(the_component) user.visible_message("[user] withdraws [the_component] from [src].", "You withdraw [the_component] from [src].") user.put_in_hands(the_component) @@ -239,11 +259,12 @@ ..() if(is_servant_of_ratvar(user) || isobserver(user)) user << "Stored components:" - user << "Belligerent Eyes: [clockwork_component_cache["belligerent_eye"]]" - user << "Vanguard Cogwheels: [clockwork_component_cache["vanguard_cogwheel"]]" - user << "Guvax Capacitors: [clockwork_component_cache["guvax_capacitor"]]" - user << "Replicant Alloys: [clockwork_component_cache["replicant_alloy"]]" - user << "Hierophant Ansibles: [clockwork_component_cache["hierophant_ansible"]]" + user << "Belligerent Eyes: [clockwork_component_cache["belligerent_eye"]]" + user << "Vanguard Cogwheels: [clockwork_component_cache["vanguard_cogwheel"]]" + user << "Guvax Capacitors: [clockwork_component_cache["guvax_capacitor"]]" + user << "Replicant Alloys: [clockwork_component_cache["replicant_alloy"]]" + user << "Hierophant Ansibles: [clockwork_component_cache["hierophant_ansible"]]" + /obj/structure/clockwork/ocular_warden //Ocular warden: Low-damage, low-range turret. Deals constant damage to whoever it makes eye contact with. name = "ocular warden" diff --git a/code/game/gamemodes/clock_cult/clock_unsorted.dm b/code/game/gamemodes/clock_cult/clock_unsorted.dm index c5e8bc42091..6af772ede54 100644 --- a/code/game/gamemodes/clock_cult/clock_unsorted.dm +++ b/code/game/gamemodes/clock_cult/clock_unsorted.dm @@ -13,6 +13,27 @@ usr.verbs -= /mob/living/carbon/human/proc/function_call return 1 +/proc/generate_cache_component(specific_component_id) //generates a component in the global component cache, either random based on lowest or a specific component + if(specific_component_id) + clockwork_component_cache[specific_component_id]++ + else + var/component_to_generate = get_weighted_component_id() + clockwork_component_cache[component_to_generate]++ + +/proc/get_weighted_component_id(obj/item/clockwork/slab/storage_slab) //returns a chosen component id based on the lowest amount of that component + if(storage_slab) + return pickweight(list("belligerent_eye" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["belligerent_eye"] + storage_slab.stored_components["belligerent_eye"]), 1), \ + "vanguard_cogwheel" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["vanguard_cogwheel"] + storage_slab.stored_components["vanguard_cogwheel"]), 1), \ + "guvax_capacitor" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["guvax_capacitor"] + storage_slab.stored_components["guvax_capacitor"]), 1), \ + "replicant_alloy" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["replicant_alloy"] + storage_slab.stored_components["replicant_alloy"]), 1), \ + "hierophant_ansible" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*(clockwork_component_cache["hierophant_ansible"] + storage_slab.stored_components["hierophant_ansible"]), 1))) + + return pickweight(list("belligerent_eye" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["belligerent_eye"], 1), \ + "vanguard_cogwheel" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["vanguard_cogwheel"], 1), \ + "guvax_capacitor" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["guvax_capacitor"], 1), \ + "replicant_alloy" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["replicant_alloy"], 1), \ + "hierophant_ansible" = max(MAX_COMPONENTS_BEFORE_RAND - LOWER_PROB_PER_COMPONENT*clockwork_component_cache["hierophant_ansible"], 1))) + //allows a mob to select a target to gate to /atom/movable/proc/procure_gateway(mob/living/invoker, time_duration, gateway_uses, two_way) var/list/possible_targets = list() diff --git a/code/game/turfs/simulated/floor/misc_floor.dm b/code/game/turfs/simulated/floor/misc_floor.dm index 1338eff7435..c2a80cfc0dc 100644 --- a/code/game/turfs/simulated/floor/misc_floor.dm +++ b/code/game/turfs/simulated/floor/misc_floor.dm @@ -123,20 +123,28 @@ ..() PoolOrNew(/obj/effect/overlay/temp/ratvar/floor, src) PoolOrNew(/obj/effect/overlay/temp/ratvar/beam, src) - SSobj.processing += src clockwork_construction_value++ /turf/open/floor/clockwork/Destroy() SSobj.processing -= src clockwork_construction_value-- + return ..() + +/turf/open/floor/clockwork/Entered(atom/movable/AM) ..() + SSobj.processing |= src /turf/open/floor/clockwork/process() + if(!healservants()) + SSobj.processing -= src + +/turf/open/floor/clockwork/proc/healservants() for(var/mob/living/L in src) if(L.stat == DEAD || !is_servant_of_ratvar(L)) continue L.adjustBruteLoss(-1) L.adjustFireLoss(-1) + . = 1 /turf/open/floor/clockwork/attackby(obj/item/I, mob/living/user, params) if(istype(I, /obj/item/weapon/crowbar)) diff --git a/icons/obj/clockwork_objects.dmi b/icons/obj/clockwork_objects.dmi index 21b91a74550..b293f7bfac9 100644 Binary files a/icons/obj/clockwork_objects.dmi and b/icons/obj/clockwork_objects.dmi differ