Merge branch 'master' into upstream-merge-28046

This commit is contained in:
LetterJay
2017-06-14 13:10:37 -05:00
committed by GitHub
382 changed files with 304519 additions and 166836 deletions
+36 -5
View File
@@ -43,7 +43,7 @@
/area/ruin/powered/greed
icon_state = "dk_yellow"
/area/ruin/unpowered/hierophant
name = "Hierophant's Arena"
icon_state = "dk_yellow"
@@ -222,16 +222,48 @@
name = "Deep Storage"
icon_state = "storage"
/area/ruin/deepstorage/airlock
name = "Deep Storage Airlock"
icon_state = "quart"
/area/ruin/deepstorage/power
name = "Deep Storage Power and Atmospherics Room"
icon_state = "engi_storage"
/area/ruin/deepstorage/hydroponics
name = "Deep Storage Hydroponics"
icon_state = "garden"
/area/ruin/deepstorage/armory
name = "Deep Storage Secure Storage"
icon_state = "armory"
/area/ruin/deepstorage/storage
name = "Deep Storage Storage"
icon_state = "storage_wing"
/area/ruin/deepstorage/dorm
name = "Deep Storage Dormory"
icon_state = "crew_quarters"
/area/ruin/deepstorage/kitchen
name = "Deep Storage Kitchen"
icon_state = "kitchen"
/area/ruin/deepstorage/crusher
name = "Deep Storage Recycler"
icon_state = "storage"
//Ruin of Abandoned Zoo
/area/ruin/abandonedzoo
name = "Abandoned Zoo"
icon_state = "green"
//Xeno Nest
/area/ruin/xenonest
name = "The Hive"
always_unpowered = 1
@@ -239,4 +271,3 @@
power_equip = 0
power_light = 0
poweralm = 0
+20
View File
@@ -59,3 +59,23 @@
/area/shuttle/abandoned
name = "Abandoned Ship"
blob_allowed = FALSE
/area/shuttle/sbc_starfury
name = "SBC Starfury"
blob_allowed = FALSE
/area/shuttle/sbc_fighter1
name = "SBC Fighter 1"
blob_allowed = FALSE
/area/shuttle/sbc_fighter2
name = "SBC Fighter 2"
blob_allowed = FALSE
/area/shuttle/sbc_corvette
name = "SBC corvette"
blob_allowed = FALSE
/area/shuttle/syndicate_scout
name = "Syndicate Scout"
blob_allowed = FALSE
+1 -6
View File
@@ -79,13 +79,8 @@
return INITIALIZE_HINT_NORMAL
//called if Initialize returns INITIALIZE_HINT_LATELOAD
//This version shouldn't be called
/atom/proc/LateInitialize()
var/static/list/warned_types = list()
if(!warned_types[type])
WARNING("Old style LateInitialize behaviour detected in [type]!")
warned_types[type] = TRUE
Initialize(FALSE)
return
/atom/Destroy()
if(alternate_appearances)
-9
View File
@@ -1,9 +0,0 @@
diff a/code/game/atoms.dm b/code/game/atoms.dm (rejected hunks)
@@ -274,6 +274,7 @@
return
/atom/proc/ex_act(severity, target)
+ set waitfor = FALSE
contents_explosion(severity, target)
/atom/proc/blob_act(obj/structure/blob/B)
+4
View File
@@ -679,3 +679,7 @@
set waitfor = FALSE
if(!anchored && has_gravity())
step(src, movedir)
//Returns an atom's power cell, if it has one. Overload for individual items.
/atom/movable/proc/get_cell()
return
@@ -57,9 +57,9 @@
/obj/effect/proc_holder/changeling/sting/transformation
name = "Transformation Sting"
desc = "We silently sting a human, injecting a retrovirus that forces them to transform."
helptext = "The victim will transform much like a changeling would. The effects will be obvious to the victim, and the process will damage our genomes."
helptext = "The victim will transform much like a changeling would. Does not provide a warning to others. Mutations will not be transferred, and monkeys will become human."
sting_icon = "sting_transform"
chemical_cost = 40
chemical_cost = 50
dna_cost = 3
var/datum/changelingprofile/selected_dna = null
@@ -86,26 +86,19 @@
return 1
/obj/effect/proc_holder/changeling/sting/transformation/sting_action(mob/user, mob/target)
set waitfor = FALSE
add_logs(user, target, "stung", "transformation sting", " new identity is [selected_dna.dna.real_name]")
var/datum/dna/NewDNA = selected_dna.dna
if(ismonkey(target))
to_chat(user, "<span class='notice'>Our genes cry out as we sting [target.name]!</span>")
var/mob/living/carbon/C = target
if(istype(C))
if(C.status_flags & CANWEAKEN)
C.do_jitter_animation(500)
C.take_bodypart_damage(20, 0) //The process is extremely painful
target.visible_message("<span class='danger'>[target] begins to violenty convulse!</span>","<span class='userdanger'>You feel a tiny prick and a begin to uncontrollably convulse!</span>")
. = TRUE
sleep(10)
if(istype(C))
C.real_name = NewDNA.real_name
NewDNA.transfer_identity(C, transfer_SE=1)
NewDNA.transfer_identity(C)
if(ismonkey(C))
C.humanize(TR_KEEPITEMS | TR_KEEPIMPLANTS | TR_KEEPORGANS | TR_KEEPDAMAGE | TR_KEEPVIRUS | TR_DEFAULTMSG)
C.updateappearance(mutcolor_update=1)
C.domutcheck()
/obj/effect/proc_holder/changeling/sting/false_armblade
+2 -3
View File
@@ -207,10 +207,9 @@ Credit where due:
text += "<br><b>The servants' objective was:</b> <br>[CLOCKCULT_OBJECTIVE]"
text += "<br>Ratvar's servants had <b>[GLOB.clockwork_caches]</b> Tinkerer's Caches."
text += "<br><b>Construction Value(CV)</b> was: <b>[GLOB.clockwork_construction_value]</b>"
var/list/scripture_states = scripture_unlock_check()
for(var/i in scripture_states)
for(var/i in SSticker.scripture_states)
if(i != SCRIPTURE_DRIVER)
text += "<br><b>[i] scripture</b> was: <b>[scripture_states[i] ? "UN":""]LOCKED</b>"
text += "<br><b>[i] scripture</b> was: <b>[SSticker.scripture_states[i] ? "UN":""]LOCKED</b>"
if(servants_of_ratvar.len)
text += "<br><b>Ratvar's servants were:</b>"
for(var/datum/mind/M in servants_of_ratvar)
@@ -204,7 +204,7 @@
else if(!GLOB.ratvar_awakens)
to_chat(user, "<span class='brass'>Hitting the [sigil_name] with brass sheets will convert them to power at a rate of <b>1</b> brass sheet to <b>[POWER_FLOOR]W</b> power.</span>")
if(!GLOB.ratvar_awakens)
to_chat(user, "<span class='brass'>You can recharge Clockwork Proselytizers from the [sigil_name].</span>")
to_chat(user, "<span class='brass'>You can recharge Replica Fabricators from the [sigil_name].</span>")
/obj/effect/clockwork/sigil/transmission/attackby(obj/item/I, mob/living/user, params)
if(is_servant_of_ratvar(user) && istype(I, /obj/item/stack/tile/brass) && !GLOB.ratvar_awakens)
@@ -29,7 +29,7 @@
if(charge)
. = min(charge, 250)
charge = use(.)
updateicon()
update_icon()
/obj/machinery/light/power_drain(clockcult_user)
if(on)
@@ -0,0 +1,372 @@
//For the clockwork fabricator, this proc exists to make it easy to customize what the fabricator does when hitting something.
//if a valid target, returns an associated list in this format;
//list("operation_time" = 15, "new_obj_type" = /obj/structure/window/reinforced/clockwork, "power_cost" = 5, "spawn_dir" = dir, "dir_in_new" = TRUE)
//otherwise, return literally any non-list thing but preferably FALSE
//returning TRUE won't produce the "cannot be fabricated" message and will still prevent fabrication
/atom/proc/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return FALSE
/atom/proc/consume_visual(obj/item/clockwork/replica_fabricator/fabricator, power_amount)
if(fabricator.can_use_power(power_amount))
var/obj/effect/temp_visual/ratvar/beam/itemconsume/B = new /obj/effect/temp_visual/ratvar/beam/itemconsume(get_turf(src))
B.pixel_x = pixel_x
B.pixel_y = pixel_y
//Turf conversion
/turf/closed/wall/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //four sheets of metal
return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 4), "spawn_dir" = SOUTH)
/turf/closed/wall/mineral/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //two sheets of metal
return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 2), "spawn_dir" = SOUTH)
/turf/closed/wall/mineral/iron/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //two sheets of metal, five rods
return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 2) - (POWER_ROD * 5), "spawn_dir" = SOUTH)
/turf/closed/wall/mineral/cult/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //no metal
return list("operation_time" = 80, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL, "spawn_dir" = SOUTH)
/turf/closed/wall/shuttle/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //two sheets of metal
return list("operation_time" = 50, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_TOTAL - (POWER_METAL * 2), "spawn_dir" = SOUTH)
/turf/closed/wall/r_wall/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return FALSE
/turf/closed/wall/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return list("operation_time" = 50, "new_obj_type" = /turf/open/floor/clockwork, "power_cost" = -POWER_WALL_MINUS_FLOOR, "spawn_dir" = SOUTH)
/turf/open/floor/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
if(floor_tile == /obj/item/stack/tile/plasteel)
new floor_tile(src)
make_plating()
playsound(src, 'sound/items/Crowbar.ogg', 10, 1) //clink
return list("operation_time" = 30, "new_obj_type" = /turf/open/floor/clockwork, "power_cost" = POWER_FLOOR, "spawn_dir" = SOUTH)
/turf/open/floor/plating/asteroid/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return FALSE
/turf/open/floor/plating/ashplanet/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return FALSE
/turf/open/floor/plating/lava/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return FALSE
/turf/open/floor/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
if(locate(/obj/structure/table) in src)
return FALSE
if(locate(/obj/structure/falsewall) in contents)
to_chat(user, "<span class='warning'>There is a false wall in the way, preventing you from fabricating a clockwork wall on [src].</span>")
return
if(is_blocked_turf(src, TRUE))
to_chat(user, "<span class='warning'>Something is in the way, preventing you from fabricating a clockwork wall on [src].</span>")
return TRUE
var/operation_time = 100
if(!GLOB.ratvar_awakens && fabricator.speed_multiplier > 0) //if ratvar isn't awake, this always takes 10 seconds
operation_time /= fabricator.speed_multiplier
return list("operation_time" = operation_time, "new_obj_type" = /turf/closed/wall/clockwork, "power_cost" = POWER_WALL_MINUS_FLOOR, "spawn_dir" = SOUTH)
//False wall conversion
/obj/structure/falsewall/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
var/cost = POWER_WALL_MINUS_FLOOR
if(ispath(mineral, /obj/item/stack/sheet/metal))
cost -= (POWER_METAL * (2 + mineral_amount)) //four sheets of metal, plus an assumption that the girder is also two
else
cost -= (POWER_METAL * 2) //anything that doesn't use metal just has the girder
return list("operation_time" = 50, "new_obj_type" = /obj/structure/falsewall/brass, "power_cost" = cost, "spawn_dir" = SOUTH)
/obj/structure/falsewall/iron/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent) //two sheets of metal, two rods; special assumption
return list("operation_time" = 50, "new_obj_type" = /obj/structure/falsewall/brass, "power_cost" = POWER_WALL_MINUS_FLOOR - (POWER_METAL * 2) - (POWER_ROD * 2), "spawn_dir" = SOUTH)
/obj/structure/falsewall/reinforced/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return FALSE
/obj/structure/falsewall/brass/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return FALSE
//Metal conversion
/obj/item/stack/tile/plasteel/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
if(source)
return FALSE
var/amount_temp = get_amount()
var/no_delete = FALSE
if(amount_temp < 2)
to_chat(user, "<span class='warning'>You need at least <b>2</b> floor tiles to convert into power.</span>")
return TRUE
if(IsOdd(amount_temp))
amount_temp--
no_delete = TRUE
use(amount_temp)
amount_temp *= 12.5 //each tile is 12.5 power so this is 2 tiles to 25 power
consume_visual(fabricator, amount_temp)
return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = -amount_temp, "spawn_dir" = SOUTH, "no_target_deletion" = no_delete)
/obj/item/stack/rods/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
if(source)
return FALSE
var/power_amount = -(amount*POWER_ROD)
consume_visual(fabricator, power_amount)
return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = power_amount, "spawn_dir" = SOUTH)
/obj/item/stack/sheet/metal/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
if(source)
return FALSE
var/power_amount = -(amount*POWER_METAL)
consume_visual(fabricator, power_amount)
return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = power_amount, "spawn_dir" = SOUTH)
/obj/item/stack/sheet/plasteel/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
if(source)
return FALSE
var/power_amount = -(amount*POWER_PLASTEEL)
consume_visual(fabricator, power_amount)
return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = power_amount, "spawn_dir" = SOUTH)
//Brass directly to power
/obj/item/stack/tile/brass/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
if(source)
return FALSE
var/power_amount = -(amount*POWER_FLOOR)
consume_visual(fabricator, power_amount)
return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = power_amount, "spawn_dir" = SOUTH)
//Airlock conversion
/obj/machinery/door/airlock/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
var/doortype = /obj/machinery/door/airlock/clockwork
if(glass)
doortype = /obj/machinery/door/airlock/clockwork/brass
return list("operation_time" = 60, "new_obj_type" = doortype, "power_cost" = POWER_WALL_TOTAL, "spawn_dir" = dir)
/obj/machinery/door/airlock/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return FALSE
//Table conversion
/obj/structure/table/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
var/fabrication_cost = POWER_STANDARD
if(framestack == /obj/item/stack/rods)
fabrication_cost -= POWER_ROD*framestackamount
else if(framestack == /obj/item/stack/tile/brass)
fabrication_cost -= POWER_FLOOR*framestackamount
if(buildstack == /obj/item/stack/sheet/metal)
fabrication_cost -= POWER_METAL*buildstackamount
else if(buildstack == /obj/item/stack/sheet/plasteel)
fabrication_cost -= POWER_PLASTEEL*buildstackamount
return list("operation_time" = 20, "new_obj_type" = /obj/structure/table/reinforced/brass, "power_cost" = fabrication_cost, "spawn_dir" = SOUTH)
/obj/structure/table/reinforced/brass/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return FALSE
/obj/structure/table_frame/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
var/fabrication_cost = POWER_FLOOR
if(framestack == /obj/item/stack/rods)
fabrication_cost -= POWER_ROD*framestackamount
else if(framestack == /obj/item/stack/tile/brass)
fabrication_cost -= POWER_FLOOR*framestackamount
return list("operation_time" = 10, "new_obj_type" = /obj/structure/table_frame/brass, "power_cost" = fabrication_cost, "spawn_dir" = SOUTH)
/obj/structure/table_frame/brass/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return FALSE
//Window conversion
/obj/structure/window/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
var/windowtype = /obj/structure/window/reinforced/clockwork
var/new_dir = TRUE
var/fabrication_time = 15
var/fabrication_cost = POWER_FLOOR
if(fulltile)
windowtype = /obj/structure/window/reinforced/clockwork/fulltile
new_dir = FALSE
fabrication_time = 30
fabrication_cost = POWER_STANDARD
if(reinf)
fabrication_cost -= POWER_ROD
if(reinf)
fabrication_cost -= POWER_ROD
for(var/obj/structure/grille/G in get_turf(src))
INVOKE_ASYNC(fabricator, /obj/item/clockwork/replica_fabricator.proc/fabricate, G, user)
return list("operation_time" = fabrication_time, "new_obj_type" = windowtype, "power_cost" = fabrication_cost, "spawn_dir" = dir, "dir_in_new" = new_dir)
/obj/structure/window/reinforced/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return FALSE
//Windoor conversion
/obj/machinery/door/window/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return list("operation_time" = 30, "new_obj_type" = /obj/machinery/door/window/clockwork, "power_cost" = POWER_STANDARD, "spawn_dir" = dir, "dir_in_new" = TRUE)
/obj/machinery/door/window/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return FALSE
//Grille conversion
/obj/structure/grille/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
var/grilletype = /obj/structure/grille/ratvar
var/fabrication_time = 15
if(broken)
grilletype = /obj/structure/grille/ratvar/broken
fabrication_time = 5
return list("operation_time" = fabrication_time, "new_obj_type" = grilletype, "power_cost" = 0, "spawn_dir" = dir)
/obj/structure/grille/ratvar/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return FALSE
//Lattice conversion
/obj/structure/lattice/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return list("operation_time" = 0, "new_obj_type" = /obj/structure/lattice/clockwork, "power_cost" = 0, "spawn_dir" = SOUTH, "no_target_deletion" = TRUE)
/obj/structure/lattice/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
ratvar_act() //just in case we're the wrong type for some reason??
return FALSE
/obj/structure/lattice/catwalk/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return list("operation_time" = 0, "new_obj_type" = /obj/structure/lattice/catwalk/clockwork, "power_cost" = 0, "spawn_dir" = SOUTH, "no_target_deletion" = TRUE)
/obj/structure/lattice/catwalk/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
return FALSE
//Girder conversion
/obj/structure/girder/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
var/fabrication_cost = POWER_GEAR - (POWER_METAL * 2)
if(state == GIRDER_REINF_STRUTS || state == GIRDER_REINF)
fabrication_cost -= POWER_PLASTEEL
return list("operation_time" = 20, "new_obj_type" = /obj/structure/destructible/clockwork/wall_gear, "power_cost" = fabrication_cost, "spawn_dir" = SOUTH)
//Hitting a clockwork structure will try to repair it.
/obj/structure/destructible/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
. = TRUE
var/list/repair_values = list()
if(!fabricator.fabricator_repair_checks(repair_values, src, user))
return
user.visible_message("<span class='notice'>[user]'s [fabricator.name] starts covering [src] in glowing orange energy...</span>", \
"<span class='alloy'>You start repairing [src]...</span>")
fabricator.repairing = src
while(fabricator && user && src)
if(!do_after(user, repair_values["healing_for_cycle"] * fabricator.speed_multiplier, target = src, \
extra_checks = CALLBACK(fabricator, /obj/item/clockwork/replica_fabricator.proc/fabricator_repair_checks, repair_values, src, user, TRUE)))
break
obj_integrity = Clamp(obj_integrity + repair_values["healing_for_cycle"], 0, max_integrity)
fabricator.modify_stored_power(-repair_values["power_required"])
playsound(src, 'sound/machines/click.ogg', 50, 1)
if(fabricator)
fabricator.repairing = null
if(user)
user.visible_message("<span class='notice'>[user]'s [fabricator.name] stops covering [src] with glowing orange energy.</span>", \
"<span class='alloy'>You finish repairing [src]. It is now at <b>[obj_integrity]/[max_integrity]</b> integrity.</span>")
//Hitting a sigil of transmission will try to charge from it.
/obj/effect/clockwork/sigil/transmission/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
. = TRUE
var/list/charge_values = list()
if(!fabricator.sigil_charge_checks(charge_values, src, user))
return
user.visible_message("<span class='notice'>[user]'s [fabricator.name] starts draining glowing orange energy from [src]...</span>", \
"<span class='alloy'>You start recharging your [fabricator.name]...</span>")
fabricator.recharging = src
while(fabricator && user && src)
if(!do_after(user, 10, target = src, extra_checks = CALLBACK(fabricator, /obj/item/clockwork/replica_fabricator.proc/sigil_charge_checks, charge_values, src, user, TRUE)))
break
modify_charge(charge_values["power_gain"])
fabricator.modify_stored_power(charge_values["power_gain"])
playsound(src, 'sound/effects/light_flicker.ogg', charge_values["power_gain"] * 0.1, 1)
if(fabricator)
fabricator.recharging = null
if(user)
user.visible_message("<span class='notice'>[user]'s [fabricator.name] stops draining glowing orange energy from [src].</span>", \
"<span class='alloy'>You finish recharging your [fabricator.name]. It now contains <b>[fabricator.get_power()]W/[fabricator.get_max_power()]W</b> power.</span>")
//Fabricator mob heal proc, to avoid as much copypaste as possible.
/mob/living/proc/fabricator_heal(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator)
var/list/repair_values = list()
if(!fabricator.fabricator_repair_checks(repair_values, src, user))
return
user.visible_message("<span class='notice'>[user]'s [fabricator.name] starts coverin[src == user ? "g [user.p_them()]" : "g [src]"] in glowing orange energy...</span>", \
"<span class='alloy'>You start repairin[src == user ? "g yourself" : "g [src]"]...</span>")
fabricator.repairing = src
while(fabricator && user && src)
if(!do_after(user, repair_values["healing_for_cycle"] * fabricator.speed_multiplier, target = src, \
extra_checks = CALLBACK(fabricator, /obj/item/clockwork/replica_fabricator.proc/fabricator_repair_checks, repair_values, src, user, TRUE)))
break
fabricator_heal_tick(repair_values["healing_for_cycle"])
fabricator.modify_stored_power(-repair_values["power_required"])
playsound(src, 'sound/machines/click.ogg', 50, 1)
if(fabricator)
fabricator.repairing = null
return TRUE
/mob/living/proc/fabricator_heal_tick(amount)
var/static/list/damage_heal_order = list(BRUTE, BURN, TOX, OXY)
heal_ordered_damage(amount, damage_heal_order)
/mob/living/simple_animal/fabricator_heal_tick(amount)
adjustHealth(-amount)
//Hitting a ratvar'd silicon will also try to repair it.
/mob/living/silicon/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
. = TRUE
if(health == maxHealth) //if we're at maximum health, replace the turf under us
return FALSE
else if(fabricator_heal(user, fabricator) && user)
user.visible_message("<span class='notice'>[user]'s [fabricator.name] stops coverin[src == user ? "g [user.p_them()]" : "g [src]"] with glowing orange energy.</span>", \
"<span class='alloy'>You finish repairin[src == user ? "g yourself. You are":"g [src]. [p_they(TRUE)] [p_are()]"] now at <b>[abs(HEALTH_THRESHOLD_DEAD - health)]/[abs(HEALTH_THRESHOLD_DEAD - maxHealth)]</b> health.</span>")
//Same with clockwork mobs.
/mob/living/simple_animal/hostile/clockwork/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
. = TRUE
if(health == maxHealth) //if we're at maximum health, replace the turf under us
return FALSE
else if(fabricator_heal(user, fabricator) && user)
user.visible_message("<span class='notice'>[user]'s [fabricator.name] stops coverin[src == user ? "g [user.p_them()]" : "g [src]"] with glowing orange energy.</span>", \
"<span class='alloy'>You finish repairin[src == user ? "g yourself. You are":"g [src]. [p_they(TRUE)] [p_are()]"] now at <b>[health]/[maxHealth]</b> health.</span>")
//Cogscarabs get special interaction because they're drones and have innate self-heals/revives.
/mob/living/simple_animal/drone/cogscarab/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent)
. = TRUE
if(stat == DEAD)
try_reactivate(user) //if we're dead, try to repair us
return
if(health == maxHealth)
return FALSE
else if(!(flags & GODMODE))
user.visible_message("<span class='notice'>[user]'s [fabricator.name] starts coverin[src == user ? "g [user.p_them()]" : "g [src]"] in glowing orange energy...</span>", \
"<span class='alloy'>You start repairin[src == user ? "g yourself" : "g [src]"]...</span>")
fabricator.repairing = src
if(do_after(user, (maxHealth - health)*2, target=src))
adjustHealth(-maxHealth)
user.visible_message("<span class='notice'>[user]'s [fabricator.name] stops coverin[src == user ? "g [user.p_them()]" : "g [src]"] with glowing orange energy.</span>", \
"<span class='alloy'>You finish repairin[src == user ? "g yourself" : "g [src]"].</span>")
if(fabricator)
fabricator.repairing = null
//Convert shards and gear bits directly to power
/obj/item/clockwork/alloy_shards/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent, power_amount)
if(!power_amount)
power_amount = -POWER_STANDARD
consume_visual(fabricator, power_amount)
if(!silent) //looper no looping
for(var/obj/item/clockwork/alloy_shards/S in get_turf(src)) //convert all other shards in the turf if we can
if(S == src)
continue //we want the shards to be fabricated after the main shard, thus this delay
addtimer(CALLBACK(fabricator, /obj/item/clockwork/replica_fabricator.proc/fabricate, S, user, TRUE), 0)
return list("operation_time" = 0, "new_obj_type" = null, "power_cost" = power_amount, "spawn_dir" = SOUTH)
/obj/item/clockwork/alloy_shards/medium/gear_bit/large/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent, power_amount)
if(!power_amount)
power_amount = -(CLOCKCULT_POWER_UNIT*0.08)
return ..()
/obj/item/clockwork/alloy_shards/large/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent, power_amount)
if(!power_amount)
power_amount = -(CLOCKCULT_POWER_UNIT*0.06)
return ..()
/obj/item/clockwork/alloy_shards/medium/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent, power_amount)
if(!power_amount)
power_amount = -(CLOCKCULT_POWER_UNIT*0.04)
return ..()
/obj/item/clockwork/alloy_shards/small/fabrication_vals(mob/living/user, obj/item/clockwork/replica_fabricator/fabricator, silent, power_amount)
if(!power_amount)
power_amount = -(CLOCKCULT_POWER_UNIT*0.02)
return ..()
@@ -49,6 +49,9 @@
/turf/open/floor/clockwork/proselytize_vals(mob/living/user, obj/item/clockwork/clockwork_proselytizer/proselytizer)
if(locate(/obj/structure/table) in src)
return FALSE
if(locate(/obj/structure/falsewall) in contents)
to_chat(user, "<span class='warning'>There is a false wall in the way, preventing you from proselytizing [src] into a clockwork wall.</span>")
return
if(is_blocked_turf(src, TRUE))
to_chat(user, "<span class='warning'>Something is in the way, preventing you from proselytizing [src] into a clockwork wall.</span>")
return TRUE
@@ -7,13 +7,17 @@
servants++
. = list(SCRIPTURE_DRIVER = TRUE, SCRIPTURE_SCRIPT = FALSE, SCRIPTURE_APPLICATION = FALSE, SCRIPTURE_REVENANT = FALSE, SCRIPTURE_JUDGEMENT = FALSE)
//Drivers: always unlocked
.[SCRIPTURE_SCRIPT] = (servants >= SCRIPT_SERVANT_REQ && GLOB.clockwork_caches >= SCRIPT_CACHE_REQ)
.[SCRIPTURE_SCRIPT] = (SSticker.scripture_states[SCRIPTURE_SCRIPT] || \
(servants >= SCRIPT_SERVANT_REQ && GLOB.clockwork_caches >= SCRIPT_CACHE_REQ))
//Script: SCRIPT_SERVANT_REQ or more non-brain servants and SCRIPT_CACHE_REQ or more clockwork caches
.[SCRIPTURE_APPLICATION] = (servants >= APPLICATION_SERVANT_REQ && GLOB.clockwork_caches >= APPLICATION_CACHE_REQ && GLOB.clockwork_construction_value >= APPLICATION_CV_REQ)
.[SCRIPTURE_APPLICATION] = (SSticker.scripture_states[SCRIPTURE_APPLICATION] || \
(servants >= APPLICATION_SERVANT_REQ && GLOB.clockwork_caches >= APPLICATION_CACHE_REQ && GLOB.clockwork_construction_value >= APPLICATION_CV_REQ))
//Application: APPLICATION_SERVANT_REQ or more non-brain servants, APPLICATION_CACHE_REQ or more clockwork caches, and at least APPLICATION_CV_REQ CV
.[SCRIPTURE_REVENANT] = (servants >= REVENANT_SERVANT_REQ && GLOB.clockwork_caches >= REVENANT_CACHE_REQ && GLOB.clockwork_construction_value >= REVENANT_CV_REQ)
.[SCRIPTURE_REVENANT] = (SSticker.scripture_states[SCRIPTURE_REVENANT] || \
(servants >= REVENANT_SERVANT_REQ && GLOB.clockwork_caches >= REVENANT_CACHE_REQ && GLOB.clockwork_construction_value >= REVENANT_CV_REQ))
//Revenant: REVENANT_SERVANT_REQ or more non-brain servants, REVENANT_CACHE_REQ or more clockwork caches, and at least REVENANT_CV_REQ CV
.[SCRIPTURE_JUDGEMENT] = (servants >= JUDGEMENT_SERVANT_REQ && GLOB.clockwork_caches >= JUDGEMENT_CACHE_REQ && GLOB.clockwork_construction_value >= JUDGEMENT_CV_REQ && !unconverted_ai_exists)
.[SCRIPTURE_JUDGEMENT] = (SSticker.scripture_states[SCRIPTURE_JUDGEMENT] || \
(servants >= JUDGEMENT_SERVANT_REQ && GLOB.clockwork_caches >= JUDGEMENT_CACHE_REQ && GLOB.clockwork_construction_value >= JUDGEMENT_CV_REQ && !unconverted_ai_exists))
//Judgement: JUDGEMENT_SERVANT_REQ or more non-brain servants, JUDGEMENT_CACHE_REQ or more clockwork caches, at least JUDGEMENT_CV_REQ CV, and there are no living, non-servant ais
//reports to servants when scripture is locked or unlocked
@@ -59,3 +63,6 @@
//changes construction value
/proc/change_construction_value(amount)
GLOB.clockwork_construction_value += amount
/proc/can_recite_scripture(mob/living/L)
return (is_servant_of_ratvar(L) && L.stat == CONSCIOUS && L.can_speak_vocal() && (GLOB.ratvar_awakens || (ishuman(L) || issilicon(L))))
@@ -153,11 +153,11 @@
icon_state = "obelisk_prism"
w_class = WEIGHT_CLASS_NORMAL
//Shards of Alloy, suitable only for proselytization.
//Shards of Alloy, suitable only as a source of power for a replica fabricator.
/obj/item/clockwork/alloy_shards
name = "replicant alloy shards"
desc = "Broken shards of some oddly malleable metal. They occasionally move and seem to glow."
clockwork_desc = "Broken shards of replicant alloy. Can be proselytized for additional power."
clockwork_desc = "Broken shards of replicant alloy."
icon_state = "alloy_shards"
resistance_flags = LAVA_PROOF | FIRE_PROOF | ACID_PROOF
var/randomsinglesprite = FALSE
@@ -172,10 +172,15 @@
pixel_x = rand(-sprite_shift, sprite_shift)
pixel_y = rand(-sprite_shift, sprite_shift)
/obj/item/clockwork/alloy_shards/examine(mob/user)
..()
if(is_servant_of_ratvar(user) || isobserver(user))
to_chat(user, "<span class='brass'>Can be consumed by a replica fabricator as a source of power.</span>")
/obj/item/clockwork/alloy_shards/proc/replace_name_desc()
name = "replicant alloy shard"
desc = "A broken shard of some oddly malleable metal. It occasionally moves and seems to glow."
clockwork_desc = "A broken shard of replicant alloy. Can be proselytized for additional power."
clockwork_desc = "A broken shard of replicant alloy."
/obj/item/clockwork/alloy_shards/large
w_class = WEIGHT_CLASS_TINY
@@ -197,7 +202,7 @@
/obj/item/clockwork/alloy_shards/medium/gear_bit/replace_name_desc()
name = "gear bit"
desc = "A broken chunk of a gear. You want it."
clockwork_desc = "A broken chunk of a gear. Can be proselytized for additional power."
clockwork_desc = "A broken chunk of a gear."
/obj/item/clockwork/alloy_shards/medium/gear_bit/large //gives more power
@@ -215,5 +220,5 @@
/obj/item/clockwork/alloy_shards/pinion_lock
name = "pinion lock"
desc = "A dented and scratched gear. It's very heavy."
clockwork_desc = "A broken gear lock for pinion airlocks. Can be proselytized for additional power."
clockwork_desc = "A broken gear lock for pinion airlocks"
icon_state = "pinion_lock"
@@ -25,7 +25,7 @@
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)
flags &= STOPSPRESSUREDMAGE
flags &= ~STOPSPRESSUREDMAGE
max_heat_protection_temperature = initial(max_heat_protection_temperature)
min_cold_protection_temperature = initial(min_cold_protection_temperature)
@@ -81,7 +81,7 @@
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)
flags &= STOPSPRESSUREDMAGE
flags &= ~STOPSPRESSUREDMAGE
max_heat_protection_temperature = initial(max_heat_protection_temperature)
min_cold_protection_temperature = initial(min_cold_protection_temperature)
@@ -142,7 +142,7 @@
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)
flags &= STOPSPRESSUREDMAGE
flags &= ~STOPSPRESSUREDMAGE
max_heat_protection_temperature = initial(max_heat_protection_temperature)
min_cold_protection_temperature = initial(min_cold_protection_temperature)
@@ -194,7 +194,7 @@
if(GLOB.ratvar_awakens)
flags |= NOSLIP
else
flags &= NOSLIP
flags &= ~NOSLIP
/obj/item/clothing/shoes/clockwork/mob_can_equip(mob/M, mob/equipper, slot, disable_warning = 0)
if(equipper && !is_servant_of_ratvar(equipper))
@@ -14,7 +14,6 @@
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/nonhuman_usable = FALSE //if the slab can be used by nonhumans, defaults to off
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
@@ -33,29 +32,24 @@
no_cost = TRUE
produces_components = FALSE
/obj/item/clockwork/slab/scarab
nonhuman_usable = TRUE
/obj/item/clockwork/slab/debug
speed_multiplier = 0
no_cost = TRUE
nonhuman_usable = TRUE
/obj/item/clockwork/slab/debug/attack_hand(mob/living/user)
..()
if(!is_servant_of_ratvar(user))
add_servant_of_ratvar(user)
/obj/item/clockwork/slab/cyborg //three scriptures, plus a spear and proselytizer
/obj/item/clockwork/slab/cyborg //three scriptures, plus a spear and fabricator
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."
nonhuman_usable = TRUE
quickbound = list(/datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/ranged_ability/linked_vanguard, \
/datum/clockwork_scripture/create_object/tinkerers_cache)
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 //five scriptures, plus a proselytizer
/obj/item/clockwork/slab/cyborg/engineer //five scriptures, plus a fabricator
quickbound = list(/datum/clockwork_scripture/create_object/replicant, /datum/clockwork_scripture/create_object/cogscarab, \
/datum/clockwork_scripture/create_object/soul_vessel, /datum/clockwork_scripture/create_object/sigil_of_transmission, /datum/clockwork_scripture/create_object/interdiction_lens)
@@ -71,7 +65,7 @@
quickbound = list(/datum/clockwork_scripture/channeled/belligerent, /datum/clockwork_scripture/ranged_ability/judicial_marker, /datum/clockwork_scripture/channeled/taunting_tirade, \
/datum/clockwork_scripture/channeled/volt_void/cyborg)
/obj/item/clockwork/slab/cyborg/janitor //five scriptures, plus a proselytizer
/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)
@@ -106,12 +100,6 @@
slab_ability = null
return ..()
/obj/item/clockwork/slab/ratvar_act()
if(GLOB.ratvar_awakens)
nonhuman_usable = TRUE
else
nonhuman_usable = initial(nonhuman_usable)
/obj/item/clockwork/slab/dropped(mob/user)
. = ..()
addtimer(CALLBACK(src, .proc/check_on_mob, user), 1) //dropped is called before the item is out of the slot, so we need to check slightly later
@@ -138,7 +126,7 @@
production_time = world.time + SLAB_PRODUCTION_TIME + production_slowdown
var/mob/living/L
L = get_atom_on_turf(src, /mob/living)
if(istype(L) && is_servant_of_ratvar(L) && (nonhuman_usable || ishuman(L)))
if(istype(L) && 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
@@ -268,7 +256,7 @@
if(busy)
to_chat(user, "<span class='warning'>[src] refuses to work, displaying the message: \"[busy]!\"</span>")
return 0
if(!nonhuman_usable && !ishuman(user))
if(!can_recite_scripture(user))
to_chat(user, "<span class='nezbere'>[src] hums fitfully in your hands, but doesn't seem to do anything...</span>")
return 0
access_display(user)
@@ -288,15 +276,14 @@
ui.open()
/obj/item/clockwork/slab/proc/recite_scripture(datum/clockwork_scripture/scripture, mob/living/user)
if(!scripture || !user || !user.canUseTopic(src) || (!nonhuman_usable && !ishuman(user)))
if(!scripture || !user || !user.canUseTopic(src) || !can_recite_scripture(user))
return FALSE
if(user.get_active_held_item() != src)
to_chat(user, "<span class='warning'>You need to hold the slab in your active hand to recite scripture!</span>")
return FALSE
var/initial_tier = initial(scripture.tier)
if(initial_tier != SCRIPTURE_PERIPHERAL)
var/list/tiers_of_scripture = scripture_unlock_check()
if(!GLOB.ratvar_awakens && !no_cost && !tiers_of_scripture[initial_tier])
if(!GLOB.ratvar_awakens && !no_cost && !SSticker.scripture_states[initial_tier])
to_chat(user, "<span class='warning'>That scripture is not unlocked, and cannot be recited!</span>")
return FALSE
var/datum/clockwork_scripture/scripture_to_recite = new scripture
@@ -415,13 +402,25 @@
if(SCRIPTURE_DRIVER)
data["tier_info"] = "<font color=#B18B25><i>These scriptures are always unlocked.</i></font>"
if(SCRIPTURE_SCRIPT)
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>"
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>"
if(SCRIPTURE_APPLICATION)
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(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_REVENANT)
data["tier_info"] = "<font color=#B18B25><i>These scriptures require at least <b>[REVENANT_SERVANT_REQ]</b> Servants, <b>[REVENANT_CACHE_REQ]</b> Tinkerer's Caches, and <b>[REVENANT_CV_REQ]CV</b>.</i></font>"
if(SSticker.scripture_states[SCRIPTURE_REVENANT])
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>[REVENANT_SERVANT_REQ]</b> Servants, <b>[REVENANT_CACHE_REQ]</b> Tinkerer's Caches, and <b>[REVENANT_CV_REQ]CV</b>.</i></font>"
if(SCRIPTURE_JUDGEMENT)
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>"
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["selected"] = selected_scripture
@@ -1,51 +1,48 @@
//Clockwork proselytizer: Converts applicable objects to Ratvarian variants.
/obj/item/clockwork/clockwork_proselytizer
name = "clockwork proselytizer"
//Replica Fabricator: Converts applicable objects to Ratvarian variants.
/obj/item/clockwork/replica_fabricator
name = "replica fabricator"
desc = "An odd, L-shaped device that hums with energy."
clockwork_desc = "A device that allows the replacing of mundane objects with Ratvarian variants. It requires power to function."
icon_state = "clockwork_proselytizer"
icon_state = "replica_fabricator"
w_class = WEIGHT_CLASS_NORMAL
force = 5
flags = NOBLUDGEON
var/stored_power = 0 //Requires power to function
var/max_power = CLOCKCULT_POWER_UNIT * 10
var/uses_power = TRUE
var/metal_to_power = FALSE
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 proselytizer works
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/clockwork_proselytizer/preloaded
/obj/item/clockwork/replica_fabricator/preloaded
stored_power = POWER_WALL_MINUS_FLOOR+POWER_WALL_TOTAL
/obj/item/clockwork/clockwork_proselytizer/scarab
name = "scarab proselytizer"
clockwork_desc = "A cogscarab's internal proselytizer. It can only be successfully used by a cogscarab and requires power to function."
metal_to_power = TRUE
/obj/item/clockwork/replica_fabricator/scarab
name = "scarab fabricator"
clockwork_desc = "A cogscarab's internal fabricator. It can only be successfully used by a cogscarab and requires power to function."
item_state = "nothing"
w_class = WEIGHT_CLASS_TINY
speed_multiplier = 0.5
charge_rate = MIN_CLOCKCULT_POWER * 2
var/debug = FALSE
/obj/item/clockwork/clockwork_proselytizer/scarab/proselytize(atom/target, mob/living/user)
/obj/item/clockwork/replica_fabricator/scarab/fabricate(atom/target, mob/living/user)
if(!debug && !isdrone(user))
return 0
return ..()
/obj/item/clockwork/clockwork_proselytizer/scarab/debug
clockwork_desc = "A cogscarab's internal proselytizer. It can convert nearly any object into a Ratvarian variant."
/obj/item/clockwork/replica_fabricator/scarab/debug
clockwork_desc = "A cogscarab's internal fabricator. It can convert nearly any object into a Ratvarian variant."
uses_power = FALSE
debug = TRUE
/obj/item/clockwork/clockwork_proselytizer/cyborg
name = "cyborg proselytizer"
clockwork_desc = "A cyborg's internal proselytizer. It is capable of using the cyborg's power in addition to stored power."
metal_to_power = TRUE
/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/clockwork_proselytizer/cyborg/get_power() //returns power and cyborg's 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
@@ -56,14 +53,14 @@
borg_power += MIN_CLOCKCULT_POWER
return ..() + borg_power
/obj/item/clockwork/clockwork_proselytizer/cyborg/get_max_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/clockwork_proselytizer/cyborg/can_use_power(amount)
/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
@@ -76,7 +73,7 @@
return FALSE
. = ..()
/obj/item/clockwork/clockwork_proselytizer/cyborg/modify_stored_power(amount)
/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)
@@ -89,15 +86,15 @@
amount -= MIN_CLOCKCULT_POWER
. = ..()
/obj/item/clockwork/clockwork_proselytizer/Initialize()
/obj/item/clockwork/replica_fabricator/Initialize()
. = ..()
START_PROCESSING(SSobj, src)
/obj/item/clockwork/clockwork_proselytizer/Destroy()
/obj/item/clockwork/replica_fabricator/Destroy()
STOP_PROCESSING(SSobj, src)
return ..()
/obj/item/clockwork/clockwork_proselytizer/process()
/obj/item/clockwork/replica_fabricator/process()
if(!charge_rate)
return
var/mob/living/L = get_atom_on_turf(src, /mob/living)
@@ -106,14 +103,14 @@
charge_delay--
return
modify_stored_power(charge_rate)
for(var/obj/item/clockwork/clockwork_proselytizer/S in L.GetAllContents()) //no multiple proselytizers
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
/obj/item/clockwork/clockwork_proselytizer/ratvar_act()
/obj/item/clockwork/replica_fabricator/ratvar_act()
if(GLOB.nezbere_invoked)
charge_rate = 1250
else
@@ -125,21 +122,19 @@
uses_power = initial(uses_power)
speed_multiplier = initial(speed_multiplier)
/obj/item/clockwork/clockwork_proselytizer/examine(mob/living/user)
/obj/item/clockwork/replica_fabricator/examine(mob/living/user)
..()
if(is_servant_of_ratvar(user) || isobserver(user))
to_chat(user, "<span class='brass'>Can be used to convert walls, floors, windows, airlocks, and a variety of other objects to clockwork variants.</span>")
to_chat(user, "<span class='brass'>Can also form some objects into Brass sheets, as well as reform Clockwork Walls into Clockwork Floors, and vice versa.</span>")
to_chat(user, "<span class='brass'>Can be used to replace walls, floors, tables, windows, windoors, and airlocks with Clockwork variants.</span>")
to_chat(user, "<span class='brass'>Can construct Clockwork Walls on Clockwork Floors and deconstruct Clockwork Walls to Clockwork Floors.</span>")
if(uses_power)
if(metal_to_power)
to_chat(user, "<span class='alloy'>It can convert rods, metal, plasteel, and brass to power at rates of <b>1:[POWER_ROD]W</b>, <b>1:[POWER_METAL]W</b>, \
<b>1:[POWER_PLASTEEL]W</b>, and <b>1:[POWER_FLOOR]W</b>, respectively.</span>")
else
to_chat(user, "<span class='alloy'>It can convert brass to power at a rate of <b>1:[POWER_FLOOR]W</b>.</span>")
to_chat(user, "<span class='alloy'>It is storing <b>[get_power()]W/[get_max_power()]W</b> of power, and is gaining <b>[charge_rate*0.5]W</b> of power per second.</span>")
to_chat(user, "<span class='alloy'>It can consume floor tiles, rods, metal, and plasteel for power at rates of <b>2:[POWER_ROD]W</b>, <b>1:[POWER_ROD]W</b>, <b>1:[POWER_METAL]W</b>, \
and <b>1:[POWER_PLASTEEL]W</b>, respectively.</span>")
to_chat(user, "<span class='alloy'>It can also consume brass sheets for power at a rate of <b>1:[POWER_FLOOR]W</b>.</span>")
to_chat(user, "<span class='alloy'>It is storing <b>[get_power()]W/[get_max_power()]W</b> of power[charge_rate ? ", and is gaining <b>[charge_rate*0.5]W</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>[POWER_WALL_TOTAL]W</b> power.</span>")
/obj/item/clockwork/clockwork_proselytizer/attack_self(mob/living/user)
/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))
@@ -148,24 +143,24 @@
modify_stored_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 user [stored_power ? "some":"all"] of [src]'s power to produce some brass sheets. It now stores <b>[get_power()]W/[get_max_power()]W</b> of power.</span>")
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>[get_power()]W/[get_max_power()]W</b> of power.</span>")
/obj/item/clockwork/clockwork_proselytizer/pre_attackby(atom/target, mob/living/user, params)
/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/weapon/storage))
return TRUE
return proselytize(target, user)
return fabricate(target, user)
/obj/item/clockwork/clockwork_proselytizer/proc/get_power()
/obj/item/clockwork/replica_fabricator/proc/get_power()
return stored_power
/obj/item/clockwork/clockwork_proselytizer/proc/get_max_power()
/obj/item/clockwork/replica_fabricator/proc/get_max_power()
return max_power
/obj/item/clockwork/clockwork_proselytizer/proc/modify_stored_power(amount)
/obj/item/clockwork/replica_fabricator/proc/modify_stored_power(amount)
stored_power = Clamp(stored_power + amount, 0, max_power)
return TRUE
/obj/item/clockwork/clockwork_proselytizer/proc/can_use_power(amount)
/obj/item/clockwork/replica_fabricator/proc/can_use_power(amount)
if(amount == RATVAR_POWER_CHECK)
if(GLOB.ratvar_awakens || !uses_power)
return TRUE
@@ -178,7 +173,7 @@
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
/obj/item/clockwork/clockwork_proselytizer/proc/proselytize(atom/target, mob/living/user, silent, no_table_check)
/obj/item/clockwork/replica_fabricator/proc/fabricate(atom/target, mob/living/user, silent, no_table_check)
if(!target || !user)
return FALSE
if(repairing)
@@ -189,59 +184,77 @@
if(!silent)
to_chat(user, "<span class='warning'>You are currently recharging [src] from the [recharging.sigil_name]!</span>")
return FALSE
var/list/proselytize_values = target.proselytize_vals(user, src, silent) //relevant values for proselytizing stuff, given as an associated list
if(!islist(proselytize_values))
if(proselytize_values != TRUE) //if we get true, fail, but don't send a message for whatever reason
if(!isturf(target)) //otherwise, if we didn't get TRUE and the original target wasn't a turf, try to proselytize the turf
return proselytize(get_turf(target), user, no_table_check)
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
if(!isturf(target)) //otherwise, if we didn't get TRUE and the original target wasn't a turf, try to fabricate the turf
return fabricate(get_turf(target), user, no_table_check)
if(!silent)
to_chat(user, "<span class='warning'>[target] cannot be proselytized!</span>")
to_chat(user, "<span class='warning'>[target] cannot be fabricated!</span>")
if(!no_table_check)
return TRUE
return FALSE
if(can_use_power(RATVAR_POWER_CHECK))
proselytize_values["power_cost"] = 0
fabrication_values["power_cost"] = 0
var/turf/Y = get_turf(user)
if(!Y || (Y.z != ZLEVEL_STATION && Y.z != ZLEVEL_CENTCOM && Y.z != ZLEVEL_MINING && Y.z != ZLEVEL_LAVALAND))
proselytize_values["operation_time"] *= 2
if(proselytize_values["power_cost"] > 0)
proselytize_values["power_cost"] *= 2
fabrication_values["operation_time"] *= 2
if(fabrication_values["power_cost"] > 0)
fabrication_values["power_cost"] *= 2
var/target_type = target.type
if(!proselytize_checks(proselytize_values, target, target_type, user, silent))
if(!fabricate_checks(fabrication_values, target, target_type, user, silent))
return FALSE
proselytize_values["operation_time"] *= speed_multiplier
fabrication_values["operation_time"] *= speed_multiplier
playsound(target, 'sound/machines/click.ogg', 50, 1)
if(proselytize_values["operation_time"])
if(fabrication_values["operation_time"])
if(!silent)
user.visible_message("<span class='warning'>[user]'s [name] begins tearing apart [target]!</span>", "<span class='brass'>You begin proselytizing [target]...</span>")
if(!do_after(user, proselytize_values["operation_time"], target = target, extra_checks = CALLBACK(src, .proc/proselytize_checks, proselytize_values, target, target_type, user, TRUE)))
var/atom/A = fabrication_values["new_obj_type"]
if(A)
user.visible_message("<span class='warning'>[user]'s [name] starts ripping [target] apart!</span>", \
"<span class='brass'>You start fabricating \a [initial(A.name)] from [target]...</span>")
else
user.visible_message("<span class='warning'>[user]'s [name] starts consuming [target]!</span>", \
"<span class='brass'>Your [name] starts consuming [target]...</span>")
if(!do_after(user, fabrication_values["operation_time"], target = target, extra_checks = CALLBACK(src, .proc/fabricate_checks, fabrication_values, target, target_type, user, TRUE)))
return FALSE
if(!silent)
user.visible_message("<span class='warning'>[user]'s [name] covers [target] in golden energy!</span>", "<span class='brass'>You proselytize [target].</span>")
var/atom/A = fabrication_values["new_obj_type"]
if(A)
user.visible_message("<span class='warning'>[user]'s [name] replaces [target] with \a [initial(A.name)]!</span>", \
"<span class='brass'>You fabricate \a [initial(A.name)] from [target].</span>")
else
user.visible_message("<span class='warning'>[user]'s [name] consumes [target]!</span>", \
"<span class='brass'>Your [name] consumes [target].</span>")
else
if(!silent)
user.visible_message("<span class='warning'>[user]'s [name] tears apart [target], covering it in golden energy!</span>", "<span class='brass'>You proselytize [target].</span>")
var/atom/A = fabrication_values["new_obj_type"]
if(A)
user.visible_message("<span class='warning'>[user]'s [name] rips apart [target], replacing it with \a [initial(A.name)]!</span>", \
"<span class='brass'>You fabricate \a [initial(A.name)] from [target].</span>")
else
user.visible_message("<span class='warning'>[user]'s [name] rapidly consumes [target]!</span>", \
"<span class='brass'>Your [name] consumes [target].</span>")
playsound(target, 'sound/items/Deconstruct.ogg', 50, 1)
var/new_thing_type = proselytize_values["new_obj_type"]
var/new_thing_type = fabrication_values["new_obj_type"]
if(isturf(target)) //if our target is a turf, we're just going to ChangeTurf it and assume it'll work out.
var/turf/T = target
T.ChangeTurf(new_thing_type)
else
if(new_thing_type)
if(proselytize_values["dir_in_new"])
new new_thing_type(get_turf(target), proselytize_values["spawn_dir"]) //please verify that your new object actually wants to get a dir in New()
if(fabrication_values["dir_in_new"])
new new_thing_type(get_turf(target), fabrication_values["spawn_dir"]) //please verify that your new object actually wants to get a dir in New()
else
var/atom/A = new new_thing_type(get_turf(target))
A.setDir(proselytize_values["spawn_dir"])
if(!proselytize_values["no_target_deletion"]) //for some cases where proselytize_vals() modifies the object but doesn't want it deleted
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(-proselytize_values["power_cost"])
modify_stored_power(-fabrication_values["power_cost"])
if(no_table_check)
return TRUE
return FALSE
@@ -250,28 +263,34 @@
//What these procs do is they take an existing list of values, which they then modify.
//This(modifying an existing object, in this case the list) is the only way to get information OUT of a do_after callback, which this is used as.
//The proselytize check proc.
/obj/item/clockwork/clockwork_proselytizer/proc/proselytize_checks(list/proselytize_values, atom/target, expected_type, mob/user, silent) //checked constantly while proselytizing
if(!islist(proselytize_values) || QDELETED(target) || QDELETED(user))
//The fabricate check proc.
/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)
return FALSE
if(target.type != expected_type)
return FALSE
if(can_use_power(RATVAR_POWER_CHECK))
proselytize_values["power_cost"] = 0
if(!can_use_power(proselytize_values["power_cost"]))
if(stored_power - proselytize_values["power_cost"] < 0)
fabrication_values["power_cost"] = 0
if(!can_use_power(fabrication_values["power_cost"]))
if(stored_power - fabrication_values["power_cost"] < 0)
if(!silent)
to_chat(user, "<span class='warning'>You need <b>[proselytize_values["power_cost"]]W</b> power to proselytize [target]!</span>")
else if(stored_power - proselytize_values["power_cost"] > max_power)
var/atom/A = fabrication_values["new_obj_type"]
if(A)
to_chat(user, "<span class='warning'>You need <b>[fabrication_values["power_cost"]]W</b> power to fabricate \a [initial(A.name)] from [target]!</span>")
else if(stored_power - fabrication_values["power_cost"] > max_power)
if(!silent)
to_chat(user, "<span class='warning'>Your [name] contains too much power to proselytize [target]!</span>")
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
//The repair check proc.
/obj/item/clockwork/clockwork_proselytizer/proc/proselytizer_repair_checks(list/repair_values, atom/target, mob/user, silent) //Exists entirely to avoid an otherwise unreadable series of checks.
/obj/item/clockwork/replica_fabricator/proc/fabricator_repair_checks(list/repair_values, atom/target, mob/user, silent) //Exists entirely to avoid an otherwise unreadable series of checks.
if(!islist(repair_values) || QDELETED(target) || QDELETED(user))
return FALSE
if(isliving(target)) //standard checks for if we can affect the target
@@ -302,7 +321,7 @@
return FALSE
if(repair_values["amount_to_heal"] <= 0) //nothing to heal!
return FALSE
repair_values["healing_for_cycle"] = min(repair_values["amount_to_heal"], PROSELYTIZER_REPAIR_PER_TICK) //modify the healing for this cycle
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(!silent)
@@ -312,7 +331,7 @@
return TRUE
//The sigil charge check proc.
/obj/item/clockwork/clockwork_proselytizer/proc/sigil_charge_checks(list/charge_values, obj/effect/clockwork/sigil/transmission/sigil, mob/user, silent)
/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))
@@ -120,7 +120,7 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
if(multiple_invokers_used && !multiple_invokers_optional && !GLOB.ratvar_awakens && !slab.no_cost)
var/nearby_servants = 0
for(var/mob/living/L in range(1, get_turf(invoker)))
if(is_servant_of_ratvar(L) && L.stat == CONSCIOUS && L.can_speak_vocal())
if(can_recite_scripture(L))
nearby_servants++
if(nearby_servants < invokers_required)
to_chat(invoker, "<span class='warning'>There aren't enough non-mute servants nearby ([nearby_servants]/[invokers_required])!</span>")
@@ -170,7 +170,7 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
if(!channel_time && invocations.len)
if(multiple_invokers_used)
for(var/mob/living/L in range(1, invoker))
if(is_servant_of_ratvar(L) && L.stat == CONSCIOUS && L.can_speak_vocal())
if(can_recite_scripture(L))
for(var/invocation in invocations)
clockwork_say(L, text2ratvar(invocation), whispered)
else
@@ -185,7 +185,7 @@ Judgement: 12 servants, 5 caches, 300 CV, and any existing AIs are converted or
return FALSE
if(multiple_invokers_used)
for(var/mob/living/L in range(1, get_turf(invoker)))
if(is_servant_of_ratvar(L) && L.stat == CONSCIOUS && L.can_speak_vocal())
if(can_recite_scripture(L))
clockwork_say(L, text2ratvar(invocation), whispered)
else
clockwork_say(invoker, text2ratvar(invocation), whispered)
@@ -53,7 +53,7 @@
/datum/clockwork_scripture/fellowship_armory/run_scripture()
for(var/mob/living/L in orange(1, invoker))
if(is_servant_of_ratvar(L) && L.stat == CONSCIOUS && L.can_speak_vocal())
if(can_recite_scripture(L))
channel_time = max(channel_time - 10, 0)
return ..()
@@ -105,11 +105,11 @@
descname = "Global Structure Buff"
name = "Invoke Nezbere, the Brass Eidolon"
desc = "Taps the limitless power of Nezbere, one of Ratvar's four generals. The restless toil of the Eidolon will empower a wide variety of clockwork apparatus for a full minute - notably, \
clockwork proselytizers will charge very rapidly."
replica fabricators will charge very rapidly."
invocations = list("I call upon you, Armorer!!", "Let your machinations reign on this miserable station!!", "Let your power flow through the tools of your master!!")
channel_time = 150
consumed_components = list(BELLIGERENT_EYE = 6, VANGUARD_COGWHEEL = 6, GEIS_CAPACITOR = 6, REPLICANT_ALLOY = 10)
usage_tip = "Ocular wardens will become empowered, clockwork proselytizers will require no alloy, tinkerer's daemons will produce twice as quickly, \
usage_tip = "Ocular wardens will become empowered, tinkerer's daemons will produce twice as quickly, \
and interdiction lenses, mania motors, tinkerer's daemons, and clockwork obelisks will all require no power."
tier = SCRIPTURE_REVENANT
primary_component = REPLICANT_ALLOY
@@ -33,7 +33,7 @@
/datum/clockwork_scripture/create_object/cogscarab
descname = "Constructor Soul Vessel Shell"
name = "Cogscarab"
desc = "Creates a small shell fitted for soul vessels. Adding an active soul vessel to it results in a small construct with tools and an inbuilt proselytizer."
desc = "Creates a small shell fitted for soul vessels. Adding an active soul vessel to it results in a small construct with tools and an inbuilt fabricator."
invocations = list("Call forth...", "...the workers of Armorer.")
channel_time = 60
consumed_components = list(BELLIGERENT_EYE = 2, HIEROPHANT_ANSIBLE = 1)
@@ -221,24 +221,24 @@
quickbind_desc = "Creates a Soul Vessel, which can be placed in construct shells and cyborg bodies once filled."
//Clockwork Proselytizer: Creates a clockwork proselytizer, used to convert objects and repair clockwork structures.
/datum/clockwork_scripture/create_object/clockwork_proselytizer
descname = "Converts Objects to Ratvarian"
name = "Clockwork Proselytizer"
desc = "Forms a device that, when used on certain objects, converts them into their Ratvarian equivalents. It requires power to function."
//Replica Fabricator: Creates a replica fabricator, used to convert objects and repair clockwork structures.
/datum/clockwork_scripture/create_object/replica_fabricator
descname = "Replaces Objects with Ratvarian Versions"
name = "Replica Fabricator"
desc = "Forms a device that, when used on certain objects, replaces them with their Ratvarian equivalents. It requires power to function."
invocations = list("With this device...", "...his presence shall be made known.")
channel_time = 20
consumed_components = list(GEIS_CAPACITOR = 1, REPLICANT_ALLOY = 2)
whispered = TRUE
object_path = /obj/item/clockwork/clockwork_proselytizer/preloaded
creator_message = "<span class='brass'>You form a clockwork proselytizer.</span>"
usage_tip = "Clockwork Walls cause nearby tinkerer's caches to generate components passively, making them a vital tool. Clockwork Floors heal toxin damage in Servants standing on them."
object_path = /obj/item/clockwork/replica_fabricator/preloaded
creator_message = "<span class='brass'>You form a replica fabricator.</span>"
usage_tip = "Clockwork Walls cause nearby Tinkerer's Caches to generate components passively, making this a vital tool. Clockwork Floors heal toxin damage in Servants standing on them."
tier = SCRIPTURE_SCRIPT
space_allowed = TRUE
primary_component = REPLICANT_ALLOY
sort_priority = 7
quickbind = TRUE
quickbind_desc = "Creates a Clockwork Proselytizer, which can convert various objects to Ratvarian variants."
quickbind_desc = "Creates a Replica Fabricator, which can convert various objects to Ratvarian variants."
//Function Call: Grants the invoker the ability to call forth a Ratvarian spear that deals significant damage to silicons.
@@ -9,7 +9,7 @@
anchored = 1
density = 1
resistance_flags = FIRE_PROOF | ACID_PROOF
var/can_be_repaired = TRUE //if a proselytizer can repair it
var/can_be_repaired = TRUE //if a fabricator can repair it
break_message = "<span class='warning'>The frog isn't a meme after all!</span>" //The message shown when a structure breaks
break_sound = 'sound/magic/clockwork/anima_fragment_death.ogg' //The sound played when a structure breaks
debris = list(/obj/item/clockwork/alloy_shards/large = 1, \
@@ -34,7 +34,7 @@
/obj/structure/destructible/clockwork/shell/cogscarab
name = "cogscarab shell"
desc = "A small brass shell with a cube-shaped receptable in its center. It gives off an aura of obsessive perfectionism."
clockwork_desc = "A dormant receptable that, when powered with a soul vessel, will become a weak construct with an inbuilt proselytizer."
clockwork_desc = "A dormant receptable that, when powered with a soul vessel, will become a weak construct with an inbuilt fabricator."
icon_state = "clockdrone_shell"
mobtype = /mob/living/simple_animal/drone/cogscarab
spawn_message = "'s eyes blink open, glowing bright red."
@@ -14,7 +14,7 @@
light_color = "#BE8700"
var/atom/prey //Whatever Ratvar is chasing
var/clashing = FALSE //If Ratvar is FUCKING FIGHTING WITH NAR-SIE
var/proselytize_range = 10
var/convert_range = 10
dangerous_possession = TRUE
/obj/structure/destructible/clockwork/massive/ratvar/Initialize()
@@ -58,10 +58,10 @@
/obj/structure/destructible/clockwork/massive/ratvar/process()
if(clashing) //I'm a bit occupied right now, thanks
return
for(var/I in circlerangeturfs(src, proselytize_range))
for(var/I in circlerangeturfs(src, convert_range))
var/turf/T = I
T.ratvar_act()
for(var/I in circleviewturfs(src, round(proselytize_range * 0.5)))
for(var/I in circleviewturfs(src, round(convert_range * 0.5)))
var/turf/T = I
T.ratvar_act(TRUE)
var/dir_to_step_in = pick(GLOB.cardinal)
+9 -3
View File
@@ -53,7 +53,6 @@
/datum/game_mode/cult/pre_setup()
cult_objectives += "sacrifice"
cult_objectives += "eldergod"
if(config.protect_roles_from_antagonist)
restricted_jobs += protected_jobs
@@ -102,6 +101,13 @@
GLOB.sac_image = reshape
else
message_admins("Cult Sacrifice: Could not find unconvertable or convertable target. WELP!")
if(!GLOB.summon_spots.len)
while(GLOB.summon_spots.len < SUMMON_POSSIBILITIES)
var/area/summon = pick(GLOB.sortedAreas - GLOB.summon_spots)
if((summon.z == ZLEVEL_STATION) && summon.valid_territory)
GLOB.summon_spots += summon
cult_objectives += "eldergod"
for(var/datum/mind/cult_mind in cultists_to_cult)
equip_cultist(cult_mind.current)
update_cult_icons_added(cult_mind)
@@ -239,11 +245,11 @@
SSblackbox.add_details("cult_objective","cult_sacrifice|FAIL")
if("eldergod")
if(!eldergod)
explanation = "Summon Nar-Sie. <span class='greenannounce'>Success!</span>"
explanation = "Summon Nar-Sie. The summoning can only be accomplished in [english_list(GLOB.summon_spots)].<span class='greenannounce'>Success!</span>"
SSblackbox.add_details("cult_objective","cult_narsie|SUCCESS")
SSticker.news_report = CULT_SUMMON
else
explanation = "Summon Nar-Sie. <span class='boldannounce'>Fail.</span>"
explanation = "Summon Nar-Sie. The summoning can only be accomplished in [english_list(GLOB.summon_spots)]<span class='boldannounce'>Fail.</span>"
SSblackbox.add_details("cult_objective","cult_narsie|FAIL")
SSticker.news_report = CULT_FAILURE
+88
View File
@@ -300,3 +300,91 @@
B.current.client.images -= GLOB.blood_target_image
QDEL_NULL(GLOB.blood_target_image)
GLOB.blood_target = null
//////// ELDRITCH PULSE /////////
/datum/action/innate/cult/master/pulse
name = "Eldritch Pulse"
desc = "Seize upon a fellow cultist or cult structure and teleport it to a nearby location."
button_icon_state = "arcane_barrage"
var/obj/effect/proc_holder/pulse/PM
var/cooldown = 0
var/base_cooldown = 150
var/throwing = FALSE
var/mob/living/throwee
/datum/action/innate/cult/master/pulse/New()
PM = new()
PM.attached_action = src
..()
/datum/action/innate/cult/master/pulse/IsAvailable()
if(!owner.mind || !owner.mind.has_antag_datum(ANTAG_DATUM_CULT_MASTER))
return FALSE
if(cooldown > world.time)
if(!PM.active)
owner << "<span class='cultlarge'><b>You need to wait [round((cooldown - world.time) * 0.1)] seconds before you can pulse again!</b></span>"
return FALSE
return ..()
/datum/action/innate/cult/master/pulse/Destroy()
QDEL_NULL(PM)
return ..()
/datum/action/innate/cult/master/pulse/Activate()
PM.toggle(owner) //the important bit
return TRUE
/obj/effect/proc_holder/pulse
active = FALSE
ranged_mousepointer = 'icons/effects/throw_target.dmi'
var/datum/action/innate/cult/master/pulse/attached_action
/obj/effect/proc_holder/pulse/Destroy()
QDEL_NULL(attached_action)
return ..()
/obj/effect/proc_holder/pulse/proc/toggle(mob/user)
if(active)
remove_ranged_ability("<span class='cult'>You cease your preparations...</span>")
attached_action.throwing = FALSE
else
add_ranged_ability(user, "<span class='cult'>You prepare to tear through the fabric of reality...</span>")
/obj/effect/proc_holder/pulse/InterceptClickOn(mob/living/caller, params, atom/target)
if(..())
return
if(ranged_ability_user.incapacitated())
remove_ranged_ability()
return
var/turf/T = get_turf(ranged_ability_user)
if(!isturf(T))
return FALSE
if(target in view(7, get_turf(ranged_ability_user)))
if((!(iscultist(target) || istype(target, /obj/structure/destructible/cult)) || target == caller) && !(attached_action.throwing))
return
if(!attached_action.throwing)
attached_action.throwing = TRUE
attached_action.throwee = target
ranged_ability_user << 'sound/weapons/thudswoosh.ogg'
to_chat(ranged_ability_user,"<span class='cult'><b>You reach through the veil with your mind's eye and seize [target]!</b></span>")
return
else
new /obj/effect/temp_visual/cult/sparks(get_turf(attached_action.throwee), ranged_ability_user.dir)
var/distance = get_dist(attached_action.throwee, target)
if(distance >= 16)
return
playsound(target,'sound/magic/exit_blood.ogg')
attached_action.throwee.Beam(target,icon_state="sendbeam",time=4)
attached_action.throwee.forceMove(get_turf(target))
new /obj/effect/temp_visual/cult/sparks(get_turf(target), ranged_ability_user.dir)
attached_action.throwing = FALSE
attached_action.cooldown = world.time + attached_action.base_cooldown
remove_mousepointer(ranged_ability_user.client)
remove_ranged_ability("<span class='cult'>A pulse of blood magic surges through you as you shift [attached_action.throwee] through time and space.</span>")
caller.update_action_buttons_icon()
addtimer(CALLBACK(caller, /mob.proc/update_action_buttons_icon), attached_action.base_cooldown)
+4 -1
View File
@@ -381,7 +381,7 @@
on_damage = 15
slot_flags = null
on = 1
var/charges = 3
var/charges = 5
/obj/item/device/flashlight/flare/culttorch/afterattack(atom/movable/A, mob/user, proximity)
if(!proximity)
@@ -408,6 +408,9 @@
to_chat(user, "<span class='cultitalic'>[cultist_to_receive] is not a follower of the Geometer!</span>")
log_game("Void torch failed - target was deconverted")
return
if(A in user.GetAllContents())
to_chat(user, "<span class='cultitalic'>[A] must be on a surface in order to teleport it!</span>")
return
to_chat(user, "<span class='cultitalic'>You ignite [A] with \the [src], turning it to ash, but through the torch's flames you see that [A] has reached [cultist_to_receive]!")
cultist_to_receive.put_in_hands(A)
charges--
+4 -9
View File
@@ -206,8 +206,8 @@ This file contains the arcane tome files.
if(!SSticker.mode.eldergod)
to_chat(user, "<span class='cultlarge'>\"I am already here. There is no need to try to summon me now.\"</span>")
return
if((loc.z && loc.z != ZLEVEL_STATION) || !A.blob_allowed)
to_chat(user, "<span class='warning'>The Geometer is not interested in lesser locations; the station is the prize!</span>")
if(!(A in GLOB.summon_spots))
to_chat(user, "<span class='cultlarge'>The Geometer can only be summoned where the veil is weak - in [english_list(GLOB.summon_spots)]!</span>")
return
var/confirm_final = alert(user, "This is the FINAL step to summon Nar-Sie; it is a long, painful ritual and the crew will be alerted to your presence", "Are you prepared for the final battle?", "My life for Nar-Sie!", "No")
if(confirm_final == "No")
@@ -215,7 +215,8 @@ This file contains the arcane tome files.
return
Turf = get_turf(user)
A = get_area(src)
if(!check_rune_turf(Turf, user) || (loc.z && loc.z != ZLEVEL_STATION)|| !A.blob_allowed)
if(!(A in GLOB.summon_spots)) // Check again to make sure they didn't move
to_chat(user, "<span class='cultlarge'>The Geometer can only be summoned where the veil is weak - in [english_list(GLOB.summon_spots)]!</span>")
return
priority_announce("Figments from an eldritch god are being summoned by [user] into [A.map_name] from an unknown dimension. Disrupt the ritual at all costs!","Central Command Higher Dimensional Affairs", 'sound/AI/spanomalies.ogg')
for(var/B in spiral_range_turfs(1, user, 1))
@@ -248,8 +249,6 @@ This file contains the arcane tome files.
SSblackbox.add_details("cult_runes_scribed", R.cultist_name)
/obj/item/weapon/tome/proc/check_rune_turf(turf/T, mob/user)
var/area/A = get_area(T)
if(isspaceturf(T))
to_chat(user, "<span class='warning'>You cannot scribe runes in space!</span>")
return FALSE
@@ -262,8 +261,4 @@ This file contains the arcane tome files.
to_chat(user, "<span class='warning'>The veil is not weak enough here.")
return FALSE
if(istype(A, /area/shuttle))
to_chat(user, "<span class='warning'>Interference from hyperspace engines disrupts the Geometer's power on shuttles.</span>")
return FALSE
return TRUE
+2 -2
View File
@@ -446,7 +446,7 @@ structure_check() searches for nearby cultist structures required for the invoca
icon_state = "rune_large"
pixel_x = -32 //So the big ol' 96x96 sprite shows up right
pixel_y = -32
scribe_delay = 450 //how long the rune takes to create
scribe_delay = 500 //how long the rune takes to create
scribe_damage = 40.1 //how much damage you take doing it
var/used = FALSE
@@ -631,7 +631,7 @@ structure_check() searches for nearby cultist structures required for the invoca
/obj/effect/rune/spirit/examine(mob/user)
..()
if(affecting)
to_chat(user, "<span class='cultitalic'>A translucent field encases [user] above the rune!</span>")
to_chat(user, "<span class='cultitalic'>A translucent field encases [affecting] above the rune!</span>")
/obj/effect/rune/spirit/can_invoke(mob/living/user)
if(rune_in_use)
+1 -1
View File
@@ -9,7 +9,7 @@
S.update_icon()
S.power_change()
var/list/skipped_areas = list(/area/engine/engineering, /area/ai_monitored/turret_protected/ai)
var/list/skipped_areas = list(/area/engine/engineering, /area/engine/supermatter, /area/engine/atmospherics_engine, /area/ai_monitored/turret_protected/ai)
for(var/area/A in world)
if( !A.requires_power || A.always_unpowered )
+51 -16
View File
@@ -80,22 +80,20 @@
report = config.intercept
addtimer(CALLBACK(GLOBAL_PROC, .proc/display_roundstart_logout_report), ROUNDSTART_LOGOUT_REPORT_TIME)
if(SSdbcore.Connect())
var/sql
if(SSticker && SSticker.mode)
sql += "game_mode = '[SSticker.mode]'"
if(sql)
sql += ", "
if(GLOB.revdata.commit)
sql += "commit_hash = '[GLOB.revdata.commit]'"
if(sql)
var/datum/DBQuery/query_round_game_mode = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET [sql] WHERE id = [GLOB.round_id]")
query_round_game_mode.Execute()
if(SSdbcore.Connect())
var/sql
if(SSticker && SSticker.mode)
sql += "game_mode = '[SSticker.mode]'"
if(GLOB.revdata.originmastercommit)
if(sql)
sql += ", "
sql += "commit_hash = '[GLOB.revdata.originmastercommit]'"
if(sql)
var/datum/DBQuery/query_round_game_mode = SSdbcore.NewQuery("UPDATE [format_table_name("round")] SET [sql] WHERE id = [GLOB.round_id]")
query_round_game_mode.Execute()
if(report)
addtimer(CALLBACK(src, .proc/send_intercept, 0), rand(waittime_l, waittime_h))
generate_station_goals()
GLOB.start_state = new /datum/station_state()
GLOB.start_state.count(1)
return 1
@@ -239,11 +237,11 @@
if(ishuman(M))
if(!M.stat)
surviving_humans++
if(M.z == ZLEVEL_CENTCOM)
if(M.z == ZLEVEL_CENTCOM)
escaped_humans++
if(!M.stat)
surviving_total++
if(M.z == ZLEVEL_CENTCOM)
if(M.z == ZLEVEL_CENTCOM)
escaped_total++
@@ -265,6 +263,43 @@
send2irc("Server", "Round just ended.")
if(cult.len && !istype(SSticker.mode,/datum/game_mode/cult))
datum_cult_completion()
if(GLOB.borers.len)
var/borerwin = FALSE
var/borertext = "<br><font size=3><b>The borers were:</b></font>"
for(var/mob/living/simple_animal/borer/B in GLOB.borers)
if((B.key || B.controlling) && B.stat != DEAD)
borertext += "<br>[B.controlling ? B.victim.key : B.key] was [B.truename] ("
var/turf/location = get_turf(B)
if(location.z == ZLEVEL_CENTCOM && B.victim)
borertext += "escaped with host"
else
borertext += "failed"
borertext += ")"
to_chat(world, borertext)
var/total_borers = 0
for(var/mob/living/simple_animal/borer/B in GLOB.borers)
if((B.key || B.victim) && B.stat != DEAD)
total_borers++
if(total_borers)
var/total_borer_hosts = 0
for(var/mob/living/carbon/C in GLOB.mob_list)
var/mob/living/simple_animal/borer/D = C.has_brain_worms()
var/turf/location = get_turf(C)
if(location.z == ZLEVEL_CENTCOM && D && D.stat != DEAD)
total_borer_hosts++
if(GLOB.total_borer_hosts_needed <= total_borer_hosts)
borerwin = TRUE
to_chat(world, "<b>There were [total_borers] borers alive at round end!</b>")
to_chat(world, "<b>A total of [total_borer_hosts] borers with hosts escaped on the shuttle alive. The borers needed [GLOB.total_borer_hosts_needed] hosts to escape.</b>")
if(borerwin)
to_chat(world, "<b><font color='green'>The borers were successful!</font></b>")
else
to_chat(world, "<b><font color='red'>The borers have failed!</font></b>")
CHECK_TICK
return 0
@@ -565,4 +600,4 @@
/datum/game_mode/proc/declare_station_goal_completion()
for(var/V in station_goals)
var/datum/station_goal/G = V
G.print_result()
G.print_result()
+4
View File
@@ -1,5 +1,6 @@
#define DOM_BLOCKED_SPAM_CAP 6
#define DOM_REQUIRED_TURFS 30
#define DOM_HULK_HITS_REQUIRED 10
/obj/machinery/dominator
name = "dominator"
@@ -20,6 +21,9 @@
var/datum/effect_system/spark_spread/spark_system
var/obj/effect/countdown/dominator/countdown
/obj/machinery/dominator/hulk_damage()
return (max_integrity - integrity_failure) / DOM_HULK_HITS_REQUIRED
/proc/dominator_excessive_walls(atom/A)
var/open = 0
for(var/turf/T in view(3, A))
+12 -2
View File
@@ -62,7 +62,7 @@ GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/
for(var/n in 1 to 3)
var/datum/mind/boss = pick(antag_candidates)
antag_candidates -= boss
G.bosses += boss
G.bosses[boss] = GANGSTER_BOSS_STARTING_INFLUENCE
boss.gang_datum = G
var/title
if(n == 1)
@@ -85,6 +85,7 @@ GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/
sleep(rand(10,100))
for(var/datum/gang/G in gangs)
for(var/datum/mind/boss_mind in G.bosses)
G.bosses[boss_mind] = GANGSTER_BOSS_STARTING_INFLUENCE //Force influence to be put on it.
G.add_gang_hud(boss_mind)
forge_gang_objectives(boss_mind)
greet_gang(boss_mind)
@@ -170,7 +171,7 @@ GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/
return 0
if(check && gangster_mind.current.isloyal()) //Check to see if the potential gangster is implanted
return 1
G.gangsters += gangster_mind
G.gangsters[gangster_mind] = GANGSTER_SOLDIER_STARTING_INFLUENCE
gangster_mind.gang_datum = G
if(check)
if(iscarbon(gangster_mind.current))
@@ -209,15 +210,24 @@ GLOBAL_LIST_INIT(gang_outfit_pool, list(/obj/item/clothing/suit/jacket/leather,/
if(!G.is_deconvertible && !remove_bosses)
return 0
if(gangster_mind in G.gangsters)
G.reclaim_points(G.gangsters[gangster_mind])
G.gangsters -= gangster_mind
removed = 1
if(remove_bosses && (gangster_mind in G.bosses))
G.reclaim_points(G.bosses[gangster_mind])
G.bosses -= gangster_mind
removed = 1
if(G.tags_by_mind[gangster_mind] && islist(G.tags_by_mind[gangster_mind]))
var/list/tags_cache = G.tags_by_mind[gangster_mind]
for(var/v in tags_cache)
var/obj/effect/decal/cleanable/crayon/gang/c = v
c.set_mind_owner(null)
G.tags_by_mind -= gangster_mind
if(!removed)
return 0
gangster_mind.special_role = null
gangster_mind.gang_datum = null
+87 -43
View File
@@ -8,6 +8,7 @@
var/list/datum/mind/gangsters = list() //gang B Members
var/list/datum/mind/bosses = list() //gang A Bosses
var/list/obj/item/device/gangtool/gangtools = list()
var/list/tags_by_mind = list() //Assoc list in format of tags_by_mind[mind_of_gangster] = list(tag1, tag2, tag3) where tags are the actual object decals.
var/style
var/fighting_style = "normal"
var/list/territory = list()
@@ -75,7 +76,7 @@
/datum/gang_item/clothing/hands,
/datum/gang_item/clothing/belt,
/datum/gang_item/weapon/shuriken,
/datum/gang_item/weapon/shuriken,
/datum/gang_item/weapon/switchblade,
/datum/gang_item/weapon/improvised,
/datum/gang_item/weapon/ammo/improvised_ammo,
@@ -202,9 +203,9 @@
return
var/added_names = ""
var/lost_names = ""
SSticker.mode.shuttle_check() // See if its time to start wrapping things up
//Re-add territories that were reclaimed, so if they got tagged over, they can still earn income if they tag it back before the next status report
var/list/reclaimed_territories = territory_new & territory_lost
territory |= reclaimed_territories
@@ -245,47 +246,90 @@
set_domination_time(new_time)
message += "<b>[seconds_remaining] seconds remain</b> in hostile takeover.<BR>"
else
for(var/obj/item/device/gangtool/G in gangtools)
var/pmessage = message
var/points_new = 0
if(istype(G, /obj/item/device/gangtool/soldier))
points_new = max(0,round(3 - G.points/10)) + (sbonus) + (LAZYLEN(G.tags)/2) // Soldier points
pmessage += "Your influence has increased by [round(sbonus)] from your gang holding [LAZYLEN(territory)] territories, and a bonus of [round(LAZYLEN(G.tags)/2)] for territories you have personally marked and kept intact.<BR>"
else
points_new = max(0,round(5 - G.points/10)) + LAZYLEN(territory) // Boss points, more focused on big picture
pmessage += "Your influence has increased by [round(points_new)] from your gang holding [territory.len] territories<BR>"
G.points += points_new
var/mob/living/carbon/human/ganger = get(G.loc, /mob/living)
var/points_newer = 0
var/static/inner = inner_outfit
var/static/outer = outer_outfit
if(ishuman(ganger) && ganger.mind in (gangsters|bosses))
for(var/obj/C in ganger.contents)
if(C.type == inner_outfit)
points_newer += 2
continue
if(C.type == outer_outfit)
points_newer += 2
continue
switch(C.type)
if(/obj/item/clothing/neck/necklace/dope)
points_newer += 2
if(/obj/item/clothing/head/collectable/petehat/gang)
points_newer += 4
if(/obj/item/clothing/shoes/gang)
points_newer += 6
if(/obj/item/clothing/mask/gskull)
points_newer += 5
if(/obj/item/clothing/gloves/gang)
points_newer += 3
if(/obj/item/weapon/storage/belt/military/gang)
points_newer += 4
if(points_newer)
G.points += points_newer
pmessage += "Your influential choice of clothing has further increased your influence by [points_newer] points.<BR>"
pmessage += "You now have <b>[G.points] influence</b>.<BR>"
to_chat(ganger, "<span class='notice'>\icon[G] [pmessage]</span>")
pay_territory_income_to_bosses()
pay_territory_income_to_soldiers(sbonus)
pay_all_clothing_bonuses()
announce_all_influence()
/datum/gang/proc/pay_all_clothing_bonuses()
for(var/datum/mind/mind in gangsters|bosses)
pay_clothing_bonus(mind)
/datum/gang/proc/pay_clothing_bonus(var/datum/mind/gangsta)
var/mob/living/carbon/human/gangbanger = gangsta.current
. = 0
if(!istype(gangbanger) || gangbanger.stat == DEAD) //Dead gangsters aren't influential at all!
return 0
var/static/inner = inner_outfit
var/static/outer = outer_outfit
for(var/obj/item/C in gangbanger.contents)
if(C.type == inner_outfit)
. += 2
continue
else if(C.type == outer_outfit)
. += 2
continue
. += C.gang_contraband_value()
adjust_influence(gangsta, .)
if(.)
announce_to_mind(gangsta, "<span class='notice'>Your influential choice of clothing has increased your influence by [.] points!</span>")
else
announce_to_mind(gangsta, "<span class='warning'>Unfortunately, you have not gained any additional influence from your drab, old, boring clothing. Learn to dress like a gangsta, bro!</span>") //Kek
/datum/gang/proc/pay_soldier_territory_income(datum/mind/soldier, sbonus = 0)
. = 0
. = max(0,round(3 - gangsters[soldier]/10)) + (sbonus) + (get_soldier_territories(soldier)/2)
adjust_influence(soldier, .)
/datum/gang/proc/get_soldier_territories(datum/mind/soldier)
if(!islist(tags_by_mind[soldier])) //They have no tagged territories!
return 0
var/list/tags = tags_by_mind[soldier]
return tags.len
/datum/gang/proc/pay_territory_income_to_soldiers(sbonus = 0)
for(var/datum/mind/soldier in gangsters)
var/returned = pay_soldier_territory_income(soldier)
if(!returned)
announce_to_mind(soldier, "<span class='warning'>You have not gained any influence from territories you personally tagged. Get to work, soldier!</span>")
else
announce_to_mind(soldier, "<span class='notice'>You have gained [returned] influence from [get_soldier_territories(soldier)] territories you have personally tagged.</span>")
/datum/gang/proc/announce_all_influence()
for(var/datum/mind/MG in bosses|gangsters)
announce_total_influence(MG)
/datum/gang/proc/pay_territory_income_to_bosses()
. = 0
for(var/datum/mind/boss_mind in bosses)
var/inc = max(0,round(5 - bosses[boss_mind]/10)) + LAZYLEN(territory)
. += inc
adjust_influence(boss_mind, inc)
announce_to_mind(boss_mind, "<span class='boldnotice'>Your influence has increased by [inc] from your gang holding [LAZYLEN(territory)] territories!</span>")
/datum/gang/proc/get_influence(datum/mind/gangster_mind)
if(gangster_mind in gangsters)
return gangsters[gangster_mind]
if(gangster_mind in bosses)
return bosses[gangster_mind]
/datum/gang/proc/adjust_influence(datum/mind/gangster_mind, amount)
if(gangster_mind in gangsters)
gangsters[gangster_mind] += amount
if(gangster_mind in bosses)
bosses[gangster_mind] += amount
/datum/gang/proc/announce_to_mind(datum/mind/gangster_mind, message)
if(gangster_mind.current && gangster_mind.current.stat != DEAD)
to_chat(gangster_mind.current, message)
/datum/gang/proc/announce_total_influence(datum/mind/gangster_mind)
announce_to_mind(gangster_mind, "<span class='boldnotice'>[name] Gang: You now have a total of [get_influence(gangster_mind)] influence!</span>")
/datum/gang/proc/reclaim_points(amount)
for(var/datum/mind/bawss in bosses)
adjust_influence(bawss, amount/bosses.len)
announce_to_mind(bawss, "<span class='notice'>[name] Gang: [amount/bosses.len] influence given from internal automatic restructuring.</span>")
//Multiverse
+33 -14
View File
@@ -11,7 +11,7 @@
if(check_canbuy && !can_buy(user, gang, gangtool))
return FALSE
var/real_cost = get_cost(user, gang, gangtool)
gangtool.points -= real_cost
gang.adjust_influence(user.mind, -real_cost)
spawn_item(user, gang, gangtool)
return TRUE
@@ -23,7 +23,7 @@
to_chat(user, spawn_msg)
/datum/gang_item/proc/can_buy(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool)
return gang && (gangtool.points >= get_cost(user, gang, gangtool)) && can_see(user, gang, gangtool)
return gang && (gang.get_influence(user.mind) >= get_cost(user, gang, gangtool)) && can_see(user, gang, gangtool)
/datum/gang_item/proc/can_see(mob/living/carbon/user, datum/gang/gang, obj/item/device/gangtool/gangtool)
return TRUE
@@ -111,17 +111,20 @@
/datum/gang_item/clothing/hat
name = "Pimp Hat"
id = "hat"
cost = 18
cost = 16
item_path = /obj/item/clothing/head/collectable/petehat/gang
/obj/item/clothing/head/collectable/petehat/gang
name = "pimpin' hat"
desc = "The undisputed king of style."
/obj/item/clothing/head/collectable/petehat/gang/gang_contraband_value()
return 4
/datum/gang_item/clothing/mask
name = "Golden Death Mask"
id = "mask"
cost = 20
cost = 18
item_path = /obj/item/clothing/mask/gskull
/obj/item/clothing/mask/gskull
@@ -129,11 +132,13 @@
icon_state = "gskull"
desc = "Strike terror, and envy, into the hearts of your enemies."
/obj/item/clothing/mask/gskull/gang_contraband_value()
return 5
/datum/gang_item/clothing/shoes
name = "Bling Boots"
id = "boots"
cost = 25
cost = 22
item_path = /obj/item/clothing/shoes/gang
/obj/item/clothing/shoes/gang
@@ -141,17 +146,19 @@
desc = "Stand aside peasants."
icon_state = "bling"
/obj/item/clothing/shoes/gang/gang_contraband_value()
return 6
/datum/gang_item/clothing/neck
name = "Gold Necklace"
id = "necklace"
cost = 10
cost = 9
item_path = /obj/item/clothing/neck/necklace/dope
/datum/gang_item/clothing/hands
name = "Decorative Brass Knuckles"
id = "hand"
cost = 12
cost = 11
item_path = /obj/item/clothing/gloves/gang
/obj/item/clothing/gloves/gang
@@ -160,10 +167,13 @@
icon_state = "knuckles"
w_class = 3
/obj/item/clothing/gloves/gang/gang_contraband_value()
return 3
/datum/gang_item/clothing/belt
name = "Badass Belt"
id = "belt"
cost = 15
cost = 13
item_path = /obj/item/weapon/storage/belt/military/gang
/obj/item/weapon/storage/belt/military/gang
@@ -173,7 +183,8 @@
desc = "The belt buckle simply reads 'BAMF'."
storage_slots = 1
/obj/item/weapon/storage/belt/military/gang/gang_contraband_value()
return 4
///////////////////
//WEAPONS
@@ -236,16 +247,24 @@
item_path = /obj/item/ammo_box/magazine/m10mm
/datum/gang_item/weapon/sniper
name = ".50cal Sniper Rifle"
name = "Black Market .50cal Sniper Rifle"
id = "sniper"
cost = 40
item_path = /obj/item/weapon/gun/ballistic/automatic/sniper_rifle
item_path = /obj/item/weapon/gun/ballistic/automatic/sniper_rifle/gang
/datum/gang_item/weapon/ammo/sniper_ammo
name = "Standard .50cal Sniper Rounds"
name = "Smuggled .50cal Sniper Rounds"
id = "sniper_ammo"
cost = 15
item_path = /obj/item/ammo_box/magazine/sniper_rounds
item_path = /obj/item/ammo_box/magazine/sniper_rounds/gang
/datum/gang_item/weapon/ammo/sleeper_ammo
name = "Illicit Tranquilizer Cartridges"
id = "sniper_ammo"
cost = 15
item_path = /obj/item/ammo_box/magazine/sniper_rounds/gang/sleeper
/datum/gang_item/weapon/machinegun
name = "Mounted Machine Gun"
+4 -7
View File
@@ -15,7 +15,6 @@
var/outfits = 2
var/free_pen = 0
var/promotable = 0
var/points = 15
var/list/tags = list()
/obj/item/device/gangtool/Initialize() //Initialize supply point income if it hasn't already been started
@@ -50,7 +49,7 @@
var/isboss = (user.mind == gang.bosses[1])
dat += "Registration: <B>[gang.name] Gang [isboss ? "Boss" : "Lieutenant"]</B><br>"
dat += "Organization Size: <B>[gang.gangsters.len + gang.bosses.len]</B> | Station Control: <B>[round((gang.territory.len/GLOB.start_state.num_territories)*100, 1)]%</B><br>"
dat += "Your Influence: <B>[points]</B><br>"
dat += "Your Influence: <B>[gang.get_influence(user.mind)]</B><br>"
dat += "Time until Influence grows: <B>[time2text(SSticker.mode.gang_points.next_point_time - world.time, "mm:ss")]</B><br>"
dat += "<hr>"
@@ -147,8 +146,9 @@
gang.gangtools += src
icon_state = "gangtool-[gang.color]"
if(!(user.mind in gang.bosses))
var/cached_influence = gang.gangsters[user.mind]
SSticker.mode.remove_gangster(user.mind, 0, 2)
gang.bosses += user.mind
gang.bosses[user.mind] = cached_influence
user.mind.gang_datum = gang
user.mind.special_role = "[gang.name] Gang Lieutenant"
gang.add_gang_hud(user.mind)
@@ -246,9 +246,6 @@
///////////// Internal tool used by gang regulars ///////////
/obj/item/device/gangtool/soldier
points = 5
/obj/item/device/gangtool/soldier/New(mob/user)
. = ..()
gang = user.mind.gang_datum
@@ -264,7 +261,7 @@
dat += "<center><font color='red'>Takeover In Progress:<br><B>[gang.domination_time_remaining()] seconds remain</B></font></center>"
dat += "Registration: <B>[gang.name] - Foot Soldier</B><br>"
dat += "Organization Size: <B>[gang.gangsters.len + gang.bosses.len]</B> | Station Control: <B>[round((gang.territory.len/GLOB.start_state.num_territories)*100, 1)]%</B><br>"
dat += "Your Influence: <B>[points]</B><br>"
dat += "Your Influence: <B>[gang.get_influence(user.mind)]</B><br>"
if(LAZYLEN(tags))
dat += "Your tags generate bonus influence for you.<br> You have tagged the following territories:"
for(var/obj/effect/decal/cleanable/crayon/gang/T in tags)
+25 -22
View File
@@ -1,3 +1,4 @@
#define DEFAULT_DOOMSDAY_TIMER 4500
/datum/AI_Module
var/uses = 0
var/module_name
@@ -37,12 +38,13 @@
to_chat(src, "<span class='notice'>Doomsday device armed.</span>")
priority_announce("Hostile runtimes detected in all station systems, please deactivate your AI to prevent possible damage to its morality core.", "Anomaly Alert", 'sound/AI/aimalf.ogg')
set_security_level("delta")
nuking = 1
var/obj/machinery/doomsday_device/DOOM = new /obj/machinery/doomsday_device(src)
nuking = TRUE
var/obj/machinery/doomsday_device/DOOM = new (src)
doomsday_device = DOOM
doomsday_device.start()
verbs -= /mob/living/silicon/ai/proc/nuke_station
for(var/obj/item/weapon/pinpointer/P in GLOB.pinpointer_list)
for(var/pinpointer in GLOB.pinpointer_list)
var/obj/item/weapon/pinpointer/P = pinpointer
P.switch_mode_to(TRACK_MALF_AI) //Pinpointers start tracking the AI wherever it goes
/obj/machinery/doomsday_device
@@ -50,34 +52,32 @@
name = "doomsday device"
icon_state = "nuclearbomb_base"
desc = "A weapon which disintegrates all organic life in a large area."
anchored = 1
density = 1
anchored = TRUE
density = TRUE
verb_exclaim = "blares"
var/timing = FALSE
var/default_timer = 4500
var/obj/effect/countdown/doomsday/countdown
var/detonation_timer
var/list/milestones = list()
var/list/milestones
/obj/machinery/doomsday_device/New()
..()
/obj/machinery/doomsday_device/Initialize()
. = ..()
countdown = new(src)
milestones = list()
/obj/machinery/doomsday_device/Destroy()
if(countdown)
qdel(countdown)
countdown = null
QDEL_NULL(countdown)
STOP_PROCESSING(SSfastprocess, src)
SSshuttle.clearHostileEnvironment(src)
SSmapping.remove_nuke_threat(src)
for(var/A in GLOB.ai_list)
var/mob/living/silicon/ai/Mlf = A
if(Mlf.doomsday_device == src)
Mlf.doomsday_device = null
. = ..()
var/mob/living/silicon/ai/AI = A
if(AI.doomsday_device == src)
AI.doomsday_device = null
return ..()
/obj/machinery/doomsday_device/proc/start()
detonation_timer = world.time + default_timer
detonation_timer = world.time + DEFAULT_DOOMSDAY_TIMER
timing = TRUE
countdown.start()
START_PROCESSING(SSfastprocess, src)
@@ -90,24 +90,24 @@
/obj/machinery/doomsday_device/process()
var/turf/T = get_turf(src)
if(!T || T.z != ZLEVEL_STATION)
minor_announce("DOOMSDAY DEVICE OUT OF STATION RANGE, ABORTING", "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4", 1)
minor_announce("DOOMSDAY DEVICE OUT OF STATION RANGE, ABORTING", "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4", TRUE)
SSshuttle.clearHostileEnvironment(src)
qdel(src)
return
if(!timing)
STOP_PROCESSING(SSfastprocess, src)
return
var/sec_left = seconds_remaining()
if(sec_left <= 0)
if(!sec_left)
timing = FALSE
detonate(T.z)
else
var/key = num2text(sec_left)
if(!(sec_left % 60) && !(key in milestones))
milestones[key] = TRUE
var/message = "[key] SECONDS UNTIL DOOMSDAY DEVICE ACTIVATION!"
minor_announce(message, "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4", 1)
minor_announce("[key] SECONDS UNTIL DOOMSDAY DEVICE ACTIVATION!", "ERROR ER0RR $R0RRO$!R41.%%!!(%$^^__+ @#F0E4", TRUE)
/obj/machinery/doomsday_device/proc/detonate(z_level = 1)
/obj/machinery/doomsday_device/proc/detonate(z_level = ZLEVEL_STATION)
for(var/mob/M in GLOB.player_list)
M << 'sound/machines/Alarm.ogg'
sleep(100)
@@ -604,3 +604,6 @@
eyeobj.relay_speech = TRUE
to_chat(src, "<span class='notice'>OTA firmware distribution complete! Cameras upgraded: Enhanced surveillance package online.</span>")
verbs -= /mob/living/silicon/ai/proc/surveillance
#undef DEFAULT_DOOMSDAY_TIMER
@@ -2,7 +2,6 @@
name = "Human Observation Console"
var/team = 0
networks = list("SS13","Abductor")
off_action = new/datum/action/innate/camera_off/abductor //specific datum
var/datum/action/innate/teleport_in/tele_in_action = new
var/datum/action/innate/teleport_out/tele_out_action = new
var/datum/action/innate/teleport_self/tele_self_action = new
@@ -23,29 +22,37 @@
eyeobj.icon_state = "camera_target"
/obj/machinery/computer/camera_advanced/abductor/GrantActions(mob/living/carbon/user)
off_action.target = user
off_action.Grant(user)
..()
jump_action.target = user
jump_action.Grant(user)
//TODO : add null checks
tele_in_action.target = console.pad
tele_in_action.Grant(user)
if(tele_in_action)
tele_in_action.target = console.pad
tele_in_action.Grant(user)
actions += tele_in_action
tele_out_action.target = console
tele_out_action.Grant(user)
if(tele_out_action)
tele_out_action.target = console
tele_out_action.Grant(user)
actions += tele_out_action
tele_self_action.target = console.pad
tele_self_action.Grant(user)
if(tele_self_action)
tele_self_action.target = console.pad
tele_self_action.Grant(user)
actions += tele_self_action
vest_mode_action.target = console
vest_mode_action.Grant(user)
if(vest_mode_action)
vest_mode_action.target = console
vest_mode_action.Grant(user)
actions += vest_mode_action
vest_disguise_action.target = console
vest_disguise_action.Grant(user)
if(vest_disguise_action)
vest_disguise_action.target = console
vest_disguise_action.Grant(user)
actions += vest_disguise_action
set_droppoint_action.target = console
set_droppoint_action.Grant(user)
if(set_droppoint_action)
set_droppoint_action.target = console
set_droppoint_action.Grant(user)
actions += set_droppoint_action
/obj/machinery/computer/camera_advanced/abductor/proc/IsScientist(mob/living/carbon/human/H)
var/datum/species/abductor/S = H.dna.species
@@ -56,30 +63,6 @@
return
return ..()
/datum/action/innate/camera_off/abductor/Activate()
if(!target || !iscarbon(target))
return
var/mob/living/carbon/C = target
var/mob/camera/aiEye/remote/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/abductor/origin = remote_eye.origin
origin.current_user = null
origin.jump_action.Remove(C)
origin.tele_in_action.Remove(C)
origin.tele_out_action.Remove(C)
origin.tele_self_action.Remove(C)
origin.vest_mode_action.Remove(C)
origin.vest_disguise_action.Remove(C)
origin.set_droppoint_action.Remove(C)
C.reset_perspective(null)
if(C.client)
C.client.images -= remote_eye.user_image
for(var/datum/camerachunk/chunk in remote_eye.visibleCameraChunks)
chunk.remove(remote_eye)
remote_eye.eye_user = null
C.remote_control = null
C.unset_machine()
Remove(C)
/datum/action/innate/teleport_in
name = "Send To"
button_icon_state = "beam_down"
+1 -1
View File
@@ -43,7 +43,7 @@
/datum/objective_item/steal/capmedal
name = "the medal of captaincy"
targetitem = /obj/item/clothing/tie/medal/gold/captain
targetitem = /obj/item/clothing/accessory/medal/gold/captain
difficulty = 5
excludefromjob = list("Captain")
+1 -1
View File
@@ -243,7 +243,7 @@
if(!is_gangster(user))
var/datum/gang/multiverse/G = new(src, "[user.real_name]")
SSticker.mode.gangs += G
G.bosses += user.mind
G.bosses[user.mind] = 0
G.add_gang_hud(user.mind)
user.mind.gang_datum = G
to_chat(user, "<span class='warning'><B>With your new found power you could easily conquer the station!</B></span>")
+1 -2
View File
@@ -106,10 +106,9 @@
name = "Fireball"
spell_type = /obj/effect/proc_holder/spell/aimed/fireball
/*
/datum/spellbook_entry/rod_form
name = "Rod Form"
spell_type = /obj/effect/proc_holder/spell/targeted/rod_form */
spell_type = /obj/effect/proc_holder/spell/targeted/rod_form
/datum/spellbook_entry/magicm
name = "Magic Missile"
+26 -89
View File
@@ -1,56 +1,35 @@
/obj/machinery/ai_slipper
name = "\improper AI liquid dispenser"
name = "foam dispenser"
desc = "A remotely-activatable dispenser for crowd-controlling foam."
icon = 'icons/obj/device.dmi'
icon_state = "ai-slipper0"
layer = PROJECTILE_HIT_THRESHHOLD_LAYER
anchored = 1
anchored = TRUE
obj_integrity = 200
max_integrity = 200
armor = list(melee = 50, bullet = 20, laser = 20, energy = 20, bomb = 0, bio = 0, rad = 0, fire = 50, acid = 30)
var/uses = 20
var/disabled = 1
var/lethal = 0
var/locked = 1
var/cooldown_time = 0
var/cooldown_timeleft = 0
var/cooldown_on = 0
var/cooldown = 0
var/cooldown_time = 100
req_access = list(GLOB.access_ai_upload)
/obj/machinery/ai_slipper/examine(mob/user)
..()
to_chat(user, "<span class='notice'>It has <b>[uses]</b> uses of foam remaining.</span>")
/obj/machinery/ai_slipper/power_change()
if(stat & BROKEN)
return
else
if( powered() )
if(powered())
stat &= ~NOPOWER
else
icon_state = "ai-slipper0"
stat |= NOPOWER
/obj/machinery/ai_slipper/proc/setState(enabled, uses)
src.disabled = disabled
src.uses = uses
src.power_change()
/obj/machinery/ai_slipper/attackby(obj/item/weapon/W, mob/user, params)
if(stat & (NOPOWER|BROKEN))
return
if (issilicon(user))
return src.attack_hand(user)
else // trying to unlock the interface
if (src.allowed(user))
locked = !locked
to_chat(user, "<span class='notice'>You [ locked ? "lock" : "unlock"] the device.</span>")
if (locked)
if (user.machine==src)
user.unset_machine()
user << browse(null, "window=ai_slipper")
else
if (user.machine==src)
src.attack_hand(user)
if((stat & (NOPOWER|BROKEN)) || cooldown_time > world.time || !uses)
icon_state = "ai-slipper0"
else
to_chat(user, "<span class='danger'>Access denied.</span>")
icon_state = "ai-slipper1"
/obj/machinery/ai_slipper/attack_ai(mob/user)
return attack_hand(user)
@@ -58,60 +37,18 @@
/obj/machinery/ai_slipper/attack_hand(mob/user)
if(stat & (NOPOWER|BROKEN))
return
if ( (get_dist(src, user) > 1 ))
if (!(issilicon(user) || IsAdminGhost(user)))
to_chat(user, text("Too far away."))
user.unset_machine()
user << browse(null, "window=ai_slipper")
return
user.set_machine(src)
var/area/A = get_area(src)
var/t = "<TT><B>AI Liquid Dispenser</B> ([format_text(A.name)])<HR>"
if(locked && (!(issilicon(user) || IsAdminGhost(user))))
t += "<I>(Swipe ID card to unlock control panel.)</I><BR>"
else
t += "Dispenser [disabled?"deactivated":"activated"] - <A href='?src=\ref[src];toggleOn=1'>[disabled?"Enable":"Disable"]?</a><br>\n"
t += "Uses Left: [uses]. <A href='?src=\ref[src];toggleUse=1'>Activate the dispenser?</A><br>\n"
user << browse(t, "window=computer;size=575x450")
onclose(user, "computer")
/obj/machinery/ai_slipper/Topic(href, href_list)
if(..())
if(!allowed(user))
to_chat(user, "<span class='danger'>Access denied.</span>")
return
if (src.locked)
if(!(issilicon(usr)|| IsAdminGhost(usr)))
to_chat(usr, "Control panel is locked!")
return
if (href_list["toggleOn"])
src.disabled = !src.disabled
icon_state = src.disabled? "ai-slipper0":"ai-slipper1"
if (href_list["toggleUse"])
if(cooldown_on || disabled)
return
else
new /obj/effect/particle_effect/foam(loc)
src.uses--
cooldown_on = 1
cooldown_time = world.timeofday + 100
slip_process()
return
src.attack_hand(usr)
/obj/machinery/ai_slipper/proc/slip_process()
while(cooldown_time - world.timeofday > 0)
var/ticksleft = cooldown_time - world.timeofday
if(ticksleft > 1e5)
cooldown_time = world.timeofday + 10 // midnight rollover
cooldown_timeleft = (ticksleft / 10)
sleep(5)
if (uses <= 0)
if(!uses)
to_chat(user, "<span class='danger'>[src] is out of foam and cannot be activated.</span>")
return
if(cooldown_time > world.time)
to_chat(user, "<span class='danger'>[src] cannot be activated for another <b>[round((world.time - cooldown_time) * 0.1)]</b> second\s.</span>")
return
if (uses >= 0)
cooldown_on = 0
src.power_change()
new /obj/effect/particle_effect/foam(loc)
uses--
to_chat(user, "<span class='notice'>You activate [src]. It now has <b>[uses]</b> uses of foam remaining.</span>")
cooldown = world.time + cooldown_time
power_change()
addtimer(CALLBACK(src, .proc/power_change), cooldown_time)
+2 -1
View File
@@ -159,9 +159,10 @@
else if(istype(W, /obj/item/stack/sheet/mineral/plasma))
if(!isEmpProof())
var/obj/item/stack/sheet/mineral/plasma/P = W
upgradeEmpProof()
to_chat(user, "[msg]")
qdel(W)
P.use(1)
else
to_chat(user, "[msg2]")
return
+1 -1
View File
@@ -71,7 +71,7 @@
/obj/machinery/cell_charger/proc/removecell()
charging.updateicon()
charging.update_icon()
charging = null
chargelevel = -1
updateicon()
+40 -21
View File
@@ -9,6 +9,7 @@
var/list/networks = list("SS13")
var/datum/action/innate/camera_off/off_action = new
var/datum/action/innate/camera_jump/jump_action = new
var/list/actions = list()
light_color = LIGHT_COLOR_RED
@@ -17,10 +18,31 @@
eyeobj.origin = src
/obj/machinery/computer/camera_advanced/proc/GrantActions(mob/living/user)
off_action.target = user
off_action.Grant(user)
jump_action.target = user
jump_action.Grant(user)
if(off_action)
off_action.target = user
off_action.Grant(user)
actions += off_action
if(jump_action)
jump_action.target = user
jump_action.Grant(user)
actions += jump_action
/obj/machinery/computer/camera_advanced/proc/remove_eye_control(mob/living/user)
if(!user)
return
for(var/V in actions)
var/datum/action/A = V
A.Remove(user)
if(user.client)
user.reset_perspective(null)
eyeobj.RemoveImages()
eyeobj.eye_user = null
user.remote_control = null
current_user = null
user.unset_machine()
playsound(src, 'sound/machines/terminal_off.ogg', 25, 0)
/obj/machinery/computer/camera_advanced/check_eye(mob/user)
if( (stat & (NOPOWER|BROKEN)) || (!Adjacent(user) && !user.has_unlimited_silicon_privilege) || user.eye_blind || user.incapacitated() )
@@ -35,7 +57,7 @@
/obj/machinery/computer/camera_advanced/on_unset_machine(mob/M)
if(M == current_user)
off_action.Activate()
remove_eye_control(M)
/obj/machinery/computer/camera_advanced/attack_hand(mob/user)
if(current_user)
@@ -69,7 +91,7 @@
/obj/machinery/computer/camera_advanced/attack_robot(mob/user)
return attack_hand(user)
obj/machinery/computer/camera_advanced/attack_ai(mob/user)
/obj/machinery/computer/camera_advanced/attack_ai(mob/user)
return //AIs would need to disable their own camera procs to use the console safely. Bugs happen otherwise.
@@ -92,13 +114,20 @@ obj/machinery/computer/camera_advanced/attack_ai(mob/user)
var/eye_initialized = 0
var/visible_icon = 0
var/image/user_image = null
/mob/camera/aiEye/remote/update_remote_sight(mob/living/user)
user.see_invisible = SEE_INVISIBLE_LIVING //can't see ghosts through cameras
user.sight = 0
user.see_in_dark = 2
return 1
/mob/camera/aiEye/remote/RemoveImages()
..()
if(visible_icon)
var/client/C = GetViewerClient()
if(C)
C.images -= user_image
/mob/camera/aiEye/remote/Destroy()
eye_user = null
origin = null
@@ -115,7 +144,8 @@ obj/machinery/computer/camera_advanced/attack_ai(mob/user)
return
T = get_turf(T)
loc = T
GLOB.cameranet.visibility(src)
if(use_static)
GLOB.cameranet.visibility(src)
if(visible_icon)
if(eye_user.client)
eye_user.client.images -= user_image
@@ -149,19 +179,8 @@ obj/machinery/computer/camera_advanced/attack_ai(mob/user)
return
var/mob/living/C = target
var/mob/camera/aiEye/remote/remote_eye = C.remote_control
remote_eye.origin.current_user = null
remote_eye.origin.jump_action.Remove(C)
if(C.client)
C.reset_perspective(null)
if(remote_eye.visible_icon)
C.client.images -= remote_eye.user_image
for(var/datum/camerachunk/chunk in remote_eye.visibleCameraChunks)
chunk.remove(remote_eye)
remote_eye.eye_user = null
C.remote_control = null
C.unset_machine()
Remove(C)
playsound(remote_eye.origin, 'sound/machines/terminal_off.ogg', 25, 0)
var/obj/machinery/computer/camera_advanced/console = remote_eye.origin
console.remove_eye_control(target)
/datum/action/innate/camera_jump
name = "Jump To Camera"
+1 -1
View File
@@ -1,7 +1,7 @@
// The communications computer
/obj/machinery/computer/communications
name = "communications console"
desc = "This can be used for various important functions. Still under developement."
desc = "A console used for high-priority announcements and emergencies."
icon_screen = "comm"
icon_keyboard = "tech_key"
req_access = list(GLOB.access_heads)
+5 -5
View File
@@ -332,7 +332,7 @@
src.active2.fields["mi_dis"] = t1
if("mi_dis_d")
if(active2)
var/t1 = stripped_multiline_input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null)
var/t1 = stripped_input("Please summarize minor dis.:", "Med. records", src.active2.fields["mi_dis_d"], null)
if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
return
src.active2.fields["mi_dis_d"] = t1
@@ -344,7 +344,7 @@
src.active2.fields["ma_dis"] = t1
if("ma_dis_d")
if(active2)
var/t1 = stripped_multiline_input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null)
var/t1 = stripped_input("Please summarize major dis.:", "Med. records", src.active2.fields["ma_dis_d"], null)
if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
return
src.active2.fields["ma_dis_d"] = t1
@@ -356,7 +356,7 @@
src.active2.fields["alg"] = t1
if("alg_d")
if(active2)
var/t1 = stripped_multiline_input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null)
var/t1 = stripped_input("Please summarize allergies:", "Med. records", src.active2.fields["alg_d"], null)
if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
return
src.active2.fields["alg_d"] = t1
@@ -368,13 +368,13 @@
src.active2.fields["cdi"] = t1
if("cdi_d")
if(active2)
var/t1 = stripped_multiline_input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null)
var/t1 = stripped_input("Please summarize diseases:", "Med. records", src.active2.fields["cdi_d"], null)
if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
return
src.active2.fields["cdi_d"] = t1
if("notes")
if(active2)
var/t1 = stripped_multiline_input("Please summarize notes:", "Med. records", src.active2.fields["notes"], null)
var/t1 = stripped_input("Please summarize notes:", "Med. records", src.active2.fields["notes"], null)
if(!canUseMedicalRecordsConsole(usr, t1, null, a2))
return
src.active2.fields["notes"] = t1
+10 -2
View File
@@ -23,6 +23,14 @@
light_color = LIGHT_COLOR_RED
/obj/machinery/computer/secure_data/laptop
name = "security laptop"
desc = "A cheap Nanotrasen security laptop, it functions as a security records console. It's bolted to the table."
icon_state = "laptop"
icon_screen = "seclaptop"
icon_keyboard = "laptop_key"
clockwork = TRUE //it'd look weird
/obj/machinery/computer/secure_data/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/weapon/card/id))
if(!scan)
@@ -620,7 +628,7 @@ What a mess.*/
if("mi_crim_add")
if(istype(active1, /datum/data/record))
var/t1 = stripped_input(usr, "Please input minor crime names:", "Secure. records", "", null)
var/t2 = stripped_multiline_input(usr, "Please input minor crime details:", "Secure. records", "", null)
var/t2 = stripped_input(usr, "Please input minor crime details:", "Secure. records", "", null)
if(!canUseSecurityRecordsConsole(usr, t1, null, a2))
return
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, worldtime2text())
@@ -634,7 +642,7 @@ What a mess.*/
if("ma_crim_add")
if(istype(active1, /datum/data/record))
var/t1 = stripped_input(usr, "Please input major crime names:", "Secure. records", "", null)
var/t2 = stripped_multiline_input(usr, "Please input major crime details:", "Secure. records", "", null)
var/t2 = stripped_input(usr, "Please input major crime details:", "Secure. records", "", null)
if(!canUseSecurityRecordsConsole(usr, t1, null, a2))
return
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, worldtime2text())
+53
View File
@@ -72,6 +72,7 @@
var/hasShocked = 0 //Prevents multiple shocks from happening
autoclose = 1
var/obj/item/device/doorCharge/charge = null //If applied, causes an explosion upon opening the door
var/obj/item/weapon/note //Any papers pinned to the airlock
var/detonated = 0
var/doorOpen = 'sound/machines/airlock.ogg'
var/doorClose = 'sound/machines/AirlockClose.ogg'
@@ -82,6 +83,7 @@
var/airlock_material = null //material of inner filling; if its an airlock with glass, this should be set to "glass"
var/overlays_file = 'icons/obj/doors/airlocks/station/overlays.dmi'
var/note_overlay_file = 'icons/obj/doors/airlocks/station/overlays.dmi' //Used for papers and photos pinned to the airlock
var/cyclelinkeddir = 0
var/obj/machinery/door/airlock/cyclelinkedairlock
@@ -213,8 +215,14 @@
if(id_tag)
for(var/obj/machinery/doorButtons/D in GLOB.machines)
D.removeMe(src)
qdel(note)
return ..()
/obj/machinery/door/airlock/handle_atom_del(atom/A)
if(A == note)
note = null
update_icon()
/obj/machinery/door/airlock/bumpopen(mob/living/user) //Airlocks now zap you when you 'bump' them open when they're electrified. --NeoFite
if(!issilicon(usr))
if(src.isElectrified())
@@ -369,6 +377,8 @@
var/mutable_appearance/weld_overlay
var/mutable_appearance/damag_overlay
var/mutable_appearance/sparks_overlay
var/mutable_appearance/note_overlay
var/notetype = note_type()
switch(state)
if(AIRLOCK_CLOSED)
@@ -393,6 +403,8 @@
lights_overlay = get_airlock_overlay("lights_bolts", overlays_file)
else if(emergency)
lights_overlay = get_airlock_overlay("lights_emergency", overlays_file)
if(note)
note_overlay = get_airlock_overlay(notetype, note_overlay_file)
if(AIRLOCK_DENY)
if(!hasPower())
@@ -414,6 +426,8 @@
if(welded)
weld_overlay = get_airlock_overlay("welded", overlays_file)
lights_overlay = get_airlock_overlay("lights_denied", overlays_file)
if(note)
note_overlay = get_airlock_overlay(notetype, note_overlay_file)
if(AIRLOCK_EMAG)
frame_overlay = get_airlock_overlay("closed", icon)
@@ -433,6 +447,8 @@
damag_overlay = get_airlock_overlay("sparks_damaged", overlays_file)
if(welded)
weld_overlay = get_airlock_overlay("welded", overlays_file)
if(note)
note_overlay = get_airlock_overlay(notetype, note_overlay_file)
if(AIRLOCK_CLOSING)
frame_overlay = get_airlock_overlay("closing", icon)
@@ -447,6 +463,8 @@
panel_overlay = get_airlock_overlay("panel_closing_protected", overlays_file)
else
panel_overlay = get_airlock_overlay("panel_closing", overlays_file)
if(note)
note_overlay = get_airlock_overlay("[notetype]_closing", note_overlay_file)
if(AIRLOCK_OPEN)
frame_overlay = get_airlock_overlay("open", icon)
@@ -461,6 +479,8 @@
panel_overlay = get_airlock_overlay("panel_open", overlays_file)
if(obj_integrity < (0.75 * max_integrity))
damag_overlay = get_airlock_overlay("sparks_open", overlays_file)
if(note)
note_overlay = get_airlock_overlay("[notetype]_open", note_overlay_file)
if(AIRLOCK_OPENING)
frame_overlay = get_airlock_overlay("opening", icon)
@@ -475,6 +495,8 @@
panel_overlay = get_airlock_overlay("panel_opening_protected", overlays_file)
else
panel_overlay = get_airlock_overlay("panel_opening", overlays_file)
if(note)
note_overlay = get_airlock_overlay("[notetype]_opening", note_overlay_file)
cut_overlays()
add_overlay(frame_overlay)
@@ -484,6 +506,7 @@
add_overlay(weld_overlay)
add_overlay(sparks_overlay)
add_overlay(damag_overlay)
add_overlay(note_overlay)
/proc/get_airlock_overlay(icon_state, icon_file)
var/obj/machinery/door/airlock/A
@@ -512,6 +535,12 @@
to_chat(user, "<span class='warning'>The maintenance panel seems haphazardly fastened.</span>")
if(charge && panel_open)
to_chat(user, "<span class='warning'>Something is wired up to the airlock's electronics!</span>")
if(note)
if(!in_range(user, src))
to_chat(user, "There's a [note.name] pinned to the front. You can't read it from here.")
else
to_chat(user, "There's a [note.name] pinned to the front...")
note.examine(user)
if(panel_open)
switch(security_level)
@@ -1094,6 +1123,12 @@
to_chat(user, "<span class='notice'>You [panel_open ? "open":"close"] the maintenance panel of the airlock.</span>")
playsound(src.loc, C.usesound, 50, 1)
src.update_icon()
else if(istype(C, /obj/item/weapon/wirecutters) && note)
user.visible_message("<span class='notice'>[user] cuts down [note] from [src].</span>", "<span class='notice'>You remove [note] from [src].</span>")
playsound(src, 'sound/items/Wirecutter.ogg', 50, 1)
note.forceMove(get_turf(user))
note = null
update_icon()
else if(is_wire_tool(C))
return attack_hand(user)
else if(istype(C, /obj/item/weapon/pai_cable))
@@ -1119,6 +1154,16 @@
update_icon()
C.forceMove(src)
charge = C
else if(istype(C, /obj/item/weapon/paper) || istype(C, /obj/item/weapon/photo))
if(note)
to_chat(user, "<span class='warning'>There's already something pinned to this airlock! Use wirecutters to remove it.<spa>")
return
if(!user.transferItemToLoc(C, src))
to_chat(user, "<span class='warning'>For some reason, you can't attach [C]!</span>")
return
user.visible_message("<span class='notice'>[user] pins [C] to [src].</span>", "<span class='notice'>You pin [C] to [src].</span>")
note = C
update_icon()
else
return ..()
@@ -1550,6 +1595,14 @@
return TRUE
return FALSE
/obj/machinery/door/airlock/proc/note_type() //Returns a string representing the type of note pinned to this airlock
if(!note)
return
else if(istype(note, /obj/item/weapon/paper))
return "note"
else if(istype(note, /obj/item/weapon/photo))
return "photo"
#undef AIRLOCK_CLOSED
#undef AIRLOCK_CLOSING
#undef AIRLOCK_OPEN
@@ -252,6 +252,7 @@
name = "external airlock"
icon = 'icons/obj/doors/airlocks/external/external.dmi'
overlays_file = 'icons/obj/doors/airlocks/external/overlays.dmi'
note_overlay_file = 'icons/obj/doors/airlocks/external/overlays.dmi'
assemblytype = /obj/structure/door_assembly/door_assembly_ext
explosion_block = 1
@@ -271,6 +272,7 @@
/obj/machinery/door/airlock/centcom
icon = 'icons/obj/doors/airlocks/centcom/centcom.dmi'
overlays_file = 'icons/obj/doors/airlocks/centcom/overlays.dmi'
note_overlay_file = 'icons/obj/doors/airlocks/centcom/overlays.dmi'
opacity = 1
assemblytype = /obj/structure/door_assembly/door_assembly_centcom
normal_integrity = 1000
@@ -286,6 +288,7 @@
name = "vault door"
icon = 'icons/obj/doors/airlocks/vault/vault.dmi'
overlays_file = 'icons/obj/doors/airlocks/vault/overlays.dmi'
note_overlay_file = 'icons/obj/doors/airlocks/vault/overlays.dmi'
opacity = 1
assemblytype = /obj/structure/door_assembly/door_assembly_vault
explosion_block = 2
@@ -301,6 +304,7 @@
name = "airtight hatch"
icon = 'icons/obj/doors/airlocks/hatch/centcom.dmi'
overlays_file = 'icons/obj/doors/airlocks/hatch/overlays.dmi'
note_overlay_file = 'icons/obj/doors/airlocks/hatch/overlays.dmi'
opacity = 1
assemblytype = /obj/structure/door_assembly/door_assembly_hatch
@@ -308,6 +312,7 @@
name = "maintenance hatch"
icon = 'icons/obj/doors/airlocks/hatch/maintenance.dmi'
overlays_file = 'icons/obj/doors/airlocks/hatch/overlays.dmi'
note_overlay_file = 'icons/obj/doors/airlocks/hatch/overlays.dmi'
opacity = 1
assemblytype = /obj/structure/door_assembly/door_assembly_mhatch
@@ -342,6 +347,7 @@
desc = "With humanity's current technological level, it could take years to hack this advanced airlock... or maybe we should give a screwdriver a try?"
icon = 'icons/obj/doors/airlocks/abductor/abductor_airlock.dmi'
overlays_file = 'icons/obj/doors/airlocks/abductor/overlays.dmi'
note_overlay_file = 'icons/obj/doors/airlocks/abductor/overlays.dmi'
assemblytype = /obj/structure/door_assembly/door_assembly_abductor
damage_deflection = 30
opacity = 1
@@ -549,6 +555,7 @@
name = "large glass airlock"
icon = 'icons/obj/doors/airlocks/glass_large/glass_large.dmi'
overlays_file = 'icons/obj/doors/airlocks/glass_large/overlays.dmi'
note_overlay_file = 'icons/obj/doors/airlocks/glass_large/overlays.dmi'
opacity = 0
assemblytype = null
glass = 1
+10 -2
View File
@@ -12,7 +12,7 @@
max_integrity = 350
armor = list(melee = 30, bullet = 30, laser = 20, energy = 20, bomb = 10, bio = 100, rad = 100, fire = 80, acid = 70)
CanAtmosPass = ATMOS_PASS_DENSITY
flags = PREVENT_CLICK_UNDER
flags = PREVENT_CLICK_UNDER
var/secondsElectrified = 0
var/shockedby = list()
@@ -32,6 +32,7 @@
var/auto_close //TO BE REMOVED, no longer used, it's just preventing a runtime with a map var edit.
var/datum/effect_system/spark_spread/spark_system
var/damage_deflection = 10
var/real_explosion_block //ignore this, just use explosion_block
/obj/machinery/door/New()
..()
@@ -45,6 +46,10 @@
spark_system = new /datum/effect_system/spark_spread
spark_system.set_up(2, 1, src)
//doors only block while dense though so we have to use the proc
real_explosion_block = explosion_block
explosion_block = EXPLOSION_BLOCK_PROC
/obj/machinery/door/Destroy()
@@ -284,7 +289,7 @@
/obj/machinery/door/proc/crush()
for(var/mob/living/L in get_turf(src))
L.visible_message("<span class='warning'>[src] closes on [L], crushing them!</span>", "<span class='userdanger'>[src] closes on you and crushes you!</span>")
L.visible_message("<span class='warning'>[src] closes on [L], crushing them!</span>", "<span class='userdanger'>[src] closes on you and crushes you!</span>")
if(isalien(L)) //For xenos
L.adjustBruteLoss(DOOR_CRUSH_DAMAGE * 1.5) //Xenos go into crit after aproximately the same amount of crushes as humans.
L.emote("roar")
@@ -346,3 +351,6 @@
//if it blows up a wall it should blow up a door
..(severity ? max(1, severity - 1) : 0, target)
/obj/machinery/door/GetExplosionBlock()
return density ? real_explosion_block : 0
+8 -17
View File
@@ -58,12 +58,11 @@ Possible to do for anyone motivated enough:
/obj/machinery/holopad/Destroy()
if(outgoing_call)
LAZYADD(holo_calls, outgoing_call)
outgoing_call.ConnectionFailure(src)
for(var/I in holo_calls)
var/datum/holocall/HC = I
HC.ConnectionFailure(src)
LAZYCLEARLIST(holo_calls)
for (var/I in masters)
clear_holo(I)
@@ -75,6 +74,13 @@ Possible to do for anyone motivated enough:
stat &= ~NOPOWER
else
stat |= NOPOWER
if(outgoing_call)
outgoing_call.ConnectionFailure(src)
/obj/machinery/holopad/obj_break()
. = ..()
if(outgoing_call)
outgoing_call.ConnectionFailure(src)
/obj/machinery/holopad/RefreshParts()
var/holograph_range = 4
@@ -99,26 +105,11 @@ Possible to do for anyone motivated enough:
return
return ..()
/obj/machinery/holopad/proc/CheckCallClose()
for(var/I in holo_calls)
var/datum/holocall/HC = I
if(usr == HC.eye)
HC.Disconnect(HC.calling_holopad) //disconnect via clicking the called holopad
return TRUE
return FALSE
/obj/machinery/holopad/Click(location,control,params)
if(!CheckCallClose())
return ..()
/obj/machinery/holopad/AltClick(mob/living/carbon/human/user)
if(isAI(user))
hangup_all_calls()
return
if(!CheckCallClose())
interact(user)
/obj/machinery/holopad/interact(mob/living/carbon/human/user) //Carn: Hologram requests.
if(!istype(user))
return
+1 -1
View File
@@ -53,7 +53,7 @@
usr.set_machine(src)
src.add_fingerprint(usr)
if(href_list["make"])
if(!wait)
if(wait < world.time)
var/p_type = text2path(href_list["make"])
var/p_dir = text2num(href_list["dir"])
var/obj/item/pipe/P = new (src.loc, pipe_type=p_type, dir=p_dir)
@@ -87,9 +87,9 @@
if(has_cover)
cover = new /obj/machinery/porta_turret_cover(loc)
cover.parent_turret = src
var/mutable_appearance/base = mutable_appearance('icons/obj/turrets.dmi', "basedark")
base.layer = NOT_HIGH_OBJ_LAYER
underlays += base
var/mutable_appearance/base = mutable_appearance('icons/obj/turrets.dmi', "basedark")
base.layer = NOT_HIGH_OBJ_LAYER
underlays += base
if(!has_cover)
INVOKE_ASYNC(src, .proc/popUp)
@@ -554,7 +554,7 @@
use_power = 0
has_cover = 0
scan_range = 9
req_access = list(GLOB.access_syndicate)
req_access = list(GLOB.access_syndicate)
stun_projectile = /obj/item/projectile/bullet
lethal_projectile = /obj/item/projectile/bullet
lethal_projectile_sound = 'sound/weapons/Gunshot.ogg'
@@ -564,6 +564,15 @@
faction = "syndicate"
emp_vunerable = 0
/obj/machinery/porta_turret/syndicate/energy
icon_state = "standard_stun"
base_icon_state = "standard"
stun_projectile = /obj/item/projectile/energy/electrode
stun_projectile_sound = 'sound/weapons/Taser.ogg'
lethal_projectile = /obj/item/projectile/beam/laser/heavylaser
lethal_projectile_sound = 'sound/weapons/lasercannonfire.ogg'
/obj/machinery/porta_turret/syndicate/setup()
return
@@ -571,8 +580,8 @@
return 10 //Syndicate turrets shoot everything not in their faction
/obj/machinery/porta_turret/syndicate/pod
max_integrity = 40
integrity_failure = 20
max_integrity = 40
integrity_failure = 20
obj_integrity = 40
stun_projectile = /obj/item/projectile/bullet/weakbullet3
lethal_projectile = /obj/item/projectile/bullet/weakbullet3
@@ -925,181 +934,3 @@
on = 0
spawn(100)
on = 1
/////// MANNED TURRET ////////
/obj/machinery/manned_turret
name = "machine gun turret"
desc = "While the trigger is held down, this gun will redistribute recoil to allow its user to easily shift targets."
icon = 'icons/obj/turrets.dmi'
icon_state = "machinegun"
can_buckle = TRUE
density = TRUE
max_integrity = 100
obj_integrity = 100
buckle_lying = 0
layer = ABOVE_MOB_LAYER
var/view_range = 10
var/cooldown = 0
var/projectile_type = /obj/item/projectile/bullet/weakbullet3
var/rate_of_fire = 1
var/number_of_shots = 40
var/cooldown_duration = 90
var/atom/target
var/turf/target_turf
var/warned = FALSE
var/mouseparams
//BUCKLE HOOKS
/obj/machinery/manned_turret/unbuckle_mob(mob/living/buckled_mob,force = 0)
playsound(src,'sound/mecha/mechmove01.ogg', 50, 1)
for(var/obj/item/I in buckled_mob.held_items)
if(istype(I, /obj/item/gun_control))
qdel(I)
if(istype(buckled_mob))
buckled_mob.pixel_x = 0
buckled_mob.pixel_y = 0
if(buckled_mob.client)
buckled_mob.client.change_view(world.view)
anchored = FALSE
. = ..()
/obj/machinery/manned_turret/user_buckle_mob(mob/living/M, mob/living/carbon/user)
if(user.incapacitated() || !istype(user))
return
M.forceMove(get_turf(src))
..()
for(var/V in M.held_items)
var/obj/item/I = V
if(istype(I))
if(M.dropItemToGround(I))
var/obj/item/gun_control/TC = new /obj/item/gun_control(src)
M.put_in_hands(TC)
else //Entries in the list should only ever be items or null, so if it's not an item, we can assume it's an empty hand
var/obj/item/gun_control/TC = new /obj/item/gun_control(src)
M.put_in_hands(TC)
M.pixel_y = 14
layer = ABOVE_MOB_LAYER
setDir(SOUTH)
playsound(src,'sound/mecha/mechmove01.ogg', 50, 1)
anchored = TRUE
if(user.client)
user.client.change_view(view_range)
/obj/item/gun_control
name = "turret controls"
icon = 'icons/obj/weapons.dmi'
icon_state = "offhand"
w_class = WEIGHT_CLASS_HUGE
flags = ABSTRACT | NODROP | NOBLUDGEON
resistance_flags = FIRE_PROOF | UNACIDABLE | ACID_PROOF
var/obj/machinery/manned_turret/turret
/obj/item/gun_control/New(obj/machinery/manned_turret/MT)
if(MT)
turret = MT
else
qdel(src)
/obj/item/gun_control/CanItemAutoclick()
return 1
/obj/item/gun_control/attack_obj(obj/O, mob/living/user)
user.changeNext_move(CLICK_CD_MELEE)
O.attacked_by(src, user)
/obj/item/gun_control/attack(mob/living/M, mob/living/user)
user.lastattacked = M
M.lastattacker = user
M.attacked_by(src, user)
add_fingerprint(user)
/obj/item/gun_control/afterattack(atom/targeted_atom, mob/user, flag, params)
..()
var/obj/machinery/manned_turret/E = user.buckled
E.setDir(get_dir(E,targeted_atom))
user.setDir(E.dir)
E.mouseparams = params
switch(E.dir)
if(NORTH)
E.layer = BELOW_MOB_LAYER
user.pixel_x = 0
user.pixel_y = -14
if(NORTHEAST)
E.layer = BELOW_MOB_LAYER
user.pixel_x = -8
user.pixel_y = -4
if(EAST)
E.layer = ABOVE_MOB_LAYER
user.pixel_x = -14
user.pixel_y = 0
if(SOUTHEAST)
E.layer = BELOW_MOB_LAYER
user.pixel_x = -8
user.pixel_y = 4
if(SOUTH)
E.layer = ABOVE_MOB_LAYER
user.pixel_x = 0
user.pixel_y = 14
if(SOUTHWEST)
E.layer = BELOW_MOB_LAYER
user.pixel_x = 8
user.pixel_y = 4
if(WEST)
E.layer = ABOVE_MOB_LAYER
user.pixel_x = 14
user.pixel_y = 0
if(NORTHWEST)
E.layer = BELOW_MOB_LAYER
user.pixel_x = 8
user.pixel_y = -4
E.checkfire(targeted_atom, user)
/obj/machinery/manned_turret/proc/checkfire(atom/targeted_atom, mob/user)
target = targeted_atom
if(target == user || target == get_turf(src))
return
if(world.time < cooldown)
if(!warned && world.time > (cooldown - cooldown_duration + rate_of_fire*number_of_shots)) // To capture the window where one is done firing
warned = TRUE
playsound(src, 'sound/weapons/sear.ogg', 100, 1)
return
else
cooldown = world.time + cooldown_duration
warned = FALSE
volley(user)
/obj/machinery/manned_turret/proc/volley(mob/user)
target_turf = get_turf(target)
for(var/i in 1 to number_of_shots)
addtimer(CALLBACK(src, /obj/machinery/manned_turret/.proc/fire_helper, user), i*rate_of_fire)
/obj/machinery/manned_turret/proc/fire_helper(mob/user)
if(!src)
return
var/turf/targets_from = get_turf(src)
if(QDELETED(target))
target = target_turf
var/obj/item/projectile/P = new projectile_type(targets_from)
P.current = targets_from
P.starting = targets_from
P.firer = user
P.original = target
playsound(src, 'sound/weapons/Gunshot_smg.ogg', 75, 1)
P.preparePixelProjectile(target, target_turf, user, mouseparams, rand(-9, 9))
P.fire()
/obj/machinery/manned_turret/ultimate // Admin-only proof of concept for autoclicker automatics
name = "Infinity Gun"
view_range = 12
projectile_type = /obj/item/projectile/bullet/weakbullet3
/obj/machinery/manned_turret/ultimate/checkfire(atom/targeted_atom, mob/user)
target = targeted_atom
if(target == user || target == get_turf(src))
return
target_turf = get_turf(target)
fire_helper(user)
+20 -36
View File
@@ -61,7 +61,7 @@
G.loc = src
charging = G
use_power = 2
update_icon(scan = TRUE)
update_icon(scan = TRUE)
else
to_chat(user, "<span class='notice'>[src] isn't connected to anything!</span>")
return 1
@@ -108,41 +108,25 @@
var/using_power = 0
if(charging)
if(istype(charging, /obj/item/weapon/gun/energy))
var/obj/item/weapon/gun/energy/E = charging
if(E.power_supply.charge < E.power_supply.maxcharge)
E.power_supply.give(E.power_supply.chargerate * recharge_coeff)
E.recharge_newshot()
var/obj/item/weapon/stock_parts/cell/C = charging.get_cell()
if(C)
if(C.charge < C.maxcharge)
C.give(C.chargerate * recharge_coeff)
use_power(250 * recharge_coeff)
using_power = 1
if(istype(charging, /obj/item/weapon/melee/baton))
var/obj/item/weapon/melee/baton/B = charging
if(B.bcell)
if(B.bcell.give(B.bcell.chargerate * recharge_coeff))
use_power(200 * recharge_coeff)
using_power = 1
update_icon(using_power)
if(istype(charging, /obj/item/weapon/gun/energy))
var/obj/item/weapon/gun/energy/E = charging
E.recharge_newshot()
return
if(istype(charging, /obj/item/ammo_box/magazine/recharge))
var/obj/item/ammo_box/magazine/recharge/R = charging
if(R.stored_ammo.len < R.max_ammo)
R.stored_ammo += new R.ammo_type(R)
use_power(200 * recharge_coeff)
using_power = 1
if(istype(charging, /obj/item/device/modular_computer))
var/obj/item/device/modular_computer/C = charging
var/obj/item/weapon/computer_hardware/battery/battery_module = C.all_components[MC_CELL]
if(battery_module)
var/obj/item/weapon/computer_hardware/battery/B = battery_module
if(B.battery)
if(B.battery.charge < B.battery.maxcharge)
B.battery.give(B.battery.chargerate * recharge_coeff)
use_power(200 * recharge_coeff)
using_power = 1
update_icon(using_power)
update_icon(using_power)
return
/obj/machinery/recharger/power_change()
..()
@@ -152,23 +136,23 @@
if(!(stat & (NOPOWER|BROKEN)) && anchored)
if(istype(charging, /obj/item/weapon/gun/energy))
var/obj/item/weapon/gun/energy/E = charging
if(E.power_supply)
E.power_supply.emp_act(severity)
if(E.cell)
E.cell.emp_act(severity)
else if(istype(charging, /obj/item/weapon/melee/baton))
var/obj/item/weapon/melee/baton/B = charging
if(B.bcell)
B.bcell.charge = 0
if(B.cell)
B.cell.charge = 0
..()
/obj/machinery/recharger/update_icon(using_power = 0, scan) //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier.
/obj/machinery/recharger/update_icon(using_power = 0, scan) //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier.
if(stat & (NOPOWER|BROKEN) || !anchored)
icon_state = "rechargeroff"
return
if(scan)
icon_state = "rechargeroff"
return
if(scan)
icon_state = "rechargeroff"
return
if(panel_open)
icon_state = "rechargeropen"
return
+1 -3
View File
@@ -49,9 +49,7 @@
/obj/structure/emergency_shield/take_damage(damage, damage_type = BRUTE, damage_flag = 0, sound_effect = 1, attack_dir)
. = ..()
if(.) //damage was dealt
set_opacity(1)
spawn(20)
set_opacity(0)
new /obj/effect/temp_visual/impact_effect/ion(loc)
/obj/structure/emergency_shield/sanguine
name = "sanguine barrier"
+3
View File
@@ -24,6 +24,9 @@
var/settableTemperatureMedian = 30 + T0C
var/settableTemperatureRange = 30
/obj/machinery/space_heater/get_cell()
return cell
/obj/machinery/space_heater/New()
..()
cell = new(src)
+8
View File
@@ -213,6 +213,14 @@
var/emotion = "Neutral"
/obj/machinery/ai_status_display/Initialize()
. = ..()
GLOB.ai_status_displays.Add(src)
/obj/machinery/ai_status_display/Destroy()
GLOB.ai_status_displays.Remove(src)
. = ..()
/obj/machinery/ai_status_display/attack_ai(mob/living/silicon/ai/user)
if(isAI(user))
user.ai_statuschange()
+2 -2
View File
@@ -995,7 +995,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/item/clothing/head/helmet/gladiator = 1,/obj/item/clothing/under/gimmick/rank/captain/suit = 1,/obj/item/clothing/head/flatcap = 1,
/obj/item/clothing/suit/toggle/labcoat/mad = 1,/obj/item/clothing/shoes/jackboots = 1,
/obj/item/clothing/under/schoolgirl = 1,/obj/item/clothing/under/schoolgirl/red = 1,/obj/item/clothing/under/schoolgirl/green = 1,/obj/item/clothing/under/schoolgirl/orange = 1,/obj/item/clothing/head/kitty = 1,/obj/item/clothing/under/skirt/black = 1,/obj/item/clothing/head/beret = 1,
/obj/item/clothing/tie/waistcoat = 1,/obj/item/clothing/under/suit_jacket = 1,/obj/item/clothing/head/that =1,/obj/item/clothing/under/kilt = 1,/obj/item/clothing/head/beret = 1,/obj/item/clothing/tie/waistcoat = 1,
/obj/item/clothing/accessory/waistcoat = 1,/obj/item/clothing/under/suit_jacket = 1,/obj/item/clothing/head/that =1,/obj/item/clothing/under/kilt = 1,/obj/item/clothing/head/beret = 1,/obj/item/clothing/accessory/waistcoat = 1,
/obj/item/clothing/glasses/monocle =1,/obj/item/clothing/head/bowler = 1,/obj/item/weapon/cane = 1,/obj/item/clothing/under/sl_suit = 1,
/obj/item/clothing/mask/fakemoustache = 1,/obj/item/clothing/suit/bio_suit/plaguedoctorsuit = 1,/obj/item/clothing/head/plaguedoctorhat = 1,/obj/item/clothing/mask/gas/plaguedoctor = 1,
/obj/item/clothing/suit/toggle/owlwings = 1, /obj/item/clothing/under/owl = 1,/obj/item/clothing/mask/gas/owl_mask = 1,
@@ -1136,7 +1136,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
/obj/item/clothing/neck/scarf/purple=1,/obj/item/clothing/neck/scarf/yellow=1,/obj/item/clothing/neck/scarf/orange=1,
/obj/item/clothing/neck/scarf/cyan=1,/obj/item/clothing/neck/scarf=1,/obj/item/clothing/neck/scarf/black=1,
/obj/item/clothing/neck/scarf/zebra=1,/obj/item/clothing/neck/scarf/christmas=1,/obj/item/clothing/neck/stripedredscarf=1,
/obj/item/clothing/neck/stripedbluescarf=1,/obj/item/clothing/neck/stripedgreenscarf=1,/obj/item/clothing/tie/waistcoat=1,
/obj/item/clothing/neck/stripedbluescarf=1,/obj/item/clothing/neck/stripedgreenscarf=1,/obj/item/clothing/accessory/waistcoat=1,
/obj/item/clothing/under/skirt/black=1,/obj/item/clothing/under/skirt/blue=1,/obj/item/clothing/under/skirt/red=1,/obj/item/clothing/under/skirt/purple=1,
/obj/item/clothing/under/sundress=2,/obj/item/clothing/under/stripeddress=1, /obj/item/clothing/under/sailordress=1, /obj/item/clothing/under/redeveninggown=1, /obj/item/clothing/under/blacktango=1,
/obj/item/clothing/under/plaid_skirt=1,/obj/item/clothing/under/plaid_skirt/blue=1,/obj/item/clothing/under/plaid_skirt/purple=1,/obj/item/clothing/under/plaid_skirt/green=1,
+4 -1
View File
@@ -142,6 +142,9 @@
diag_hud_set_mechstat()
diag_hud_set_mechtracking()
/obj/mecha/get_cell()
return cell
/obj/mecha/Destroy()
go_out()
@@ -154,7 +157,7 @@
M.forceMove(loc)
if(prob(30))
explosion(get_turf(loc), 0, 0, 1, 3)
explosion(get_turf(loc), 0, 0, 1, 3)
if(wreckage)
var/obj/structure/mecha_wreckage/WR = new wreckage(loc, AI)
+8 -10
View File
@@ -43,19 +43,19 @@
buckled_mobs = list()
if(!istype(M))
return 0
return FALSE
if(check_loc && M.loc != loc)
return 0
return FALSE
if((!can_buckle && !force) || M.buckled || (buckled_mobs.len >= max_buckled_mobs) || (buckle_requires_restraints && !M.restrained()) || M == src)
return 0
return FALSE
if(!M.can_buckle() && !force)
if(M == usr)
to_chat(M, "<span class='warning'>You are unable to buckle yourself to the [src]!</span>")
else
to_chat(usr, "<span class='warning'>You are unable to buckle [M] to the [src]!</span>")
return 0
return FALSE
if(M.pulledby && buckle_prevents_pull)
M.pulledby.stop_pulling()
@@ -70,7 +70,7 @@
M.throw_alert("buckled", /obj/screen/alert/restrained/buckled, new_master = src)
post_buckle_mob(M)
return 1
return TRUE
/obj/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
. = ..()
@@ -105,11 +105,11 @@
//Wrapper procs that handle sanity and user feedback
/atom/movable/proc/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE)
if(!in_range(user, src) || user.stat || user.restrained())
return 0
return FALSE
add_fingerprint(user)
if(buckle_mob(M, check_loc = check_loc))
. = buckle_mob(M, check_loc = check_loc)
if(.)
if(M == user)
M.visible_message(\
"<span class='notice'>[M] buckles [M.p_them()]self to [src].</span>",\
@@ -120,8 +120,6 @@
"<span class='warning'>[user] buckles [M] to [src]!</span>",\
"<span class='warning'>[user] buckles you to [src]!</span>",\
"<span class='italics'>You hear metal clanking.</span>")
return 1
/atom/movable/proc/user_unbuckle_mob(mob/living/buckled_mob, mob/user)
var/mob/living/M = unbuckle_mob(buckled_mob)
+14 -6
View File
@@ -30,27 +30,35 @@
layer = HIGH_OBJ_LAYER //Harder to hide
do_icon_rotate = FALSE //These are designed to always face south, so no rotation please.
var/datum/gang/gang
var/obj/item/device/gangtool/linked_tool
var/datum/mind/user_mind
var/area/territory
/obj/effect/decal/cleanable/crayon/gang/Initialize(mapload, var/datum/gang/G, var/e_name = "gang tag", var/rotation = 0, var/mob/user)
if(!type || !G)
qdel(src)
user_mind = user.mind
territory = get_area(src)
gang = G
var/newcolor = G.color_hex
icon_state = G.name
G.territory_new |= list(territory.type = territory.name)
linked_tool = locate(/obj/item/device/gangtool) in user.contents
if(linked_tool)
linked_tool.tags += src
//If this isn't tagged by a specific gangster there's no bonus income.
set_mind_owner(user_mind)
..(mapload, newcolor, icon_state, e_name, rotation)
/obj/effect/decal/cleanable/crayon/gang/proc/set_mind_owner(datum/mind/mind)
if(istype(user_mind) && istype(gang) && islist(gang.tags_by_mind[user_mind])) //Clear us out of old ownership
gang.tags_by_mind[user_mind] -= src
if(istype(mind))
if(!islist(gang.tags_by_mind[mind]))
gang.tags_by_mind[mind] = list()
gang.tags_by_mind[mind] += src
user_mind = mind
/obj/effect/decal/cleanable/crayon/gang/Destroy()
if(linked_tool)
linked_tool.tags -= src
if(gang)
gang.territory -= territory.type
set_mind_owner(null)
gang.territory_new -= territory.type
gang.territory_lost |= list(territory.type = territory.name)
return ..()
+4 -1
View File
@@ -64,4 +64,7 @@
icon_state = "sandyfloor"
/obj/effect/turf_decal/sand/plating
icon_state = "sandyplating"
icon_state = "sandyplating"
/obj/effect/turf_decal/plaque
icon_state = "plaque"
+2 -2
View File
@@ -60,7 +60,7 @@
/obj/effect/spawner/bundle/costume/butler
name = "butler costume spawner"
items = list(
/obj/item/clothing/tie/waistcoat,
/obj/item/clothing/accessory/waistcoat,
/obj/item/clothing/under/suit_jacket,
/obj/item/clothing/head/that)
@@ -73,7 +73,7 @@
/obj/effect/spawner/bundle/costume/prig
name = "prig costume spawner"
items = list(
/obj/item/clothing/tie/waistcoat,
/obj/item/clothing/accessory/waistcoat,
/obj/item/clothing/glasses/monocle,
/obj/effect/spawner/lootdrop/minor/bowler_or_that,
/obj/item/clothing/shoes/sneakers/black,
+30 -1
View File
@@ -54,6 +54,35 @@
/obj/item/trash/sosjerky = 1,
/obj/item/trash/syndi_cakes = 1)
/obj/effect/spawner/lootdrop/three_course_meal
name = "three course meal spawner"
lootcount = 3
lootdoubles = FALSE
var/soups = list(
/obj/item/weapon/reagent_containers/food/snacks/soup/beet,
/obj/item/weapon/reagent_containers/food/snacks/soup/sweetpotato,
/obj/item/weapon/reagent_containers/food/snacks/soup/stew,
/obj/item/weapon/reagent_containers/food/snacks/soup/hotchili,
/obj/item/weapon/reagent_containers/food/snacks/soup/nettle,
/obj/item/weapon/reagent_containers/food/snacks/soup/meatball)
var/salads = list(
/obj/item/weapon/reagent_containers/food/snacks/salad/herbsalad,
/obj/item/weapon/reagent_containers/food/snacks/salad/validsalad,
/obj/item/weapon/reagent_containers/food/snacks/salad/fruit,
/obj/item/weapon/reagent_containers/food/snacks/salad/jungle,
/obj/item/weapon/reagent_containers/food/snacks/salad/aesirsalad)
var/mains = list(
/obj/item/weapon/reagent_containers/food/snacks/bearsteak,
/obj/item/weapon/reagent_containers/food/snacks/enchiladas,
/obj/item/weapon/reagent_containers/food/snacks/stewedsoymeat,
/obj/item/weapon/reagent_containers/food/snacks/burger/bigbite,
/obj/item/weapon/reagent_containers/food/snacks/burger/superbite,
/obj/item/weapon/reagent_containers/food/snacks/burger/fivealarm)
/obj/effect/spawner/lootdrop/three_course_meal/Initialize(mapload)
loot = list(pick(soups) = 1,pick(salads) = 1,pick(mains) = 1)
. = ..()
/obj/effect/spawner/lootdrop/maintenance
name = "maintenance loot spawner"
// see code/_globalvars/lists/maintenance_loot.dm for loot table
@@ -85,7 +114,7 @@
/obj/item/organ/heart/gland/spiderman = 5,
/obj/item/organ/heart/gland/ventcrawling = 1,
/obj/item/organ/body_egg/alien_embryo = 1,
/obj/item/organ/hivelord_core = 2)
/obj/item/organ/regenerative_core = 2)
lootcount = 3
/obj/effect/spawner/lootdrop/two_percent_xeno_egg_spawner
+1 -1
View File
@@ -172,7 +172,7 @@
amount_grown += rand(0,2)
if(amount_grown >= 100)
if(!grow_as)
grow_as = pick(typesof(/mob/living/simple_animal/hostile/poison/giant_spider))
grow_as = pick(/mob/living/simple_animal/hostile/poison/giant_spider, /mob/living/simple_animal/hostile/poison/giant_spider/hunter, /mob/living/simple_animal/hostile/poison/giant_spider/nurse)
var/mob/living/simple_animal/hostile/poison/giant_spider/S = new grow_as(src.loc)
S.poison_per_bite = poison_per_bite
S.poison_type = poison_type
@@ -18,11 +18,13 @@
icon_state = "bloodout"
/obj/effect/temp_visual/dir_setting/cult/phase // The veil shifter teleport
icon = 'icons/effects/cult_effects.dmi'
name = "phase glow"
duration = 7
icon_state = "cultin"
/obj/effect/temp_visual/dir_setting/cult/phase/out
icon = 'icons/effects/cult_effects.dmi'
icon_state = "cultout"
/obj/effect/temp_visual/cult/sac
@@ -169,7 +169,9 @@
/obj/effect/temp_visual/fire
icon = 'icons/effects/fire.dmi'
icon_state = "3"
duration = 20
light_range = 3
light_color = LIGHT_COLOR_FIRE
duration = 10
/obj/effect/temp_visual/revenant
name = "spooky lights"
+2
View File
@@ -630,3 +630,5 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
/obj/item/proc/microwave_act(obj/machinery/microwave/M)
if(M && M.dirty < 100)
M.dirty++
/obj/item/proc/on_mob_death(mob/living/L, gibbed)
+11 -2
View File
@@ -10,9 +10,9 @@
// add an entry in change_appearance() if you add to here
var/list/possible_appearances = list("Assistant", "Clown", "Mime",
"Traitor", "Nuke Op", "Cultist", "Clockwork Cultist",
"Revolutionary", "Wizard", "Shadowling", "Xenomorph", "Swarmer",
"Revolutionary", "Wizard", "Shadowling", "Xenomorph", "Xenomorph Maid", "Swarmer",
"Ash Walker", "Deathsquad Officer", "Ian", "Slaughter Demon",
"Laughter Demon")
"Laughter Demon", "Private Security Officer")
var/pushed_over = FALSE //If the cutout is pushed over and has to be righted
var/deceptive = FALSE //If the cutout actually appears as what it portray and not a discolored version
@@ -142,6 +142,10 @@
icon_state = "cutout_fukken_xeno"
if(prob(25))
alpha = 75 //Spooky sneaking!
if("Xenomorph Maid")
name = "lusty xenomorph maid ([rand(1, 999)])"
desc = "A cardboard cutout of a xenomorph maid."
icon_state = "cutout_lusty"
if("Swarmer")
name = "Swarmer ([rand(1, 999)])"
desc = "A cardboard cutout of a swarmer."
@@ -168,6 +172,11 @@
desc = "A cardboard cutout of a laughter demon."
icon = 'icons/mob/mob.dmi'
icon_state = "bowmon"
if("Private Security Officer")
name = "Private Security Officer"
desc = "A cardboard cutout of a private security officer."
icon = 'icons/mob/mob.dmi'
icon_state = "cutout_ntsec"
return 1
/obj/item/cardboard_cutout/setDir(newdir)
+17 -80
View File
@@ -227,12 +227,8 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += "<a href='byond://?src=\ref[src];choice=Ringtone'><img src=pda_bell.png> Set Ringtone</a> | "
dat += "<a href='byond://?src=\ref[src];choice=21'><img src=pda_mail.png> Messages</a><br>"
if (istype(cartridge, /obj/item/weapon/cartridge/syndicate))
dat += "<b>[cartridge:shock_charges] detonation charges left.</b><HR>"
if (istype(cartridge, /obj/item/weapon/cartridge/clown))
dat += "<b>[cartridge:honk_charges] viral files left.</b><HR>"
if (istype(cartridge, /obj/item/weapon/cartridge/mime))
dat += "<b>[cartridge:mime_charges] viral files left.</b><HR>"
if(cartridge)
dat += cartridge.message_header()
dat += "<h4><img src=pda_menu.png> Detected PDAs</h4>"
@@ -244,12 +240,8 @@ GLOBAL_LIST_EMPTY(PDAs)
if (P == src)
continue
dat += "<li><a href='byond://?src=\ref[src];choice=Message;target=\ref[P]'>[P]</a>"
if (istype(cartridge, /obj/item/weapon/cartridge/syndicate) && P.detonate)
dat += " (<a href='byond://?src=\ref[src];choice=Detonate;target=\ref[P]'><img src=pda_boom.png>*Detonate*</a>)"
if (istype(cartridge, /obj/item/weapon/cartridge/clown))
dat += " (<a href='byond://?src=\ref[src];choice=Send Honk;target=\ref[P]'><img src=pda_honk.png>*Send Virus*</a>)"
if (istype(cartridge, /obj/item/weapon/cartridge/mime))
dat += " (<a href='byond://?src=\ref[src];choice=Send Silence;target=\ref[P]'>*Send Virus*</a>)"
if(cartridge)
dat += cartridge.message_special(P)
dat += "</li>"
count++
dat += "</ul>"
@@ -424,16 +416,15 @@ GLOBAL_LIST_EMPTY(PDAs)
tnote = null
if("Ringtone")
var/t = input(U, "Please enter new ringtone", name, ttone) as text
if(in_range(src, U) && loc == U)
if(t)
if(hidden_uplink && (trim(lowertext(t)) == trim(lowertext(lock_code))))
hidden_uplink.interact(U)
to_chat(U, "The PDA softly beeps.")
U << browse(null, "window=pda")
src.mode = 0
else
t = copytext(sanitize(t), 1, 20)
ttone = t
if(in_range(src, U) && loc == U && t)
if(hidden_uplink && (trim(lowertext(t)) == trim(lowertext(lock_code))))
hidden_uplink.interact(U)
to_chat(U, "The PDA softly beeps.")
U << browse(null, "window=pda")
src.mode = 0
else
t = copytext(sanitize(t), 1, 20)
ttone = t
else
U << browse(null, "window=pda")
return
@@ -444,30 +435,9 @@ GLOBAL_LIST_EMPTY(PDAs)
if("MessageAll")
src.send_to_all(U)
if("Send Honk")//Honk virus
if(istype(cartridge, /obj/item/weapon/cartridge/clown))//Cartridge checks are kind of unnecessary since everything is done through switch.
var/obj/item/device/pda/P = locate(href_list["target"])//Leaving it alone in case it may do something useful, I guess.
if(!isnull(P))
if (!P.toff && cartridge:honk_charges > 0)
cartridge:honk_charges--
U.show_message("<span class='notice'>Virus sent!</span>", 1)
P.honkamt = (rand(15,20))
else
to_chat(U, "PDA not found.")
else
U << browse(null, "window=pda")
return
if("Send Silence")//Silent virus
if(istype(cartridge, /obj/item/weapon/cartridge/mime))
var/obj/item/device/pda/P = locate(href_list["target"])
if(!isnull(P))
if (!P.toff && cartridge:mime_charges > 0)
cartridge:mime_charges--
U.show_message("<span class='notice'>Virus sent!</span>", 1)
P.silent = 1
P.ttone = "silence"
else
to_chat(U, "PDA not found.")
if("cart")
if(cartridge)
cartridge.special(U, href_list)
else
U << browse(null, "window=pda")
return
@@ -483,38 +453,6 @@ GLOBAL_LIST_EMPTY(PDAs)
else
M.close()
if("Detonate")//Detonate PDA
if(istype(cartridge, /obj/item/weapon/cartridge/syndicate))
var/obj/item/device/pda/P = locate(href_list["target"])
if(!isnull(P))
if (!P.toff && cartridge:shock_charges > 0)
cartridge:shock_charges--
var/difficulty = 0
if(P.cartridge)
difficulty += P.cartridge.access_medical
difficulty += P.cartridge.access_security
difficulty += P.cartridge.access_engine
difficulty += P.cartridge.access_clown
difficulty += P.cartridge.access_janitor
difficulty += P.cartridge.access_manifest * 2
else
difficulty += 2
if(prob(difficulty * 15) || (P.hidden_uplink))
U.show_message("<span class='danger'>An error flashes on your [src].</span>", 1)
else
U.show_message("<span class='notice'>Success!</span>", 1)
P.explode()
else
to_chat(U, "PDA not found.")
else
U.unset_machine()
U << browse(null, "window=pda")
return
//pAI FUNCTIONS===================================
if("pai")
switch(href_list["option"])
@@ -896,7 +834,7 @@ GLOBAL_LIST_EMPTY(PDAs)
if(T)
T.hotspot_expose(700,125)
if(istype(cartridge, /obj/item/weapon/cartridge/syndicate))
if(istype(cartridge, /obj/item/weapon/cartridge/virus/syndicate))
explosion(T, -1, 1, 3, 4)
else
explosion(T, -1, -1, 2, 3)
@@ -1002,4 +940,3 @@ GLOBAL_LIST_EMPTY(PDAs)
for(var/obj/item/device/pda/P in GLOB.PDAs)
if(!P.owner || P.toff || P.hidden) continue
. += P
return .
@@ -1,7 +1,7 @@
//Clown PDA is slippery.
/obj/item/device/pda/clown
name = "clown PDA"
default_cartridge = /obj/item/weapon/cartridge/clown
default_cartridge = /obj/item/weapon/cartridge/virus/clown
icon_state = "pda-clown"
desc = "A portable microcomputer by Thinktronic Systems, LTD. The surface is coated with polytetrafluoroethylene and banana drippings."
ttone = "honk"
@@ -11,10 +11,10 @@
var/mob/living/carbon/M = AM
if(M.slip(0, 6, src, NO_SLIP_WHEN_WALKING))
if (ishuman(M) && (M.real_name != src.owner))
if (istype(src.cartridge, /obj/item/weapon/cartridge/clown))
var/obj/item/weapon/cartridge/clown/cart = src.cartridge
if(cart.honk_charges < 5)
cart.honk_charges++
if (istype(src.cartridge, /obj/item/weapon/cartridge/virus/clown))
var/obj/item/weapon/cartridge/virus/cart = src.cartridge
if(cart.charges < 5)
cart.charges++
// Special AI/pAI PDAs that cannot explode.
@@ -79,7 +79,7 @@
/obj/item/device/pda/mime
name = "mime PDA"
default_cartridge = /obj/item/weapon/cartridge/mime
default_cartridge = /obj/item/weapon/cartridge/virus/mime
icon_state = "pda-mime"
silent = 1
ttone = "silence"
@@ -134,7 +134,7 @@
icon_state = "pda-miner"
/obj/item/device/pda/syndicate
default_cartridge = /obj/item/weapon/cartridge/syndicate
default_cartridge = /obj/item/weapon/cartridge/virus/syndicate
icon_state = "pda-syndi"
name = "military PDA"
owner = "John Doe"
+11 -19
View File
@@ -96,18 +96,6 @@
access_security = 1
spam_enabled = 1
/obj/item/weapon/cartridge/clown
name = "\improper Honkworks 5.0 cartridge"
icon_state = "cart-clown"
access_clown = 1
var/honk_charges = 5
/obj/item/weapon/cartridge/mime
name = "\improper Gestur-O 1000 cartridge"
icon_state = "cart-mi"
access_mime = 1
var/mime_charges = 5
/obj/item/weapon/cartridge/curator
name = "\improper Lib-Tweet cartridge"
icon_state = "cart-s"
@@ -232,13 +220,6 @@
..()
radio = new /obj/item/radio/integrated/signal(src)
/obj/item/weapon/cartridge/syndicate
name = "\improper Detomatix cartridge"
icon_state = "cart"
access_remote_door = 1
remote_door_id = "smindicate" //Make sure this matches the syndicate shuttle's shield/door id!! //don't ask about the name, testing.
var/shock_charges = 4
/obj/item/weapon/cartridge/proc/unlock()
if (!istype(loc, /obj/item/device/pda))
return
@@ -785,3 +766,14 @@ Code:
return
return menu
//If the cartridge adds a special line to the top of the messaging app
/obj/item/weapon/cartridge/proc/message_header()
return ""
//If the cartridge adds something to each potetial messaging target
/obj/item/weapon/cartridge/proc/message_special(obj/item/device/pda/target)
return ""
//This is called for special abilities of cartridges
/obj/item/weapon/cartridge/proc/special(mov/living/user, list/params)
@@ -0,0 +1,108 @@
/obj/item/weapon/cartridge/virus
name = "Generic Virus PDA cart"
var/charges = 5
/obj/item/weapon/cartridge/virus/proc/send_virus(obj/item/device/pda/target, mob/living/U)
return
/obj/item/weapon/cartridge/virus/message_header()
return "<b>[charges] viral files left.</b><HR>"
/obj/item/weapon/cartridge/virus/message_special(obj/item/device/pda/target)
if (!istype(loc, /obj/item/device/pda))
return "" //Sanity check, this shouldn't be possible.
return " (<a href='byond://?src=\ref[loc];choice=cart;special=virus;target=\ref[target]'>*Send Virus*</a>)"
/obj/item/weapon/cartridge/virus/special(mob/living/user, list/params)
var/obj/item/device/pda/P = locate(params["target"])//Leaving it alone in case it may do something useful, I guess.
send_virus(P,user)
/obj/item/weapon/cartridge/virus/clown
name = "\improper Honkworks 5.0 cartridge"
icon_state = "cart-clown"
desc = "A data cartridge for portable microcomputers. It smells vaguely of banannas"
access_clown = 1
/obj/item/weapon/cartridge/virus/clown/send_virus(obj/item/device/pda/target, mob/living/U)
if(charges <= 0)
to_chat(U, "<span class='notice'>Out of charges.</span>")
return
if(!isnull(target) && !target.toff)
charges--
to_chat(U, "<span class='notice'>Virus Sent!</span>")
target.honkamt = (rand(15,20))
else
to_chat(U, "PDA not found.")
/obj/item/weapon/cartridge/virus/mime
name = "\improper Gestur-O 1000 cartridge"
icon_state = "cart-mi"
access_mime = 1
/obj/item/weapon/cartridge/virus/mime/send_virus(obj/item/device/pda/target, mob/living/U)
if(charges <= 0)
to_chat(U, "<span class='notice'>Out of charges.</span>")
return
if(!isnull(target) && !target.toff)
charges--
to_chat(U, "<span class='notice'>Virus Sent!</span>")
target.silent = 1
target.ttone = "silence"
else
to_chat(U, "PDA not found.")
/obj/item/weapon/cartridge/virus/syndicate
name = "\improper Detomatix cartridge"
icon_state = "cart"
access_remote_door = 1
remote_door_id = "smindicate" //Make sure this matches the syndicate shuttle's shield/door id!! //don't ask about the name, testing.
charges = 4
/obj/item/weapon/cartridge/virus/syndicate/send_virus(obj/item/device/pda/target, mob/living/U)
if(charges <= 0)
to_chat(U, "<span class='notice'>Out of charges.</span>")
return
if(!isnull(target) && !target.toff)
charges--
var/difficulty = 0
if(target.cartridge)
difficulty += target.cartridge.access_medical
difficulty += target.cartridge.access_security
difficulty += target.cartridge.access_engine
difficulty += target.cartridge.access_clown
difficulty += target.cartridge.access_janitor
difficulty += target.cartridge.access_manifest * 2
else
difficulty += 2
if(prob(difficulty * 15) || (target.hidden_uplink))
U.show_message("<span class='danger'>An error flashes on your [src].</span>", 1)
else
U.show_message("<span class='notice'>Success!</span>", 1)
target.explode()
else
to_chat(U, "PDA not found.")
/obj/item/weapon/cartridge/virus/frame
name = "\improper F.R.A.M.E. cartridge"
icon_state = "cart"
var/telecrystals = 0
/obj/item/weapon/cartridge/virus/frame/send_virus(obj/item/device/pda/target, mob/living/U)
if(charges <= 0)
to_chat(U, "<span class='notice'>Out of charges.</span>")
return
if(!isnull(target) && !target.toff)
charges--
var/lock_code = "[rand(100,999)] [pick("Alpha","Bravo","Charlie","Delta","Echo","Foxtrot","Golf","Hotel","India","Juliet","Kilo","Lima","Mike","November","Oscar","Papa","Quebec","Romeo","Sierra","Tango","Uniform","Victor","Whiskey","X-ray","Yankee","Zulu")]"
to_chat(U, "<span class='notice'>Virus Sent! The unlock code to the target is: [lock_code]</span>")
if(!target.hidden_uplink)
var/obj/item/device/uplink/uplink = new(target)
target.hidden_uplink = uplink
target.lock_code = lock_code
else
target.hidden_uplink.hidden_crystals += target.hidden_uplink.telecrystals //Temporarially hide the PDA's crystals, so you can't steal telecrystals.
target.hidden_uplink.telecrystals = telecrystals
telecrystals = 0
target.hidden_uplink.active = TRUE
else
to_chat(U, "PDA not found.")
@@ -36,6 +36,11 @@
A.UpdateButtonIcon()
return 1
/obj/item/device/flashlight/suicide_act(mob/living/carbon/human/user)
user.visible_message("<span class='suicide'>[user] is putting [src] close to [user.p_their()] eyes and turning it on! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (FIRELOSS)
/obj/item/device/flashlight/attack(mob/living/carbon/M, mob/living/carbon/human/user)
add_fingerprint(user)
@@ -52,6 +57,10 @@
to_chat(user, "<span class='warning'>[M] doesn't have a head!</span>")
return
if(flashlight_power < 1)
to_chat(user, "<span class='warning'>\The [src] isn't bright enough to see anything!</span> ")
return
switch(user.zone_selected)
if("eyes")
if((M.head && M.head.flags_cover & HEADCOVERSEYES) || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSEYES) || (M.glasses && M.glasses.flags_cover & GLASSESCOVERSEYES))
@@ -578,6 +578,10 @@
. = ..()
host = loc
/obj/item/borg/projectile_dampen/on_mob_death()
deactivate_field()
. = ..()
/obj/item/borg/projectile_dampen/process()
process_recharge()
process_usage()
+12 -5
View File
@@ -20,11 +20,18 @@
/obj/item/stack/telecrystal/afterattack(obj/item/I, mob/user, proximity)
if(!proximity)
return
if(istype(I, /obj/item))
if(I.hidden_uplink && I.hidden_uplink.active) //No metagaming by using this on every PDA around just to see if it gets used up.
I.hidden_uplink.telecrystals += amount
use(amount)
to_chat(user, "<span class='notice'>You slot [src] into the [I] and charge its internal uplink.</span>")
if(istype(I, /obj/item) && I.hidden_uplink && I.hidden_uplink.active) //No metagaming by using this on every PDA around just to see if it gets used up.
I.hidden_uplink.telecrystals += amount
use(amount)
to_chat(user, "<span class='notice'>You slot [src] into the [I] and charge its internal uplink.</span>")
else if(istype(I, /obj/item/weapon/cartridge/virus/frame))
var/obj/item/weapon/cartridge/virus/frame/cart = I
if(!cart.charges)
to_chat(user, "<span class='notice'>The [cart] is out of charges, it's refusing to accept the [src]</span>")
return
cart.telecrystals += amount
use(amount)
to_chat(user, "<span class='notice'>You slot [src] into the [cart]. The next time it's used, it will also give telecrystals</span>")
/obj/item/stack/telecrystal/five
amount = 5
@@ -107,6 +107,14 @@
turf_type = /turf/open/floor/carpet
resistance_flags = FLAMMABLE
/obj/item/stack/tile/carpet/black
name = "black carpet"
icon_state = "tile-carpet-black"
turf_type = /turf/open/floor/carpet/black
/obj/item/stack/tile/carpet/black/fifty
amount = 50
/obj/item/stack/tile/fakespace
name = "astral carpet"
@@ -92,6 +92,13 @@
if(mapload && access_txt)
access = text2access(access_txt)
/obj/item/weapon/card/id/vv_edit_var(var_name, var_value)
. = ..()
if(.)
switch(var_name)
if("assignment","registered_name")
update_label()
/obj/item/weapon/card/id/attack_self(mob/user)
user.visible_message("<span class='notice'>[user] shows you: \icon[src] [src.name].</span>", \
"<span class='notice'>You show \the [src.name].</span>")
@@ -1,6 +1,6 @@
#define STATION_RENAME_TIME_LIMIT 3000
/obj/item/station_charter
/obj/item/weapon/station_charter
name = "station charter"
icon = 'icons/obj/wizard.dmi'
icon_state = "scroll2"
@@ -16,7 +16,7 @@
var/static/regex/standard_station_regex
/obj/item/station_charter/New()
/obj/item/weapon/station_charter/New()
. = ..()
if(!standard_station_regex)
var/prefixes = jointext(GLOB.station_prefixes, "|")
@@ -26,13 +26,13 @@
var/regexstr = "(([prefixes]) )?(([names]) ?)([suffixes]) ([numerals])"
standard_station_regex = new(regexstr)
/obj/item/station_charter/Destroy()
/obj/item/weapon/station_charter/Destroy()
if(response_timer_id)
deltimer(response_timer_id)
response_timer_id = null
. = ..()
/obj/item/station_charter/attack_self(mob/living/user)
/obj/item/weapon/station_charter/attack_self(mob/living/user)
if(used)
to_chat(user, "The [name_type] has already been named.")
return
@@ -63,7 +63,7 @@
response_timer_id = addtimer(CALLBACK(src, .proc/rename_station, new_name, user.name, user.real_name, key_name(user)), approval_time, TIMER_STOPPABLE)
to_chat(GLOB.admins, "<span class='adminnotice'><b><font color=orange>CUSTOM STATION RENAME:</font></b>[ADMIN_LOOKUPFLW(user)] proposes to rename the [name_type] to [new_name] (will autoapprove in [approval_time / 10] seconds). [ADMIN_SMITE(user)] (<A HREF='?_src_=holder;reject_custom_name=\ref[src]'>REJECT</A>) [ADMIN_CENTCOM_REPLY(user)]</span>")
/obj/item/station_charter/proc/reject_proposed(user)
/obj/item/weapon/station_charter/proc/reject_proposed(user)
if(!user)
return
if(!response_timer_id)
@@ -79,7 +79,7 @@
deltimer(response_timer_id)
response_timer_id = null
/obj/item/station_charter/proc/rename_station(designation, uname, ureal_name, ukey)
/obj/item/weapon/station_charter/proc/rename_station(designation, uname, ureal_name, ukey)
set_station_name(designation)
minor_announce("[ureal_name] has designated your station as [station_name()]", "Captain's Charter", 0)
log_game("[ukey] has renamed the station as [station_name()].")
@@ -91,7 +91,7 @@
if(!unlimited_uses)
used = TRUE
/obj/item/station_charter/admin
/obj/item/weapon/station_charter/admin
unlimited_uses = TRUE
ignores_timeout = TRUE
@@ -99,14 +99,14 @@
/obj/item/weapon/station_charter/flag
name = "nanotrasen banner"
icon = 'icons/obj/items.dmi'
var/name_type = "planet"
name_type = "planet"
icon_state = "banner"
item_state = "banner"
desc = "A cunning device used to claim ownership of planets."
w_class = 5
force = 15
/obj/item/station_charter/flag/rename_station(designation, uname, ureal_name, ukey)
/obj/item/weapon/station_charter/flag/rename_station(designation, uname, ureal_name, ukey)
set_station_name(designation)
minor_announce("[ureal_name] has designated the planet as [station_name()]", "Captain's Banner", 0)
log_game("[ukey] has renamed the planet as [station_name()].")
@@ -116,6 +116,4 @@
if(!unlimited_uses)
used = TRUE
#undef STATION_RENAME_TIME_LIMIT
@@ -484,7 +484,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM
icon_state = "[initial(icon_state)]"
/obj/item/weapon/lighter/ignition_effect(atom/A, mob/user)
. = "<span class='rose'>With a single flick of their wrist, [user] smoothly lights [A] with [src]. Damn [user.p_theyre()] cool.</span>"
if(is_hot())
. = "<span class='rose'>With a single flick of their wrist, [user] smoothly lights [A] with [src]. Damn [user.p_theyre()] cool.</span>"
/obj/item/weapon/lighter/proc/set_lit(new_lit)
lit = new_lit
@@ -581,7 +582,8 @@ CIGARETTE PACKETS ARE IN FANCY.DM
add_overlay(base_overlay)
/obj/item/weapon/lighter/greyscale/ignition_effect(atom/A, mob/user)
. = "<span class='notice'>After some fiddling, [user] manages to light [A] with [src].</span>"
if(is_hot())
. = "<span class='notice'>After some fiddling, [user] manages to light [A] with [src].</span>"
///////////
+25 -23
View File
@@ -19,7 +19,7 @@
var/safety = 1 //if you can zap people with the defibs on harm mode
var/powered = 0 //if there's a cell in the defib with enough power for a revive, blocks paddles from reviving otherwise
var/obj/item/weapon/twohanded/shockpaddles/paddles
var/obj/item/weapon/stock_parts/cell/high/bcell = null
var/obj/item/weapon/stock_parts/cell/high/cell
var/combat = 0 //can we revive through space suits?
var/grab_ghost = FALSE // Do we pull the ghost back into their body?
@@ -29,10 +29,13 @@
update_icon()
return
/obj/item/weapon/defibrillator/get_cell()
return cell
/obj/item/weapon/defibrillator/loaded/Initialize() //starts with hicap
. = ..()
paddles = make_paddles()
bcell = new(src)
cell = new(src)
update_icon()
return
@@ -42,8 +45,8 @@
update_charge()
/obj/item/weapon/defibrillator/proc/update_power()
if(bcell)
if(bcell.charge < paddles.revivecost)
if(cell)
if(cell.charge < paddles.revivecost)
powered = 0
else
powered = 1
@@ -56,21 +59,21 @@
add_overlay("[initial(icon_state)]-paddles")
if(powered)
add_overlay("[initial(icon_state)]-powered")
if(!bcell)
if(!cell)
add_overlay("[initial(icon_state)]-nocell")
if(!safety)
add_overlay("[initial(icon_state)]-emagged")
/obj/item/weapon/defibrillator/proc/update_charge()
if(powered) //so it doesn't show charge if it's unpowered
if(bcell)
var/ratio = bcell.charge / bcell.maxcharge
if(cell)
var/ratio = cell.charge / cell.maxcharge
ratio = Ceiling(ratio*4) * 25
add_overlay("[initial(icon_state)]-charge[ratio]")
/obj/item/weapon/defibrillator/CheckParts(list/parts_list)
..()
bcell = locate(/obj/item/weapon/stock_parts/cell) in contents
cell = locate(/obj/item/weapon/stock_parts/cell) in contents
update_icon()
/obj/item/weapon/defibrillator/ui_action_click()
@@ -105,7 +108,7 @@
toggle_paddles()
else if(istype(W, /obj/item/weapon/stock_parts/cell))
var/obj/item/weapon/stock_parts/cell/C = W
if(bcell)
if(cell)
to_chat(user, "<span class='notice'>[src] already has a cell.</span>")
else
if(C.maxcharge < paddles.revivecost)
@@ -113,15 +116,15 @@
return
if(!user.transferItemToLoc(W, src))
return
bcell = W
cell = W
to_chat(user, "<span class='notice'>You install a cell in [src].</span>")
update_icon()
else if(istype(W, /obj/item/weapon/screwdriver))
if(bcell)
bcell.updateicon()
bcell.loc = get_turf(src.loc)
bcell = null
if(cell)
cell.update_icon()
cell.loc = get_turf(src.loc)
cell = null
to_chat(user, "<span class='notice'>You remove the cell from [src].</span>")
update_icon()
else
@@ -136,7 +139,7 @@
to_chat(user, "<span class='notice'>You silently enable [src]'s safety protocols with the cryptographic sequencer.")
/obj/item/weapon/defibrillator/emp_act(severity)
if(bcell)
if(cell)
deductcharge(1000 / severity)
if(safety)
safety = 0
@@ -200,11 +203,11 @@
update_icon()
/obj/item/weapon/defibrillator/proc/deductcharge(chrgdeductamt)
if(bcell)
if(bcell.charge < (paddles.revivecost+chrgdeductamt))
if(cell)
if(cell.charge < (paddles.revivecost+chrgdeductamt))
powered = 0
update_icon()
if(bcell.use(chrgdeductamt))
if(cell.use(chrgdeductamt))
update_icon()
return 1
else
@@ -213,8 +216,8 @@
/obj/item/weapon/defibrillator/proc/cooldowncheck(mob/user)
spawn(50)
if(bcell)
if(bcell.charge >= paddles.revivecost)
if(cell)
if(cell.charge >= paddles.revivecost)
user.visible_message("<span class='notice'>[src] beeps: Unit ready.</span>")
playsound(get_turf(src), 'sound/machines/defib_ready.ogg', 50, 0)
else
@@ -240,7 +243,7 @@
/obj/item/weapon/defibrillator/compact/loaded/Initialize()
. = ..()
paddles = make_paddles()
bcell = new(src)
cell = new(src)
update_icon()
/obj/item/weapon/defibrillator/compact/combat
@@ -252,7 +255,7 @@
/obj/item/weapon/defibrillator/compact/combat/loaded/Initialize()
. = ..()
paddles = make_paddles()
bcell = new /obj/item/weapon/stock_parts/cell/infinite(src)
cell = new /obj/item/weapon/stock_parts/cell/infinite(src)
update_icon()
/obj/item/weapon/defibrillator/compact/combat/loaded/attackby(obj/item/weapon/W, mob/user, params)
@@ -273,7 +276,6 @@
force = 0
throwforce = 6
w_class = WEIGHT_CLASS_BULKY
flags = NODROP
var/revivecost = 1000
var/cooldown = 0
@@ -15,10 +15,10 @@
det_time = 50
display_timer = 0
var/range = 3
var/times = list()
var/list/times
/obj/item/weapon/grenade/iedcasing/New(loc)
..()
/obj/item/weapon/grenade/iedcasing/Initialize()
. = ..()
add_overlay("improvised_grenade_filled")
add_overlay("improvised_grenade_wired")
times = list("5" = 10, "-1" = 20, "[rand(30,80)]" = 50, "[rand(65,180)]" = 20)// "Premature, Dud, Short Fuse, Long Fuse"=[weighting value]
@@ -33,6 +33,8 @@
..()
var/obj/item/weapon/reagent_containers/food/drinks/soda_cans/can = locate() in contents
if(can)
can.pixel_x = 0 //Reset the sprite's position to make it consistent with the rest of the IED
can.pixel_y = 0
var/mutable_appearance/can_underlay = new(can)
can_underlay.layer = FLOAT_LAYER
can_underlay.plane = FLOAT_PLANE
@@ -43,7 +45,7 @@
if(!active)
if(clown_check(user))
to_chat(user, "<span class='warning'>You light the [name]!</span>")
active = 1
active = TRUE
cut_overlay("improvised_grenade_filled")
icon_state = initial(icon_state) + "_active"
add_fingerprint(user)
@@ -33,3 +33,9 @@
<b>Integrity:</b> Gradient creates slight risk of being overcharged and frying the
circuitry. As a result neurotoxins can cause massive damage."}
return dat
/obj/item/weapon/implantcase/track
name = "implant case - 'Tracking'"
desc = "A glass case containing a tracking implant."
imp_type = /obj/item/weapon/implant/tracking
+183
View File
@@ -0,0 +1,183 @@
/obj/item/weapon/inducer
name = "inducer"
desc = "A tool for inductively charging internal power cells."
icon = 'icons/obj/tools.dmi'
icon_state = "inducer-engi"
item_state = "inducer-engi"
origin_tech = "engineering=4;magnets=4;powerstorage=4"
force = 7
var/powertransfer = 1000
var/opened = FALSE
var/cell_type = /obj/item/weapon/stock_parts/cell/high
var/obj/item/weapon/stock_parts/cell/cell
var/recharging = FALSE
/obj/item/weapon/inducer/Initialize()
. = ..()
if(!cell && cell_type)
cell = new cell_type
/obj/item/weapon/inducer/proc/induce(obj/item/weapon/stock_parts/cell/target, coefficient)
var/totransfer = min(cell.charge,(powertransfer * coefficient))
var/transferred = target.give(totransfer)
cell.use(transferred)
cell.update_icon()
target.update_icon()
/obj/item/weapon/inducer/get_cell()
return cell
/obj/item/weapon/inducer/emp_act(severity)
..()
if(cell)
cell.emp_act()
/obj/item/weapon/inducer/attack_obj(obj/O, mob/living/carbon/user)
if(user.a_intent == INTENT_HARM)
return ..()
if(cantbeused(user))
return
if(recharge(O, user))
return
return ..()
/obj/item/weapon/inducer/proc/cantbeused(mob/user)
if(!user.IsAdvancedToolUser())
to_chat(user, "<span class='warning'>You don't have the dexterity to use \the [src]!</span>")
return TRUE
if(!cell)
to_chat(user, "<span class='warning'>\The [src] doesn't have a power cell installed!</span>")
return TRUE
if(!cell.charge)
to_chat(user, "<span class='warning'>\The [src]'s battery is dead!</span>")
return TRUE
return FALSE
/obj/item/weapon/inducer/attackby(obj/item/weapon/W, mob/user)
if(istype(W,/obj/item/weapon/screwdriver))
playsound(src, W.usesound, 50, 1)
if(!opened)
to_chat(user, "<span class='notice'>You unscrew the battery compartment.</span>")
opened = TRUE
update_icon()
return
else
to_chat(user, "<span class='notice'>You close the battery compartment.</span>")
opened = FALSE
update_icon()
return
if(istype(W,/obj/item/weapon/stock_parts/cell))
if(opened)
if(!cell)
if(!user.transferItemToLoc(W, src))
return
to_chat(user, "<span class='notice'>You insert \the [W] into \the [src].</span>")
cell = W
update_icon()
return
else
to_chat(user, "<span class='notice'>\The [src] already has \a [cell] installed!</span>")
return
if(cantbeused(user))
return
if(recharge(W, user))
return
return ..()
/obj/item/weapon/inducer/proc/recharge(atom/movable/A, mob/user)
if(recharging)
return TRUE
else
recharging = TRUE
var/obj/item/weapon/stock_parts/cell/C = A.get_cell()
var/obj/item/weapon/gun/energy/E
var/obj/O
var/coefficient = 1
if(istype(A, /obj/item/weapon/gun/energy))
coefficient = 0.075 // 14 loops to recharge an egun from 0-1000
E = A
if(istype(A, /obj))
O = A
if(C)
if(C.charge >= C.maxcharge)
to_chat(user, "<span class='notice'>\The [A] is fully charged!</span>")
recharging = FALSE
return TRUE
user.visible_message("[user] starts recharging \the [A] with \the [src]","<span class='notice'>You start recharging [A] with \the [src]</span>")
while(C.charge < C.maxcharge)
if(E)
E.chambered = null // Prevents someone from firing continuously while recharging the gun.
if(do_after(user, 10, target = user) && cell.charge)
induce(C, coefficient)
do_sparks(1, FALSE, A)
if(O)
O.update_icon()
else
break
if(E)
E.recharge_newshot() //We're done charging, so we'll let someone fire it now.
user.visible_message("[user] recharged \the [A]!","<span class='notice'>You recharged \the [A]!</span>")
recharging = FALSE
return TRUE
/obj/item/weapon/inducer/attack(mob/M, mob/user)
if(user.a_intent == INTENT_HARM)
return ..()
if(cantbeused(user))
return
if(recharge(M, user))
return
return ..()
/obj/item/weapon/inducer/attack_self(mob/user)
if(opened && cell)
user.visible_message("[user] removes \the [cell] from \the [src]!","<span class='notice'>You remove \the [cell].</span>")
cell.update_icon()
user.put_in_hands(cell)
cell = null
update_icon()
/obj/item/weapon/inducer/examine(mob/living/M)
..()
if(cell)
to_chat(M, "<span class='notice'>It's display shows: [cell.charge]W</span>")
else
to_chat(M,"<span class='notice'>It's display is dark.</span>")
if(opened)
to_chat(M,"<span class='notice'>It's battery compartment is open.</span>")
/obj/item/weapon/inducer/update_icon()
cut_overlays()
if(opened)
if(!cell)
add_overlay("inducer-nobat")
else
add_overlay("inducer-bat")
/obj/item/weapon/inducer/sci
icon_state = "inducer-sci"
item_state = "inducer-sci"
desc = "A tool for inductively charging internal power cells. This one has a science color scheme, and is less potent than it's engineering counterpart."
cell_type = null
powertransfer = 500
opened = TRUE
/obj/item/weapon/inducer/sci/Initialize()
. = ..()
update_icon()
@@ -317,42 +317,42 @@
revealed = 1
/obj/item/weapon/storage/backpack/dufflebag
name = "dufflebag"
desc = "A large dufflebag for holding extra things."
name = "dufflebag"
desc = "A large dufflebag for holding extra things."
icon_state = "duffle"
item_state = "duffle"
slowdown = 1
max_combined_w_class = 30
/obj/item/weapon/storage/backpack/dufflebag/captain
name = "captain's dufflebag"
desc = "A large dufflebag for holding extra captainly goods."
name = "captain's dufflebag"
desc = "A large dufflebag for holding extra captainly goods."
icon_state = "duffle-captain"
item_state = "duffle-captain"
resistance_flags = 0
/obj/item/weapon/storage/backpack/dufflebag/med
name = "medical dufflebag"
desc = "A large dufflebag for holding extra medical supplies."
name = "medical dufflebag"
desc = "A large dufflebag for holding extra medical supplies."
icon_state = "duffle-med"
item_state = "duffle-med"
/obj/item/weapon/storage/backpack/dufflebag/sec
name = "security dufflebag"
desc = "A large dufflebag for holding extra security supplies and ammunition."
name = "security dufflebag"
desc = "A large dufflebag for holding extra security supplies and ammunition."
icon_state = "duffle-sec"
item_state = "duffle-sec"
/obj/item/weapon/storage/backpack/dufflebag/engineering
name = "industrial dufflebag"
desc = "A large dufflebag for holding extra tools and supplies."
name = "industrial dufflebag"
desc = "A large dufflebag for holding extra tools and supplies."
icon_state = "duffle-eng"
item_state = "duffle-eng"
resistance_flags = 0
/obj/item/weapon/storage/backpack/dufflebag/drone
name = "drone dufflebag"
desc = "A large dufflebag for holding tools and hats."
name = "drone dufflebag"
desc = "A large dufflebag for holding tools and hats."
icon_state = "duffle-drone"
item_state = "duffle-drone"
resistance_flags = FIRE_PROOF
@@ -367,8 +367,8 @@
new /obj/item/device/multitool(src)
/obj/item/weapon/storage/backpack/dufflebag/clown
name = "clown's dufflebag"
desc = "A large dufflebag for holding lots of funny gags!"
name = "clown's dufflebag"
desc = "A large dufflebag for holding lots of funny gags!"
icon_state = "duffle-clown"
item_state = "duffle-clown"
@@ -377,8 +377,8 @@
new /obj/item/weapon/reagent_containers/food/snacks/pie/cream(src)
/obj/item/weapon/storage/backpack/dufflebag/syndie
name = "suspicious looking dufflebag"
desc = "A large dufflebag for holding extra tactical supplies."
name = "suspicious looking dufflebag"
desc = "A large dufflebag for holding extra tactical supplies."
icon_state = "duffle-syndie"
item_state = "duffle-syndie"
origin_tech = "syndicate=1"
@@ -386,14 +386,14 @@
slowdown = 0
/obj/item/weapon/storage/backpack/dufflebag/syndie/med
name = "medical dufflebag"
desc = "A large dufflebag for holding extra tactical medical supplies."
name = "medical dufflebag"
desc = "A large dufflebag for holding extra tactical medical supplies."
icon_state = "duffle-syndiemed"
item_state = "duffle-syndiemed"
/obj/item/weapon/storage/backpack/dufflebag/syndie/surgery
name = "surgery dufflebag"
desc = "A suspicious looking dufflebag for holding surgery tools."
name = "surgery dufflebag"
desc = "A suspicious looking dufflebag for holding surgery tools."
icon_state = "duffle-syndiemed"
item_state = "duffle-syndiemed"
@@ -410,13 +410,13 @@
new /obj/item/device/mmi/syndie(src)
/obj/item/weapon/storage/backpack/dufflebag/syndie/ammo
name = "ammunition dufflebag"
desc = "A large dufflebag for holding extra weapons ammunition and supplies."
name = "ammunition dufflebag"
desc = "A large dufflebag for holding extra weapons ammunition and supplies."
icon_state = "duffle-syndieammo"
item_state = "duffle-syndieammo"
/obj/item/weapon/storage/backpack/dufflebag/syndie/ammo/shotgun
desc = "A large dufflebag, packed to the brim with Bulldog shotgun ammo."
desc = "A large dufflebag, packed to the brim with Bulldog shotgun ammo."
/obj/item/weapon/storage/backpack/dufflebag/syndie/ammo/shotgun/PopulateContents()
for(var/i in 1 to 6)
@@ -426,14 +426,14 @@
new /obj/item/ammo_box/magazine/m12g/dragon(src)
/obj/item/weapon/storage/backpack/dufflebag/syndie/ammo/smg
desc = "A large dufflebag, packed to the brim with C20r magazines."
desc = "A large dufflebag, packed to the brim with C20r magazines."
/obj/item/weapon/storage/backpack/dufflebag/syndie/ammo/smg/PopulateContents()
for(var/i in 1 to 9)
new /obj/item/ammo_box/magazine/smgm45(src)
/obj/item/weapon/storage/backpack/dufflebag/syndie/c20rbundle
desc = "A large dufflebag containing a C20r, some magazines, and a cheap looking suppressor."
desc = "A large dufflebag containing a C20r, some magazines, and a cheap looking suppressor."
/obj/item/weapon/storage/backpack/dufflebag/syndie/c20rbundle/PopulateContents()
new /obj/item/ammo_box/magazine/smgm45(src)
@@ -442,7 +442,7 @@
new /obj/item/weapon/suppressor/specialoffer(src)
/obj/item/weapon/storage/backpack/dufflebag/syndie/bulldogbundle
desc = "A large dufflebag containing a Bulldog, several drums, and a collapsed hardsuit."
desc = "A large dufflebag containing a Bulldog, several drums, and a collapsed hardsuit."
/obj/item/weapon/storage/backpack/dufflebag/syndie/bulldogbundle/PopulateContents()
new /obj/item/ammo_box/magazine/m12g(src)
@@ -451,7 +451,7 @@
new /obj/item/clothing/glasses/thermal/syndi(src)
/obj/item/weapon/storage/backpack/dufflebag/syndie/med/medicalbundle
desc = "A large dufflebag containing a medical equipment, a Donksoft machine gun, a big jumbo box of darts, and a knock-off pair of magboots."
desc = "A large dufflebag containing a medical equipment, a Donksoft machine gun, a big jumbo box of darts, and a knock-off pair of magboots."
/obj/item/weapon/storage/backpack/dufflebag/syndie/med/medicalbundle/PopulateContents()
new /obj/item/clothing/shoes/magboots/syndie(src)
@@ -460,7 +460,7 @@
new /obj/item/ammo_box/foambox/riot(src)
/obj/item/weapon/storage/backpack/dufflebag/syndie/med/medicalbundle
desc = "A large dufflebag containing a medical equipment, a Donksoft machine gun, a big jumbo box of darts, and a knock-off pair of magboots."
desc = "A large dufflebag containing a medical equipment, a Donksoft machine gun, a big jumbo box of darts, and a knock-off pair of magboots."
/obj/item/weapon/storage/backpack/dufflebag/syndie/med/medicalbundle/PopulateContents()
new /obj/item/clothing/shoes/magboots/syndie(src)
@@ -469,7 +469,7 @@
new /obj/item/ammo_box/foambox/riot(src)
/obj/item/weapon/storage/backpack/dufflebag/syndie/med/bioterrorbundle
desc = "A large dufflebag containing a deadly chemicals, a chemical spray, chemical grenade, a Donksoft assault rifle, riot grade darts, a minature syringe gun, and a box of syringes"
desc = "A large dufflebag containing a deadly chemicals, a chemical spray, chemical grenade, a Donksoft assault rifle, riot grade darts, a minature syringe gun, and a box of syringes"
/obj/item/weapon/storage/backpack/dufflebag/syndie/med/bioterrorbundle/PopulateContents()
new /obj/item/weapon/reagent_containers/spray/chemsprayer/bioterror(src)
@@ -489,7 +489,7 @@
new /obj/item/weapon/grenade/plastic/x4(src)
/obj/item/weapon/storage/backpack/dufflebag/syndie/firestarter
desc = "A large dufflebag containing New Russian pyro backpack sprayer, a pistol, a pipebomb, fireproof hardsuit, ammo, and other equipment."
desc = "A large dufflebag containing New Russian pyro backpack sprayer, a pistol, a pipebomb, fireproof hardsuit, ammo, and other equipment."
/obj/item/weapon/storage/backpack/dufflebag/syndie/firestarter/PopulateContents()
new /obj/item/clothing/under/syndicate/soviet(src)
@@ -200,10 +200,10 @@
/obj/item/weapon/storage/pill_bottle,
/obj/item/weapon/ore,
/obj/item/weapon/reagent_containers/food/drinks,
/obj/item/organ/hivelord_core,
/obj/item/organ/regenerative_core,
/obj/item/device/wormhole_jaunter,
/obj/item/weapon/storage/bag/plants,
/obj/item/stack/marker_beacon
/obj/item/stack/marker_beacon
)
@@ -247,10 +247,10 @@
)
/obj/item/weapon/storage/belt/military
name = "chest rig"
desc = "A set of tactical webbing worn by Syndicate boarding parties."
icon_state = "militarywebbing"
item_state = "militarywebbing"
name = "chest rig"
desc = "A set of tactical webbing worn by Syndicate boarding parties."
icon_state = "militarywebbing"
item_state = "militarywebbing"
max_w_class = WEIGHT_CLASS_SMALL
/obj/item/weapon/storage/belt/military/abductor
@@ -568,7 +568,7 @@
/obj/item/weapon/storage/box/deputy/PopulateContents()
for(var/i in 1 to 7)
new /obj/item/clothing/tie/armband/deputy(src)
new /obj/item/clothing/accessory/armband/deputy(src)
/obj/item/weapon/storage/box/metalfoam
name = "box of metal foam grenades"
+157 -116
View File
@@ -1,116 +1,157 @@
/obj/item/weapon/storage/lockbox
name = "lockbox"
desc = "A locked box."
icon_state = "lockbox+l"
item_state = "syringe_kit"
w_class = WEIGHT_CLASS_BULKY
max_w_class = WEIGHT_CLASS_NORMAL
max_combined_w_class = 14 //The sum of the w_classes of all the items in this storage item.
storage_slots = 4
req_access = list(GLOB.access_armory)
var/locked = 1
var/broken = 0
var/icon_locked = "lockbox+l"
var/icon_closed = "lockbox"
var/icon_broken = "lockbox+b"
/obj/item/weapon/storage/lockbox/attackby(obj/item/weapon/W, mob/user, params)
if(W.GetID())
if(broken)
to_chat(user, "<span class='danger'>It appears to be broken.</span>")
return
if(allowed(user))
locked = !locked
if(locked)
icon_state = icon_locked
to_chat(user, "<span class='danger'>You lock the [src.name]!</span>")
close_all()
return
else
icon_state = icon_closed
to_chat(user, "<span class='danger'>You unlock the [src.name]!</span>")
return
else
to_chat(user, "<span class='danger'>Access Denied.</span>")
return
if(!locked)
return ..()
else
to_chat(user, "<span class='danger'>It's locked!</span>")
/obj/item/weapon/storage/lockbox/MouseDrop(over_object, src_location, over_location)
if (locked)
src.add_fingerprint(usr)
to_chat(usr, "<span class='warning'>It's locked!</span>")
return 0
..()
/obj/item/weapon/storage/lockbox/emag_act(mob/user)
if(!broken)
broken = 1
locked = 0
desc += "It appears to be broken."
icon_state = src.icon_broken
if(user)
visible_message("<span class='warning'>\The [src] has been broken by [user] with an electromagnetic card!</span>")
return
/obj/item/weapon/storage/lockbox/show_to(mob/user)
if(locked)
to_chat(user, "<span class='warning'>It's locked!</span>")
else
..()
return
//Check the destination item type for contentto.
/obj/item/weapon/storage/lockbox/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
if(locked)
to_chat(user, "<span class='warning'>It's locked!</span>")
return 0
return ..()
/obj/item/weapon/storage/lockbox/can_be_inserted(obj/item/W, stop_messages = 0)
if(locked)
return 0
return ..()
/obj/item/weapon/storage/lockbox/loyalty
name = "lockbox of mindshield implants"
req_access = list(GLOB.access_security)
/obj/item/weapon/storage/lockbox/loyalty/PopulateContents()
for(var/i in 1 to 3)
new /obj/item/weapon/implantcase/mindshield(src)
new /obj/item/weapon/implanter/mindshield(src)
/obj/item/weapon/storage/lockbox/clusterbang
name = "lockbox of clusterbangs"
desc = "You have a bad feeling about opening this."
req_access = list(GLOB.access_security)
/obj/item/weapon/storage/lockbox/clusterbang/PopulateContents()
new /obj/item/weapon/grenade/clusterbuster(src)
/obj/item/weapon/storage/lockbox/medal
name = "medal box"
desc = "A locked box used to store medals of honor."
icon_state = "medalbox+l"
item_state = "syringe_kit"
w_class = WEIGHT_CLASS_NORMAL
max_w_class = WEIGHT_CLASS_SMALL
storage_slots = 10
req_access = list(GLOB.access_captain)
icon_locked = "medalbox+l"
icon_closed = "medalbox"
icon_broken = "medalbox+b"
/obj/item/weapon/storage/lockbox/medal/PopulateContents()
new /obj/item/clothing/tie/medal/silver/valor(src)
new /obj/item/clothing/tie/medal/bronze_heart(src)
for(var/i in 1 to 3)
new /obj/item/clothing/tie/medal/conduct(src)
new /obj/item/clothing/tie/medal/gold/captain(src)
new /obj/item/clothing/tie/medal/silver/security(src)
new /obj/item/clothing/tie/medal/nobel_science(src)
new /obj/item/clothing/tie/medal/gold/heroism(src)
/obj/item/weapon/storage/lockbox
name = "lockbox"
desc = "A locked box."
icon_state = "lockbox+l"
item_state = "syringe_kit"
w_class = WEIGHT_CLASS_BULKY
max_w_class = WEIGHT_CLASS_NORMAL
max_combined_w_class = 14 //The sum of the w_classes of all the items in this storage item.
storage_slots = 4
req_access = list(GLOB.access_armory)
var/locked = 1
var/broken = 0
var/icon_locked = "lockbox+l"
var/icon_closed = "lockbox"
var/icon_broken = "lockbox+b"
/obj/item/weapon/storage/lockbox/attackby(obj/item/weapon/W, mob/user, params)
if(W.GetID())
if(broken)
to_chat(user, "<span class='danger'>It appears to be broken.</span>")
return
if(allowed(user))
locked = !locked
if(locked)
icon_state = icon_locked
to_chat(user, "<span class='danger'>You lock the [src.name]!</span>")
close_all()
return
else
icon_state = icon_closed
to_chat(user, "<span class='danger'>You unlock the [src.name]!</span>")
return
else
to_chat(user, "<span class='danger'>Access Denied.</span>")
return
if(!locked)
return ..()
else
to_chat(user, "<span class='danger'>It's locked!</span>")
/obj/item/weapon/storage/lockbox/MouseDrop(over_object, src_location, over_location)
if (locked)
src.add_fingerprint(usr)
to_chat(usr, "<span class='warning'>It's locked!</span>")
return 0
..()
/obj/item/weapon/storage/lockbox/emag_act(mob/user)
if(!broken)
broken = 1
locked = 0
desc += "It appears to be broken."
icon_state = src.icon_broken
if(user)
visible_message("<span class='warning'>\The [src] has been broken by [user] with an electromagnetic card!</span>")
return
/obj/item/weapon/storage/lockbox/show_to(mob/user)
if(locked)
to_chat(user, "<span class='warning'>It's locked!</span>")
else
..()
return
//Check the destination item type for contentto.
/obj/item/weapon/storage/lockbox/storage_contents_dump_act(obj/item/weapon/storage/src_object, mob/user)
if(locked)
to_chat(user, "<span class='warning'>It's locked!</span>")
return 0
return ..()
/obj/item/weapon/storage/lockbox/can_be_inserted(obj/item/W, stop_messages = 0)
if(locked)
return 0
return ..()
/obj/item/weapon/storage/lockbox/loyalty
name = "lockbox of mindshield implants"
req_access = list(GLOB.access_security)
/obj/item/weapon/storage/lockbox/loyalty/PopulateContents()
for(var/i in 1 to 3)
new /obj/item/weapon/implantcase/mindshield(src)
new /obj/item/weapon/implanter/mindshield(src)
/obj/item/weapon/storage/lockbox/clusterbang
name = "lockbox of clusterbangs"
desc = "You have a bad feeling about opening this."
req_access = list(GLOB.access_security)
/obj/item/weapon/storage/lockbox/clusterbang/PopulateContents()
new /obj/item/weapon/grenade/clusterbuster(src)
/obj/item/weapon/storage/lockbox/medal
name = "medal box"
desc = "A locked box used to store medals of honor."
icon_state = "medalbox+l"
item_state = "syringe_kit"
w_class = WEIGHT_CLASS_NORMAL
max_w_class = WEIGHT_CLASS_SMALL
storage_slots = 10
max_combined_w_class = 20
req_access = list(GLOB.access_captain)
icon_locked = "medalbox+l"
icon_closed = "medalbox"
icon_broken = "medalbox+b"
can_hold = list(/obj/item/clothing/accessory/medal)
/obj/item/weapon/storage/lockbox/medal/PopulateContents()
new /obj/item/clothing/accessory/medal/silver/valor(src)
new /obj/item/clothing/accessory/medal/bronze_heart(src)
for(var/i in 1 to 3)
new /obj/item/clothing/accessory/medal/conduct(src)
new /obj/item/clothing/accessory/medal/gold/captain(src)
new /obj/item/clothing/accessory/medal/silver/security(src)
new /obj/item/clothing/accessory/medal/plasma(src)
new /obj/item/clothing/accessory/medal/plasma/nobel_science(src)
new /obj/item/clothing/accessory/medal/gold/heroism(src)
/obj/item/weapon/storage/lockbox/secmedal
name = "security medal box"
desc = "A locked box used to store medals to be given to members of the security department."
icon_state = "medalbox+l"
item_state = "syringe_kit"
w_class = WEIGHT_CLASS_NORMAL
max_w_class = WEIGHT_CLASS_SMALL
storage_slots = 10
max_combined_w_class = 20
req_access = list(GLOB.access_hos)
icon_locked = "medalbox+l"
icon_closed = "medalbox"
icon_broken = "medalbox+b"
can_hold = list(/obj/item/clothing/accessory/medal)
/obj/item/weapon/storage/lockbox/secmedal/PopulateContents()
for(var/i in 1 to 3)
new /obj/item/clothing/accessory/medal/silver/security(src)
/obj/item/weapon/storage/lockbox/scimedal
name = "science medal box"
desc = "A locked box used to store medals to be given to members of the science department."
icon_state = "medalbox+l"
item_state = "syringe_kit"
w_class = WEIGHT_CLASS_NORMAL
max_w_class = WEIGHT_CLASS_SMALL
storage_slots = 10
max_combined_w_class = 20
req_access = list(GLOB.access_rd)
icon_locked = "medalbox+l"
icon_closed = "medalbox"
icon_broken = "medalbox+b"
can_hold = list(/obj/item/clothing/accessory/medal)
/obj/item/weapon/storage/lockbox/scimedal/PopulateContents()
for(var/i in 1 to 3)
new /obj/item/clothing/accessory/medal/plasma/nobel_science(src)
@@ -21,15 +21,15 @@
if(has_latches)
if(prob(10))
latches = "double_latch"
if(prob(1))
latches = "triple_latch"
if(prob(1))
latches = "triple_latch"
update_icon()
/obj/item/weapon/storage/toolbox/update_icon()
..()
cut_overlays()
if(has_latches)
add_overlay(latches)
add_overlay(latches)
/obj/item/weapon/storage/toolbox/suicide_act(mob/user)
@@ -140,10 +140,10 @@
max_combined_w_class = 28
storage_slots = 28
attack_verb = list("robusted", "crushed", "smashed")
var/proselytizer_type = /obj/item/clockwork/clockwork_proselytizer/scarab
var/fabricator_type = /obj/item/clockwork/replica_fabricator/scarab
/obj/item/weapon/storage/toolbox/brass/prefilled/PopulateContents()
new proselytizer_type(src)
new fabricator_type(src)
new /obj/item/weapon/screwdriver/brass(src)
new /obj/item/weapon/wirecutters/brass(src)
new /obj/item/weapon/wrench/brass(src)
@@ -151,7 +151,7 @@
new /obj/item/weapon/weldingtool/experimental/brass(src)
/obj/item/weapon/storage/toolbox/brass/prefilled/ratvar
var/slab_type = /obj/item/clockwork/slab/scarab
var/slab_type = /obj/item/clockwork/slab
/obj/item/weapon/storage/toolbox/brass/prefilled/ratvar/PopulateContents()
..()
@@ -159,7 +159,7 @@
/obj/item/weapon/storage/toolbox/brass/prefilled/ratvar/admin
slab_type = /obj/item/clockwork/slab/debug
proselytizer_type = /obj/item/clockwork/clockwork_proselytizer/scarab/debug
fabricator_type = /obj/item/clockwork/replica_fabricator/scarab/debug
/obj/item/weapon/storage/toolbox/artistic
@@ -87,7 +87,7 @@
new /obj/item/device/doorCharge(src)
new /obj/item/device/camera_bug(src)
new /obj/item/device/sbeacondrop/powersink(src)
new /obj/item/weapon/cartridge/syndicate(src)
new /obj/item/weapon/cartridge/virus/syndicate(src)
new /obj/item/weapon/storage/toolbox/syndicate(src) //To actually get to those places
new /obj/item/pizzabox/bomb
+23 -23
View File
@@ -13,7 +13,7 @@
var/stunforce = 7
var/status = 0
var/obj/item/weapon/stock_parts/cell/high/bcell = null
var/obj/item/weapon/stock_parts/cell/high/cell = null
var/hitcost = 1000
var/throw_hit_chance = 35
@@ -21,8 +21,8 @@
user.visible_message("<span class='suicide'>[user] is putting the live [name] in [user.p_their()] mouth! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (FIRELOSS)
/obj/item/weapon/melee/baton/Initialize()
. = ..()
/obj/item/weapon/melee/baton/Initialize()
. = ..()
update_icon()
/obj/item/weapon/melee/baton/throw_impact(atom/hit_atom)
@@ -31,16 +31,16 @@
if(status && prob(throw_hit_chance) && iscarbon(hit_atom))
baton_stun(hit_atom)
/obj/item/weapon/melee/baton/loaded/Initialize() //this one starts with a cell pre-installed.
bcell = new(src)
. = ..()
/obj/item/weapon/melee/baton/loaded/Initialize() //this one starts with a cell pre-installed.
cell = new(src)
. = ..()
/obj/item/weapon/melee/baton/proc/deductcharge(chrgdeductamt)
if(bcell)
if(cell)
//Note this value returned is significant, as it will determine
//if a stun is applied or not
. = bcell.use(chrgdeductamt)
if(status && bcell.charge < hitcost)
. = cell.use(chrgdeductamt)
if(status && cell.charge < hitcost)
//we're below minimum, turn off
status = 0
update_icon()
@@ -50,22 +50,22 @@
/obj/item/weapon/melee/baton/update_icon()
if(status)
icon_state = "[initial(name)]_active"
else if(!bcell)
else if(!cell)
icon_state = "[initial(name)]_nocell"
else
icon_state = "[initial(name)]"
/obj/item/weapon/melee/baton/examine(mob/user)
..()
if(bcell)
to_chat(user, "<span class='notice'>The baton is [round(bcell.percent())]% charged.</span>")
if(cell)
to_chat(user, "<span class='notice'>The baton is [round(cell.percent())]% charged.</span>")
else
to_chat(user, "<span class='warning'>The baton does not have a power source installed.</span>")
to_chat(user, "<span class='warning'>The baton does not have a power source installed.</span>")
/obj/item/weapon/melee/baton/attackby(obj/item/weapon/W, mob/user, params)
if(istype(W, /obj/item/weapon/stock_parts/cell))
var/obj/item/weapon/stock_parts/cell/C = W
if(bcell)
if(cell)
to_chat(user, "<span class='notice'>[src] already has a cell.</span>")
else
if(C.maxcharge < hitcost)
@@ -73,15 +73,15 @@
return
if(!user.transferItemToLoc(W, src))
return
bcell = W
cell = W
to_chat(user, "<span class='notice'>You install a cell in [src].</span>")
update_icon()
else if(istype(W, /obj/item/weapon/screwdriver))
if(bcell)
bcell.updateicon()
bcell.loc = get_turf(src.loc)
bcell = null
if(cell)
cell.update_icon()
cell.forceMove(get_turf(src))
cell = null
to_chat(user, "<span class='notice'>You remove the cell from [src].</span>")
status = 0
update_icon()
@@ -89,13 +89,13 @@
return ..()
/obj/item/weapon/melee/baton/attack_self(mob/user)
if(bcell && bcell.charge > hitcost)
if(cell && cell.charge > hitcost)
status = !status
to_chat(user, "<span class='notice'>[src] is now [status ? "on" : "off"].</span>")
playsound(loc, "sparks", 75, 1, -1)
else
status = 0
if(!bcell)
if(!cell)
to_chat(user, "<span class='warning'>[src] does not have a power source!</span>")
else
to_chat(user, "<span class='warning'>[src] is out of charge.</span>")
@@ -186,8 +186,8 @@
slot_flags = SLOT_BACK
var/obj/item/device/assembly/igniter/sparkler = 0
/obj/item/weapon/melee/baton/cattleprod/Initialize()
. = ..()
/obj/item/weapon/melee/baton/cattleprod/Initialize()
. = ..()
sparkler = new (src)
/obj/item/weapon/melee/baton/cattleprod/baton_stun()
+1 -1
View File
@@ -28,7 +28,7 @@
/obj/item/weapon/melee/baton/cattleprod/attackby(obj/item/I, mob/user, params)//handles sticking a crystal onto a stunprod to make a teleprod
if(istype(I, /obj/item/weapon/ore/bluespace_crystal))
if(!bcell)
if(!cell)
var/obj/item/weapon/melee/baton/cattleprod/teleprod/S = new /obj/item/weapon/melee/baton/cattleprod/teleprod
remove_item_from_storage(user)
qdel(src)
+2
View File
@@ -66,6 +66,7 @@
materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25)
origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get
force = 8 //might or might not be too high, subject to change
w_class = WEIGHT_CLASS_SMALL
throwforce = 8
attack_verb = list("drilled", "screwed", "jabbed")
toolspeed = 0.25
@@ -188,6 +189,7 @@
materials = list(MAT_METAL=150,MAT_SILVER=50,MAT_TITANIUM=25)
origin_tech = "materials=2;engineering=2" //done for balance reasons, making them high value for research, but harder to get
force = 8 //might or might not be too high, subject to change
w_class = WEIGHT_CLASS_SMALL
throwforce = 8
throw_speed = 2
throw_range = 3//it's heavier than a screw driver/wrench, so it does more damage, but can't be thrown as far
+4
View File
@@ -259,3 +259,7 @@ GLOBAL_DATUM_INIT(acid_overlay, /mutable_appearance, mutable_appearance('icons/e
obj_break(damage_type)
return TRUE
return FALSE
//returns how much the object blocks an explosion
/obj/proc/GetExplosionBlock()
CRASH("Unimplemented GetExplosionBlock()")
+9 -3
View File
@@ -23,7 +23,7 @@
var/persistence_replacement //have something WAY too amazing to live to the next round? Set a new path here. Overuse of this var will make me upset.
var/unique_rename = FALSE // can you customize the description/name of the thing?
var/dangerous_possession = FALSE //Admin possession yes/no
/obj/vv_edit_var(vname, vval)
@@ -37,7 +37,7 @@
..()
/obj/Initialize()
. = ..()
. = ..()
if (!armor)
armor = list(melee = 0, bullet = 0, laser = 0, energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0)
if(on_blueprints && isturf(loc))
@@ -182,7 +182,10 @@
/obj/proc/check_uplink_validity()
return 1
/obj/proc/on_mob_move(dir, mob)
/obj/proc/on_mob_move(dir, mob, oldLoc)
return
/obj/proc/on_mob_turn(dir, mob)
return
/obj/vv_get_dropdown()
@@ -193,3 +196,6 @@
..()
if(unique_rename)
to_chat(user, "<span class='notice'>Use a pen on it to rename it or change its description.</span>")
/obj/proc/gang_contraband_value()
return 0
@@ -15,8 +15,8 @@
new /obj/item/clothing/under/sl_suit(src)
new /obj/item/clothing/under/rank/bartender(src)
new /obj/item/clothing/under/rank/bartender(src)
new /obj/item/clothing/tie/waistcoat(src)
new /obj/item/clothing/tie/waistcoat(src)
new /obj/item/clothing/accessory/waistcoat(src)
new /obj/item/clothing/accessory/waistcoat(src)
new /obj/item/clothing/head/soft/black(src)
new /obj/item/clothing/head/soft/black(src)
new /obj/item/clothing/shoes/sneakers/black(src)
@@ -39,8 +39,8 @@
new /obj/item/clothing/under/waiter(src)
new /obj/item/device/radio/headset/headset_srv(src)
new /obj/item/device/radio/headset/headset_srv(src)
new /obj/item/clothing/tie/waistcoat(src)
new /obj/item/clothing/tie/waistcoat(src)
new /obj/item/clothing/accessory/waistcoat(src)
new /obj/item/clothing/accessory/waistcoat(src)
for(var/i in 1 to 3)
new /obj/item/clothing/suit/apron/chef(src)
new /obj/item/clothing/head/soft/mime(src)
@@ -95,8 +95,8 @@
new /obj/item/clothing/suit/toggle/lawyer/black(src)
new /obj/item/clothing/shoes/laceup(src)
new /obj/item/clothing/shoes/laceup(src)
new /obj/item/clothing/tie/lawyers_badge(src)
new /obj/item/clothing/tie/lawyers_badge(src)
new /obj/item/clothing/accessory/lawyers_badge(src)
new /obj/item/clothing/accessory/lawyers_badge(src)
/obj/structure/closet/wardrobe/chaplain_black
name = "chapel wardrobe"
@@ -26,6 +26,7 @@
new /obj/item/clothing/glasses/meson/engine(src)
new /obj/item/weapon/door_remote/chief_engineer(src)
new /obj/item/weapon/pipe_dispenser(src)
new /obj/item/weapon/inducer(src)
/obj/structure/closet/secure_closet/engineering_electrical
name = "electrical supplies locker"
@@ -37,6 +38,8 @@
..()
new /obj/item/clothing/gloves/color/yellow(src)
new /obj/item/clothing/gloves/color/yellow(src)
new /obj/item/weapon/inducer(src)
new /obj/item/weapon/inducer(src)
for(var/i in 1 to 3)
new /obj/item/weapon/storage/toolbox/electrical(src)
for(var/i in 1 to 3)
@@ -24,3 +24,4 @@
new /obj/item/device/laser_pointer(src)
new /obj/item/weapon/door_remote/research_director(src)
new /obj/item/weapon/storage/box/firingpins(src)
new /obj/item/weapon/storage/lockbox/scimedal(src)
@@ -11,7 +11,7 @@
else
new /obj/item/weapon/storage/backpack/satchel/cap(src)
new /obj/item/clothing/neck/cloak/cap(src)
new /obj/item/weapon/storage/daki(src)
new /obj/item/weapon/storage/daki(src)
new /obj/item/weapon/storage/backpack/dufflebag/captain(src)
new /obj/item/clothing/head/crown/fancy(src)
new /obj/item/clothing/suit/captunic(src)
@@ -83,6 +83,9 @@
new /obj/item/weapon/gun/energy/e_gun/hos(src)
new /obj/item/device/flashlight/seclite(src)
new /obj/item/weapon/pinpointer(src)
new /obj/item/clothing/under/rank/head_of_security/grey(src)
new /obj/item/clothing/under/rank/head_of_security/grey(src)
new /obj/item/weapon/storage/lockbox/secmedal(src)
/obj/structure/closet/secure_closet/warden
name = "\proper warden's locker"
@@ -106,7 +109,7 @@
new /obj/item/device/flashlight/seclite(src)
new /obj/item/clothing/gloves/krav_maga/sec(src)
new /obj/item/weapon/door_remote/head_of_security(src)
new /obj/item/weapon/gun/ballistic/shotgun/automatic/combat/compact(src)
new /obj/item/weapon/gun/ballistic/shotgun/automatic/combat/compact(src)
/obj/structure/closet/secure_closet/security
name = "security officer's locker"
@@ -132,28 +135,28 @@
/obj/structure/closet/secure_closet/security/cargo/PopulateContents()
..()
new /obj/item/clothing/tie/armband/cargo(src)
new /obj/item/clothing/accessory/armband/cargo(src)
new /obj/item/device/encryptionkey/headset_cargo(src)
/obj/structure/closet/secure_closet/security/engine
/obj/structure/closet/secure_closet/security/engine/PopulateContents()
..()
new /obj/item/clothing/tie/armband/engine(src)
new /obj/item/clothing/accessory/armband/engine(src)
new /obj/item/device/encryptionkey/headset_eng(src)
/obj/structure/closet/secure_closet/security/science
/obj/structure/closet/secure_closet/security/science/PopulateContents()
..()
new /obj/item/clothing/tie/armband/science(src)
new /obj/item/clothing/accessory/armband/science(src)
new /obj/item/device/encryptionkey/headset_sci(src)
/obj/structure/closet/secure_closet/security/med
/obj/structure/closet/secure_closet/security/med/PopulateContents()
..()
new /obj/item/clothing/tie/armband/medblue(src)
new /obj/item/clothing/accessory/armband/medblue(src)
new /obj/item/device/encryptionkey/headset_med(src)
/obj/structure/closet/secure_closet/detective
@@ -171,7 +174,7 @@
new /obj/item/clothing/head/det_hat(src)
new /obj/item/clothing/gloves/color/black(src)
new /obj/item/clothing/under/rank/det/grey(src)
new /obj/item/clothing/tie/waistcoat(src)
new /obj/item/clothing/accessory/waistcoat(src)
new /obj/item/clothing/suit/det_suit/grey(src)
new /obj/item/clothing/head/fedora(src)
new /obj/item/clothing/shoes/laceup(src)
@@ -435,5 +435,6 @@
suit_store = /obj/item/weapon/gun/ballistic/revolver/mateba
back = /obj/item/weapon/storage/backpack/satchel/leather
head = /obj/item/clothing/head/HoS/syndicate
mask = /obj/item/clothing/mask/cigarette/cigar/havana
mask = /obj/item/clothing/mask/cigarette/cigar/havana
glasses = /obj/item/clothing/glasses/thermal/eyepatch

Some files were not shown because too many files have changed in this diff Show More