mirror of
https://github.com/PolarisSS13/Polaris.git
synced 2026-07-12 08:42:49 +01:00
Security / PseudoCargo Expansion (#6482)
* Security Expansion work. * Weaponized Racism, Stowaways, Meteors * Fix Fix. Prep modular armor for addition. * Fix the boots. * More modular armor work. Now in cargo! * Fixfix * Fixfix * Thank you anxiety very cool. * Make a Stowaway Antag * FixFix
This commit is contained in:
@@ -116,6 +116,18 @@
|
||||
|
||||
return 0
|
||||
|
||||
/datum/language/swarmbot
|
||||
name = LANGUAGE_SWARMBOT
|
||||
desc = "A confusing mechanical language spoken by some form of ancient machine."
|
||||
speech_verb = "clatters"
|
||||
ask_verb = "chatters"
|
||||
exclaim_verb = "shrieks"
|
||||
colour = "changeling"
|
||||
key = "_"
|
||||
flags = NO_STUTTER | RESTRICTED
|
||||
syllables = list("^", "v", "-", ".", "~")
|
||||
space_chance = 60
|
||||
|
||||
//for your antag purposes.
|
||||
/datum/language/minbus
|
||||
name = LANGUAGE_MINBUS
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
var/will_patrol = 0 // If set to 1, will patrol, duh
|
||||
var/patrol_speed = 1 // How many times per tick we move when patrolling
|
||||
var/target_speed = 2 // Ditto for chasing the target
|
||||
var/panic_on_alert = FALSE // Will the bot go faster when the alert level is raised?
|
||||
var/min_target_dist = 1 // How close we try to get to the target
|
||||
var/max_target_dist = 50 // How far we are willing to go
|
||||
var/max_patrol_dist = 250
|
||||
@@ -170,14 +171,20 @@
|
||||
if(!A || !A.loc || prob(1))
|
||||
ignore_list -= A
|
||||
handleRegular()
|
||||
|
||||
var/panic_speed_mod = 0
|
||||
|
||||
if(panic_on_alert)
|
||||
panic_speed_mod = handlePanic()
|
||||
|
||||
if(target && confirmTarget(target))
|
||||
if(Adjacent(target))
|
||||
handleAdjacentTarget()
|
||||
else
|
||||
handleRangedTarget()
|
||||
if(!wait_if_pulled || !pulledby)
|
||||
for(var/i = 1 to target_speed)
|
||||
sleep(20 / (target_speed + 1))
|
||||
for(var/i = 1 to (target_speed + panic_speed_mod))
|
||||
sleep(20 / (target_speed + panic_speed_mod + 1))
|
||||
stepToTarget()
|
||||
if(max_frustration && frustration > max_frustration * target_speed)
|
||||
handleFrustrated(1)
|
||||
@@ -186,7 +193,7 @@
|
||||
lookForTargets()
|
||||
if(will_patrol && !pulledby && !target)
|
||||
if(patrol_path && patrol_path.len)
|
||||
for(var/i = 1 to patrol_speed)
|
||||
for(var/i = 1 to (patrol_speed + panic_speed_mod))
|
||||
sleep(20 / (patrol_speed + 1))
|
||||
handlePatrol()
|
||||
if(max_frustration && frustration > max_frustration * patrol_speed)
|
||||
@@ -205,6 +212,32 @@
|
||||
/mob/living/bot/proc/handleRangedTarget()
|
||||
return
|
||||
|
||||
/mob/living/bot/proc/handlePanic() // Speed modification based on alert level.
|
||||
. = 0
|
||||
switch(get_security_level())
|
||||
if("green")
|
||||
. = 0
|
||||
|
||||
if("yellow")
|
||||
. = 0
|
||||
|
||||
if("violet")
|
||||
. = 0
|
||||
|
||||
if("orange")
|
||||
. = 0
|
||||
|
||||
if("blue")
|
||||
. = 1
|
||||
|
||||
if("red")
|
||||
. = 2
|
||||
|
||||
if("delta")
|
||||
. = 2
|
||||
|
||||
return .
|
||||
|
||||
/mob/living/bot/proc/stepToTarget()
|
||||
if(!target || !target.loc)
|
||||
return
|
||||
|
||||
@@ -38,6 +38,32 @@
|
||||
spawn(600)
|
||||
ignore_list -= g
|
||||
|
||||
/mob/living/bot/cleanbot/handlePanic() // Speed modification based on alert level.
|
||||
. = 0
|
||||
switch(get_security_level())
|
||||
if("green")
|
||||
. = 0
|
||||
|
||||
if("yellow")
|
||||
. = 1
|
||||
|
||||
if("violet")
|
||||
. = 1
|
||||
|
||||
if("orange")
|
||||
. = 1
|
||||
|
||||
if("blue")
|
||||
. = 2
|
||||
|
||||
if("red")
|
||||
. = 2
|
||||
|
||||
if("delta")
|
||||
. = 2
|
||||
|
||||
return .
|
||||
|
||||
/mob/living/bot/cleanbot/lookForTargets()
|
||||
for(var/obj/effect/decal/cleanable/D in view(world.view, src)) // There was some odd code to make it start with nearest decals, it's unnecessary, this works
|
||||
if(confirmTarget(D))
|
||||
|
||||
@@ -300,6 +300,32 @@
|
||||
else if(amount > maxAmount)
|
||||
amount = maxAmount
|
||||
|
||||
/mob/living/bot/floorbot/handlePanic() // Speed modification based on alert level.
|
||||
. = 0
|
||||
switch(get_security_level())
|
||||
if("green")
|
||||
. = 0
|
||||
|
||||
if("yellow")
|
||||
. = 0
|
||||
|
||||
if("violet")
|
||||
. = 0
|
||||
|
||||
if("orange")
|
||||
. = 1
|
||||
|
||||
if("blue")
|
||||
. = 1
|
||||
|
||||
if("red")
|
||||
. = 2
|
||||
|
||||
if("delta")
|
||||
. = 2
|
||||
|
||||
return .
|
||||
|
||||
/* Assembly */
|
||||
|
||||
/obj/item/weapon/storage/toolbox/mechanical/attackby(var/obj/item/stack/tile/floor/T, mob/living/user as mob)
|
||||
|
||||
@@ -49,6 +49,32 @@
|
||||
/mob/living/bot/medbot/handleAdjacentTarget()
|
||||
UnarmedAttack(target)
|
||||
|
||||
/mob/living/bot/medbot/handlePanic() // Speed modification based on alert level.
|
||||
. = 0
|
||||
switch(get_security_level())
|
||||
if("green")
|
||||
. = 0
|
||||
|
||||
if("yellow")
|
||||
. = 0
|
||||
|
||||
if("violet")
|
||||
. = 1
|
||||
|
||||
if("orange")
|
||||
. = 0
|
||||
|
||||
if("blue")
|
||||
. = 1
|
||||
|
||||
if("red")
|
||||
. = 2
|
||||
|
||||
if("delta")
|
||||
. = 2
|
||||
|
||||
return .
|
||||
|
||||
/mob/living/bot/medbot/lookForTargets()
|
||||
for(var/mob/living/carbon/human/H in view(7, src)) // Time to find a patient!
|
||||
if(confirmTarget(H))
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
patrol_speed = 2
|
||||
target_speed = 3
|
||||
|
||||
density = 1
|
||||
|
||||
var/default_icon_state = "secbot"
|
||||
var/idcheck = FALSE // If true, arrests for having weapons without authorization.
|
||||
var/check_records = FALSE // If true, arrests people without a record.
|
||||
@@ -39,6 +41,8 @@
|
||||
name = "Officer Beepsky"
|
||||
desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey."
|
||||
will_patrol = TRUE
|
||||
maxHealth = 130
|
||||
health = 130
|
||||
|
||||
/mob/living/bot/secbot/slime
|
||||
name = "Slime Securitron"
|
||||
@@ -56,6 +60,8 @@
|
||||
/mob/living/bot/secbot/slime/slimesky
|
||||
name = "Doctor Slimesky"
|
||||
desc = "An old friend of Officer Beep O'sky. He prescribes beatings to rowdy slimes so that real doctors don't need to treat the xenobiologists."
|
||||
maxHealth = 130
|
||||
health = 130
|
||||
|
||||
/mob/living/bot/secbot/update_icons()
|
||||
if(on && busy)
|
||||
@@ -219,6 +225,32 @@
|
||||
global_announcer.autosay("[src] is [action] a level [threat] [action != "fighting" ? "suspect" : "threat"] <b>[target_name(target)]</b> in <b>[get_area(src)]</b>.", "[src]", "Security")
|
||||
UnarmedAttack(target)
|
||||
|
||||
/mob/living/bot/secbot/handlePanic() // Speed modification based on alert level.
|
||||
. = 0
|
||||
switch(get_security_level())
|
||||
if("green")
|
||||
. = 0
|
||||
|
||||
if("yellow")
|
||||
. = 0
|
||||
|
||||
if("violet")
|
||||
. = 0
|
||||
|
||||
if("orange")
|
||||
. = 0
|
||||
|
||||
if("blue")
|
||||
. = 1
|
||||
|
||||
if("red")
|
||||
. = 2
|
||||
|
||||
if("delta")
|
||||
. = 2
|
||||
|
||||
return .
|
||||
|
||||
// So Beepsky talks while beating up simple mobs.
|
||||
/mob/living/bot/secbot/proc/insult(var/mob/living/L)
|
||||
if(can_next_insult > world.time)
|
||||
|
||||
@@ -419,6 +419,10 @@
|
||||
|
||||
// Called in life() when the mob has no client.
|
||||
/datum/species/proc/handle_npc(var/mob/living/carbon/human/H)
|
||||
if(H.stat == CONSCIOUS && H.ai_holder)
|
||||
if(H.resting)
|
||||
H.resting = FALSE
|
||||
H.update_canmove()
|
||||
return
|
||||
|
||||
// Called when lying down on a water tile.
|
||||
|
||||
@@ -50,8 +50,10 @@
|
||||
if(H)
|
||||
if(H.looksSynthetic())
|
||||
return "flashing a 'system offline' light"
|
||||
else
|
||||
else if(!H.ai_holder)
|
||||
return show_ssd
|
||||
else
|
||||
return
|
||||
|
||||
/datum/species/proc/get_blood_colour(var/mob/living/carbon/human/H)
|
||||
if(H)
|
||||
|
||||
@@ -62,6 +62,8 @@
|
||||
if(prob(1))
|
||||
H.emote(pick("scratch","jump","roll","tail"))
|
||||
|
||||
..()
|
||||
|
||||
/datum/species/monkey/get_random_name()
|
||||
return "[lowertext(name)] ([rand(100,999)])"
|
||||
|
||||
|
||||
@@ -60,6 +60,8 @@ var/list/mob_hat_cache = list()
|
||||
var/serial_number = 0
|
||||
var/name_override = 0
|
||||
|
||||
var/foreign_droid = FALSE
|
||||
|
||||
holder_type = /obj/item/weapon/holder/drone
|
||||
|
||||
can_be_antagged = FALSE
|
||||
@@ -118,7 +120,8 @@ var/list/mob_hat_cache = list()
|
||||
updatename()
|
||||
|
||||
/mob/living/silicon/robot/drone/init()
|
||||
aiCamera = new/obj/item/device/camera/siliconcam/drone_camera(src)
|
||||
if(!scrambledcodes && !foreign_droid)
|
||||
aiCamera = new/obj/item/device/camera/siliconcam/drone_camera(src)
|
||||
additional_law_channels["Drone"] = ":d"
|
||||
if(!laws) laws = new law_type
|
||||
if(!module) module = new module_type(src)
|
||||
@@ -253,10 +256,10 @@ var/list/mob_hat_cache = list()
|
||||
//For some goddamn reason robots have this hardcoded. Redefining it for our fragile friends here.
|
||||
/mob/living/silicon/robot/drone/updatehealth()
|
||||
if(status_flags & GODMODE)
|
||||
health = 35
|
||||
health = maxHealth
|
||||
stat = CONSCIOUS
|
||||
return
|
||||
health = 35 - (getBruteLoss() + getFireLoss())
|
||||
health = maxHealth - (getBruteLoss() + getFireLoss())
|
||||
return
|
||||
|
||||
//Easiest to check this here, then check again in the robot proc.
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
for(var/mob/living/silicon/robot/drone/D in mob_list)
|
||||
if(D.z != src.z)
|
||||
continue
|
||||
if(D.foreign_droid)
|
||||
continue
|
||||
|
||||
dat += "<BR>[D.real_name] ([D.stat == 2 ? "<font color='red'>INACTIVE</FONT>" : "<font color='green'>ACTIVE</FONT>"])"
|
||||
dat += "<font dize = 9><BR>Cell charge: [D.cell.charge]/[D.cell.maxcharge]."
|
||||
dat += "<BR>Currently located in: [get_area(D)]."
|
||||
|
||||
@@ -56,6 +56,22 @@
|
||||
/obj/item/weapon/stock_parts
|
||||
)
|
||||
|
||||
/obj/item/weapon/gripper/security
|
||||
name = "security gripper"
|
||||
desc = "A simple grasping tool for corporate security work."
|
||||
icon_state = "gripper-sec"
|
||||
|
||||
can_hold = list(
|
||||
/obj/item/weapon/paper,
|
||||
/obj/item/weapon/paper_bundle,
|
||||
/obj/item/weapon/pen,
|
||||
/obj/item/weapon/sample,
|
||||
/obj/item/weapon/forensics/sample_kit,
|
||||
/obj/item/device/taperecorder,
|
||||
/obj/item/device/tape,
|
||||
/obj/item/device/uv_light
|
||||
)
|
||||
|
||||
/obj/item/weapon/gripper/paperwork
|
||||
name = "paperwork gripper"
|
||||
desc = "A simple grasping tool for clerical work."
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/mob/living/silicon/robot/drone/swarm
|
||||
name = "swarm drone"
|
||||
real_name = "drone"
|
||||
icon = 'icons/mob/swarmbot.dmi'
|
||||
icon_state = "swarmer"
|
||||
faction = "swarmer"
|
||||
maxHealth = 75
|
||||
health = 75
|
||||
cell_emp_mult = 0.5
|
||||
universal_speak = 0
|
||||
universal_understand = 1
|
||||
gender = NEUTER
|
||||
pass_flags = PASSTABLE
|
||||
braintype = "Drone"
|
||||
lawupdate = 0
|
||||
density = 1
|
||||
idcard_type = /obj/item/weapon/card/id/syndicate
|
||||
req_access = list(999)
|
||||
integrated_light_power = 3
|
||||
local_transmit = 0
|
||||
|
||||
can_pull_size = ITEMSIZE_NO_CONTAINER
|
||||
can_pull_mobs = MOB_PULL_SMALLER
|
||||
can_enter_vent_with = list(
|
||||
/obj)
|
||||
|
||||
mob_always_swap = 1
|
||||
|
||||
softfall = TRUE
|
||||
|
||||
mob_size = MOB_LARGE
|
||||
|
||||
law_type = /datum/ai_laws/swarm_drone
|
||||
module_type = /obj/item/weapon/robot_module/drone/swarm
|
||||
|
||||
hat_x_offset = 0
|
||||
hat_y_offset = -10
|
||||
|
||||
foreign_droid = TRUE
|
||||
scrambledcodes = TRUE
|
||||
|
||||
holder_type = /obj/item/weapon/holder/drone
|
||||
|
||||
can_be_antagged = TRUE
|
||||
|
||||
var/spell_setup = list(
|
||||
/spell/aoe_turf/conjure/swarmer,
|
||||
/spell/aoe_turf/conjure/forcewall/swarm,
|
||||
/spell/aoe_turf/blink/swarm,
|
||||
/spell/aoe_turf/conjure/swarmer/gunner,
|
||||
/spell/aoe_turf/conjure/swarmer/melee
|
||||
)
|
||||
|
||||
/mob/living/silicon/robot/drone/swarm/Initialize()
|
||||
..()
|
||||
|
||||
add_language(LANGUAGE_SWARMBOT, 1)
|
||||
|
||||
for(var/spell in spell_setup)
|
||||
src.add_spell(new spell, "nano_spell_ready", /obj/screen/movable/spell_master/swarm)
|
||||
|
||||
/mob/living/silicon/robot/drone/swarm/init()
|
||||
..()
|
||||
QDEL_NULL(aiCamera)
|
||||
flavor_text = "Some form of ancient machine."
|
||||
|
||||
/mob/living/silicon/robot/drone/swarm/gunner
|
||||
name = "swarm gunner"
|
||||
real_name = "drone"
|
||||
icon = 'icons/mob/swarmbot.dmi'
|
||||
icon_state = "swarmer_ranged"
|
||||
faction = "swarmer"
|
||||
|
||||
law_type = /datum/ai_laws/swarm_drone/soldier
|
||||
module_type = /obj/item/weapon/robot_module/drone/swarm/ranged
|
||||
|
||||
spell_setup = list(
|
||||
/spell/aoe_turf/conjure/swarmer,
|
||||
/spell/aoe_turf/conjure/forcewall/swarm,
|
||||
/spell/aoe_turf/blink/swarm
|
||||
)
|
||||
|
||||
/mob/living/silicon/robot/drone/swarm/melee
|
||||
name = "swarm melee"
|
||||
real_name = "drone"
|
||||
icon = 'icons/mob/swarmbot.dmi'
|
||||
icon_state = "swarmer_melee"
|
||||
faction = "swarmer"
|
||||
|
||||
law_type = /datum/ai_laws/swarm_drone/soldier
|
||||
module_type = /obj/item/weapon/robot_module/drone/swarm/melee
|
||||
|
||||
spell_setup = list(
|
||||
/spell/aoe_turf/conjure/swarmer,
|
||||
/spell/aoe_turf/conjure/forcewall/swarm,
|
||||
/spell/aoe_turf/blink/swarm
|
||||
)
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
|
||||
/spell/aoe_turf/conjure/swarmer
|
||||
name = "Self Replication"
|
||||
desc = "This ability constructs a standard swarmer shell that may activate at some point."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 120 SECONDS
|
||||
spell_flags = 0
|
||||
invocation = "none"
|
||||
invocation_type = SpI_NONE
|
||||
range = 0
|
||||
|
||||
summon_type = list(/obj/structure/ghost_pod/ghost_activated/swarm_drone/event)
|
||||
|
||||
hud_state = "swarm_replicate"
|
||||
|
||||
/spell/aoe_turf/conjure/swarmer/conjure_animation(var/atom/movable/overlay/animation, var/turf/target)
|
||||
animation.icon_state = "deflect_static"
|
||||
flick("shield2",animation)
|
||||
spawn(1 SECOND)
|
||||
qdel(animation)
|
||||
|
||||
/spell/aoe_turf/conjure/forcewall/swarm
|
||||
name = "Null-Field"
|
||||
desc = "Create a bubble of null-point energy."
|
||||
summon_type = list(/obj/effect/forcefield/swarm)
|
||||
duration = 30 SECONDS
|
||||
charge_max = 60 SECONDS
|
||||
|
||||
school = "conjuration"
|
||||
invocation = "none"
|
||||
invocation_type = SpI_NONE
|
||||
range = 0
|
||||
|
||||
hud_state = "wiz_shield"
|
||||
|
||||
/obj/effect/forcefield/swarm
|
||||
desc = "A pocket of strange energy."
|
||||
name = "Null-Field"
|
||||
icon = 'icons/effects/effects.dmi'
|
||||
icon_state = "shield-old"
|
||||
invisibility = 0
|
||||
|
||||
/spell/aoe_turf/conjure/zeropointwell
|
||||
name = "Zero-Point Well"
|
||||
desc = "This ability constructs a standard zero-point energy well, capable of charging nearby swarmers."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 120 SECONDS
|
||||
spell_flags = 0
|
||||
invocation = "none"
|
||||
invocation_type = SpI_NONE
|
||||
range = 0
|
||||
|
||||
summon_type = list(/obj/structure/cult/pylon/swarm/zp_well)
|
||||
|
||||
hud_state = "swarm_zeropoint"
|
||||
|
||||
/spell/aoe_turf/conjure/zeropointbarricade
|
||||
name = "Zero-Point Barricade"
|
||||
desc = "This ability constructs a standard zero-point energy wall, used to create a secure passageway for allies, and a bastion for defense."
|
||||
|
||||
school = "conjuration"
|
||||
charge_max = 120 SECONDS
|
||||
spell_flags = 0
|
||||
invocation = "none"
|
||||
invocation_type = SpI_NONE
|
||||
range = 0
|
||||
|
||||
summon_type = list(/obj/structure/cult/pylon/swarm/defender)
|
||||
|
||||
hud_state = "swarm_barricade"
|
||||
|
||||
/spell/aoe_turf/blink/swarm
|
||||
name = "Warp"
|
||||
desc = "Your null-point drive jaunts you to a new location."
|
||||
|
||||
school = "abjuration"
|
||||
charge_max = 5 MINUTES
|
||||
spell_flags = Z2NOCAST | IGNOREDENSE
|
||||
invocation = "none"
|
||||
invocation_type = SpI_NONE
|
||||
range = 10
|
||||
inner_radius = 5
|
||||
hud_state = "swarm_warp"
|
||||
|
||||
/spell/aoe_turf/conjure/swarmer/gunner
|
||||
name = "Generate Gunner"
|
||||
desc = "This spell constructs a gunner swarmer shell that may activate at some point."
|
||||
|
||||
school = "conjuration"
|
||||
charge_type = Sp_CHARGES
|
||||
charge_max = 1
|
||||
spell_flags = 0
|
||||
invocation = "none"
|
||||
invocation_type = SpI_NONE
|
||||
range = 0
|
||||
|
||||
summon_type = list(/obj/structure/ghost_pod/ghost_activated/swarm_drone/event/gunner)
|
||||
|
||||
hud_state = "swarm_replicate"
|
||||
|
||||
/spell/aoe_turf/conjure/swarmer/melee
|
||||
name = "Generate Impaler"
|
||||
desc = "This spell constructs an impaler swarmer shell that may activate at some point."
|
||||
|
||||
school = "conjuration"
|
||||
charge_type = Sp_CHARGES
|
||||
charge_max = 1
|
||||
spell_flags = 0
|
||||
invocation = "none"
|
||||
invocation_type = SpI_NONE
|
||||
range = 0
|
||||
|
||||
summon_type = list(/obj/structure/ghost_pod/ghost_activated/swarm_drone/event/melee)
|
||||
|
||||
hud_state = "swarm_replicate"
|
||||
@@ -0,0 +1,162 @@
|
||||
|
||||
//Swarm Assimilator / Breacher
|
||||
/obj/item/weapon/matter_decompiler/swarm
|
||||
name = "matter assimilator"
|
||||
desc = "Used to eat some forms of simple machinery; and large, wall-shaped blocks of metal with energetic fields."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "decompiler_swarm"
|
||||
|
||||
var/field_cooldown = 1 MINUTE
|
||||
var/last_field = 0
|
||||
|
||||
/obj/item/weapon/matter_decompiler/swarm/afterattack(atom/target as mob|obj|turf|area, mob/living/user as mob|obj, proximity, params)
|
||||
|
||||
if(!proximity) return //Not adjacent.
|
||||
|
||||
//We only want to deal with using this on turfs. Specific items aren't important.
|
||||
var/turf/T = get_turf(target)
|
||||
if(!istype(T))
|
||||
return
|
||||
|
||||
//Used to give the right message.
|
||||
var/grabbed_something = FALSE
|
||||
|
||||
for(var/mob/M in T)
|
||||
if(istype(M,/mob/living/simple_mob/animal/passive/lizard) || istype(M,/mob/living/simple_mob/animal/passive/mouse))
|
||||
src.loc.visible_message("<span class='danger'>[src.loc] sucks [M] into its decompiler. There's a horrible crunching noise.</span>","<span class='danger'>It's a bit of a struggle, but you manage to suck [M] into your decompiler. It makes a series of visceral crunching noises.</span>")
|
||||
new/obj/effect/decal/cleanable/blood/splatter(get_turf(src))
|
||||
qdel(M)
|
||||
if(wood)
|
||||
wood.add_charge(2000)
|
||||
if(plastic)
|
||||
plastic.add_charge(2000)
|
||||
return
|
||||
|
||||
else if(istype(M,/mob/living/silicon/robot/drone) && !M.client)
|
||||
|
||||
var/mob/living/silicon/robot/D = src.loc
|
||||
|
||||
if(!istype(D))
|
||||
return
|
||||
|
||||
to_chat(D, "<span class='danger'>You begin decompiling [M].</span>")
|
||||
|
||||
if(!do_after(D,50))
|
||||
to_chat(D, "<span class='danger'>You need to remain still while decompiling such a large object.</span>")
|
||||
return
|
||||
|
||||
if(!M || !D) return
|
||||
|
||||
to_chat(D, "<span class='danger'>You carefully and thoroughly decompile [M], storing as much of its resources as you can within yourself.</span>")
|
||||
qdel(M)
|
||||
new/obj/effect/decal/cleanable/blood/oil(get_turf(src))
|
||||
|
||||
if(metal)
|
||||
metal.add_charge(15000)
|
||||
if(glass)
|
||||
glass.add_charge(15000)
|
||||
if(wood)
|
||||
wood.add_charge(2000)
|
||||
if(plastic)
|
||||
plastic.add_charge(1000)
|
||||
return
|
||||
else
|
||||
continue
|
||||
|
||||
for(var/obj/W in T)
|
||||
//Different classes of items give different commodities.
|
||||
if(istype(W,/obj/structure/girder))
|
||||
if(metal)
|
||||
metal.add_charge(500)
|
||||
else if(istype(W,/obj/machinery/power/emitter))
|
||||
if(metal)
|
||||
metal.add_charge(3000)
|
||||
if(plastic)
|
||||
plastic.add_charge(1000)
|
||||
else if(istype(W,/obj/machinery/space_heater))
|
||||
if(metal)
|
||||
metal.add_charge(1500)
|
||||
if(plastic)
|
||||
plastic.add_charge(750)
|
||||
else if(istype(W,/obj/structure/closet))
|
||||
var/obj/structure/closet/C = W
|
||||
if(!C.opened)
|
||||
continue
|
||||
if(istype(W,/obj/structure/closet/coffin))
|
||||
if(wood)
|
||||
wood.add_charge(1000)
|
||||
else if(istype(W,/obj/structure/closet/crate/plastic))
|
||||
if(plastic)
|
||||
plastic.add_charge(750)
|
||||
else
|
||||
if(metal)
|
||||
metal.add_charge(1000)
|
||||
else
|
||||
continue
|
||||
|
||||
qdel(W)
|
||||
grabbed_something = TRUE
|
||||
|
||||
if(istype(T,/turf/simulated/wall) && (last_field < world.time + field_cooldown))
|
||||
if(!(locate(/obj/effect/temporary_effect/pulse/disintegrate)))
|
||||
last_field = world.time
|
||||
to_chat(user, "<span class='alien'>You deploy an energetic field through \the [T], beginning its deconstruction.</span>")
|
||||
to_chat(user, "<span class='warning'>You should stand back.</span>")
|
||||
new /obj/effect/temporary_effect/pulse/disintegrate(T)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>There is already a disintigration field affecting \the [T].</span>")
|
||||
|
||||
if(grabbed_something)
|
||||
to_chat(user, "<span class='notice'>You deploy your decompiler and clear out the contents of \the [T].</span>")
|
||||
else
|
||||
to_chat(user, "<span class='danger'>Nothing on \the [T] is useful to you.</span>")
|
||||
return
|
||||
|
||||
/obj/effect/temporary_effect/pulse/disintegrate
|
||||
name = "molecular debonding field"
|
||||
desc = "This is something you do not want to near."
|
||||
icon = 'icons/mob/swarmbot.dmi'
|
||||
icon_state = "disintegrate_pulse"
|
||||
light_range = 4
|
||||
light_power = 5
|
||||
light_color = "#00B4D9"
|
||||
pulses_remaining = 5
|
||||
pulse_delay = 2 SECONDS
|
||||
|
||||
/obj/effect/temporary_effect/pulse/disintegrate/emp_act()
|
||||
visible_message("<span class='warning'>\The [src] flickers, before dispersing energetically.</span>")
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/temporary_effect/pulse/disintegrate/on_pulse()
|
||||
var/turf/T = get_turf(src)
|
||||
if(istype(T,/turf/simulated/wall))
|
||||
explosion(get_turf(src), -1, -1, 1, 3, adminlog = 0)
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
/obj/effect/temporary_effect/pulse/disintegrate/Destroy()
|
||||
if(istype(get_turf(src), /turf/simulated/wall))
|
||||
explosion(get_turf(src), -1, 1, 2, 5, adminlog = 1)
|
||||
..()
|
||||
|
||||
/obj/item/weapon/gun/energy/xray/swarm
|
||||
name = "spectral projector"
|
||||
desc = "A high-power laser gun capable of expelling concentrated gamma blasts, which are able to penetrate matter easier than \
|
||||
standard xray beams, resulting in an effective 'anti-everything' energy weapon."
|
||||
icon_state = "xray"
|
||||
item_state = "xray"
|
||||
origin_tech = list(TECH_COMBAT = 5, TECH_MATERIAL = 3, TECH_MAGNET = 2)
|
||||
projectile_type = /obj/item/projectile/beam/shock
|
||||
charge_cost = 175
|
||||
|
||||
self_recharge = TRUE
|
||||
use_external_power = TRUE
|
||||
|
||||
firemodes = list(
|
||||
list(mode_name="kill", projectile_type=/obj/item/projectile/beam/gamma, charge_cost = 300),
|
||||
list(mode_name="deter", projectile_type=/obj/item/projectile/beam/shock, charge_cost = 175),
|
||||
)
|
||||
|
||||
/obj/item/weapon/gun/energy/xray/swarm/Initialize()
|
||||
..()
|
||||
adjust_scale(-1, 1)
|
||||
@@ -521,6 +521,7 @@ var/global/list/robot_modules = list(
|
||||
src.modules += new /obj/item/weapon/gun/energy/taser/xeno/sec/robot(src)
|
||||
src.modules += new /obj/item/taperoll/police(src)
|
||||
src.modules += new /obj/item/weapon/reagent_containers/spray/pepper(src)
|
||||
src.modules += new /obj/item/weapon/gripper/security(src)
|
||||
src.emag = new /obj/item/weapon/gun/energy/laser/mounted(src)
|
||||
|
||||
/obj/item/weapon/robot_module/robot/security/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/obj/item/weapon/robot_module/drone/swarm
|
||||
name = "swarm drone module"
|
||||
var/id
|
||||
|
||||
/obj/item/weapon/robot_module/drone/swarm/New(var/mob/living/silicon/robot/robot)
|
||||
..()
|
||||
|
||||
id = robot.idcard
|
||||
src.modules += id
|
||||
|
||||
src.modules += new /obj/item/weapon/rcd/electric/mounted/borg/swarm(src)
|
||||
src.modules += new /obj/item/device/flash/robot(src)
|
||||
src.modules += new /obj/item/weapon/handcuffs/cable/tape/cyborg(src)
|
||||
src.modules += new /obj/item/weapon/melee/baton/robot(src)
|
||||
src.modules += new /obj/item/weapon/gun/energy/taser/mounted/cyborg/swarm(src)
|
||||
src.modules += new /obj/item/weapon/matter_decompiler/swarm(src)
|
||||
|
||||
/obj/item/weapon/robot_module/drone/swarm/ranged
|
||||
name = "swarm gunner module"
|
||||
|
||||
/obj/item/weapon/robot_module/drone/swarm/ranged/New(var/mob/living/silicon/robot/robot)
|
||||
..()
|
||||
|
||||
src.modules += new /obj/item/weapon/gun/energy/xray/swarm(src)
|
||||
|
||||
/obj/item/weapon/robot_module/drone/swarm/melee/New(var/mob/living/silicon/robot/robot)
|
||||
..()
|
||||
|
||||
src.modules += new /obj/item/weapon/melee/energy/sword/ionic_rapier/lance(src)
|
||||
@@ -117,3 +117,17 @@
|
||||
if(prob(poison_chance))
|
||||
to_chat(L, "<span class='warning'>You feel a tiny prick.</span>")
|
||||
L.reagents.add_reagent(poison_type, poison_per_bite)
|
||||
|
||||
/mob/living/simple_mob/animal/giant_spider/proc/make_spiderling()
|
||||
adjust_scale(icon_scale_x * 0.7, icon_scale_y * 0.7)
|
||||
maxHealth = round(maxHealth * 0.5)
|
||||
health = round(health * 0.5)
|
||||
melee_damage_lower *= 0.7
|
||||
melee_damage_upper *= 0.7
|
||||
|
||||
response_harm = "kicks"
|
||||
|
||||
see_in_dark = max(2, round(see_in_dark * 0.6))
|
||||
|
||||
if(poison_per_bite)
|
||||
poison_per_bite *= 1.3
|
||||
|
||||
@@ -22,3 +22,23 @@
|
||||
speak_emote = list("hisses")
|
||||
|
||||
say_list_type = /datum/say_list/lizard
|
||||
|
||||
/mob/living/simple_mob/animal/passive/lizard/large
|
||||
desc = "A cute, big lizard."
|
||||
maxHealth = 20
|
||||
health = 20
|
||||
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 15
|
||||
|
||||
attack_sharp = TRUE
|
||||
|
||||
/mob/living/simple_mob/animal/passive/lizard/large/Initialize()
|
||||
..()
|
||||
adjust_scale(rand(12, 20) / 10)
|
||||
|
||||
/mob/living/simple_mob/animal/passive/lizard/large/defensive
|
||||
maxHealth = 30
|
||||
health = 30
|
||||
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/retaliate/cooperative
|
||||
|
||||
@@ -97,6 +97,17 @@
|
||||
body_color = "brown"
|
||||
icon_state = "mouse_brown"
|
||||
|
||||
/mob/living/simple_mob/animal/passive/mouse/rat
|
||||
name = "rat"
|
||||
maxHealth = 20
|
||||
health = 20
|
||||
|
||||
ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive
|
||||
|
||||
/mob/living/simple_mob/animal/passive/mouse/rat/Initialize()
|
||||
..()
|
||||
adjust_scale(1.2)
|
||||
|
||||
//TOM IS ALIVE! SQUEEEEEEEE~K :)
|
||||
/mob/living/simple_mob/animal/passive/mouse/brown/Tom
|
||||
name = "Tom"
|
||||
|
||||
@@ -425,6 +425,20 @@ proc/is_blind(A)
|
||||
lname = "<span class='name'>[lname]</span> "
|
||||
M << "<span class='deadsay'>" + create_text_tag("dead", "DEAD:", M.client) + " [lname][follow][message]</span>"
|
||||
|
||||
/proc/say_dead_object(var/message, var/obj/subject = null)
|
||||
for(var/mob/M in player_list)
|
||||
if(M.client && ((!istype(M, /mob/new_player) && M.stat == DEAD) || (M.client.holder && M.client.holder.rights)) && M.is_preference_enabled(/datum/client_preference/show_dsay))
|
||||
var/follow
|
||||
var/lname = "Game Master"
|
||||
if(M.forbid_seeing_deadchat && !M.client.holder)
|
||||
continue
|
||||
|
||||
if(subject)
|
||||
lname = "[subject.name] ([subject.x],[subject.y],[subject.z])"
|
||||
|
||||
lname = "<span class='name'>[lname]</span> "
|
||||
M << "<span class='deadsay'>" + create_text_tag("event_dead", "EVENT:", M.client) + " [lname][follow][message]</span>"
|
||||
|
||||
//Announces that a ghost has joined/left, mainly for use with wizards
|
||||
/proc/announce_ghost_joinleave(O, var/joined_ghosts = 1, var/message = "")
|
||||
var/client/C
|
||||
|
||||
Reference in New Issue
Block a user