Removes Old Deprecated Stuff (#15241)

This commit is contained in:
SleepyGemmy
2023-01-02 14:27:29 +01:00
committed by GitHub
parent 8cd958c560
commit 5179dad83e
164 changed files with 546 additions and 8217 deletions
-419
View File
@@ -1,419 +0,0 @@
#define SECBOT_IDLE 0 // idle
#define SECBOT_HUNT 1 // found target, hunting
#define SECBOT_ARREST 2 // arresting target
#define SECBOT_START_PATROL 3 // start patrol
#define SECBOT_WAIT_PATROL 4 // waiting for signals
#define SECBOT_PATROL 5 // patrolling
#define SECBOT_SUMMON 6 // summoned by PDA
#define SECBOT_STOP 7 // basically 'do nothing'
#define SECBOT_FOLLOW 8 // follows a target
/mob/living/bot/secbot/ed209
name = "Security Assault Robot"
desc = "A security robot. He looks less than thrilled."
icon = 'icons/obj/aibots.dmi'
icon_state = "ed2090"
density = 0
health = 100
maxHealth = 100
bot_version = "2.5"
is_ranged = 1
preparing_arrest_sounds = new()
a_intent = I_HURT
mob_bump_flag = HEAVY
mob_swap_flags = ~HEAVY
mob_push_flags = HEAVY
var/shot_delay = 4
var/last_shot = 0
// vars for verbal commands
var/short_name = null
var/list/command_buffer = list()
var/list/known_commands = list("stay", "stop", "arrest", "detain", "follow", "patrol")
var/emote_hear = "states"
move_to_delay = 3
/mob/living/bot/secbot/ed209/Initialize()
. = ..()
if(!short_name)
short_name = name
/mob/living/bot/secbot/ed209/hear_say(var/message, var/verb = "says", var/datum/language/language = null, var/alt_name = "", var/italics = 0, var/mob/speaker = null, var/sound/speech_sound, var/sound_vol)
if(thinking_enabled && !stat && has_ui_access(speaker))
command_buffer.Add(speaker)
command_buffer.Add(lowertext(html_decode(message)))
return 0
/mob/living/bot/secbot/ed209/hear_radio(var/message, var/verb="says", var/datum/language/language=null, var/part_a, var/part_b, var/part_c, var/mob/speaker = null, var/hard_to_hear = 0)
if(thinking_enabled && !stat && has_ui_access(speaker))
command_buffer.Add(speaker)
command_buffer.Add(lowertext(html_decode(message)))
return 0
/mob/living/bot/secbot/ed209/think()
while(command_buffer.len > 0)
var/mob/speaker = command_buffer[1]
var/text = command_buffer[2]
var/filtered_name = lowertext(html_decode(name))
var/filtered_short = lowertext(html_decode(short_name))
if(dd_hasprefix(text,filtered_name))
var/substring = copytext(text,length(filtered_name)+1) //get rid of the name.
listen(speaker,substring)
else if(dd_hasprefix(text,filtered_short))
var/substring = copytext(text,length(filtered_short)+1) //get rid of the name.
listen(speaker,substring)
command_buffer.Remove(command_buffer[1],command_buffer[2])
..()
switch(mode)
if(SECBOT_FOLLOW)
follow_target()
if(SECBOT_STOP)
commanded_stop()
/mob/living/bot/secbot/ed209/on_think_disabled()
..()
command_buffer.Cut()
/mob/living/bot/secbot/ed209/proc/follow_target()
if(!target)
return
if(target in view(7, src))
walk_to(src,target,1,move_to_delay)
/mob/living/bot/secbot/ed209/proc/commanded_stop() //basically a proc that runs whenever we are asked to stay put. Probably going to remain unused.
return
/mob/living/bot/secbot/ed209/proc/listen(var/mob/speaker, var/text)
for(var/command in known_commands)
if(findtext(text,command))
switch(command)
if("stay")
if(stay_command(speaker,text)) //find a valid command? Stop. Dont try and find more.
break
if("stop")
if(stop_command(speaker,text))
break
if("arrest")
if(arrest_command(speaker,text))
break
if("detain")
if(arrest_command(speaker,text))
break
if("follow")
if(follow_command(speaker,text))
break
if("patrol")
if(patrol_command(speaker, text))
break
return 1
//returns a list of everybody we wanna do stuff with.
/mob/living/bot/secbot/ed209/proc/get_target_by_name(var/text)
var/list/possible_targets = hearers(src,10)
for(var/mob/M in possible_targets)
if(findtext(text, "[M]"))
return M
else
var/list/parsed_name = splittext(replace_characters(lowertext(html_decode("[M]")),list("-"=" ", "."=" ", "," = " ", "'" = " ")), " ") //this big MESS is basically 'turn this into words, no punctuation, lowercase so we can check first name/last name/etc'
for(var/a in parsed_name)
if(a == "the" || length(a) < 2) //get rid of shit words.
continue
if(findtext(text,"[a]"))
return M
return null
/mob/living/bot/secbot/ed209/proc/arrest_command(var/mob/speaker,var/text)
target = null //want me to attack something? Well I better forget my old target.
walk_to(src,0)
target = get_target_by_name(text)
if(!(target in view(7, src)))
return 0
if(findtext(text,"detain"))
arrest_type = 1
else
arrest_type = 0
if(isnull(target))
custom_emote(AUDIBLE_MESSAGE, "[emote_hear], \"Error, unit is unable to find target in view range!\"")
return 0
else
if(ishuman(target))
idcheck = TRUE
var/mob/living/carbon/human/H = target
var/perpname = H.name
var/obj/item/card/id/id = H.GetIdCard()
if(id)
perpname = id.registered_name
var/datum/record/general/R = SSrecords.find_record("name", perpname)
if(R && R.security)
R.security.criminal = "*Arrest*"
else
custom_emote(AUDIBLE_MESSAGE, "[emote_hear], \"Warning, [target] does not have Security records! Enabling security records check mode!\"")
check_records = TRUE
mode = SECBOT_HUNT
custom_emote(AUDIBLE_MESSAGE, "[emote_hear], \"[arrest_type ? ("Detaining") : ("Arresting")] [target]\"")
/mob/living/bot/secbot/ed209/proc/stay_command(var/mob/speaker,var/text)
walk_to(src, src, 0, move_to_delay)
mode = SECBOT_IDLE
auto_patrol = 0
target = null
check_records = FALSE
custom_emote(AUDIBLE_MESSAGE, "[emote_hear], \"Roger that, going into idle mode. Auto patrol disabled.\"")
return 1
/mob/living/bot/secbot/ed209/proc/stop_command(var/mob/speaker,var/text)
if(!on)
return
walk_to(src, src, 0, move_to_delay)
check_records = FALSE
custom_emote(AUDIBLE_MESSAGE, "[emote_hear], \"Roger that, unit going offline.\"")
turn_off()
return 1
/mob/living/bot/secbot/ed209/proc/patrol_command(var/mob/speaker,var/text)
walk_to(src, src, 0, move_to_delay)
mode = SECBOT_IDLE
auto_patrol = 1
target = null
custom_emote(AUDIBLE_MESSAGE, "[emote_hear], \"Roger that, starting patrol now.\"")
return 1
/mob/living/bot/secbot/ed209/proc/follow_command(var/mob/speaker,var/text)
//we can assume 'stop following' is handled by stop_command
if(findtext(text,"me"))
mode = SECBOT_FOLLOW
target = speaker
custom_emote(AUDIBLE_MESSAGE, "[emote_hear], \"Roger that, following you\"")
return 1
target = get_target_by_name(text)
if(!(target in view(7, src)))
return 0
if(!target)
return 0
mode = SECBOT_FOLLOW
custom_emote(AUDIBLE_MESSAGE, "[emote_hear], \"Roger that, following [target]\"")
return 1
/mob/living/bot/secbot/ed209/verb/change_name()
set name = "Change nickname"
set category = "IC"
set src in view(1)
if(!usr.mind) return 0
// Check if they are set to arrest
if(ishuman(usr))
var/mob/living/carbon/human/H = usr
var/perpname = H.name
var/obj/item/card/id/id = H.GetIdCard()
if(id)
perpname = id.registered_name
var/datum/record/general/R = SSrecords.find_record("name", perpname)
if(R && R.security && R.security.criminal == "*Arrest*")
to_chat(usr, "<span class='warning'>Warning, you do not have access!</span>")
// Check if they have access to the bot
if(!has_ui_access(usr))
to_chat(usr, "<span class='warning'>Warning, you do not have access!</span>")
return 0
var/short_input = sanitizeSafe(input("What do you want [src] respond to?", , ""), MAX_NAME_LEN)
if(src && short_input && !usr.stat && in_range(usr,src))
short_name = short_input
return 1
/mob/living/bot/secbot/ed209/update_icon()
if(on && is_attacking)
icon_state = "ed209-c"
else
icon_state = "ed209[on]"
/mob/living/bot/secbot/ed209/explode()
visible_message("<span class='danger'>[src] blows apart!</span>")
var/turf/Tsec = get_turf(src)
new /obj/item/secbot_assembly/ed209_assembly(Tsec)
var/obj/item/gun/energy/taser/G = new /obj/item/gun/energy/taser(Tsec)
G.power_supply.charge = 0
if(prob(50))
new /obj/item/robot_parts/l_leg(Tsec)
if(prob(50))
new /obj/item/robot_parts/r_leg(Tsec)
if(prob(50))
if(prob(50))
new /obj/item/clothing/head/helmet(Tsec)
else
new /obj/item/clothing/suit/armor/vest(Tsec)
spark(src, 3, alldirs)
new /obj/effect/decal/cleanable/blood/oil(Tsec)
qdel(src)
/mob/living/bot/secbot/ed209/RangedAttack(var/atom/A)
if(!(target in view(7, src)))
walk_to(src, target, 6, move_to_delay)
return
if(last_shot + shot_delay > world.time)
to_chat(src, "You are not ready to fire yet!")
return
last_shot = world.time
var/projectile = /obj/item/projectile/beam/stun
if(emagged)
projectile = /obj/item/projectile/beam
playsound(loc, emagged ? 'sound/weapons/laser1.ogg' : 'sound/weapons/Taser.ogg', 50, 1)
var/obj/item/projectile/P = new projectile(loc)
var/def_zone = get_exposed_defense_zone(A)
P.launch_projectile(A, def_zone)
// Assembly
/obj/item/secbot_assembly/ed209_assembly
name = "security assault robot assembly"
desc = "Some sort of bizarre assembly."
icon = 'icons/obj/aibots.dmi'
icon_state = "ed209_frame"
item_state = "ed209_frame"
created_name = "Security Assault Robot"
var/lasercolor = ""
/obj/item/secbot_assembly/ed209_assembly/attackby(var/obj/item/W as obj, var/mob/user as mob)
..()
if(W.ispen())
var/t = sanitizeSafe(input(user, "Enter new robot name", name, created_name), MAX_NAME_LEN)
if(!t)
return
if(!in_range(src, usr) && src.loc != usr)
return
created_name = t
return
switch(build_step)
if(0, 1)
if(istype(W, /obj/item/robot_parts/l_leg) || istype(W, /obj/item/robot_parts/r_leg))
user.drop_from_inventory(W,get_turf(src))
qdel(W)
build_step++
to_chat(user, "<span class='notice'>You add the robot leg to [src].</span>")
name = "legs/frame assembly"
if(build_step == 1)
item_state = "ed209_leg"
icon_state = "ed209_leg"
else
item_state = "ed209_legs"
icon_state = "ed209_legs"
return 1
if(2)
if(istype(W, /obj/item/clothing/accessory/armor_plate))
user.drop_from_inventory(W,get_turf(src))
qdel(W)
build_step++
to_chat(user, "<span class='notice'>You add the armor to [src].</span>")
name = "vest/legs/frame assembly"
item_state = "ed209_shell"
icon_state = "ed209_shell"
return 1
if(3)
if(W.iswelder())
var/obj/item/weldingtool/WT = W
if(WT.use(0, user))
build_step++
name = "shielded frame assembly"
to_chat(user, "<span class='notice'>You welded the armor to [src].</span>")
return 1
if(4)
if(istype(W, /obj/item/clothing/head/helmet))
user.drop_from_inventory(W,get_turf(src))
qdel(W)
build_step++
to_chat(user, "<span class='notice'>You add the helmet to [src].</span>")
name = "covered and shielded frame assembly"
item_state = "ed209_hat"
icon_state = "ed209_hat"
return 1
if(5)
if(isprox(W))
user.drop_from_inventory(W,get_turf(src))
qdel(W)
build_step++
to_chat(user, "<span class='notice'>You add the prox sensor to [src].</span>")
name = "covered, shielded and sensored frame assembly"
item_state = "ed209_prox"
icon_state = "ed209_prox"
return 1
if(6)
if(W.iscoil())
var/obj/item/stack/cable_coil/C = W
if (C.get_amount() < 1)
to_chat(user, "<span class='warning'>You need one coil of wire to wire [src].</span>")
return
to_chat(user, "<span class='notice'>You start to wire [src].</span>")
if(W.use_tool(src, user, 40, volume = 50) && build_step == 6)
if(C.use(1))
build_step++
to_chat(user, "<span class='notice'>You wire the security assault robot assembly.</span>")
name = "wired security assault robot assembly"
return
if(7)
if(istype(W, /obj/item/gun/energy/disruptorpistol))
name = "taser security assault robot assembly"
build_step++
to_chat(user, "<span class='notice'>You add [W] to [src].</span>")
item_state = "ed209_taser"
icon_state = "ed209_taser"
user.drop_from_inventory(W,get_turf(src))
qdel(W)
return 1
if(8)
if(W.isscrewdriver())
var/turf/T = get_turf(user)
to_chat(user, "<span class='notice'>Now attaching the gun to the frame...</span>")
if(!W.use_tool(src, user, 40, volume = 50)) return
if(get_turf(user) == T && build_step == 8)
build_step++
name = "armed [name]"
to_chat(user, "<span class='notice'>Taser gun attached.</span>")
if(9)
if(istype(W, /obj/item/cell))
build_step++
to_chat(user, "<span class='notice'>You complete the security assault robot.</span>")
var/turf/T = get_turf(src)
new /mob/living/bot/secbot/ed209(T,created_name,lasercolor)
user.drop_from_inventory(W,get_turf(src))
qdel(W)
qdel(src)
return 1
#undef SECBOT_IDLE
#undef SECBOT_HUNT
#undef SECBOT_ARREST
#undef SECBOT_START_PATROL
#undef SECBOT_WAIT_PATROL
#undef SECBOT_PATROL
#undef SECBOT_SUMMON
#undef SECBOT_STOP
#undef SECBOT_FOLLOW
-398
View File
@@ -1,398 +0,0 @@
/mob/living/bot/floorbot
name = "Floorbot"
desc = "A little floor repairing robot, he looks so excited!"
icon_state = "floorbot0"
req_one_access = list(access_construction, access_robotics)
var/amount = 10 // 1 for tile, 2 for lattice
var/maxAmount = 60
var/tilemake = 0 // When it reaches 100, bot makes a tile
var/repairing = 0
var/improvefloors = 0
var/eattiles = 0
var/maketiles = 0
var/targetdirection = null
var/list/path = list()
var/list/ignorelist = list()
var/turf/target
var/floor_build_type = /decl/flooring/tiling // Basic steel floor.
/mob/living/bot/floorbot/update_icon()
if(repairing)
icon_state = "floorbot-c"
else if(amount > 0)
icon_state = "floorbot[on]"
else
icon_state = "floorbot[on]e"
/mob/living/bot/floorbot/attack_hand(var/mob/user)
if (!has_ui_access(user))
to_chat(user, "<span class='warning'>The unit's interface refuses to unlock!</span>")
return
user.set_machine(src)
var/dat = ""
dat += "Status: <A href='?src=\ref[src];operation=start'>[src.on ? "On" : "Off"]</A><BR>"
dat += "Maintenance panel is [open ? "opened" : "closed"]<BR>"
//dat += "Tiles left: [amount]<BR>"
dat += "Behvaiour controls are [locked ? "locked" : "unlocked"]<BR>"
if(!locked || issilicon(user))
dat += "Improves floors: <A href='?src=\ref[src];operation=improve'>[improvefloors ? "Yes" : "No"]</A><BR>"
dat += "Finds tiles: <A href='?src=\ref[src];operation=tiles'>[eattiles ? "Yes" : "No"]</A><BR>"
dat += "Make singles pieces of metal into tiles when empty: <A href='?src=\ref[src];operation=make'>[maketiles ? "Yes" : "No"]</A><BR>"
var/bmode
if(targetdirection)
bmode = dir2text(targetdirection)
else
bmode = "Disabled"
dat += "<BR><BR>Bridge Mode : <A href='?src=\ref[src];operation=bridgemode'>[bmode]</A><BR>"
var/datum/browser/bot_win = new(user, "autorepair", "Automatic Repairbot v1.2 Controls")
bot_win.set_content(dat)
bot_win.open()
/mob/living/bot/floorbot/emag_act(var/remaining_charges, var/mob/user)
. = ..()
if(!emagged)
emagged = 1
if(user)
to_chat(user, "<span class='notice'>The [src] buzzes and beeps.</span>")
return 1
/mob/living/bot/floorbot/Topic(href, href_list)
if(..())
return
usr.set_machine(src)
add_fingerprint(usr)
if (!has_ui_access(usr))
to_chat(usr, "<span class='warning'>Insufficient permissions.</span>")
return
switch(href_list["operation"])
if("start")
if (on)
turn_off()
else
turn_on()
if("improve")
improvefloors = !improvefloors
if("tiles")
eattiles = !eattiles
if("make")
maketiles = !maketiles
if("bridgemode")
switch(targetdirection)
if(null)
targetdirection = 1
if(1)
targetdirection = 2
if(2)
targetdirection = 4
if(4)
targetdirection = 8
if(8)
targetdirection = null
else
targetdirection = null
attack_hand(usr)
/mob/living/bot/floorbot/turn_off()
..()
target = null
path = list()
ignorelist = list()
/mob/living/bot/floorbot/Life()
..()
if(!on)
return
++tilemake
if(tilemake >= 100)
tilemake = 0
addTiles(1)
if(prob(5))
custom_emote(AUDIBLE_MESSAGE, "makes an excited booping beeping sound!")
/mob/living/bot/floorbot/think()
..()
if (!on)
return
if(amount && !emagged)
if(!target && targetdirection) // Building a bridge
var/turf/T = get_step(src, targetdirection)
while(T in range(src))
if(istype(T, /turf/space))
target = T
break
T = get_step(T, targetdirection)
if(!target) // Fixing floors
for(var/turf/T in view(src))
if (istype(T.loc, /area/space))
continue
if(T in ignorelist)
continue
if(istype(T, /turf/space))
if(get_turf(T) == loc || prob(40)) // So they target the same tile all the time
target = T
if(improvefloors && istype(T, /turf/simulated/floor))
var/turf/simulated/floor/F = T
if(!F.flooring && (get_turf(T) == loc || prob(40)))
target = T
if(emagged) // Time to griff
for(var/turf/simulated/floor/D in view(src))
if (istype(D.loc, /area/space))
continue
if(D in ignorelist)
continue
target = D
break
if(!target && amount < maxAmount && eattiles || maketiles) // Eat tiles
if(eattiles)
for(var/obj/item/stack/tile/floor/T in view(src))
if(T in ignorelist)
continue
target = T
break
if(maketiles && !target)
for(var/obj/item/stack/material/steel/T in view(src))
if(T in ignorelist)
continue
target = T
break
if(target && get_turf(target) == loc)
INVOKE_ASYNC(src, .proc/UnarmedAttack, target)
if(target && get_turf(target) != loc && !path.len)
spawn(0)
path = AStar(loc, get_turf(target), /turf/proc/AdjacentTurfsSpace, /turf/proc/Distance, 0, 30, id = botcard)
if(!path)
path = list()
ignorelist += target
target = null
if(path.len)
step_to(src, path[1])
path -= path[1]
if(ignorelist.len) // Don't stick forever
for(var/T in ignorelist)
if(prob(1))
ignorelist -= T
/mob/living/bot/floorbot/on_think_disabled()
..()
ignorelist.Cut()
path.Cut()
target = null
/mob/living/bot/floorbot/UnarmedAttack(var/atom/A, var/proximity)
. = ..()
if(!.)
return
if(repairing)
return
if(!src.Adjacent(A))
return
if(emagged && istype(A, /turf/simulated/floor))
var/turf/simulated/floor/F = A
repairing = 1
update_icon()
if(F.is_plating())
visible_message("<span class='warning'>[src] begins to tear the floor tile from the floor!</span>")
if(do_after(src, 50))
F.break_tile_to_plating()
addTiles(1)
else
visible_message("<span class='danger'>[src] begins to tear through the floor!</span>")
if(do_after(src, 150)) // Extra time because this can and will kill.
F.ReplaceWithLattice()
addTiles(1)
target = null
repairing = 0
update_icon()
else if(istype(A, /turf/space))
var/building = 2
if(locate(/obj/structure/lattice, A))
building = 1
if(amount < building)
return
repairing = 1
update_icon()
visible_message("<span class='notice'>[src] begins to repair the hole.</span>")
if(do_after(src, 50))
if(A && (locate(/obj/structure/lattice, A) && building == 1 || !locate(/obj/structure/lattice, A) && building == 2)) // Make sure that it still needs repairs
var/obj/item/I
if(building == 1)
I = new /obj/item/stack/tile/floor(src)
else
I = new /obj/item/stack/rods(src)
A.attackby(I, src)
target = null
repairing = 0
update_icon()
else if(istype(A, /turf/simulated/floor))
var/turf/simulated/floor/F = A
if(!F.flooring && amount)
repairing = 1
update_icon()
visible_message("<span class='notice'>[src] begins to improve the floor.</span>")
if(do_after(src, 50))
if(!F.flooring)
F.set_flooring(decls_repository.get_decl(floor_build_type))
addTiles(-1)
target = null
repairing = 0
update_icon()
else if(istype(A, /obj/item/stack/tile/floor) && amount < maxAmount)
var/obj/item/stack/tile/floor/T = A
visible_message("<span class='notice'>[src] begins to collect tiles.</span>")
repairing = 1
update_icon()
if(do_after(src, 20))
if(T)
var/eaten = min(maxAmount - amount, T.get_amount())
T.use(eaten)
addTiles(eaten)
target = null
repairing = 0
update_icon()
else if(istype(A, /obj/item/stack/material) && amount + 4 <= maxAmount)
var/obj/item/stack/material/M = A
if(M.get_material_name() == DEFAULT_WALL_MATERIAL)
visible_message("<span class='notice'>[src] begins to make tiles.</span>")
repairing = 1
update_icon()
if(do_after(50))
if(M)
M.use(1)
addTiles(4)
/mob/living/bot/floorbot/explode()
turn_off()
visible_message("<span class='danger'>[src] blows apart!</span>")
var/turf/Tsec = get_turf(src)
var/obj/item/storage/toolbox/mechanical/N = new /obj/item/storage/toolbox/mechanical(Tsec)
N.contents = list()
new /obj/item/device/assembly/prox_sensor(Tsec)
if(prob(50))
new /obj/item/robot_parts/l_arm(Tsec)
var/obj/item/stack/tile/floor/T = new /obj/item/stack/tile/floor(Tsec)
T.amount = amount
spark(src, 3, alldirs)
qdel(src)
/mob/living/bot/floorbot/proc/addTiles(var/am)
amount += am
if(amount < 0)
amount = 0
else if(amount > maxAmount)
amount = maxAmount
/* Assembly */
/obj/item/storage/toolbox/mechanical/attackby(var/obj/item/stack/tile/floor/T, mob/user as mob)
if(!istype(T, /obj/item/stack/tile/floor))
..()
return
if(contents.len >= 1)
to_chat(user, "<span class='notice'>They wont fit in as there is already stuff inside.</span>")
return
if(user.s_active)
user.s_active.close(user)
if(T.use(10))
var/obj/item/toolbox_tiles/B = new /obj/item/toolbox_tiles
user.put_in_hands(B)
to_chat(user, "<span class='notice'>You add the tiles into the empty toolbox. They protrude from the top.</span>")
qdel(src)
else
to_chat(user, "<span class='warning'>You need 10 floor tiles for a floorbot.</span>")
return
/obj/item/toolbox_tiles
desc = "It's a toolbox with tiles sticking out the top"
name = "tiles and toolbox"
icon = 'icons/obj/aibots.dmi'
icon_state = "toolbox_tiles"
force = 3.0
throwforce = 10.0
throw_speed = 2
throw_range = 5
w_class = ITEMSIZE_NORMAL
var/created_name = "Floorbot"
/obj/item/toolbox_tiles/attackby(var/obj/item/W, mob/user as mob)
..()
if(isprox(W))
qdel(W)
var/obj/item/toolbox_tiles_sensor/B = new /obj/item/toolbox_tiles_sensor()
B.created_name = created_name
user.put_in_hands(B)
to_chat(user, "<span class='notice'>You add the sensor to the toolbox and tiles!</span>")
qdel(src)
return 1
else if (W.ispen())
var/t = sanitizeSafe(input(user, "Enter new robot name", name, created_name), MAX_NAME_LEN)
if(!t)
return
if(!in_range(src, user) && loc != user)
return
created_name = t
/obj/item/toolbox_tiles_sensor
desc = "It's a toolbox with tiles sticking out the top and a sensor attached"
name = "tiles, toolbox and sensor arrangement"
icon = 'icons/obj/aibots.dmi'
icon_state = "toolbox_tiles_sensor"
force = 3.0
throwforce = 10.0
throw_speed = 2
throw_range = 5
w_class = ITEMSIZE_NORMAL
var/created_name = "Floorbot"
/obj/item/toolbox_tiles_sensor/attackby(var/obj/item/W, mob/user as mob)
..()
if(istype(W, /obj/item/robot_parts/l_arm) || istype(W, /obj/item/robot_parts/r_arm))
qdel(W)
var/turf/T = get_turf(user.loc)
var/mob/living/bot/floorbot/A = new /mob/living/bot/floorbot(T)
A.name = created_name
to_chat(user, "<span class='notice'>You add the robot arm to the odd looking toolbox assembly! Boop beep!</span>")
qdel(src)
return 1
else if(W.ispen())
var/t = sanitizeSafe(input(user, "Enter new robot name", name, created_name), MAX_NAME_LEN)
if(!t)
return
if(!in_range(src, user) && loc != user)
return
created_name = t
/mob/living/bot/floorbot/floorbob
name = "B.O.B."
desc = "A little floor repairing robot, he can build it!"
icon_state = "floorbob0"
req_one_access = list(access_construction, access_robotics)
amount = 120 // 1 for tile, 2 for lattice
maxAmount = 120
/mob/living/bot/floorbot/floorbob/update_icon()
if(repairing)
icon_state = "floorbob-c"
else if(amount > 0)
icon_state = "floorbob[on]"
else
icon_state = "floorbob[on]e"
-726
View File
@@ -1,726 +0,0 @@
#define SECBOT_IDLE 0 // idle
#define SECBOT_HUNT 1 // found target, hunting
#define SECBOT_ARREST 2 // arresting target
#define SECBOT_START_PATROL 3 // start patrol
#define SECBOT_WAIT_PATROL 4 // waiting for signals
#define SECBOT_PATROL 5 // patrolling
#define SECBOT_SUMMON 6 // summoned by PDA
/mob/living/bot/secbot
name = "Securitron"
desc = "A little security robot. He looks less than thrilled."
icon_state = "secbot0"
maxHealth = 50
health = 50
req_one_access = list(access_security, access_forensics_lockers, access_weapons)
botcard_access = list(access_security, access_sec_doors, access_forensics_lockers, access_morgue, access_maint_tunnels)
var/mob/target
var/idcheck = 0 // If true, arrests for having weapons without authorization.
var/check_records = 0 // If true, arrests people without a record.
var/check_arrest = 1 // If true, arrests people who are set to arrest.
var/arrest_type = 0 // If true, doesn't handcuff. You monster.
var/declare_arrests = 0 // If true, announces arrests over sechuds.
var/auto_patrol = 0 // If true, patrols on its own
var/mode = 0
var/is_attacking = 0
var/is_ranged = 0
var/awaiting_surrender = 0
var/obj/secbot_listener/listener = null
var/beacon_freq = 1445 // Navigation beacon frequency
var/control_freq = BOT_FREQ // Bot control frequency
var/list/turf/path = list()
var/frustration = 0
var/turf/patrol_target = null // This is where we are headed
var/closest_dist // Used to find the closest beakon
var/destination = "__nearest__" // This is the current beacon's ID
var/next_destination = "__nearest__" // This is the next beacon's ID
var/nearest_beacon // Tag of the beakon that we assume to be the closest one
var/bot_version = 1.5
var/list/threat_found_sounds = list(
'sound/voice/bcriminal.ogg',
'sound/voice/bjustice.ogg',
'sound/voice/bfreeze.ogg'
)
var/list/preparing_arrest_sounds = list(
'sound/voice/bgod.ogg',
'sound/voice/biamthelaw.ogg',
'sound/voice/bsecureday.ogg',
'sound/voice/bradio.ogg',
'sound/voice/binsult.ogg',
'sound/voice/bcreep.ogg'
)
var/datum/callback/patrol_callback // this is here so we don't constantly recreate this datum, it being identical each time.
var/move_to_delay = 4 //delay for the automated movement.
can_take_pai = FALSE
/mob/living/bot/secbot/beepsky
name = "Officer Beepsky"
desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey."
auto_patrol = 1
/mob/living/bot/secbot/Initialize()
. = ..()
listener = new /obj/secbot_listener(src)
listener.secbot = src
if(SSradio)
SSradio.add_object(listener, control_freq, filter = RADIO_SECBOT)
SSradio.add_object(listener, beacon_freq, filter = RADIO_NAVBEACONS)
/mob/living/bot/secbot/Destroy()
QDEL_NULL(listener)
target = null
return ..()
/mob/living/bot/secbot/turn_off()
..()
walk_to(src, src, 0, move_to_delay)
target = null
frustration = 0
mode = SECBOT_IDLE
/mob/living/bot/secbot/update_icon()
if(on && is_attacking)
icon_state = "secbot-c"
else
icon_state = "secbot[on]"
if(on)
set_light(1.4, 1, "#FF6A00")
else
set_light(0)
/mob/living/bot/secbot/attack_hand(var/mob/user)
if (!has_ui_access(user))
to_chat(user, "<span class='warning'>The unit's interface refuses to unlock!</span>")
return
user.set_machine(src)
var/dat = ""
dat += "Status: <A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A><BR>"
dat += "Behaviour controls are [locked ? "locked" : "unlocked"]<BR>"
dat += "Maintenance panel is [open ? "opened" : "closed"]"
if(!locked || issilicon(user))
dat += "<BR>Check for Weapon Authorization: <A href='?src=\ref[src];operation=idcheck'>[idcheck ? "Yes" : "No"]</A><BR>"
dat += "Check Security Records: <A href='?src=\ref[src];operation=ignorerec'>[check_records ? "Yes" : "No"]</A><BR>"
dat += "Check Arrest Status: <A href='?src=\ref[src];operation=ignorearr'>[check_arrest ? "Yes" : "No"]</A><BR>"
dat += "Operating Mode: <A href='?src=\ref[src];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A><BR>"
dat += "Report Arrests: <A href='?src=\ref[src];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A><BR>"
dat += "Auto Patrol: <A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>"
var/datum/browser/bot_win = new(user, "autosec", "Automatic Securitron v[bot_version] Controls")
bot_win.set_content(dat)
bot_win.open()
/mob/living/bot/secbot/Topic(href, href_list)
if(..())
return
usr.set_machine(src)
add_fingerprint(usr)
if (!has_ui_access(usr))
to_chat(usr, "<span class='warning'>Insufficient permissions.</span>")
return
if(href_list["power"])
if(on)
turn_off()
else
turn_on()
attack_hand(usr)
if (locked && !issilicon(usr))
return
switch(href_list["operation"])
if("idcheck")
idcheck = !idcheck
if("ignorerec")
check_records = !check_records
if("ignorearr")
check_arrest = !check_arrest
if("switchmode")
arrest_type = !arrest_type
if("patrol")
auto_patrol = !auto_patrol
mode = SECBOT_IDLE
if("declarearrests")
declare_arrests = !declare_arrests
attack_hand(usr)
/mob/living/bot/secbot/attackby(var/obj/item/O, var/mob/user)
var/curhealth = health
..()
if(health < curhealth)
target = user
awaiting_surrender = 5
mode = SECBOT_HUNT
/mob/living/bot/secbot/think()
..()
if(!on)
return
if(QDELETED(target))
scan_view()
if(!locked && (mode == SECBOT_START_PATROL || mode == SECBOT_PATROL)) // Stop running away when we set you up
mode = SECBOT_IDLE
switch(mode)
if(SECBOT_IDLE)
if(auto_patrol && locked)
mode = SECBOT_START_PATROL
return
if(SECBOT_HUNT) // Target is in the view or has been recently - chase it
if(frustration > 7)
target = null
frustration = 0
awaiting_surrender = 0
mode = SECBOT_IDLE
return
if(target)
var/threat = check_threat(target)
if(threat < 4) // Re-evaluate in case they dropped the weapon or something
target = null
frustration = 0
awaiting_surrender = 0
mode = SECBOT_IDLE
return
if(!(target in view(7, src)))
++frustration
if(Adjacent(target))
mode = SECBOT_ARREST
return
else
if(is_ranged)
RangedAttack(target)
else
walk_to(src, target, 1, move_to_delay) // Melee bots chase a bit faster
if(SECBOT_ARREST) // Target is next to us - attack it
if(!target)
mode = SECBOT_IDLE
if(!Adjacent(target))
awaiting_surrender = 5 // I'm done playing nice
mode = SECBOT_HUNT
return
var/threat = check_threat(target)
walk_to(src, src, 0, move_to_delay)
if(threat < 4)
target = null
awaiting_surrender = 0
frustration = 0
mode = SECBOT_IDLE
return
if(awaiting_surrender < 5 && ishuman(target) && !target.lying)
if(awaiting_surrender == 0)
say("Down on the floor, [target]! You have five seconds to comply.")
++awaiting_surrender
else
UnarmedAttack(target)
if(ishuman(target) && declare_arrests)
var/area/location = get_area(src)
broadcast_security_hud_message("[src] is [arrest_type ? "detaining" : "arresting"] a level [check_threat(target)] suspect <b>[target]</b> in <b>[location]</b>.", src)
return
if(SECBOT_START_PATROL)
if(path.len && patrol_target)
mode = SECBOT_PATROL
return
else if(patrol_target)
spawn(0)
calc_path()
if(!path.len)
patrol_target = null
mode = SECBOT_IDLE
else
mode = SECBOT_PATROL
if(!patrol_target)
if(next_destination)
find_next_target()
else
find_patrol_target()
say("Engaging patrol mode.")
mode = SECBOT_WAIT_PATROL
return
if(SECBOT_WAIT_PATROL)
if(patrol_target)
mode = SECBOT_START_PATROL
else
++frustration
if(frustration > 120)
frustration = 0
mode = SECBOT_IDLE
if(SECBOT_PATROL)
patrol_step()
return
if(SECBOT_SUMMON)
patrol_step()
return
/mob/living/bot/secbot/UnarmedAttack(var/mob/M, var/proximity)
if(!..())
return
if(!istype(M))
return
if(istype(M, /mob/living/carbon))
var/mob/living/carbon/C = M
var/cuff = 1
if(istype(C, /mob/living/carbon/human))
var/mob/living/carbon/human/H = C
if(istype(H.back, /obj/item/rig) && istype(H.gloves,/obj/item/clothing/gloves/rig))
cuff = 0
if(!C.lying || C.handcuffed || arrest_type)
cuff = 0
if(!cuff)
C.stun_effect_act(0, 60, null)
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
do_attack_animation(C)
is_attacking = 1
update_icon()
addtimer(CALLBACK(src, .proc/stop_attacking_cb), 2)
visible_message("<span class='warning'>[C] was prodded by [src] with a stun baton!</span>")
else
playsound(loc, 'sound/weapons/handcuffs.ogg', 30, 1, -2)
visible_message("<span class='warning'>[src] is trying to put handcuffs on [C]!</span>")
if(do_mob(src, C, 60))
if(!C.handcuffed)
C.handcuffed = new /obj/item/handcuffs(C)
C.update_inv_handcuffed()
if(preparing_arrest_sounds.len)
playsound(loc, pick(preparing_arrest_sounds), 50, 0)
else if(istype(M, /mob/living/simple_animal) && !istype(M, /mob/living/bot/secbot))
var/mob/living/simple_animal/S = M
S.adjustBruteLoss(15)
do_attack_animation(M)
playsound(loc, /decl/sound_category/swing_hit_sound, 50, 1, -1)
is_attacking = 1
update_icon()
addtimer(CALLBACK(src, .proc/stop_attacking_cb), 2)
visible_message("<span class='warning'>[M] was beaten by [src] with a stun baton!</span>")
/mob/living/bot/secbot/proc/stop_attacking_cb()
is_attacking = FALSE
update_icon()
/mob/living/bot/secbot/explode()
visible_message("<span class='warning'>[src] blows apart!</span>")
var/turf/Tsec = get_turf(src)
var/obj/item/secbot_assembly/Sa = new /obj/item/secbot_assembly(Tsec)
Sa.build_step = 1
Sa.add_overlay("hs_hole")
Sa.created_name = name
new /obj/item/device/assembly/prox_sensor(Tsec)
new /obj/item/melee/baton(Tsec)
if(prob(50))
new /obj/item/robot_parts/l_arm(Tsec)
spark(src, 3, alldirs)
new /obj/effect/decal/cleanable/blood/oil(Tsec)
qdel(src)
/mob/living/bot/secbot/emag_act(var/remaining_charges, var/mob/user, var/feedback)
if(!emagged)
emagged = 1
to_chat(user, (feedback ? feedback : "You short out the lock of \the [src]."))
return 1
/mob/living/bot/secbot/proc/scan_view()
target = null
for(var/mob/living/M in view(7, src))
if(M.invisibility >= INVISIBILITY_LEVEL_ONE)
continue
if(M.stat)
continue
var/threat = check_threat(M)
if(threat >= 4)
target = M
say("Level [threat] infraction alert!")
custom_emote(VISIBLE_MESSAGE, "points at [M.name]!")
mode = SECBOT_HUNT
break
return
/mob/living/bot/secbot/proc/calc_path(var/turf/avoid = null)
path = AStar(loc, patrol_target, /turf/proc/CardinalTurfsWithAccess, /turf/proc/Distance, 0, 120, id=botcard, exclude=avoid)
if(isnull(path) || !path.len)
path = list()
return
var/list/path_new = list()
var/turf/last = path[path.len]
path_new.Add(path[1])
for(var/i = 2, i < path.len, i++)
if((path[i + 1].x == path[i].x) || (path[i + 1].y == path[i].y)) // we have a straight line, scan for more to cut down
path_new.Add(path[i])
for(var/j = i + 1, j < path.len, j++)
if((path[j + 1].x != path[j - 1].x) && (path[j + 1].y != path[j - 1].y)) // This is a corner and end point of our line
path_new.Add(path[j])
i = j + 1
break
else if(j == path.len - 1)
path = list()
path = path_new.Copy()
path.Add(last)
return
else
path_new.Add(path[i])
path = list()
path = path_new.Copy()
path.Add(last)
/mob/living/bot/secbot/proc/check_threat(var/mob/living/M)
if(!M || !istype(M) || M.stat || src == M)
return 0
if(emagged)
return 10
return M.assess_perp(access_scanner, 0, idcheck, check_records, check_arrest)
/mob/living/bot/secbot/proc/patrol_step()
if(loc == patrol_target)
patrol_target = null
path = list()
mode = SECBOT_IDLE
walk_to(src, src, 0, move_to_delay + 2)
return
if(path.len && patrol_target)
var/turf/next = path[1]
if(loc == next)
path -= next
walk_to(src, src, 0, move_to_delay + 2)
return
walk_to(src, next, 0, move_to_delay + 2)
return
else
mode = SECBOT_START_PATROL
/mob/living/bot/secbot/proc/find_patrol_target()
send_status()
nearest_beacon = null
next_destination = "__nearest__"
listener.post_signal(beacon_freq, "findbeacon", "patrol")
/mob/living/bot/secbot/proc/find_next_target()
send_status()
nearest_beacon = null
listener.post_signal(beacon_freq, "findbeacon", "patrol")
/mob/living/bot/secbot/proc/send_status()
var/list/kv = list(
"type" = "secbot",
"name" = name,
"loca" = get_area(loc),
"mode" = mode
)
listener.post_signal_multiple(control_freq, kv)
/obj/secbot_listener
var/mob/living/bot/secbot/secbot = null
/obj/secbot_listener/Destroy()
secbot = null
return ..()
/obj/secbot_listener/proc/post_signal(var/freq, var/key, var/value) // send a radio signal with a single data key/value pair
post_signal_multiple(freq, list("[key]" = value))
/obj/secbot_listener/proc/post_signal_multiple(var/freq, var/list/keyval) // send a radio signal with multiple data key/values
var/datum/radio_frequency/frequency = SSradio.return_frequency(freq)
if(!frequency)
return
var/datum/signal/signal = new()
signal.source = secbot
signal.transmission_method = TRANSMISSION_RADIO
signal.data = keyval.Copy()
if(signal.data["findbeacon"])
frequency.post_signal(secbot, signal, filter = RADIO_NAVBEACONS)
else if(signal.data["type"] == "secbot")
frequency.post_signal(secbot, signal, filter = RADIO_SECBOT)
else
frequency.post_signal(secbot, signal)
/obj/secbot_listener/receive_signal(datum/signal/signal)
if(!secbot || !secbot.on)
return
var/recv = signal.data["command"]
if(recv == "bot_status")
secbot.send_status()
return
if(signal.data["active"] == secbot)
switch(recv)
if("stop")
secbot.mode = SECBOT_IDLE
secbot.auto_patrol = 0
return
if("go")
secbot.mode = SECBOT_IDLE
secbot.auto_patrol = 1
return
if("summon")
secbot.patrol_target = signal.data["target"]
secbot.next_destination = secbot.destination
secbot.destination = null
//secbot.awaiting_beacon = 0
secbot.mode = SECBOT_SUMMON
secbot.calc_path()
secbot.say("Responding.")
return
recv = signal.data["beacon"]
var/valid = signal.data["patrol"]
if(!recv || !valid)
return
if(recv == secbot.next_destination) // This beacon is our target
secbot.destination = secbot.next_destination
secbot.patrol_target = signal.source.loc
secbot.next_destination = signal.data["next_patrol"]
else if(secbot.next_destination == "__nearest__")
var/dist = get_dist(secbot, signal.source.loc)
if(dist <= 1)
return
if(secbot.nearest_beacon)
if(dist < secbot.closest_dist)
secbot.nearest_beacon = recv
secbot.patrol_target = secbot.nearest_beacon
secbot.next_destination = signal.data["next_patrol"]
secbot.closest_dist = dist
return
else
secbot.nearest_beacon = recv
secbot.patrol_target = secbot.nearest_beacon
secbot.next_destination = signal.data["next_patrol"]
secbot.closest_dist = dist
/mob/living/bot/secbot/attack_hand(mob/living/carbon/human/M as mob)
..()
if(M.a_intent == I_HURT ) //assume he wants to hurt us.
idcheck = TRUE
target = M
mode = SECBOT_HUNT
var/mob/living/carbon/human/H = M
var/perpname = H.name
var/obj/item/card/id/id = H.GetIdCard()
if(id)
perpname = id.registered_name
var/datum/record/general/R = SSrecords.find_record("name", perpname)
if(R && R.security)
R.security.criminal = "*Arrest*"
else
check_records = TRUE
broadcast_security_hud_message("[src] is under attack by <b>[target]</b>, [arrest_type ? "detaining" : "arresting"] a level [check_threat(target)] suspect in <b>[get_area(src)]</b>. Requesting backup", src)
/mob/living/bot/secbot/attack_generic(var/mob/user, var/damage, var/attack_message)
..()
target = user
mode = SECBOT_HUNT
if(ishuman(user))
idcheck = TRUE
var/mob/living/carbon/human/H = user
var/perpname = H.name
var/obj/item/card/id/id = H.GetIdCard()
if(id)
perpname = id.registered_name
var/datum/record/general/R = SSrecords.find_record("name", perpname)
if(R && R.security)
R.security.criminal = "*Arrest*"
else
check_records = TRUE
broadcast_security_hud_message("[src] is under attack by <b>[target]</b>, [arrest_type ? "detaining" : "arresting"] a level [check_threat(target)] suspect in <b>[get_area(src)]</b>. Requesting backup", src)
/mob/living/bot/secbot/bullet_act(var/obj/item/projectile/P, var/def_zone)
..()
if (ismob(P.firer))
var/found = 0
// Check if we can see them.
for(var/mob/living/M in view(7, src))
if(M.invisibility >= INVISIBILITY_LEVEL_ONE)
continue
if(M.stat)
continue
if(M == P.firer)
found = 1
break
if(!found)
broadcast_security_hud_message("[src] was shot with <b>[P]</b>, Unable to locate source! Requesting backup", src)
return
target = P.firer
mode = SECBOT_HUNT
if(ishuman(P.firer))
idcheck = TRUE
var/mob/living/carbon/human/H = P.firer
var/perpname = H.name
var/obj/item/card/id/id = H.GetIdCard()
if(id)
perpname = id.registered_name
var/datum/record/general/R = SSrecords.find_record("name", perpname)
if(R && R.security)
R.security.criminal = "*Arrest*"
else
check_records = TRUE
broadcast_security_hud_message("[src] was shot with <b>[P]</b>, projectile came from <b>[target]</b>, [arrest_type ? "detaining" : "arresting"] a level [check_threat(target)] suspect in <b>[get_area(src)]</b>. Requesting backup", src)
/mob/living/bot/secbot/attackby(var/obj/item/O, var/mob/user)
..()
if(O.GetID() || O.ispen())
return
target = user
mode = SECBOT_HUNT
if(ishuman(user))
idcheck = TRUE
var/mob/living/carbon/human/H = user
var/perpname = H.name
var/obj/item/card/id/id = H.GetIdCard()
if(id)
perpname = id.registered_name
var/datum/record/general/R = SSrecords.find_record("name", perpname)
if(R && R.security)
R.security.criminal = "*Arrest*"
else
check_records = TRUE
broadcast_security_hud_message("[src] is under attack by <b>[target]</b> with <b>[O]</b>, [arrest_type ? "detaining" : "arresting"] a level [check_threat(target)] suspect in <b>[get_area(src)]</b>. Requesting backup", src)
/mob/living/bot/secbot/hitby(atom/movable/AM as mob|obj,var/speed = THROWFORCE_SPEED_DIVISOR)
..()
if(istype(AM,/obj/))
var/obj/O = AM
if(ismob(O.thrower))
target = O.thrower
mode = SECBOT_HUNT
if(ishuman(O.thrower))
idcheck = TRUE
var/mob/living/carbon/human/H = O.thrower
var/perpname = H.name
var/obj/item/card/id/id = H.GetIdCard()
if(id)
perpname = id.registered_name
var/datum/record/general/R = SSrecords.find_record("name", perpname)
if(R && R.security)
R.security.criminal = "*Arrest*"
else
check_records = TRUE
broadcast_security_hud_message("[src] is under attack by <b>[target]</b> with <b>[O]</b>, [arrest_type ? "detaining" : "arresting"] a level [check_threat(target)] suspect in <b>[get_area(src)]</b>. Requesting backup", src)
//Secbot Construction
/obj/item/clothing/head/helmet/attackby(var/obj/item/device/assembly/signaler/S, mob/user as mob)
..()
if(!issignaler(S))
..()
return
if(type != /obj/item/clothing/head/helmet/security) //Eh, but we don't want people making secbots out of space helmets.
return
if(S.secured)
qdel(S)
var/obj/item/secbot_assembly/A = new /obj/item/secbot_assembly
user.put_in_hands(A)
to_chat(user, "You add the signaler to the helmet.")
user.drop_from_inventory(src)
qdel(src)
return 1
else
return
/obj/item/secbot_assembly
name = "helmet/signaler assembly"
desc = "Some sort of bizarre assembly."
icon = 'icons/obj/aibots.dmi'
icon_state = "helmet_signaler"
item_state = "helmet"
var/build_step = 0
var/created_name = "Securitron"
/obj/item/secbot_assembly/attackby(var/obj/item/O, var/mob/user)
..()
if(O.iswelder() && !build_step)
var/obj/item/weldingtool/WT = O
if(WT.use(0, user))
build_step = 1
add_overlay("hs_hole")
to_chat(user, "You weld a hole in \the [src].")
return 1
else if(isprox(O) && (build_step == 1))
build_step = 2
to_chat(user, "You add \the [O] to [src].")
add_overlay("hs_eye")
name = "helmet/signaler/prox sensor assembly"
user.drop_from_inventory(O,get_turf(src))
qdel(O)
return 1
else if((istype(O, /obj/item/robot_parts/l_arm) || istype(O, /obj/item/robot_parts/r_arm)) && build_step == 2)
build_step = 3
to_chat(user, "You add \the [O] to [src].")
name = "helmet/signaler/prox sensor/robot arm assembly"
add_overlay("hs_arm")
user.drop_from_inventory(O,get_turf(src))
qdel(O)
return 1
else if(istype(O, /obj/item/melee/baton) && build_step == 3)
to_chat(user, "You complete the Securitron! Beep boop.")
var/mob/living/bot/secbot/S = new /mob/living/bot/secbot(get_turf(src))
S.name = created_name
user.drop_from_inventory(O,get_turf(src))
qdel(O)
qdel(src)
return 1
else if(O.ispen())
var/t = sanitizeSafe(input(user, "Enter new robot name", name, created_name), MAX_NAME_LEN)
if(!t)
return
if(!in_range(src, usr) && loc != usr)
return
created_name = t
#undef SECBOT_IDLE
#undef SECBOT_HUNT
#undef SECBOT_ARREST
#undef SECBOT_START_PATROL
#undef SECBOT_WAIT_PATROL
#undef SECBOT_PATROL
#undef SECBOT_SUMMON
+11 -12
View File
@@ -1,24 +1,25 @@
/mob/living/carbon/alien
name = "alien"
desc = "What IS that?"
name = "La Creatura"
desc = "La creatura. Huh wuh?"
icon = 'icons/mob/npc/alien.dmi'
icon_state = "alien_s"
icon_state = "la_creatura"
pass_flags = PASSTABLE
health = 100
maxHealth = 100
health = 50
maxHealth = 50
mob_size = 4
var/adult_form
var/dead_icon
var/icon_dead
var/amount_grown = 0
var/max_grown = 200
var/time_of_birth
var/language
var/death_msg = "lets out a waning guttural screech, green blood bubbling from its maw."
var/death_msg = "lets out a waning guttural screech!"
var/meat_amount = 0
var/meat_type = /obj/item/reagent_containers/food/snacks/xenomeat
icon_dead = "la_creatura_dead"
/mob/living/carbon/alien/Initialize()
. = ..()
@@ -47,9 +48,7 @@
return 0
/mob/living/carbon/alien/show_inv(mob/user as mob)
return //Consider adding cuffs and hats to this, for the sake of fun.
return // Consider adding cuffs and hats to this, for the sake of fun.
/mob/living/carbon/alien/cannot_use_vents()
return
return
@@ -1,4 +1,4 @@
/mob/living/carbon/alien/death(gibbed)
if(!gibbed && dead_icon)
icon_state = dead_icon
if(!gibbed && icon_dead)
icon_state = icon_dead
return ..(gibbed,death_msg)
@@ -1,18 +1,3 @@
/obj/item/organ/pariah_brain
name = "brain remnants"
desc = "Did someone tread on this? It looks useless for cloning or cyborgification."
organ_tag = "brain"
parent_organ = BP_HEAD
icon = 'icons/mob/npc/alien.dmi'
icon_state = "chitin"
vital = TRUE
/obj/item/organ/internal/brain/xeno
name = "thinkpan"
desc = "It looks kind of like an enormous wad of purple bubblegum."
icon = 'icons/mob/npc/alien.dmi'
icon_state = "chitin"
/obj/item/organ/internal/brain/slime
name = "slime core"
desc = "A complex, organic knot of jelly and crystalline particles."
@@ -32,4 +17,4 @@
slot_l_hand_str = 'icons/mob/items/lefthand_books.dmi',
slot_r_hand_str = 'icons/mob/items/righthand_books.dmi'
)
can_prepare = 0
can_prepare = 0
@@ -380,13 +380,9 @@
mob_win.open()
// called when something steps onto a human
// this handles mulebots and vehicles
// this handles vehicles
/mob/living/carbon/human/Crossed(var/atom/movable/AM)
..()
if(istype(AM, /obj/machinery/bot/mulebot))
var/obj/machinery/bot/mulebot/MB = AM
MB.RunOver(src)
if(istype(AM, /obj/vehicle))
var/obj/vehicle/V = AM
V.RunOver(src)
-661
View File
@@ -1,661 +0,0 @@
// === MEMETIC ANOMALY ===
// =======================
//Taken from ancient baystation code- LL
/**
This life form is a form of parasite that can gain a certain level of control
over its host. Its player will share vision and hearing with the host, and it'll
be able to influence the host through various commands.
**/
// The maximum amount of points a meme can gather.
var/global/const/MAXIMUM_MEME_POINTS = 750
var/mob/living/parasite/host_brain
var/controlling
// === PARASITE ===
// ================
// a list of all the parasites in the mob
/mob/living/carbon/var/list/parasites = list()
/mob/living/parasite
var/mob/living/carbon/host // the host that this parasite occupies
/mob/living/parasite/LateLogin()
..()
// make the client see through the host instead
client.eye = host
client.perspective = EYE_PERSPECTIVE
/mob/living/parasite/proc/enter_host(mob/living/carbon/host)
// by default, parasites can't share a body with other life forms
if(host.parasites.len > 0)
return 0
src.host = host
src.forceMove(host)
host.parasites.Add(src)
if(client) client.eye = host
return 1
/mob/living/parasite/proc/exit_host()
src.host.parasites.Remove(src)
src.host = null
src.loc = null
return 1
// === MEME ===
// ============
// Memes use points for many actions
/mob/living/parasite/meme/var/meme_points = 100
/mob/living/parasite/meme/var/dormant = 0
// Memes have a list of indoctrinated hosts
/mob/living/parasite/meme/var/list/indoctrinated = list()
/mob/living/parasite/meme/Life()
..()
if(client)
if(blinded) client.eye = null
else client.eye = host
if(!host) return
// recover meme points slowly
var/gain = 3
if(dormant) gain = 9 // dormant recovers points faster
meme_points = min(meme_points + gain, MAXIMUM_MEME_POINTS)
// if there are sleep toxins in the host's body, that's bad
if(host.reagents.has_reagent(/decl/reagent/soporific))
to_chat(src, "<span class='danger'>Something in your host's blood makes you lose consciousness, you fade away...</span>")
src.death()
return
// a host without brain is no good
if(!host.mind)
to_chat(src, "<span class='danger'>Your host has no mind, you fade away...</span>")
src.death()
return
if(host.stat == 2)
to_chat(src, "<span class='danger'>Your host has died, you fade away...</span>")
src.death()
return
if(host.blinded && host.stat != 1) src.blinded = 1
else src.blinded = 0
/mob/living/parasite/meme/death()
// make sure the mob is on the actual map before gibbing
if(host)
src.forceMove(host.loc)
src.stat = 2
..()
qdel(src)
// When a meme speaks, it speaks through its host
/mob/living/parasite/meme/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
if(dormant)
to_chat(src, "<span class='notice'>You are dormant! </span>")
return
if(!host)
to_chat(usr, "<span class='notice'>You can't speak without a host! </span>")
return
return host.say(message)
// Same as speak, just with whisper
/mob/living/parasite/meme/whisper(message as text)
if(dormant)
to_chat(src, "<span class='notice'>You are dormant! </span>")
return
if(!host)
to_chat(usr, "<span class='notice'>You can't speak without a host! </span>")
return
return host.whisper(message)
// Make the host do things
/mob/living/parasite/meme/me_verb(message as text)
set name = "Me"
if(dormant)
to_chat(src, "<span class='notice'>You are dormant! </span>")
return
if(!host)
to_chat(usr, "<span class='notice'>You can't speak without a host! </span>")
return
return host.me_verb(message)
// A meme understands everything their host understands
/mob/living/parasite/meme/say_understands(mob/other)
if(!host) return 0
return host.say_understands(other)
// Try to use amount points, return 1 if successful
/mob/living/parasite/meme/proc/use_points(amount)
if(dormant)
to_chat(src, "<span class='notice'>You are dormant! </span>")
return
if(src.meme_points < amount)
to_chat(src, "<span class='notice'>You don't have enough meme points(need [amount]).</span>")
return 0
src.meme_points -= round(amount)
return 1
// Let the meme choose one of his indoctrinated mobs as target
/mob/living/parasite/meme/proc/select_indoctrinated(var/title, var/message)
var/list/candidates
// Can only affect other mobs thant he host if not blinded
if(blinded)
candidates = list()
to_chat(src, "<span class='notice'>You are blinded, so you can not affect mobs other than your host.</span>")
else
candidates = indoctrinated.Copy()
candidates.Add(src.host)
var/mob/target = null
if(candidates.len == 1)
target = candidates[1]
else
var/selected
var/list/text_candidates = list()
var/list/map_text_to_mob = list()
for(var/mob/living/carbon/human/M in candidates)
text_candidates += M.real_name
map_text_to_mob[M.real_name] = M
selected = input(message,title) as null|anything in text_candidates
if(!selected) return null
target = map_text_to_mob[selected]
return target
// A meme can make people hear things with the thought ability
/mob/living/parasite/meme/verb/Thought(mob/M as mob in oview())
set category = "Meme"
set name = "Thought(150)"
set desc = "Implants a thought into the target."
if(!use_points(150)) return
var/message = sanitize(input("Message:", "Thought") as text|null)
if(message)
log_say("MemeThought: [key_name(src)]->[M.key] : [message]",ckey=key_name(src))
to_chat(M, "[message]")
to_chat(src, "You said: \"[message]\" to [M]")
return
// Mutes the host
/mob/living/parasite/meme/verb/Mute()
set category = "Meme"
set name = "Mute(250)"
set desc = "Prevents your host from talking for a while."
if(!src.host) return
/*if(!host.silent)
to_chat(usr, "\red Your host already can't speak..")
return*/
if(!use_points(250)) return
spawn
// backup the host incase we switch hosts after using the verb
//var/mob/host = src.host
to_chat(host, "<span class='danger'>Your tongue feels numb.. You lose your ability to speak.</span>")
to_chat(usr, "<span class='notice'>Your host can't speak anymore.</span>")
host.silent += 60
sleep(1200)
to_chat(host, "<span class='danger'>Your tongue has feeling again.</span>")
to_chat(usr, "<span class='notice'>[host] can speak again.</span>")
// Makes the host unable to emote
/mob/living/parasite/meme/verb/Paralyze()
set category = "Meme"
set name = "Paralyze(250)"
set desc = "Prevents your host from using emote for a while."
if(!src.host) return
/*if(!host.Weaken())
to_chat(usr, "\red Your host already can't use body language..")
return*/
if(!use_points(250)) return
spawn
// backup the host incase we switch hosts after using the verb
var/mob/host = src.host
to_chat(host, "<span class='danger'>Your body feels numb. You lose your ability to use body language.</span>")
to_chat(usr, "<span class='notice'>Your host can't use body language anymore.</span>")
host.Weaken(60)
sleep(1200)
to_chat(host, "<span class='warning'>Your body has feeling again.</span>")
to_chat(usr, "<span class='notice'>[host] can use body language again.</span>")
// Cause great agony with the host, used for conditioning the host
/mob/living/parasite/meme/verb/Agony()
set category = "Meme"
set name = "Agony(200)"
set desc = "Causes significant pain in your host."
if(!src.host) return
if(!use_points(200)) return
spawn
// backup the host incase we switch hosts after using the verb
var/mob/host = src.host
host.paralysis = max(host.paralysis, 2)
host.flash_pain(10)
to_chat(host, "<span class='danger'><font size=5>You feel excrutiating pain all over your body! It is so bad you can't think or articulate yourself properly.</font></span>")
to_chat(usr, "<span class='notice'>You send a jolt of agonizing pain through [host], they should be unable to concentrate on anything else for half a minute.</span>")
host.emote("scream")
for(var/i=0, i<10, i++)
host.stuttering = 2
sleep(50)
if(prob(80)) host.flash_pain(10)
if(prob(10)) host.paralysis = max(host.paralysis, 2)
if(prob(15)) host.emote("twitch")
else if(prob(15)) host.emote("scream")
else if(prob(10)) host.emote("collapse")
if(i == 10)
to_chat(host, "<span class='danger'>THE PAIN! AGHH, THE PAIN! MAKE IT STOP! ANYTHING TO MAKE IT STOP!</span>")
to_chat(host, "<span class='warning'>The pain subsides.</span>")
// Cause great joy with the host, used for conditioning the host
/mob/living/parasite/meme/verb/Joy()
set category = "Meme"
set name = "Joy(200)"
set desc = "Causes significant joy in your host."
if(!src.host) return
if(!use_points(200)) return
spawn
var/mob/host = src.host
host.druggy = max(host.druggy, 50)
host.slurring = max(host.slurring, 10)
to_chat(usr, "<span class='notice'>You stimulate [host.name]'s brain, injecting waves of endorphines and dopamine into the tissue. They should now forget all their worries, particularly relating to you, for around a minute.</span>")
to_chat(host, "<span class='notice'><font size=5>You are feeling wonderful! Your head is numb and drowsy, and you can't help forgetting all the worries in the world.</font></span>")
while(host.druggy > 0)
sleep(10)
to_chat(host, "<span class='warning'>You are feeling clear-headed again.</span>")
// Cause the target to hallucinate.
/mob/living/parasite/meme/verb/Hallucinate(mob/living/carbon/human/target as mob in oview())
set category = "Meme"
set name = "Hallucinate(300)"
set desc = "Makes your host hallucinate, has a short delay."
if(!istype(target, /mob/living/carbon/human) || !target.mind)
to_chat(src, "<span class='warning'>You can't remotely ruin this ones mind.</span>")
return
if(!(target in view(host)))
to_chat(src, "<span class='warning'>You need to make eye-contact with the target.</span>")
return
if(!(target in indoctrinated))
to_chat(src, "<span class='warning'>You need to attune the target first.</span>")
return
if(!target) return
if(!use_points(300)) return
spawn(rand(300,600))
if(target) target.hallucination += 400
to_chat(usr, "<span class='notice'>You make [target] hallucinate.</span>")
// Jump to a closeby target through a whisper
/mob/living/parasite/meme/verb/SubtleJump(mob/living/carbon/human/target as mob in oview())
set category = "Meme"
set name = "Subtle Jump(350)"
set desc = "Move to a closeby human through a whisper."
if(!istype(target, /mob/living/carbon/human) || !target.mind)
to_chat(src, "<span class='warning'>You can't jump to this creature.</span>")
return
if(target.isSynthetic())
to_chat(src, "<span class='warning'>You can't affect synthetics.</span>")
return
if(!(target in view(1, host)+src))
to_chat(src, "<span class='warning'>The target is not close enough.</span>")
return
// Find out whether we can speak
if (host.silent || (host.disabilities & 64))
to_chat(src, "<span class='warning'>Your host can't speak.</span>")
return
if(!use_points(350)) return
for(var/mob/M in view(1, host))
M.show_message("<B>[host]</B> whispers something incoherent.",2) // 2 stands for hearable message
// Find out whether the target can hear
if(target.disabilities & 32 || isdeaf(target))
to_chat(src, "<span class='warning'>Your target doesn't seem to hear you.</span>")
return
if(target.parasites.len > 0)
to_chat(src, "<span class='warning'>Your target already is possessed by something.</span>")
return
src.exit_host()
src.enter_host(target)
to_chat(usr, "<span class='notice'>You successfully jumped to [target].</span>")
log_admin("[src.key] has jumped to [target]",ckey=key_name(src))
message_admins("[src.key] has jumped to [target]")
// Jump to a distant target through a shout
/mob/living/parasite/meme/verb/ObviousJump(mob/living/carbon/human/target as mob in world)
set category = "Meme"
set name = "Obvious Jump(750)"
set desc = "Move to any mob in view through a shout."
if(!istype(target, /mob/living/carbon/human) || !target.mind)
to_chat(src, "<span class='warning'>You can't jump to this creature.</span>")
return
if(target.isSynthetic())
to_chat(src, "<span class='warning'>You can't affect synthetics.</span>")
return
if(!(target in view(host)))
to_chat(src, "<span class='warning'>The target is not close enough.</span>")
return
// Find out whether we can speak
if (host.silent || (host.disabilities & 64))
to_chat(src, "<span class='warning'>Your host can't speak.</span>")
return
if(!use_points(750)) return
for(var/mob/M in view(host)+src)
M.show_message("<B>[host]</B> screams something incoherent!",2) // 2 stands for hearable message
// Find out whether the target can hear
if(target.disabilities & 32 || isdeaf(target))
to_chat(src, "<span class='warning'>Your target doesn't seem to hear you.</span>")
return
if(target.parasites.len > 0)
to_chat(src, "<span class='warning'>Your target already is possessed by something.</span>")
return
src.exit_host()
src.enter_host(target)
to_chat(usr, "<span class='notice'>You successfully jumped to [target].</span>")
log_admin("[src.key] has jumped to [target]",ckey=key_name(src))
message_admins("[src.key] has jumped to [target]")
// Jump to an attuned mob for free
/mob/living/parasite/meme/verb/AttunedJump(mob/living/carbon/human/target as mob in world)
set category = "Meme"
set name = "Attuned Jump(0)"
set desc = "Move to a mob in sight that you have already attuned."
if(!istype(target, /mob/living/carbon/human) || !target.mind)
to_chat(src, "<span class='warning'>You can't jump to this creature.</span>")
return
if(target.isSynthetic())
to_chat(src, "<span class='warning'>You can't affect synthetics.</span>")
return
if(!(target in view(host)))
to_chat(src, "<span class='warning'>You need to make eye-contact with the target.</span>")
return
if(!(target in indoctrinated))
to_chat(src, "<span class='warning'>You need to attune the target first.</span>")
return
src.exit_host()
src.enter_host(target)
to_chat(usr, "<span class='notice'>You successfully jumped to [target].</span>")
log_admin("[src.key] has jumped to [target]",ckey=key_name(src))
message_admins("[src.key] has jumped to [target]")
// ATTUNE a mob, adding it to the indoctrinated list
/mob/living/parasite/meme/verb/Attune()
set category = "Meme"
set name = "Attune(400)"
set desc = "Change the host's brain structure, making it easier for you to manipulate him."
if(host in src.indoctrinated)
to_chat(usr, "<span class='notice'>You have already attuned this host.</span>")
return
if(!host) return
for (var/obj/item/implant/mindshield/I in host)
if (I.implanted)
to_chat(src, "<span class='warning'>Your host's mind is shielded!</span>")
return
if(!use_points(400)) return
src.indoctrinated.Add(host)
to_chat(usr, "<span class='notice'>You successfully indoctrinated [host].</span>")
to_chat(host, "<span class='danger'>Your head feels a bit roomier...</span>")
log_admin("[src.key] has attuned [host]",ckey=key_name(src))
message_admins("[src.key] has attuned [host]")
// Enables the mob to take a lot more damage
/mob/living/parasite/meme/verb/Analgesic()
set category = "Meme"
set name = "Analgesic(500)"
set desc = "Combat drug that allows the host to move normally, even under life-threatening pain."
if(!host) return
if(!(host in indoctrinated))
to_chat(usr, "<span class='warning'>You need to attune the host first.</span>")
return
if(!use_points(500)) return
to_chat(usr, "<span class='notice'>You inject drugs into [host].</span>")
to_chat(host, "<span class='danger'>You feel your body strengthen and your pain subside.</span>")
host.analgesic = 60
while(host.analgesic > 0)
sleep(60)
to_chat(host, "<span class='notice'>The dizziness wears off, and you can feel pain again.</span>")
/mob/proc/clearHUD()
//update_clothing()
if(client) client.screen.Cut()
// Take control of the mob
/mob/living/parasite/meme/verb/Possession()
set category = "Meme"
set name = "Possession(500)"
set desc = "Take direct control of the host for a while."
if(!host)
to_chat(src, "You have discovered a severe bug - NO HOST. CONTACT DEVELOPER.")
return
if(src.stat)
to_chat(src, "<span class='warning'>You cannot do that in your current state.</span>")
return
for (var/obj/item/implant/mindshield/I in host)
if (I.implanted)
to_chat(src, "<span class='warning'>Your host's mind is shielded!</span>")
return
if(!use_points(500)) return
to_chat(src, "<span class='danger'>You assume direct control!</span>")
spawn()
if(!host || !src || controlling)
return
else
to_chat(src, "<span class='warning'>You shroud your hosts brain, assuming control!</span>")
to_chat(host, "<span class='danger'>You can feel thoughts that arent your own begin to dictate your body's actions.</span>")
// host -> brain
var/h2b_id = host.computer_id
var/h2b_ip= host.lastKnownIP
host.computer_id = null
host.lastKnownIP = null
qdel(host_brain)
host_brain = new(src)
host_brain.ckey = host.ckey
host_brain.name = host.name
if(!host_brain.computer_id)
host_brain.computer_id = h2b_id
if(!host_brain.lastKnownIP)
host_brain.lastKnownIP = h2b_ip
// self -> host
var/s2h_id = src.computer_id
var/s2h_ip= src.lastKnownIP
src.computer_id = null
src.lastKnownIP = null
host.ckey = src.ckey
if(!host.computer_id)
host.computer_id = s2h_id
if(!host.lastKnownIP)
host.lastKnownIP = s2h_ip
controlling = 1
spawn(300)
detatch()
return
/mob/living/parasite/meme/proc/detatch()
if(!host || !controlling) return
if(istype(host,/mob/living/carbon/human))
var/mob/living/carbon/human/H = host
var/obj/item/organ/external/head = H.get_organ(BP_HEAD)
head.implants -= src
controlling = 0
if(host_brain)
// these are here so bans and multikey warnings are not triggered on the wrong people when ckey is changed.
// computer_id and IP are not updated magically on their own in offline mobs -walter0o
// host -> self
var/h2s_id = host.computer_id
var/h2s_ip= host.lastKnownIP
host.computer_id = null
host.lastKnownIP = null
src.ckey = host.ckey
if(!src.computer_id)
src.computer_id = h2s_id
if(!host_brain.lastKnownIP)
src.lastKnownIP = h2s_ip
// brain -> host
var/b2h_id = host_brain.computer_id
var/b2h_ip= host_brain.lastKnownIP
host_brain.computer_id = null
host_brain.lastKnownIP = null
host.ckey = host_brain.ckey
if(!host.computer_id)
host.computer_id = b2h_id
if(!host.lastKnownIP)
host.lastKnownIP = b2h_ip
qdel(host_brain)
// Enter dormant mode, increases meme point gain
/mob/living/parasite/meme/verb/Dormant()
set category = "Meme"
set name = "Dormant(100)"
set desc = "Speed up point recharging, will force you to cease all actions until all points are recharged."
if(!host) return
if(!use_points(100)) return
to_chat(usr, "<span class='warning'>You enter dormant mode.You won't be able to take action until all your points have recharged.</span>")
dormant = 1
while(meme_points < MAXIMUM_MEME_POINTS)
sleep(10)
dormant = 0
to_chat(usr, "<span class='danger'>You have regained all points and exited dormant mode!</span>")
/mob/living/parasite/meme/verb/Show_Points()
set category = "Meme"
to_chat(usr, "<b>Meme Points: [src.meme_points]/[MAXIMUM_MEME_POINTS]</b>")
// Stat panel to show meme points, copypasted from alien
/mob/living/parasite/meme/Stat()
..()
statpanel("Status")
if (client && client.holder)
stat(null, "([x], [y], [z])")
if (client && client.statpanel == "Status")
stat(null, "Meme Points: [src.meme_points]")
@@ -1,29 +0,0 @@
/mob/living/parasite/captive_brain
name = "host brain"
real_name = "host brain"
universal_understand = 1
/mob/living/parasite/captive_brain/say(var/message, var/datum/language/speaking = null, var/verb="says", var/alt_name="", var/ghost_hearing = GHOSTS_ALL_HEAR, var/whisper = FALSE)
if(istype(src.loc,/mob/living/parasite/meme))
if (!message)
return
log_say("[key_name(src)] : [message]",ckey=key_name(src))
if (stat == 2)
return say_dead(message)
var/mob/living/parasite/meme/ME = src.loc
to_chat(src, "You whisper silently, \"[message]\"")
to_chat(ME.host, "The captive mind of [src] whispers, \"[message]\"")
for (var/mob/M in player_list)
if (istype(M, /mob/abstract/new_player))
continue
else if(M.stat == 2 && M.client.prefs.toggles & CHAT_GHOSTEARS)
to_chat(M, "The captive mind of [src] whispers, \"[message]\"")
/mob/living/parasite/captive_brain/emote(var/message)
return
/mob/living/parasite/captive_brain/send_emote()
return
@@ -47,6 +47,3 @@
stat(null, "Maintenance Lock: [B.locked ? "Locked" : "Unlocked"]")
if(B.emagged)
stat(null, "Bot M#$FUN90: MALFUNC--")
if(istype(card.loc, /mob/living/bot/floorbot))
var/mob/living/bot/floorbot/F = card.loc
stat(null, "Metal Count: [F.amount]/[F.maxAmount]")
@@ -143,20 +143,6 @@
return FALSE
/obj/item/robot_parts/robot_suit/attackby(obj/item/W, mob/user)
if(istype(W, /obj/item/stack/material) && W.get_material_name() == DEFAULT_WALL_MATERIAL && !l_arm && !r_arm && !l_leg && !r_leg && !chest && !head)
var/obj/item/stack/material/M = W
if(M.use(1))
var/obj/item/secbot_assembly/ed209_assembly/B = new /obj/item/secbot_assembly/ed209_assembly
B.forceMove(get_turf(src))
to_chat(user, SPAN_NOTICE("You armed the robot frame."))
if(user.get_inactive_hand() == src)
user.remove_from_mob(src)
user.put_in_inactive_hand(B)
qdel(src)
else
to_chat(user, SPAN_WARNING("You need one sheet of metal to arm the robot frame."))
return
if(istype(W, /obj/item/robot_parts/l_leg))
if(l_leg)
to_chat(user, SPAN_WARNING("\The [src] already has \a [l_leg] installed."))
@@ -1,102 +1,3 @@
/mob/living/simple_animal/hostile/alien
name = "alien hunter"
desc = "Hiss!"
icon = 'icons/mob/npc/alien.dmi'
icon_state = "alienh_running"
icon_living = "alienh_running"
icon_dead = "alien_l"
icon_gib = "syndicate_gib"
response_help = "pokes"
response_disarm = "shoves"
response_harm = "hits"
speed = -1
meat_type = /obj/item/reagent_containers/food/snacks/xenomeat
organ_names = list("chest", "lower body", "left arm", "right arm", "left leg", "right leg", "head")
maxHealth = 100
health = 100
blood_type = "#5BDD04"
harm_intent_damage = 5
melee_damage_lower = 25
melee_damage_upper = 25
attacktext = "slashed"
a_intent = I_HURT
attack_sound = 'sound/weapons/bladeslice.ogg'
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
unsuitable_atoms_damage = 15
faction = "alien"
environment_smash = 2
status_flags = CANPUSH
minbodytemp = 0
heat_damage_per_tick = 20
mob_size = 10
tameable = FALSE
attack_emote = "growls at"
smart_ranged = TRUE
butchering_products = list(/obj/item/stack/material/animalhide/xeno = 5)
/mob/living/simple_animal/hostile/alien/drone
name = "alien drone"
icon_state = "aliend_running"
icon_living = "aliend_running"
icon_dead = "aliend_l"
health = 60
melee_damage_lower = 15
melee_damage_upper = 15
/mob/living/simple_animal/hostile/alien/sentinel
name = "alien sentinel"
icon_state = "aliens_running"
icon_living = "aliens_running"
icon_dead = "aliens_l"
health = 120
melee_damage_lower = 15
melee_damage_upper = 15
ranged = 1
projectiletype = /obj/item/projectile/neurotox
projectilesound = 'sound/weapons/pierce.ogg'
/mob/living/simple_animal/hostile/alien/queen
name = "alien queen"
icon_state = "alienq_running"
icon_living = "alienq_running"
icon_dead = "alienq_l"
health = 250
maxHealth = 250
melee_damage_lower = 15
melee_damage_upper = 15
ranged = 1
move_to_delay = 3
projectiletype = /obj/item/projectile/neurotox
projectilesound = 'sound/weapons/pierce.ogg'
rapid = 1
status_flags = 0
mob_size = 12
/mob/living/simple_animal/hostile/alien/queen/large
name = "alien empress"
icon = 'icons/mob/npc/alienqueen.dmi'
icon_state = "queen_s"
icon_living = "queen_s"
icon_dead = "queen_dead"
move_to_delay = 4
maxHealth = 400
health = 400
mob_size = 14
/obj/item/projectile/neurotox
damage = 30
icon_state = "toxin"
// Xenoarch aliens.
/mob/living/simple_animal/hostile/retaliate/samak
name = "samak"
@@ -1,6 +1,6 @@
/mob/living/simple_animal/hostile/faithless
name = "Faithless"
desc = "The Wish Granter's faith in humanity, incarnate."
name = "faithless"
desc = "A creature. Darkness incarnate?"
icon = 'icons/mob/npc/human.dmi'
icon_state = "faithless"
icon_living = "faithless"