Merge branch 'master' into upstream-merge-31044

This commit is contained in:
LetterJay
2017-09-30 14:53:08 -04:00
committed by GitHub
346 changed files with 9273 additions and 7009 deletions
@@ -0,0 +1,50 @@
//This is the innate action for "binding" and calling weapons to yourself. These weapons can appear and disappear at will.
//You can invoke a cooldown period by calling "weapon_reset(cooldown in deciseconds)." By default, this only applies to dismissing weapons.
/datum/action/innate/call_weapon
name = "Call Weapon"
desc = "This definitely shouldn't exist."
icon_icon = 'icons/mob/actions/actions_clockcult.dmi'
button_icon_state = "ratvarian_spear"
background_icon_state = "bg_clock"
check_flags = AB_CHECK_RESTRAINED|AB_CHECK_STUN|AB_CHECK_CONSCIOUS
buttontooltipstyle = "clockcult"
var/cooldown = 0
var/obj/item/clockwork/weapon/weapon_type //The type of weapon to create
var/obj/item/clockwork/weapon/weapon
/datum/action/innate/call_weapon/IsAvailable()
if(!is_servant_of_ratvar(owner))
qdel(src)
return
if(cooldown > world.time)
return
return ..()
/datum/action/innate/call_weapon/Activate()
if(!owner.get_empty_held_indexes())
to_chat(usr, "<span class='warning'>You need an empty hand to call forth your [initial(weapon_type.name)]!</span>")
return
if(weapon)
if(weapon.loc == owner)
owner.visible_message("<span class='danger'>[owner]'s [weapon.name] flickers and disappears!</span>")
to_chat(owner, "<span class='brass'>You dismiss [weapon].</span>")
owner.drop_item()
QDEL_NULL(weapon)
weapon_reset(RATVARIAN_SPEAR_COOLDOWN * 0.5)
return
else
weapon.visible_message("<span class='warning'>[weapon] suddenly flickers and disappears!</span>")
owner.visible_message("<span class='danger'>A [weapon.name] suddenly flickers into [owner]'s hands!</span>", "<span class='brass'>You recall [weapon] to you.</span>")
else
weapon = new weapon_type (get_turf(usr), src)
owner.visible_message("<span class='warning'>A [weapon.name] materializes in [owner]'s hands!</span>", "<span class='brass'>You call forth your [weapon.name]!</span>")
weapon.forceMove(get_turf(owner))
owner.put_in_hands(weapon)
owner.update_action_buttons_icon()
return TRUE
/datum/action/innate/call_weapon/proc/weapon_reset(cooldown_time)
cooldown = world.time + cooldown_time
addtimer(CALLBACK(owner, /mob.proc/update_action_buttons_icon), cooldown_time)
owner.update_action_buttons_icon()
QDEL_NULL(weapon)
@@ -1,13 +1,10 @@
//Ratvarian spear: A relatively fragile spear from the Celestial Derelict. Deals extreme damage to silicons and enemy cultists, but doesn't last long when summoned.
/obj/item/clockwork/ratvarian_spear
/obj/item/clockwork/weapon/ratvarian_spear
name = "ratvarian spear"
desc = "A razor-sharp spear made of brass. It thrums with barely-contained energy."
clockwork_desc = "A powerful spear of Ratvarian making. It's more effective against enemy cultists and silicons."
icon = 'icons/obj/clockwork_objects.dmi'
icon_state = "ratvarian_spear"
item_state = "ratvarian_spear"
lefthand_file = 'icons/mob/inhands/antag/clockwork_lefthand.dmi'
righthand_file = 'icons/mob/inhands/antag/clockwork_righthand.dmi'
force = 15 //Extra damage is dealt to targets in attack()
throwforce = 25
armour_penetration = 10
@@ -16,42 +13,27 @@
hitsound = 'sound/weapons/bladeslice.ogg'
w_class = WEIGHT_CLASS_BULKY
var/bonus_burn = 5
var/timerid
/obj/item/clockwork/ratvarian_spear/Destroy()
deltimer(timerid)
return ..()
/obj/item/clockwork/ratvarian_spear/ratvar_act()
/obj/item/clockwork/weapon/ratvarian_spear/ratvar_act()
if(GLOB.ratvar_awakens) //If Ratvar is alive, the spear is extremely powerful
force = 20
bonus_burn = 10
throwforce = 40
armour_penetration = 50
clockwork_desc = initial(clockwork_desc)
deltimer(timerid)
else
force = initial(force)
bonus_burn = initial(bonus_burn)
throwforce = initial(throwforce)
armour_penetration = initial(armour_penetration)
clockwork_desc = "A powerful spear of Ratvarian making. It's more effective against enemy cultists and silicons, though it won't last for long."
deltimer(timerid)
timerid = addtimer(CALLBACK(src, .proc/break_spear), RATVARIAN_SPEAR_DURATION, TIMER_STOPPABLE)
/obj/item/clockwork/ratvarian_spear/cyborg/ratvar_act() //doesn't break!
..()
clockwork_desc = "A powerful spear of Ratvarian making. It's more effective against enemy cultists and silicons."
deltimer(timerid)
/obj/item/clockwork/ratvarian_spear/examine(mob/user)
/obj/item/clockwork/weapon/ratvarian_spear/examine(mob/user)
..()
if(is_servant_of_ratvar(user) || isobserver(user))
to_chat(user, "<span class='inathneq_small'>Attacks on living non-Servants will generate <b>[bonus_burn]</b> units of vitality.</span>")
if(!iscyborg(user))
to_chat(user, "<span class='brass'>Throwing the spear will do massive damage, break the spear, and knock down the target.</span>")
/obj/item/clockwork/ratvarian_spear/attack(mob/living/target, mob/living/carbon/human/user)
/obj/item/clockwork/weapon/ratvarian_spear/attack(mob/living/target, mob/living/carbon/human/user)
. = ..()
if(!QDELETED(target) && target.stat != DEAD && !target.null_rod_check() && !is_servant_of_ratvar(target)) //we do bonus damage on attacks unless they're a servant, have a null rod, or are dead
var/bonus_damage = bonus_burn //normally a total of 20 damage, 30 with ratvar
@@ -63,7 +45,7 @@
bonus_damage *= 3 //total 30 damage on cultists, 50 with ratvar
GLOB.clockwork_vitality += target.adjustFireLoss(bonus_damage) //adds the damage done to existing vitality
/obj/item/clockwork/ratvarian_spear/throw_impact(atom/target)
/obj/item/clockwork/weapon/ratvarian_spear/throw_impact(atom/target)
var/turf/T = get_turf(target)
if(isliving(target))
var/mob/living/L = target
@@ -83,11 +65,12 @@
else
..()
/obj/item/clockwork/ratvarian_spear/proc/break_spear(turf/T)
/obj/item/clockwork/weapon/ratvarian_spear/proc/break_spear(turf/T)
if(src)
if(!T)
T = get_turf(src)
if(T) //make sure we're not in null or something
T.visible_message("<span class='warning'>[src] [pick("cracks in two and fades away", "snaps in two and dematerializes")]!</span>")
new /obj/effect/temp_visual/ratvar/spearbreak(T)
qdel(src)
action.weapon_reset(RATVARIAN_SPEAR_COOLDOWN)
@@ -6,7 +6,8 @@
icon_state = "clockwork_helmet"
w_class = WEIGHT_CLASS_NORMAL
resistance_flags = FIRE_PROOF | ACID_PROOF
armor = list(melee = 80, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100)
flags_inv = HIDEEARS|HIDEHAIR|HIDEFACE
armor = list(melee = 50, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100)
/obj/item/clothing/head/helmet/clockwork/Initialize()
. = ..()
@@ -23,8 +24,13 @@
flags_1 |= STOPSPRESSUREDMAGE_1
max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
else if(GLOB.ratvar_approaches)
armor = list(melee = 70, bullet = 80, laser = -15, energy = 25, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100)
flags_1 |= STOPSPRESSUREDMAGE_1
max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
else
armor = list(melee = 80, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100)
armor = list(melee = 60, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100)
flags_1 &= ~STOPSPRESSUREDMAGE_1
max_heat_protection_temperature = initial(max_heat_protection_temperature)
min_cold_protection_temperature = initial(min_cold_protection_temperature)
@@ -61,7 +67,7 @@
cold_protection = CHEST|GROIN|LEGS
heat_protection = CHEST|GROIN|LEGS
resistance_flags = FIRE_PROOF | ACID_PROOF
armor = list(melee = 80, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100)
armor = list(melee = 60, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100)
allowed = list(/obj/item/clockwork, /obj/item/clothing/glasses/wraith_spectacles, /obj/item/clothing/glasses/judicial_visor, /obj/item/device/mmi/posibrain/soul_vessel)
/obj/item/clothing/suit/armor/clockwork/Initialize()
@@ -79,8 +85,13 @@
flags_1 |= STOPSPRESSUREDMAGE_1
max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
else if(GLOB.ratvar_approaches)
armor = list(melee = 70, bullet = 80, laser = -15, energy = 25, bomb = 70, bio = 0, rad = 0, fire = 100, acid = 100)
flags_1 |= STOPSPRESSUREDMAGE_1
max_heat_protection_temperature = FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
else
armor = list(melee = 80, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100)
armor = list(melee = 60, bullet = 70, laser = -25, energy = 0, bomb = 60, bio = 0, rad = 0, fire = 100, acid = 100)
flags_1 &= ~STOPSPRESSUREDMAGE_1
max_heat_protection_temperature = initial(max_heat_protection_temperature)
min_cold_protection_temperature = initial(min_cold_protection_temperature)
@@ -1,9 +1,7 @@
/obj/item/clockwork/slab //Clockwork slab: The most important tool in Ratvar's arsenal. Allows scripture recital, tutorials, and generates components.
name = "clockwork slab"
desc = "A strange metal tablet. A clock in the center turns around and around."
clockwork_desc = "A link between you and the Celestial Derelict. It produces components, contains information, and is your most vital tool as a Servant.\n\
Use the <span class='brass'>Hierophant Network</span> action button to discreetly talk with other Servants.\n\
Clockwork slabs will only make components if held or if inside an item held by a human, and when making a component will prevent all other slabs held from making components.\n\
clockwork_desc = "A link between you and the Celestial Derelict. It contains information, recites scripture, and is your most vital tool as a Servant.\n\
Hitting a slab, a Servant with a slab, or a cache will <b>transfer</b> this slab's components into the target, the target's slab, or the global cache, respectively."
icon_state = "dread_ipad"
lefthand_file = 'icons/mob/inhands/antag/clockwork_lefthand.dmi'
@@ -11,30 +9,21 @@
var/inhand_overlay //If applicable, this overlay will be applied to the slab's inhand
slot_flags = SLOT_BELT
w_class = WEIGHT_CLASS_SMALL
var/list/stored_components = list(BELLIGERENT_EYE = 0, VANGUARD_COGWHEEL = 0, GEIS_CAPACITOR = 0, REPLICANT_ALLOY = 0, HIEROPHANT_ANSIBLE = 0)
var/busy //If the slab is currently being used by something
var/production_time = 0
var/target_component_id //the target component ID to create, if any
var/no_cost = FALSE //If the slab is admin-only and needs no components and has no scripture locks
var/speed_multiplier = 1 //multiples how fast this slab recites scripture
var/produces_components = TRUE //if it produces components at all
var/selected_scripture = SCRIPTURE_DRIVER
var/recollecting = FALSE //if we're looking at fancy recollection
var/obj/effect/proc_holder/slab/slab_ability //the slab's current bound ability, for certain scripture
var/list/quickbound = list(/datum/clockwork_scripture/ranged_ability/geis, /datum/clockwork_scripture/create_object/sigil_of_submission, \
/datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/tinkerers_cache) //quickbound scripture, accessed by index
var/list/quickbound = list(/datum/clockwork_scripture/abscond, \
/datum/clockwork_scripture/ranged_ability/kindle, /datum/clockwork_scripture/ranged_ability/hateful_manacles) //quickbound scripture, accessed by index
var/maximum_quickbound = 5 //how many quickbound scriptures we can have
var/recollection_category = "Default"
actions_types = list(/datum/action/item_action/clock/hierophant)
/obj/item/clockwork/slab/starter
stored_components = list(BELLIGERENT_EYE = 1, VANGUARD_COGWHEEL = 1, GEIS_CAPACITOR = 1, REPLICANT_ALLOY = 1, HIEROPHANT_ANSIBLE = 1)
/obj/item/clockwork/slab/internal //an internal motor for mobs running scripture
name = "scripture motor"
quickbound = list()
no_cost = TRUE
produces_components = FALSE
/obj/item/clockwork/slab/debug
speed_multiplier = 0
@@ -49,33 +38,33 @@
clockwork_desc = "A divine link to the Celestial Derelict, allowing for limited recital of scripture.\n\
Hitting a slab, a Servant with a slab, or a cache will <b>transfer</b> this slab's components into the target, the target's slab, or the global cache, respectively."
quickbound = list(/datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/ranged_ability/linked_vanguard, \
/datum/clockwork_scripture/create_object/tinkerers_cache)
/datum/clockwork_scripture/create_object/stargazer)
maximum_quickbound = 6 //we usually have one or two unique scriptures, so if ratvar is up let us bind one more
actions_types = list()
/obj/item/clockwork/slab/cyborg/engineer //two scriptures, plus a fabricator
quickbound = list(/datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transmission)
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transmission)
/obj/item/clockwork/slab/cyborg/medical //five scriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/ranged_ability/sentinels_compromise, \
/datum/clockwork_scripture/create_object/vitality_matrix, /datum/clockwork_scripture/channeled/mending_mantra, /datum/clockwork_scripture/fellowship_armory)
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/ranged_ability/sentinels_compromise, \
/datum/clockwork_scripture/create_object/vitality_matrix, /datum/clockwork_scripture/channeled/mending_mantra)
/obj/item/clockwork/slab/cyborg/security //twoscriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/channeled/belligerent, /datum/clockwork_scripture/ranged_ability/judicial_marker)
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/hateful_manacles, /datum/clockwork_scripture/ranged_ability/judicial_marker)
/obj/item/clockwork/slab/cyborg/peacekeeper //two scriptures, plus a spear
quickbound = list(/datum/clockwork_scripture/channeled/belligerent, /datum/clockwork_scripture/ranged_ability/judicial_marker)
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/hateful_manacles, /datum/clockwork_scripture/ranged_ability/judicial_marker)
/obj/item/clockwork/slab/cyborg/janitor //five scriptures, plus a fabricator
quickbound = list(/datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transgression, \
/datum/clockwork_scripture/create_object/ocular_warden, /datum/clockwork_scripture/create_object/mania_motor, /datum/clockwork_scripture/create_object/tinkerers_daemon)
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/sigil_of_transgression, \
/datum/clockwork_scripture/create_object/ocular_warden, /datum/clockwork_scripture/create_object/mania_motor, /datum/clockwork_scripture/create_object/stargazer)
/obj/item/clockwork/slab/cyborg/service //five scriptures, plus xray vision
quickbound = list(/datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/tinkerers_cache, \
/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/fellowship_armory, /datum/clockwork_scripture/create_object/clockwork_obelisk)
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/stargazer, \
/datum/clockwork_scripture/spatial_gateway, /datum/clockwork_scripture/create_object/clockwork_obelisk)
/obj/item/clockwork/slab/cyborg/miner //two scriptures, plus a spear and xray vision
quickbound = list(/datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/spatial_gateway)
quickbound = list(/datum/clockwork_scripture/abscond, /datum/clockwork_scripture/ranged_ability/linked_vanguard, /datum/clockwork_scripture/spatial_gateway)
/obj/item/clockwork/slab/cyborg/access_display(mob/living/user)
if(!GLOB.ratvar_awakens)
@@ -92,7 +81,9 @@
. = ..()
update_slab_info(src)
START_PROCESSING(SSobj, src)
production_time = world.time + SLAB_PRODUCTION_TIME
if(GLOB.ratvar_approaches)
name = "supercharged [name]"
speed_multiplier = max(0.1, speed_multiplier - 0.25)
/obj/item/clockwork/slab/Destroy()
STOP_PROCESSING(SSobj, src)
@@ -115,35 +106,12 @@
if(user && !(src in user.held_items) && slab_ability && slab_ability.ranged_ability_user) //if we happen to check and we AREN'T in user's hands, remove whatever ability we have
slab_ability.remove_ranged_ability()
//Component Generation
//Power generation
/obj/item/clockwork/slab/process()
if(!produces_components)
STOP_PROCESSING(SSobj, src)
return
if(production_time > world.time)
return
var/servants = 0
var/production_slowdown = 0
for(var/mob/living/M in GLOB.living_mob_list)
if(is_servant_of_ratvar(M) && (ishuman(M) || issilicon(M)))
servants++
if(servants > SCRIPT_SERVANT_REQ)
servants -= SCRIPT_SERVANT_REQ
production_slowdown = min(SLAB_SERVANT_SLOWDOWN * servants, SLAB_SLOWDOWN_MAXIMUM) //SLAB_SERVANT_SLOWDOWN additional seconds for each servant above 5, up to SLAB_SLOWDOWN_MAXIMUM
production_time = world.time + SLAB_PRODUCTION_TIME + production_slowdown
var/mob/living/L
L = get_atom_on_turf(src, /mob/living)
if(istype(L) && (no_cost || can_recite_scripture(L)))
var/component_to_generate = target_component_id
if(!component_to_generate)
component_to_generate = get_weighted_component_id(src) //more likely to generate components that we have less of
stored_components[component_to_generate]++
update_slab_info(src)
for(var/obj/item/clockwork/slab/S in L.GetAllContents()) //prevent slab abuse today
if(S == src)
continue
S.production_time = production_time + 50 //set it to our next production plus five seconds, so that if you hold the same slabs, the same one will always generate
to_chat(L, "<span class='warning'>Your slab cl[pick("ank", "ink", "unk", "ang")]s as it produces a </span><span class='[get_component_span(component_to_generate)]'>component</span><span class='warning'>.</span>")
if(GLOB.ratvar_approaches && speed_multiplier == initial(speed_multiplier))
name = "supercharged [name]"
speed_multiplier = max(0.1, speed_multiplier - 0.25)
adjust_clockwork_power(0.1) //Slabs serve as very weak power generators on their own (no, not enough to justify spamming them)
/obj/item/clockwork/slab/examine(mob/user)
..()
@@ -154,97 +122,14 @@
continue
var/datum/clockwork_scripture/quickbind_slot = quickbound[i]
to_chat(user, "<b>Quickbind</b> button: <span class='[get_component_span(initial(quickbind_slot.primary_component))]'>[initial(quickbind_slot.name)]</span>.")
if(GLOB.clockwork_caches) //show components on examine
to_chat(user, "<b>Stored components (with global cache):</b>")
for(var/i in stored_components)
to_chat(user, "[get_component_icon(i)] <span class='[get_component_span(i)]_small'><i>[get_component_name(i)][i != REPLICANT_ALLOY ? "s":""]:</i> <b>[stored_components[i]]</b> \
(<b>[stored_components[i] + GLOB.clockwork_component_cache[i]]</b>)</span>")
else
to_chat(user, "<b>Stored components:</b>")
for(var/i in stored_components)
to_chat(user, "[get_component_icon(i)] <span class='[get_component_span(i)]_small'><i>[get_component_name(i)][i != REPLICANT_ALLOY ? "s":""]:</i> <b>[stored_components[i]]</b></span>")
//Component Transferal
/obj/item/clockwork/slab/attack(mob/living/target, mob/living/carbon/human/user)
if(is_servant_of_ratvar(user) && is_servant_of_ratvar(target))
var/obj/item/clockwork/slab/targetslab
var/highest_component_amount = 0
for(var/obj/item/clockwork/slab/S in target.GetAllContents())
if(!istype(S, /obj/item/clockwork/slab/internal))
var/totalcomponents = 0
for(var/i in S.stored_components)
totalcomponents += S.stored_components[i]
if(!targetslab || totalcomponents > highest_component_amount)
highest_component_amount = totalcomponents
targetslab = S
if(targetslab)
if(targetslab == src)
to_chat(user, "<span class='heavy_brass'>\"You can't transfer components into your own slab, idiot.\"</span>")
else
for(var/i in stored_components)
targetslab.stored_components[i] += stored_components[i]
stored_components[i] = 0
update_slab_info(targetslab)
update_slab_info(src)
user.visible_message("<span class='notice'>[user] empties [src] into [target]'s [targetslab.name].</span>", \
"<span class='notice'>You transfer your slab's components into [target]'s [targetslab.name].</span>")
else
to_chat(user, "<span class='warning'>[target] has no slabs to transfer components to.</span>")
else
return ..()
/obj/item/clockwork/slab/attackby(obj/item/I, mob/user, params)
var/ratvarian = is_servant_of_ratvar(user)
if(istype(I, /obj/item/clockwork/component) && ratvarian)
var/obj/item/clockwork/component/C = I
if(!C.component_id)
return 0
user.visible_message("<span class='notice'>[user] inserts [C] into [src].</span>", "<span class='notice'>You insert [C] into [src]\
[GLOB.clockwork_caches ? ", where it is added to the global cache":""].</span>")
if(GLOB.clockwork_caches)
GLOB.clockwork_component_cache[C.component_id]++
update_slab_info()
else
stored_components[C.component_id]++
update_slab_info(src)
user.drop_item()
qdel(C)
return 1
else if(istype(I, /obj/item/clockwork/slab) && ratvarian)
var/obj/item/clockwork/slab/S = I
var/needs_update = FALSE
for(var/i in stored_components)
stored_components[i] += S.stored_components[i]
S.stored_components[i] = 0
if(S.stored_components[i])
needs_update = TRUE
if(needs_update)
update_slab_info(src)
update_slab_info(S)
user.visible_message("<span class='notice'>[user] empties [src] into [S].</span>", "<span class='notice'>You transfer your slab's components into [S].</span>")
else
return ..()
to_chat(user, "<b>Available Power:</b> <span class='bold brass'>[DisplayPower(get_clockwork_power())]</span>")
//Slab actions; Hierophant, Quickbind
/obj/item/clockwork/slab/ui_action_click(mob/user, action)
if(istype(action, /datum/action/item_action/clock/hierophant))
show_hierophant(user)
else if(istype(action, /datum/action/item_action/clock/quickbind))
if(istype(action, /datum/action/item_action/clock/quickbind))
var/datum/action/item_action/clock/quickbind/Q = action
recite_scripture(quickbound[Q.scripture_index], user, FALSE)
/obj/item/clockwork/slab/proc/show_hierophant(mob/living/user)
if(!user.can_speak_vocal())
to_chat(user, "<span class='warning'>You cannot speak into the slab!</span>")
return FALSE
var/message = stripped_input(user, "Enter a message to send to your fellow Servants.", "Hierophant")
if(!message || !user || !user.canUseTopic(src) || !user.can_speak_vocal())
return FALSE
clockwork_say(user, text2ratvar("Servants, hear my words: [html_decode(message)]"), TRUE)
log_talk(user,"CLOCK:[key_name(user)] : [message]",LOGSAY)
titled_hierophant_message(user, message)
return TRUE
//Scripture Recital
/obj/item/clockwork/slab/attack_self(mob/living/user)
if(iscultist(user))
@@ -310,34 +195,10 @@
textlist += "HONOR RATVAR "
textlist += "</b></font>"
else
var/servants = 0
var/production_time = SLAB_PRODUCTION_TIME
for(var/mob/living/M in GLOB.living_mob_list)
if(is_servant_of_ratvar(M) && (ishuman(M) || issilicon(M)))
servants++
if(servants > SCRIPT_SERVANT_REQ)
servants -= SCRIPT_SERVANT_REQ
production_time += min(SLAB_SERVANT_SLOWDOWN * servants, SLAB_SLOWDOWN_MAXIMUM)
var/production_text_addon = ""
if(production_time != SLAB_PRODUCTION_TIME+SLAB_SLOWDOWN_MAXIMUM)
production_text_addon = ", which increases for each human or silicon Servant above <b>[SCRIPT_SERVANT_REQ]</b>"
production_time = production_time/600
var/list/production_text
if(round(production_time))
production_text = list("<b>[round(production_time)] minute\s")
if(production_time != round(production_time))
production_time -= round(production_time)
production_time *= 60
if(!LAZYLEN(production_text))
production_text = list("<b>[round(production_time, 1)] second\s")
else
production_text += " and [round(production_time, 1)] second\s"
production_text += "</b>"
production_text += production_text_addon
production_text = production_text.Join()
textlist = list("<font color=#BE8700 size=3><b><center>[text2ratvar("Purge all untruths and honor Engine.")]</center></b></font><br>\
\
<b><i>NOTICE:</b> This information is out of date. Read the Ark & You primer in your backpack or read the wiki page for current info.</i><br>\
<hr><br>\
These pages serve as the archives of Ratvar, the Clockwork Justiciar. This section of your slab has information on being as a Servant, advice for what to do next, and \
pointers for serving the master well. You should recommended that you check this area for help if you get stuck or need guidance on what to do next.<br><br>\
\
@@ -402,11 +263,6 @@
dat += "<font color=#BE8700><b>CV:</b></font> Construction Value. All clockwork structures, floors, and walls increase this number.<br>"
dat += "<font color=#BE8700><b>Vitality:</b></font> Used for healing effects, produced by Ratvarian spear attacks and Vitality Matrices.<br>"
dat += "<font color=#BE8700><b>Geis:</b></font> An important scripture used to make normal crew and robots into Servants of Ratvar.<br>"
dat += "<font color=#6E001A><b>[get_component_icon(BELLIGERENT_EYE)]BE:</b></font> Belligerent Eye, a component type used in offensive scriptures.<br>"
dat += "<font color=#1E8CE1><b>[get_component_icon(VANGUARD_COGWHEEL)]VC:</b></font> Vanguard Cogwheel, a component type used in defensive scriptures.<br>"
dat += "<font color=#AF0AAF><b>[get_component_icon(GEIS_CAPACITOR)]GC:</b></font> Geis Capacitor, a component type used in mind-related scriptures.<br>"
dat += "<font color=#5A6068><b>[get_component_icon(REPLICANT_ALLOY)]RA:</b></font> Replicant Alloy, a component type used in construction scriptures.<br>"
dat += "<font color=#DAAA18><b>[get_component_icon(HIEROPHANT_ANSIBLE)]HA:</b></font> Hierophant Ansible, a component type used in energy-related scriptures.<br>"
dat += "<font color=#BE8700><b>Ark:</b></font> The cult's win condition, a huge structure that needs to be defended.<br><br>"
dat += "<font color=#BE8700 size=3>Items</font><br>"
dat += "<font color=#BE8700><b>Slab:</b></font> A clockwork slab, a Servant's most important tool. You're holding one! Keep it safe and hidden.<br>"
@@ -431,42 +287,12 @@
dat += "<font color=#BE8700><b>Transmission:</b></font> Drains and stores power for clockwork structures. Feeding it brass sheets will create additional power.<br><br>"
dat += "<font color=#BE8700 size=3>-=-=-=-=-=-</font>"
if("Components")
var/servants = 0 //Calculate the current production time for slab components
var/production_time = SLAB_PRODUCTION_TIME
for(var/mob/living/M in GLOB.living_mob_list)
if(is_servant_of_ratvar(M) && (ishuman(M) || issilicon(M)))
servants++
if(servants > SCRIPT_SERVANT_REQ)
servants -= SCRIPT_SERVANT_REQ
production_time += min(SLAB_SERVANT_SLOWDOWN * servants, SLAB_SLOWDOWN_MAXIMUM)
var/production_text_addon = ""
if(production_time != SLAB_PRODUCTION_TIME+SLAB_SLOWDOWN_MAXIMUM)
production_text_addon = ", which increases for each human or silicon Servant above <b>[SCRIPT_SERVANT_REQ]</b>"
production_time = production_time/600
var/list/production_text
if(round(production_time))
production_text = list("<b>[round(production_time)] minute\s")
if(production_time != round(production_time))
production_time -= round(production_time)
production_time *= 60
if(!LAZYLEN(production_text))
production_text = list("<b>[round(production_time, 1)] second\s")
else
production_text += " and [round(production_time, 1)] second\s"
production_text += "</b>"
production_text += production_text_addon
production_text = production_text.Join()
dat += "<font color=#BE8700 size=3>Components & Their Uses</font><br><br>"
dat += "<b>Components</b> are your primary resource as a Servant. There are five types of component, with each one being used in different roles:<br><br>"
dat += "<font color=#6E001A>[get_component_icon(BELLIGERENT_EYE)]BE</font> Belligerent Eyes are aggressive and judgemental, and are used in offensive scripture;<br>"
dat += "<font color=#1E8CE1>[get_component_icon(VANGUARD_COGWHEEL)]VC</font> Vanguard Cogwheels are defensive and repairing, and are used in defensive scripture;<br>"
dat += "<font color=#AF0AAF>[get_component_icon(GEIS_CAPACITOR)]GC</font> Geis Capacitors are for conversion and control, and are used in mind-related scripture;<br>"
dat += "<font color=#5A6068>[get_component_icon(REPLICANT_ALLOY)]RA</font> Replicant Alloy is a strong, malleable metal and is used for construction and creation;<br>"
dat += "<font color=#DAAA18>[get_component_icon(HIEROPHANT_ANSIBLE)]HA</font> Hierophant Ansibles are for transmission and power, and are used in power and teleportation scripture<br><br>"
dat += "Although this is a good rule of thumb, their effects become much more nuanced when used together. For instance, a turret might have both belligerent eyes and \
vanguard cogwheels as construction requirements, because it defends its allies by harming its enemies.<br><br>"
dat += "Components' primary use is fueling <b>scripture</b> (covered in its own section), and they can be created through various ways. This clockwork slab, for instance, \
will make a random component of every type - or a specific one, if you choose a target component from the interface - every <b>[production_text]</b>. This number will increase \
will make a random component of every type - or a specific one, if you choose a target component from the interface - every <b>remove me already</b>. This number will increase \
as the amount of Servants in the covenant increase; additionally, slabs can only produce components when held by a Servant, and holding more than one slab will cause both \
of them to halt progress until one of them is removed from their person.<br><br>"
dat += "Your slab has an internal storage of components, but it isn't meant to be the main one. Instead, there's a <b>global storage</b> of components that can be \
@@ -487,7 +313,7 @@
dat += "It should also be noted that some scripture cannot be recited alone. Especially with more powerful scripture, you may need multiple Servants to recite a piece of \
scripture; both of you will need to stand still until the recital completes. <i>Only human and silicon Servants are valid for scripture recital!</i> Constructs cannot help \
in reciting scripture.<br><br>"
dat += "Finally, scripture is separated into four \"tiers\" based on power: Drivers, Scripts, Applications, and Judgement.[prob(1) ? " (The Revenant tier was removed a long time ago. \
dat += "Finally, scripture is separated into three \"tiers\" based on power: Drivers, Scripts, and Applications.[prob(1) ? " (The Revenant tier was removed a long time ago. \
Get with the times.)" : ""] You can view the requirements to unlock each tier in its scripture list. Once a tier is unlocked, it's unlocked permanently; the cult only needs to fill the \
requirement for unlocking a tier once!<br><br>"
dat += "<font color=#BE8700 size=3>-=-=-=-=-=-</font>"
@@ -551,7 +377,7 @@
One of the cogscarabs must've misplaced this section, because the game wasn't able to find any info regarding it. Report this to the coders!"
return "<br><br>[dat.Join()]<br><br>"
//Gets the quickbound scripture as a text block."
//Gets the quickbound scripture as a text block.
/obj/item/clockwork/slab/proc/get_recollection_quickbinds()
var/list/dat = list()
dat += "<font color=#BE8700 size=3>Quickbound Scripture</font><br>\
@@ -568,24 +394,7 @@
/obj/item/clockwork/slab/ui_data(mob/user) //we display a lot of data via TGUI
var/list/data = list()
data["components"] = stored_components.Copy()
var/list/temp_data = list("<font color=#B18B25>")
for(var/i in data["components"]) //display the slab's components
temp_data += "<font color=[get_component_color_bright(i)]>[get_component_icon(i)] <b>[data["components"][i]]</b></font>"
if(i != HIEROPHANT_ANSIBLE)
temp_data += " "
else
temp_data += " ("
if(GLOB.clockwork_caches) //if we have caches, display what's in the global cache
for(var/i in GLOB.clockwork_component_cache)
temp_data += "<font color=[get_component_color_bright(i)]>[get_component_icon(i)] <b>[data["components"][i] + GLOB.clockwork_component_cache[i]]</b></font>"
if(i != HIEROPHANT_ANSIBLE)
temp_data += " "
else
temp_data += "<b>NONE</b>"
temp_data += ")</font>"
temp_data = temp_data.Join()
data["components"] = temp_data
data["power"] = "<b><font color=#B18B25>[DisplayPower(get_clockwork_power())]</b> power is available for scripture and other consumers.</font>"
switch(selected_scripture) //display info based on selected scripture tier
if(SCRIPTURE_DRIVER)
@@ -594,24 +403,15 @@
if(SSticker.scripture_states[SCRIPTURE_SCRIPT])
data["tier_info"] = "<font color=#B18B25><b>These scriptures are permenantly unlocked.</b></font>"
else
data["tier_info"] = "<font color=#B18B25><i>These scriptures require at least <b>[SCRIPT_SERVANT_REQ]</b> Servants and <b>[SCRIPT_CACHE_REQ]</b> Tinkerer's Cache.</i></font>"
data["tier_info"] = "<font color=#B18B25><i>These scriptures will automatically unlock when the Ark is halfway ready or if [DisplayPower(SCRIPT_UNLOCK_THRESHOLD)] of power is reached.</i></font>"
if(SCRIPTURE_APPLICATION)
if(SSticker.scripture_states[SCRIPTURE_APPLICATION])
data["tier_info"] = "<font color=#B18B25><b>These scriptures are permenantly unlocked.</b></font>"
else
data["tier_info"] = "<font color=#B18B25><i>These scriptures require at least <b>[APPLICATION_SERVANT_REQ]</b> Servants, <b>[APPLICATION_CACHE_REQ]</b> Tinkerer's Caches, and <b>[APPLICATION_CV_REQ]CV</b>.</i></font>"
if(SCRIPTURE_JUDGEMENT)
if(SSticker.scripture_states[SCRIPTURE_JUDGEMENT])
data["tier_info"] = "<font color=#B18B25><b>This scripture is permenantly unlocked.</b></font>"
else
data["tier_info"] = "<font color=#B18B25><i>This scripture requires at least <b>[JUDGEMENT_SERVANT_REQ]</b> Servants, <b>[JUDGEMENT_CACHE_REQ]</b> Tinkerer's Caches, and <b>[JUDGEMENT_CV_REQ]CV</b>.<br>In addition, there may not be any active non-Servant AIs.</i></font>"
data["tier_info"] = "<font color=#B18B25><i>Unlock these optional scriptures by converting another servant or if [DisplayPower(APPLICATION_UNLOCK_THRESHOLD)] of power is reached..</i></font>"
data["selected"] = selected_scripture
data["target_comp"] = "<font color=#B18B25>NONE</font>"
if(target_component_id) //if we have a component to make, display that, too
data["target_comp"] = "<font color=[get_component_color_bright(target_component_id)]>[get_component_icon(target_component_id)]</font>"
generate_all_scripture()
data["scripture"] = list()
@@ -622,7 +422,7 @@
var/list/temp_info = list("name" = "<font color=[scripture_color]><b>[S.name]</b></font>",
"descname" = "<font color=[scripture_color]>([S.descname])</font>",
"tip" = "[S.desc]\n[S.usage_tip]",
"required" = list(BELLIGERENT_EYE = 0, VANGUARD_COGWHEEL = 0, GEIS_CAPACITOR = 0, REPLICANT_ALLOY = 0, HIEROPHANT_ANSIBLE = 0),
"required" = "([DisplayPower(S.power_cost)][S.special_power_text ? "+ [replacetext(S.special_power_text, "POWERCOST", "[DisplayPower(S.special_power_cost)]")]" : ""])",
"type" = "[S.type]",
"quickbind" = S.quickbind)
var/found = quickbound.Find(S.type)
@@ -630,20 +430,6 @@
temp_info["bound"] = "<b>[found]</b>"
if(S.invokers_required > 1)
temp_info["invokers"] = "<font color=#B18B25>Invokers: <b>[S.invokers_required]</b></font>"
var/costs_components = FALSE
for(var/i in S.consumed_components)
if(S.consumed_components[i])
temp_info["required"][i] += S.consumed_components[i]
costs_components = TRUE
if(costs_components) //if we have a component cost, we'll need a : next to the recital button
var/list/really_temp_data = list(": ")
for(var/i in temp_info["required"])
if(temp_info["required"][i])
really_temp_data += "<font color=[get_component_color_bright(i)]>[get_component_icon(i)] <b>[temp_info["required"][i]]</b></font> "
really_temp_data = really_temp_data.Join()
temp_info["required"] = really_temp_data
else //and if we don't, we won't.
temp_info["required"] = ""
data["scripture"] += list(temp_info)
data["recollection"] = recollecting
if(recollecting)
@@ -669,16 +455,6 @@
INVOKE_ASYNC(src, .proc/recite_scripture, text2path(params["category"]), usr, FALSE)
if("select")
selected_scripture = params["category"]
if("component")
var/list/components = list("Random Components")
for(var/i in GLOB.clockwork_component_cache)
var/cache_components = 0
if(GLOB.clockwork_caches)
cache_components = GLOB.clockwork_component_cache[i]
components["[get_component_name(i)] [(cache_components + stored_components[i])]"] = i
var/input_component = input("Choose a component type.", "Target Component") as null|anything in components
if(input_component && !..())
target_component_id = components[input_component]
if("bind")
var/datum/clockwork_scripture/path = text2path(params["category"]) //we need a path and not a string
var/found_index = quickbound.Find(path)
@@ -723,14 +499,7 @@
Q.scripture_index = i
var/datum/clockwork_scripture/quickbind_slot = GLOB.all_scripture[quickbound[i]]
Q.name = "[quickbind_slot.name] ([Q.scripture_index])"
var/list/temp_desc = list()
for(var/c in quickbind_slot.consumed_components) //show how much the bound scripture costs
if(quickbind_slot.consumed_components[c])
temp_desc += "<font color=[get_component_color_bright(c)]>[get_component_icon(c)] <b>[quickbind_slot.consumed_components[c]]</b></font> "
if(LAZYLEN(temp_desc))
temp_desc += "<br>"
temp_desc += "[quickbind_slot.quickbind_desc]"
Q.desc = temp_desc.Join()
Q.desc = quickbind_slot.quickbind_desc
Q.button_icon_state = quickbind_slot.name
Q.UpdateButtonIcon()
if(isliving(loc))
@@ -0,0 +1,15 @@
//This is the base type for clockwork melee weapons.
/obj/item/clockwork/weapon
name = "clockwork weapon"
desc = "Weaponized brass. Whould've thunk it?"
clockwork_desc = "This shouldn't exist. Report it to a coder."
icon = 'icons/obj/clockwork_objects.dmi'
lefthand_file = 'icons/mob/inhands/antag/clockwork_lefthand.dmi'
righthand_file = 'icons/mob/inhands/antag/clockwork_righthand.dmi'
var/datum/action/innate/call_weapon/action //Some melee weapons use an action that lets you return and dismiss them
/obj/item/clockwork/weapon/Initialize(mapload, new_action)
. = ..()
if(new_action)
action = new_action
action.weapon = src
@@ -0,0 +1,69 @@
//Construct shells that can be activated by ghosts.
/obj/item/clockwork/construct_chassis
name = "construct chassis"
desc = "A shell formed out of brass, presumably for housing machinery."
clockwork_desc = "A construct chassis. It can be activated at any time by a willing ghost."
var/construct_name = "basic construct"
var/construct_desc = "<span class='alloy'>There is no construct for this chassis. Report this to a coder.</span>"
icon_state = "anime_fragment"
resistance_flags = FIRE_PROOF | ACID_PROOF
w_class = WEIGHT_CLASS_HUGE
var/creation_message = "<span class='brass'>The chassis shudders and hums to life!</span>"
var/construct_type //The construct this shell will create
/obj/item/clockwork/construct_chassis/Initialize()
. = ..()
var/area/A = get_area(src)
if(A && construct_type)
notify_ghosts("A [construct_name] chassis has been created in [A.name]!", 'sound/magic/clockwork/fellowship_armory.ogg', source = src, action = NOTIFY_ORBIT, flashwindow = FALSE)
GLOB.poi_list += src
/obj/item/clockwork/construct_chassis/Destroy()
GLOB.poi_list -= src
. = ..()
/obj/item/clockwork/construct_chassis/examine(mob/user)
clockwork_desc = "[clockwork_desc]<br>[construct_desc]"
..()
clockwork_desc = initial(clockwork_desc)
/obj/item/clockwork/construct_chassis/attack_hand(mob/living/user)
if(w_class >= WEIGHT_CLASS_HUGE)
to_chat(user, "<span class='warning'>[src] is too cumbersome to carry! Drag it around instead!</span>")
return
. = ..()
/obj/item/clockwork/construct_chassis/attack_ghost(mob/user)
if(alert(user, "Become a [construct_name]? You can no longer be cloned!", construct_name, "Yes", "Cancel") == "Cancel")
return
if(QDELETED(src))
to_chat(user, "<span class='danger'>You were too late! Better luck next time.</span>")
return
visible_message(creation_message)
var/mob/living/construct = new construct_type(get_turf(src))
construct.key = user.key
qdel(user)
qdel(src)
//Marauder armor, used to create clockwork marauders - sturdy frontline combatants that can deflect projectiles.
/obj/item/clockwork/construct_chassis/clockwork_marauder
name = "marauder armor"
desc = "A pile of sleek and well-polished brass armor. A small red gemstone sits in its faceplate."
icon_state = "marauder_armor"
construct_name = "clockwork marauder"
construct_desc = "<span class='neovgre_small'>It will become a <b>clockwork marauder,</b> a well-rounded frontline combatant.</span>"
creation_message = "<span class='neovgre_small bold'>Crimson fire begins to rage in the armor as it rises into the air with its arnaments!</span>"
construct_type = /mob/living/simple_animal/hostile/clockwork/marauder
//Cogscarab shell, used to create cogcarabs - fragile but zippy little drones that build and maintain the base.
/obj/item/clockwork/construct_chassis/cogscarab
name = "cogscarab shell"
desc = "A small, complex shell that resembles a repair drone, but much larger and made out of brass."
icon_state = "cogscarab_shell"
construct_name = "cogscarab"
construct_desc = "<span class='alloy'>It will become a <b>cogscarab,</b> a small and fragile drone that builds, repairs, and maintains.</span>"
creation_message = "<span class='alloy bold'>The cogscarab clicks and whirrs as it hops up and springs to life!</span>"
construct_type = /mob/living/simple_animal/drone/cogscarab
w_class = WEIGHT_CLASS_SMALL
@@ -0,0 +1,38 @@
#define COG_MAX_SIPHON_THRESHOLD 0.25 //The cog will not siphon power if the APC's cell is at this % of power
//Can be used on an open APC to replace its guts with clockwork variants, and begin passively siphoning power from it
/obj/item/clockwork/integration_cog
name = "integration cog"
desc = "A small cogwheel that fits in the palm of your hand."
clockwork_desc = "A small cogwheel that can be inserted into an open APC to siphon power from it passively.<br>\
<span class='brass'>It can be used on a locked APC to open its cover!</span><br>\
<span class='brass'>Siphons <b>5 W</b> of power per second while in an APC.</span>"
icon_state = "wall_gear"
w_class = WEIGHT_CLASS_TINY
flags_1 = NOBLUDGEON_1
var/obj/machinery/power/apc/apc
/obj/item/clockwork/integration_cog/Initialize()
. = ..()
transform *= 0.5 //little cog!
/obj/item/clockwork/integration_cog/Destroy()
STOP_PROCESSING(SSfastprocess, src)
. = ..()
/obj/item/clockwork/integration_cog/process()
if(!apc)
if(istype(loc, /obj/machinery/power/apc))
apc = loc
else
STOP_PROCESSING(SSfastprocess, src)
else
var/obj/item/stock_parts/cell/cell = apc.cell
if(cell && (cell.charge / cell.maxcharge > COG_MAX_SIPHON_THRESHOLD))
cell.use(1)
adjust_clockwork_power(1) //Power is shared, so only do it once; this runs very quickly so it's about 1W/second
if(prob(1))
playsound(apc, 'sound/machines/clockcult/steam_whoosh.ogg', 10, TRUE)
new/obj/effect/temp_visual/steam(get_turf(apc), pick(GLOB.cardinals))
#undef COG_MAX_SIPHON_THRESHOLD
@@ -170,7 +170,7 @@
if(!QDELETED(B))
B.duration = world.time + 30
C.Knockdown(5) //knocks down for half a second if affected
sleep(16)
sleep(!GLOB.ratvar_approaches ? 16 : 10)
name = "judicial blast"
layer = ABOVE_ALL_MOB_LAYER
flick("judicial_explosion", src)
@@ -9,17 +9,9 @@
w_class = WEIGHT_CLASS_NORMAL
force = 5
flags_1 = NOBLUDGEON_1
var/stored_power = 0 //Requires power to function
var/max_power = CLOCKCULT_POWER_UNIT * 10
var/speed_multiplier = 1 //The speed ratio the fabricator operates at
var/uses_power = TRUE
var/repairing = null //what we're currently repairing, if anything
var/obj/effect/clockwork/sigil/transmission/recharging = null //the sigil we're charging from, if any
var/speed_multiplier = 1 //how fast this fabricator works
var/charge_rate = MIN_CLOCKCULT_POWER //how much power we gain every two seconds
var/charge_delay = 2 //how many proccess ticks remain before we can start to charge
/obj/item/clockwork/replica_fabricator/preloaded
stored_power = POWER_WALL_MINUS_FLOOR+POWER_WALL_TOTAL
/obj/item/clockwork/replica_fabricator/scarab
name = "scarab fabricator"
@@ -27,7 +19,6 @@
item_state = "nothing"
w_class = WEIGHT_CLASS_TINY
speed_multiplier = 0.5
charge_rate = MIN_CLOCKCULT_POWER * 2
var/debug = FALSE
/obj/item/clockwork/replica_fabricator/scarab/fabricate(atom/target, mob/living/user)
@@ -42,75 +33,7 @@
/obj/item/clockwork/replica_fabricator/cyborg
name = "cyborg fabricator"
clockwork_desc = "A cyborg's internal fabricator. It is capable of using the cyborg's power in addition to stored power."
/obj/item/clockwork/replica_fabricator/cyborg/get_power() //returns power and cyborg's power
var/mob/living/silicon/robot/R = get_atom_on_turf(src, /mob/living)
var/borg_power = 0
var/current_charge = 0
if(istype(R) && R.cell)
current_charge = R.cell.charge
while(current_charge > MIN_CLOCKCULT_POWER)
current_charge -= MIN_CLOCKCULT_POWER
borg_power += MIN_CLOCKCULT_POWER
return ..() + borg_power
/obj/item/clockwork/replica_fabricator/cyborg/get_max_power()
var/mob/living/silicon/robot/R = get_atom_on_turf(src, /mob/living)
var/cell_maxcharge = 0
if(istype(R) && R.cell)
cell_maxcharge = R.cell.maxcharge
return ..() + cell_maxcharge
/obj/item/clockwork/replica_fabricator/cyborg/can_use_power(amount)
if(amount != RATVAR_POWER_CHECK)
var/mob/living/silicon/robot/R = get_atom_on_turf(src, /mob/living)
var/current_charge = 0
if(istype(R) && R.cell)
current_charge = R.cell.charge
while(amount > 0 && stored_power - amount < 0) //amount is greater than 0 and stored power minus the amount is still less than 0
current_charge -= MIN_CLOCKCULT_POWER
amount -= MIN_CLOCKCULT_POWER
if(current_charge < 0)
return FALSE
. = ..()
/obj/item/clockwork/replica_fabricator/cyborg/modify_stored_power(amount)
var/mob/living/silicon/robot/R = get_atom_on_turf(src, /mob/living)
if(istype(R) && R.cell && amount)
if(amount < 0)
while(amount < 0 && stored_power + amount < 0) //amount is less than 0 and stored alloy plus the amount is less than 0
R.cell.use(MIN_CLOCKCULT_POWER)
amount += MIN_CLOCKCULT_POWER
else
while(amount > 0 && R.cell.charge + MIN_CLOCKCULT_POWER < R.cell.maxcharge) //amount is greater than 0 and cell charge plus MIN_CLOCKCULT_POWER is less than maximum cell charge
R.cell.give(MIN_CLOCKCULT_POWER)
amount -= MIN_CLOCKCULT_POWER
. = ..()
/obj/item/clockwork/replica_fabricator/Initialize()
. = ..()
START_PROCESSING(SSobj, src)
/obj/item/clockwork/replica_fabricator/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/clockwork/replica_fabricator/process()
if(!charge_rate)
return
var/mob/living/L = get_atom_on_turf(src, /mob/living)
if(istype(L) && is_servant_of_ratvar(L))
if(charge_delay)
charge_delay--
return
modify_stored_power(charge_rate)
for(var/obj/item/clockwork/replica_fabricator/S in L.GetAllContents()) //no multiple fabricators
if(S == src)
continue
S.charge_delay = 2
else
charge_delay = 2
clockwork_desc = "A cyborg's internal fabricator."
/obj/item/clockwork/replica_fabricator/ratvar_act()
if(GLOB.ratvar_awakens)
@@ -129,45 +52,24 @@
to_chat(user, "<span class='alloy'>It can consume floor tiles, rods, metal, and plasteel for power at rates of <b>2:[DisplayPower(POWER_ROD)]</b>, <b>1:[DisplayPower(POWER_ROD)]</b>, <b>1:[DisplayPower(POWER_METAL)]</b>, \
and <b>1:[DisplayPower(POWER_PLASTEEL)]</b>, respectively.</span>")
to_chat(user, "<span class='alloy'>It can also consume brass sheets for power at a rate of <b>1:[DisplayPower(POWER_FLOOR)]</b>.</span>")
to_chat(user, "<span class='alloy'>It is storing <b>[DisplayPower(get_power())]/[DisplayPower(get_max_power())]</b> of power[charge_rate ? ", and is gaining <b>[DisplayPower(charge_rate*0.5)]</b> of power per second":""].</span>")
to_chat(user, "<span class='alloy'>Use it in-hand to produce <b>5</b> brass sheets at a cost of <b>[DisplayPower(POWER_WALL_TOTAL)]</b> power.</span>")
to_chat(user, "<span class='alloy'>It has access to <b>[DisplayPower(get_clockwork_power())]</b> of power.</span>")
/obj/item/clockwork/replica_fabricator/attack_self(mob/living/user)
if(is_servant_of_ratvar(user))
if(uses_power)
if(!can_use_power(POWER_WALL_TOTAL))
if(!get_clockwork_power(POWER_WALL_TOTAL))
to_chat(user, "<span class='warning'>[src] requires <b>[DisplayPower(POWER_WALL_TOTAL)]</b> of power to produce brass sheets!</span>")
return
modify_stored_power(-POWER_WALL_TOTAL)
adjust_clockwork_power(-POWER_WALL_TOTAL)
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
new/obj/item/stack/tile/brass(user.loc, 5)
to_chat(user, "<span class='brass'>You use [stored_power ? "some":"all"] of [src]'s power to produce <b>5</b> brass sheets. It now stores <b>[DisplayPower(get_power())]/[DisplayPower(get_max_power())]</b> of power.</span>")
to_chat(user, "<span class='brass'>You use [get_clockwork_power() ? "some":"all"] of [src]'s power to produce <b>5</b> brass sheets. It now has access to <b>[DisplayPower(get_clockwork_power())]</b> of power.</span>")
/obj/item/clockwork/replica_fabricator/pre_attackby(atom/target, mob/living/user, params)
if(!target || !user || !is_servant_of_ratvar(user) || istype(target, /obj/item/storage))
return TRUE
return fabricate(target, user)
/obj/item/clockwork/replica_fabricator/proc/get_power()
return stored_power
/obj/item/clockwork/replica_fabricator/proc/get_max_power()
return max_power
/obj/item/clockwork/replica_fabricator/proc/modify_stored_power(amount)
stored_power = Clamp(stored_power + amount, 0, max_power)
return TRUE
/obj/item/clockwork/replica_fabricator/proc/can_use_power(amount)
if(amount == RATVAR_POWER_CHECK)
if(GLOB.ratvar_awakens || !uses_power)
return TRUE
else
return FALSE
if(stored_power - amount < 0)
return FALSE
if(stored_power - amount > max_power)
return FALSE
return TRUE
//A note here; return values are for if we CAN BE PUT ON A TABLE, not IF WE ARE SUCCESSFUL, unless no_table_check is TRUE
@@ -178,10 +80,6 @@
if(!silent)
to_chat(user, "<span class='warning'>You are currently repairing [repairing] with [src]!</span>")
return FALSE
if(recharging)
if(!silent)
to_chat(user, "<span class='warning'>You are currently recharging [src] from the [recharging.sigil_name]!</span>")
return FALSE
var/list/fabrication_values = target.fabrication_vals(user, src, silent) //relevant values for fabricating stuff, given as an associated list
if(!islist(fabrication_values))
if(fabrication_values != TRUE) //if we get true, fail, but don't send a message for whatever reason
@@ -192,7 +90,7 @@
if(!no_table_check)
return TRUE
return FALSE
if(can_use_power(RATVAR_POWER_CHECK))
if(get_clockwork_power(RATVAR_POWER_CHECK))
fabrication_values["power_cost"] = 0
var/turf/Y = get_turf(user)
@@ -252,7 +150,7 @@
A.setDir(fabrication_values["spawn_dir"])
if(!fabrication_values["no_target_deletion"]) //for some cases where fabrication_vals() modifies the object but doesn't want it deleted
qdel(target)
modify_stored_power(-fabrication_values["power_cost"])
adjust_clockwork_power(-fabrication_values["power_cost"])
if(no_table_check)
return TRUE
return FALSE
@@ -265,25 +163,18 @@
/obj/item/clockwork/replica_fabricator/proc/fabricate_checks(list/fabrication_values, atom/target, expected_type, mob/user, silent) //checked constantly while fabricating
if(!islist(fabrication_values) || QDELETED(target) || QDELETED(user))
return FALSE
if(repairing || recharging)
if(repairing)
return FALSE
if(target.type != expected_type)
return FALSE
if(can_use_power(RATVAR_POWER_CHECK))
if(get_clockwork_power(RATVAR_POWER_CHECK))
fabrication_values["power_cost"] = 0
if(!can_use_power(fabrication_values["power_cost"]))
if(stored_power - fabrication_values["power_cost"] < 0)
if(!get_clockwork_power(fabrication_values["power_cost"]))
if(get_clockwork_power() - fabrication_values["power_cost"] < 0)
if(!silent)
var/atom/A = fabrication_values["new_obj_type"]
if(A)
to_chat(user, "<span class='warning'>You need <b>[DisplayPower(fabrication_values["power_cost"])]</b> power to fabricate \a [initial(A.name)] from [target]!</span>")
else if(stored_power - fabrication_values["power_cost"] > max_power)
if(!silent)
var/atom/A = fabrication_values["new_obj_type"]
if(A)
to_chat(user, "<span class='warning'>Your [name] contains too much power to fabricate \a [initial(A.name)] from [target]!</span>")
else
to_chat(user, "<span class='warning'>Your [name] contains too much power to consume [target]!</span>")
return FALSE
return TRUE
@@ -321,26 +212,9 @@
return FALSE
repair_values["healing_for_cycle"] = min(repair_values["amount_to_heal"], FABRICATOR_REPAIR_PER_TICK) //modify the healing for this cycle
repair_values["power_required"] = round(repair_values["healing_for_cycle"]*MIN_CLOCKCULT_POWER, MIN_CLOCKCULT_POWER) //and get the power cost from that
if(!can_use_power(RATVAR_POWER_CHECK) && !can_use_power(repair_values["power_required"]))
if(!get_clockwork_power(RATVAR_POWER_CHECK) && !get_clockwork_power(repair_values["power_required"]))
if(!silent)
to_chat(user, "<span class='warning'>You need at least <b>[DisplayPower(repair_values["power_required"])]</b> power to start repairin[target == user ? "g yourself" : "g [target]"], and at least \
<b>[DisplayPower(repair_values["amount_to_heal"]*MIN_CLOCKCULT_POWER, MIN_CLOCKCULT_POWER)]</b> to fully repair [target == user ? "yourself" : "[target.p_them()]"]!</span>")
return FALSE
return TRUE
//The sigil charge check proc.
/obj/item/clockwork/replica_fabricator/proc/sigil_charge_checks(list/charge_values, obj/effect/clockwork/sigil/transmission/sigil, mob/user, silent)
if(!islist(charge_values) || QDELETED(sigil) || QDELETED(user))
return FALSE
if(can_use_power(RATVAR_POWER_CHECK))
return FALSE
charge_values["power_gain"] = Clamp(sigil.power_charge, 0, POWER_WALL_MINUS_FLOOR)
if(!charge_values["power_gain"])
if(!silent)
to_chat(user, "<span class='warning'>The [sigil.sigil_name] contains no power!</span>")
return FALSE
if(stored_power + charge_values["power_gain"] > max_power)
if(!silent)
to_chat(user, "<span class='warning'>Your [name] contains too much power to charge from the [sigil.sigil_name]!</span>")
return FALSE
return TRUE
@@ -23,6 +23,7 @@
autoping = FALSE
resistance_flags = FIRE_PROOF | ACID_PROOF
force_replace_ai_name = TRUE
overrides_aicore_laws = TRUE
/obj/item/device/mmi/posibrain/soul_vessel/Initialize()
. = ..()
@@ -83,7 +83,7 @@
return
set_vision_vars(TRUE)
if(is_servant_of_ratvar(user))
to_chat(user, "<span class='heavy_brass'>As you put on the spectacles, all is revealed to you.[GLOB.ratvar_awakens ? "" : " Your eyes begin to itch - you cannot do this for long."]</span>")
to_chat(user, "<span class='heavy_brass'>As you put on the spectacles, all is revealed to you.[GLOB.ratvar_awakens || GLOB.ratvar_approaches ? "" : " Your eyes begin to itch - you cannot do this for long."]</span>")
var/datum/status_effect/wraith_spectacles/WS = user.has_status_effect(STATUS_EFFECT_WRAITHSPECS)
if(WS)
WS.apply_eye_damage(user)
@@ -138,7 +138,7 @@
var/mob/living/carbon/human/H = owner
var/glasses_right = istype(H.glasses, /obj/item/clothing/glasses/wraith_spectacles)
var/obj/item/clothing/glasses/wraith_spectacles/WS = H.glasses
if(glasses_right && !WS.up && !GLOB.ratvar_awakens)
if(glasses_right && !WS.up && !GLOB.ratvar_awakens && !GLOB.ratvar_approaches)
apply_eye_damage(H)
else
if(GLOB.ratvar_awakens)
@@ -148,15 +148,15 @@
eye_damage_done = 0
else if(prob(50) && eye_damage_done)
H.adjust_eye_damage(-1)
eye_damage_done--
eye_damage_done = max(0, eye_damage_done - 1)
if(!eye_damage_done)
qdel(src)
/datum/status_effect/wraith_spectacles/proc/apply_eye_damage(mob/living/carbon/human/H)
if(H.disabilities & BLIND)
return
H.adjust_eye_damage(1)
eye_damage_done++
H.adjust_eye_damage(0.5)
eye_damage_done += 0.5
if(eye_damage_done >= 20)
H.adjust_blurriness(2)
if(eye_damage_done >= nearsight_breakpoint)