[MIRROR] Fixes language code ignoring holder restrictions (#858)

* Fixes language code ignoring holder restrictions

* resolve .rej file.
This commit is contained in:
CitadelStationBot
2017-05-18 04:13:57 -05:00
committed by Poojawa
parent e84191b5c3
commit 8bcaa54cbe
30 changed files with 7396 additions and 7396 deletions
+178 -178
View File
@@ -1,178 +1,178 @@
/datum/emote/living/carbon/human
mob_type_allowed_typecache = list(/mob/living/carbon/human)
/datum/emote/living/carbon/human/cry
key = "cry"
key_third_person = "cries"
message = "cries."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/dap
key = "dap"
key_third_person = "daps"
message = "sadly can't find anybody to give daps to, and daps themself. Shameful."
message_param = "give daps to %t."
restraint_check = TRUE
/datum/emote/living/carbon/human/eyebrow
key = "eyebrow"
message = "raises an eyebrow."
/datum/emote/living/carbon/human/grumble
key = "grumble"
key_third_person = "grumbles"
message = "grumbles!"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/handshake
key = "handshake"
message = "shakes their own hands."
message_param = "shakes hands with %t."
restraint_check = TRUE
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/hug
key = "hug"
key_third_person = "hugs"
message = "hugs themself."
message_param = "hugs %t."
restraint_check = TRUE
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/mumble
key = "mumble"
key_third_person = "mumbles"
message = "mumbles!"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/pale
key = "pale"
message = "goes pale for a second."
/datum/emote/living/carbon/human/raise
key = "raise"
key_third_person = "raises"
message = "raises a hand."
restraint_check = TRUE
/datum/emote/living/carbon/human/salute
key = "salute"
key_third_person = "salutes"
message = "salutes."
message_param = "salutes to %t."
restraint_check = TRUE
/datum/emote/living/carbon/human/shrug
key = "shrug"
key_third_person = "shrugs"
message = "shrugs."
/datum/emote/living/carbon/human/wag
key = "wag"
key_third_person = "wags"
message = "wags their tail."
/datum/emote/living/carbon/human/wag/run_emote(mob/user, params)
. = ..()
var/mob/living/carbon/human/H = user
if(.)
H.startTailWag()
else
H.endTailWag()
/datum/emote/living/carbon/human/wag/can_run_emote(mob/user)
if(!..())
return FALSE
var/mob/living/carbon/human/H = user
if(H.dna && H.dna.species && ((H.dna.features["tail_lizard"] != "None") || (H.dna.features["tail_human"] != "None") || ("mam_tail" in H.dna.species.mutant_bodyparts)))
return TRUE
/datum/emote/living/carbon/human/wag/select_message_type(mob/user)
. = ..()
var/mob/living/carbon/human/H = user
if(("waggingtail_lizard" in H.dna.species.mutant_bodyparts) || ("waggingtail_human" in H.dna.species.mutant_bodyparts) || ("mam_waggingtail" in H.dna.species.mutant_bodyparts))
. = null
/datum/emote/living/carbon/human/wing
key = "wing"
key_third_person = "wings"
message = "their wings."
/datum/emote/living/carbon/human/wing/run_emote(mob/user, params)
. = ..()
if(.)
var/mob/living/carbon/human/H = user
if(findtext(select_message_type(user), "open"))
H.OpenWings()
else
H.CloseWings()
/datum/emote/living/carbon/human/wing/select_message_type(mob/user)
. = ..()
var/mob/living/carbon/human/H = user
if("wings" in H.dna.species.mutant_bodyparts)
. = "opens " + message
else
. = "closes " + message
/datum/emote/living/carbon/human/wing/can_run_emote(mob/user)
if(!..())
return FALSE
var/mob/living/carbon/human/H = user
if(H.dna && H.dna.species && (H.dna.features["wings"] != "None"))
return TRUE
//Don't know where else to put this, it's basically an emote
/mob/living/carbon/human/proc/startTailWag()
if(!dna || !dna.species)
return
if("tail_lizard" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "tail_lizard"
dna.species.mutant_bodyparts -= "spines"
dna.species.mutant_bodyparts |= "waggingtail_lizard"
dna.species.mutant_bodyparts |= "waggingspines"
if("tail_human" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "tail_human"
dna.species.mutant_bodyparts |= "waggingtail_human"
if("mam_tail" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "mam_tail"
dna.species.mutant_bodyparts |= "mam_waggingtail"
update_body()
/mob/living/carbon/human/proc/endTailWag()
if(!dna || !dna.species)
return
if("waggingtail_lizard" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "waggingtail_lizard"
dna.species.mutant_bodyparts -= "waggingspines"
dna.species.mutant_bodyparts |= "tail_lizard"
dna.species.mutant_bodyparts |= "spines"
if("waggingtail_human" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "waggingtail_human"
dna.species.mutant_bodyparts |= "tail_human"
if("mam_waggingtail" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "mam_waggingtail"
dna.species.mutant_bodyparts |= "mam_tail"
update_body()
/mob/living/carbon/human/proc/OpenWings()
if(!dna || !dna.species)
return
if("wings" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "wings"
dna.species.mutant_bodyparts |= "wingsopen"
update_body()
/mob/living/carbon/human/proc/CloseWings()
if(!dna || !dna.species)
return
if("wingsopen" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "wingsopen"
dna.species.mutant_bodyparts |= "wings"
update_body()
if(isturf(loc))
var/turf/T = loc
T.Entered(src)
//Ayy lmao
/datum/emote/living/carbon/human
mob_type_allowed_typecache = list(/mob/living/carbon/human)
/datum/emote/living/carbon/human/cry
key = "cry"
key_third_person = "cries"
message = "cries."
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/dap
key = "dap"
key_third_person = "daps"
message = "sadly can't find anybody to give daps to, and daps themself. Shameful."
message_param = "give daps to %t."
restraint_check = TRUE
/datum/emote/living/carbon/human/eyebrow
key = "eyebrow"
message = "raises an eyebrow."
/datum/emote/living/carbon/human/grumble
key = "grumble"
key_third_person = "grumbles"
message = "grumbles!"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/handshake
key = "handshake"
message = "shakes their own hands."
message_param = "shakes hands with %t."
restraint_check = TRUE
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/hug
key = "hug"
key_third_person = "hugs"
message = "hugs themself."
message_param = "hugs %t."
restraint_check = TRUE
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/mumble
key = "mumble"
key_third_person = "mumbles"
message = "mumbles!"
emote_type = EMOTE_AUDIBLE
/datum/emote/living/carbon/human/pale
key = "pale"
message = "goes pale for a second."
/datum/emote/living/carbon/human/raise
key = "raise"
key_third_person = "raises"
message = "raises a hand."
restraint_check = TRUE
/datum/emote/living/carbon/human/salute
key = "salute"
key_third_person = "salutes"
message = "salutes."
message_param = "salutes to %t."
restraint_check = TRUE
/datum/emote/living/carbon/human/shrug
key = "shrug"
key_third_person = "shrugs"
message = "shrugs."
/datum/emote/living/carbon/human/wag
key = "wag"
key_third_person = "wags"
message = "wags their tail."
/datum/emote/living/carbon/human/wag/run_emote(mob/user, params)
. = ..()
var/mob/living/carbon/human/H = user
if(.)
H.startTailWag()
else
H.endTailWag()
/datum/emote/living/carbon/human/wag/can_run_emote(mob/user)
if(!..())
return FALSE
var/mob/living/carbon/human/H = user
if(H.dna && H.dna.species && ((H.dna.features["tail_lizard"] != "None") || (H.dna.features["tail_human"] != "None") || ("mam_tail" in H.dna.species.mutant_bodyparts)))
return TRUE
/datum/emote/living/carbon/human/wag/select_message_type(mob/user)
. = ..()
var/mob/living/carbon/human/H = user
if(("waggingtail_lizard" in H.dna.species.mutant_bodyparts) || ("waggingtail_human" in H.dna.species.mutant_bodyparts) || ("mam_waggingtail" in H.dna.species.mutant_bodyparts))
. = null
/datum/emote/living/carbon/human/wing
key = "wing"
key_third_person = "wings"
message = "their wings."
/datum/emote/living/carbon/human/wing/run_emote(mob/user, params)
. = ..()
if(.)
var/mob/living/carbon/human/H = user
if(findtext(select_message_type(user), "open"))
H.OpenWings()
else
H.CloseWings()
/datum/emote/living/carbon/human/wing/select_message_type(mob/user)
. = ..()
var/mob/living/carbon/human/H = user
if("wings" in H.dna.species.mutant_bodyparts)
. = "opens " + message
else
. = "closes " + message
/datum/emote/living/carbon/human/wing/can_run_emote(mob/user)
if(!..())
return FALSE
var/mob/living/carbon/human/H = user
if(H.dna && H.dna.species && (H.dna.features["wings"] != "None"))
return TRUE
//Don't know where else to put this, it's basically an emote
/mob/living/carbon/human/proc/startTailWag()
if(!dna || !dna.species)
return
if("tail_lizard" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "tail_lizard"
dna.species.mutant_bodyparts -= "spines"
dna.species.mutant_bodyparts |= "waggingtail_lizard"
dna.species.mutant_bodyparts |= "waggingspines"
if("tail_human" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "tail_human"
dna.species.mutant_bodyparts |= "waggingtail_human"
if("mam_tail" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "mam_tail"
dna.species.mutant_bodyparts |= "mam_waggingtail"
update_body()
/mob/living/carbon/human/proc/endTailWag()
if(!dna || !dna.species)
return
if("waggingtail_lizard" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "waggingtail_lizard"
dna.species.mutant_bodyparts -= "waggingspines"
dna.species.mutant_bodyparts |= "tail_lizard"
dna.species.mutant_bodyparts |= "spines"
if("waggingtail_human" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "waggingtail_human"
dna.species.mutant_bodyparts |= "tail_human"
if("mam_waggingtail" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "mam_waggingtail"
dna.species.mutant_bodyparts |= "mam_tail"
update_body()
/mob/living/carbon/human/proc/OpenWings()
if(!dna || !dna.species)
return
if("wings" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "wings"
dna.species.mutant_bodyparts |= "wingsopen"
update_body()
/mob/living/carbon/human/proc/CloseWings()
if(!dna || !dna.species)
return
if("wingsopen" in dna.species.mutant_bodyparts)
dna.species.mutant_bodyparts -= "wingsopen"
dna.species.mutant_bodyparts |= "wings"
update_body()
if(isturf(loc))
var/turf/T = loc
T.Entered(src)
//Ayy lmao
File diff suppressed because it is too large Load Diff
@@ -1,421 +1,421 @@
/mob/living/simple_animal/bot/secbot
name = "\improper Securitron"
desc = "A little security robot. He looks less than thrilled."
icon = 'icons/mob/aibots.dmi'
icon_state = "secbot0"
density = 0
anchored = 0
health = 25
maxHealth = 25
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
pass_flags = PASSMOB
radio_key = /obj/item/device/encryptionkey/secbot //AI Priv + Security
radio_channel = "Security" //Security channel
bot_type = SEC_BOT
model = "Securitron"
bot_core_type = /obj/machinery/bot_core/secbot
var/baton_type = /obj/item/weapon/melee/baton
window_id = "autosec"
window_name = "Automatic Security Unit v1.6"
allow_pai = 0
data_hud_type = DATA_HUD_SECURITY_ADVANCED
var/mob/living/carbon/target
var/oldtarget_name
var/threatlevel = 0
var/target_lastloc //Loc of target when arrested.
var/last_found //There's a delay
var/declare_arrests = 1 //When making an arrest, should it notify everyone on the security channel?
var/idcheck = 0 //If true, arrest people with no IDs
var/weaponscheck = 0 //If true, arrest people for weapons if they lack access
var/check_records = 1 //Does it check security records?
var/arrest_type = 0 //If true, don't handcuff
/mob/living/simple_animal/bot/secbot/beepsky
name = "Officer Beep O'sky"
desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey."
idcheck = 0
weaponscheck = 0
auto_patrol = 1
/mob/living/simple_animal/bot/secbot/beepsky/jr
name = "Officer Pipsqueak"
desc = "It's Officer Beep O'sky's smaller, just-as aggressive cousin, Pipsqueak."
/mob/living/simple_animal/bot/secbot/beepsky/jr/Initialize()
..()
resize = 0.8
update_transform()
/mob/living/simple_animal/bot/secbot/beepsky/explode()
var/turf/Tsec = get_turf(src)
new /obj/item/weapon/stock_parts/cell/potato(Tsec)
var/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/shotglass/S = new(Tsec)
S.reagents.add_reagent("whiskey", 15)
S.on_reagent_change()
..()
/mob/living/simple_animal/bot/secbot/pingsky
name = "Officer Pingsky"
desc = "It's Officer Pingsky! Delegated to satellite guard duty for harbouring anti-human sentiment."
radio_channel = "AI Private"
/mob/living/simple_animal/bot/secbot/Initialize()
..()
icon_state = "secbot[on]"
spawn(3)
var/datum/job/detective/J = new/datum/job/detective
access_card.access += J.get_access()
prev_access = access_card.access
//SECHUD
var/datum/atom_hud/secsensor = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
secsensor.add_hud_to(src)
/mob/living/simple_animal/bot/secbot/turn_on()
..()
icon_state = "secbot[on]"
/mob/living/simple_animal/bot/secbot/turn_off()
..()
icon_state = "secbot[on]"
/mob/living/simple_animal/bot/secbot/bot_reset()
..()
target = null
oldtarget_name = null
anchored = 0
walk_to(src,0)
last_found = world.time
/mob/living/simple_animal/bot/secbot/set_custom_texts()
text_hack = "You overload [name]'s target identification system."
text_dehack = "You reboot [name] and restore the target identification."
text_dehack_fail = "[name] refuses to accept your authority!"
/mob/living/simple_animal/bot/secbot/get_controls(mob/user)
var/dat
dat += hack(user)
dat += showpai(user)
dat += text({"
<TT><B>Securitron v1.6 controls</B></TT><BR><BR>
Status: []<BR>
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
Maintenance panel panel is [open ? "opened" : "closed"]"},
"<A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A>" )
if(!locked || issilicon(user) || IsAdminGhost(user))
dat += text({"<BR>
Arrest Unidentifiable Persons: []<BR>
Arrest for Unauthorized Weapons: []<BR>
Arrest for Warrant: []<BR>
Operating Mode: []<BR>
Report Arrests[]<BR>
Auto Patrol: []"},
"<A href='?src=\ref[src];operation=idcheck'>[idcheck ? "Yes" : "No"]</A>",
"<A href='?src=\ref[src];operation=weaponscheck'>[weaponscheck ? "Yes" : "No"]</A>",
"<A href='?src=\ref[src];operation=ignorerec'>[check_records ? "Yes" : "No"]</A>",
"<A href='?src=\ref[src];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A>",
"<A href='?src=\ref[src];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A>",
"<A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
return dat
/mob/living/simple_animal/bot/secbot/Topic(href, href_list)
if(..())
return 1
switch(href_list["operation"])
if("idcheck")
idcheck = !idcheck
update_controls()
if("weaponscheck")
weaponscheck = !weaponscheck
update_controls()
if("ignorerec")
check_records = !check_records
update_controls()
if("switchmode")
arrest_type = !arrest_type
update_controls()
if("declarearrests")
declare_arrests = !declare_arrests
update_controls()
/mob/living/simple_animal/bot/secbot/proc/retaliate(mob/living/carbon/human/H)
threatlevel = H.assess_threat(src)
threatlevel += 6
if(threatlevel >= 4)
target = H
mode = BOT_HUNT
/mob/living/simple_animal/bot/secbot/attack_hand(mob/living/carbon/human/H)
if((H.a_intent == INTENT_HARM) || (H.a_intent == INTENT_DISARM))
retaliate(H)
return ..()
/mob/living/simple_animal/bot/secbot/attackby(obj/item/weapon/W, mob/user, params)
..()
if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != INTENT_HARM) // Any intent but harm will heal, so we shouldn't get angry.
return
if(!istype(W, /obj/item/weapon/screwdriver) && (W.force) && (!target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
retaliate(user)
/mob/living/simple_animal/bot/secbot/emag_act(mob/user)
..()
if(emagged == 2)
if(user)
to_chat(user, "<span class='danger'>You short out [src]'s target assessment circuits.</span>")
oldtarget_name = user.name
audible_message("<span class='danger'>[src] buzzes oddly!</span>")
declare_arrests = 0
icon_state = "secbot[on]"
/mob/living/simple_animal/bot/secbot/bullet_act(obj/item/projectile/Proj)
if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet))
if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
if(!Proj.nodamage && Proj.damage < src.health)
retaliate(Proj.firer)
..()
/mob/living/simple_animal/bot/secbot/UnarmedAttack(atom/A)
if(!on)
return
if(iscarbon(A))
var/mob/living/carbon/C = A
if(!C.stunned || arrest_type)
stun_attack(A)
else if(C.canBeHandcuffed() && !C.handcuffed)
cuff(A)
else
..()
/mob/living/simple_animal/bot/secbot/hitby(atom/movable/AM, skipcatch = 0, hitpush = 1, blocked = 0)
if(istype(AM, /obj/item))
var/obj/item/I = AM
if(I.throwforce < src.health && I.thrownby && ishuman(I.thrownby))
var/mob/living/carbon/human/H = I.thrownby
retaliate(H)
..()
/mob/living/simple_animal/bot/secbot/proc/cuff(mob/living/carbon/C)
mode = BOT_ARREST
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
C.visible_message("<span class='danger'>[src] is trying to put zipties on [C]!</span>",\
"<span class='userdanger'>[src] is trying to put zipties on you!</span>")
spawn(60)
if( !Adjacent(C) || !isturf(C.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
return
if(!C.handcuffed)
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C)
C.update_handcuffed()
playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0)
back_to_idle()
/mob/living/simple_animal/bot/secbot/proc/stun_attack(mob/living/carbon/C)
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
icon_state = "secbot-c"
spawn(2)
icon_state = "secbot[on]"
var/threat = 5
if(ishuman(C))
C.stuttering = 5
C.Stun(5)
C.Weaken(5)
var/mob/living/carbon/human/H = C
threat = H.assess_threat(src)
else
C.Weaken(5)
C.stuttering = 5
C.Stun(5)
threat = C.assess_threat()
add_logs(src,C,"stunned")
if(declare_arrests)
var/area/location = get_area(src)
speak("[arrest_type ? "Detaining" : "Arresting"] level [threat] scumbag <b>[C]</b> in [location].", radio_channel)
C.visible_message("<span class='danger'>[src] has stunned [C]!</span>",\
"<span class='userdanger'>[src] has stunned you!</span>")
/mob/living/simple_animal/bot/secbot/handle_automated_action()
if(!..())
return
switch(mode)
if(BOT_IDLE) // idle
walk_to(src,0)
look_for_perp() // see if any criminals are in range
if(!mode && auto_patrol) // still idle, and set to patrol
mode = BOT_START_PATROL // switch to patrol mode
if(BOT_HUNT) // hunting for perp
// if can't reach perp for long enough, go idle
if(frustration >= 8)
walk_to(src,0)
back_to_idle()
return
if(target) // make sure target exists
if(Adjacent(target) && isturf(target.loc)) // if right next to perp
stun_attack(target)
mode = BOT_PREP_ARREST
anchored = 1
target_lastloc = target.loc
return
else // not next to perp
var/turf/olddist = get_dist(src, target)
walk_to(src, target,1,4)
if((get_dist(src, target)) >= (olddist))
frustration++
else
frustration = 0
else
back_to_idle()
if(BOT_PREP_ARREST) // preparing to arrest target
// see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again.
if( !Adjacent(target) || !isturf(target.loc) || target.weakened < 2 )
back_to_hunt()
return
if(iscarbon(target) && target.canBeHandcuffed())
if(!arrest_type)
if(!target.handcuffed) //he's not cuffed? Try to cuff him!
cuff(target)
else
back_to_idle()
return
else
back_to_idle()
return
if(BOT_ARREST)
if(!target)
anchored = 0
mode = BOT_IDLE
last_found = world.time
frustration = 0
return
if(target.handcuffed) //no target or target cuffed? back to idle.
back_to_idle()
return
if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && target.weakened < 2)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again.
back_to_hunt()
return
else //Try arresting again if the target escapes.
mode = BOT_PREP_ARREST
anchored = 0
if(BOT_START_PATROL)
look_for_perp()
start_patrol()
if(BOT_PATROL)
look_for_perp()
bot_patrol()
return
/mob/living/simple_animal/bot/secbot/proc/back_to_idle()
anchored = 0
mode = BOT_IDLE
target = null
last_found = world.time
frustration = 0
spawn(0)
handle_automated_action() //ensure bot quickly responds
/mob/living/simple_animal/bot/secbot/proc/back_to_hunt()
anchored = 0
frustration = 0
mode = BOT_HUNT
spawn(0)
handle_automated_action() //ensure bot quickly responds
// look for a criminal in view of the bot
/mob/living/simple_animal/bot/secbot/proc/look_for_perp()
anchored = 0
for (var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal
if((C.stat) || (C.handcuffed))
continue
if((C.name == oldtarget_name) && (world.time < last_found + 100))
continue
threatlevel = C.assess_threat(src)
if(!threatlevel)
continue
else if(threatlevel >= 4)
target = C
oldtarget_name = C.name
speak("Level [threatlevel] infraction alert!")
playsound(loc, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, 0)
visible_message("<b>[src]</b> points at [C.name]!")
mode = BOT_HUNT
spawn(0)
handle_automated_action() // ensure bot quickly responds to a perp
break
else
continue
/mob/living/simple_animal/bot/secbot/proc/check_for_weapons(var/obj/item/slot_item)
if(slot_item && slot_item.needs_permit)
return 1
return 0
/mob/living/simple_animal/bot/secbot/explode()
walk_to(src,0)
visible_message("<span class='boldannounce'>[src] blows apart!</span>")
var/turf/Tsec = get_turf(src)
var/obj/item/weapon/secbot_assembly/Sa = new /obj/item/weapon/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 baton_type(Tsec)
if(prob(50))
new /obj/item/bodypart/l_arm/robot(Tsec)
do_sparks(3, TRUE, src)
new /obj/effect/decal/cleanable/oil(loc)
..()
/mob/living/simple_animal/bot/secbot/attack_alien(var/mob/living/carbon/alien/user as mob)
..()
if(!isalien(target))
target = user
mode = BOT_HUNT
/mob/living/simple_animal/bot/secbot/Crossed(atom/movable/AM)
if(ismob(AM) && target)
var/mob/living/carbon/C = AM
if(!istype(C) || !C || in_range(src, target))
return
knockOver(C)
return
..()
/obj/machinery/bot_core/secbot
req_access = list(GLOB.access_security)
/mob/living/simple_animal/bot/secbot
name = "\improper Securitron"
desc = "A little security robot. He looks less than thrilled."
icon = 'icons/mob/aibots.dmi'
icon_state = "secbot0"
density = 0
anchored = 0
health = 25
maxHealth = 25
damage_coeff = list(BRUTE = 0.5, BURN = 0.7, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0)
pass_flags = PASSMOB
radio_key = /obj/item/device/encryptionkey/secbot //AI Priv + Security
radio_channel = "Security" //Security channel
bot_type = SEC_BOT
model = "Securitron"
bot_core_type = /obj/machinery/bot_core/secbot
var/baton_type = /obj/item/weapon/melee/baton
window_id = "autosec"
window_name = "Automatic Security Unit v1.6"
allow_pai = 0
data_hud_type = DATA_HUD_SECURITY_ADVANCED
var/mob/living/carbon/target
var/oldtarget_name
var/threatlevel = 0
var/target_lastloc //Loc of target when arrested.
var/last_found //There's a delay
var/declare_arrests = 1 //When making an arrest, should it notify everyone on the security channel?
var/idcheck = 0 //If true, arrest people with no IDs
var/weaponscheck = 0 //If true, arrest people for weapons if they lack access
var/check_records = 1 //Does it check security records?
var/arrest_type = 0 //If true, don't handcuff
/mob/living/simple_animal/bot/secbot/beepsky
name = "Officer Beep O'sky"
desc = "It's Officer Beep O'sky! Powered by a potato and a shot of whiskey."
idcheck = 0
weaponscheck = 0
auto_patrol = 1
/mob/living/simple_animal/bot/secbot/beepsky/jr
name = "Officer Pipsqueak"
desc = "It's Officer Beep O'sky's smaller, just-as aggressive cousin, Pipsqueak."
/mob/living/simple_animal/bot/secbot/beepsky/jr/Initialize()
..()
resize = 0.8
update_transform()
/mob/living/simple_animal/bot/secbot/beepsky/explode()
var/turf/Tsec = get_turf(src)
new /obj/item/weapon/stock_parts/cell/potato(Tsec)
var/obj/item/weapon/reagent_containers/food/drinks/drinkingglass/shotglass/S = new(Tsec)
S.reagents.add_reagent("whiskey", 15)
S.on_reagent_change()
..()
/mob/living/simple_animal/bot/secbot/pingsky
name = "Officer Pingsky"
desc = "It's Officer Pingsky! Delegated to satellite guard duty for harbouring anti-human sentiment."
radio_channel = "AI Private"
/mob/living/simple_animal/bot/secbot/Initialize()
..()
icon_state = "secbot[on]"
spawn(3)
var/datum/job/detective/J = new/datum/job/detective
access_card.access += J.get_access()
prev_access = access_card.access
//SECHUD
var/datum/atom_hud/secsensor = GLOB.huds[DATA_HUD_SECURITY_ADVANCED]
secsensor.add_hud_to(src)
/mob/living/simple_animal/bot/secbot/turn_on()
..()
icon_state = "secbot[on]"
/mob/living/simple_animal/bot/secbot/turn_off()
..()
icon_state = "secbot[on]"
/mob/living/simple_animal/bot/secbot/bot_reset()
..()
target = null
oldtarget_name = null
anchored = 0
walk_to(src,0)
last_found = world.time
/mob/living/simple_animal/bot/secbot/set_custom_texts()
text_hack = "You overload [name]'s target identification system."
text_dehack = "You reboot [name] and restore the target identification."
text_dehack_fail = "[name] refuses to accept your authority!"
/mob/living/simple_animal/bot/secbot/get_controls(mob/user)
var/dat
dat += hack(user)
dat += showpai(user)
dat += text({"
<TT><B>Securitron v1.6 controls</B></TT><BR><BR>
Status: []<BR>
Behaviour controls are [locked ? "locked" : "unlocked"]<BR>
Maintenance panel panel is [open ? "opened" : "closed"]"},
"<A href='?src=\ref[src];power=1'>[on ? "On" : "Off"]</A>" )
if(!locked || issilicon(user) || IsAdminGhost(user))
dat += text({"<BR>
Arrest Unidentifiable Persons: []<BR>
Arrest for Unauthorized Weapons: []<BR>
Arrest for Warrant: []<BR>
Operating Mode: []<BR>
Report Arrests[]<BR>
Auto Patrol: []"},
"<A href='?src=\ref[src];operation=idcheck'>[idcheck ? "Yes" : "No"]</A>",
"<A href='?src=\ref[src];operation=weaponscheck'>[weaponscheck ? "Yes" : "No"]</A>",
"<A href='?src=\ref[src];operation=ignorerec'>[check_records ? "Yes" : "No"]</A>",
"<A href='?src=\ref[src];operation=switchmode'>[arrest_type ? "Detain" : "Arrest"]</A>",
"<A href='?src=\ref[src];operation=declarearrests'>[declare_arrests ? "Yes" : "No"]</A>",
"<A href='?src=\ref[src];operation=patrol'>[auto_patrol ? "On" : "Off"]</A>" )
return dat
/mob/living/simple_animal/bot/secbot/Topic(href, href_list)
if(..())
return 1
switch(href_list["operation"])
if("idcheck")
idcheck = !idcheck
update_controls()
if("weaponscheck")
weaponscheck = !weaponscheck
update_controls()
if("ignorerec")
check_records = !check_records
update_controls()
if("switchmode")
arrest_type = !arrest_type
update_controls()
if("declarearrests")
declare_arrests = !declare_arrests
update_controls()
/mob/living/simple_animal/bot/secbot/proc/retaliate(mob/living/carbon/human/H)
threatlevel = H.assess_threat(src)
threatlevel += 6
if(threatlevel >= 4)
target = H
mode = BOT_HUNT
/mob/living/simple_animal/bot/secbot/attack_hand(mob/living/carbon/human/H)
if((H.a_intent == INTENT_HARM) || (H.a_intent == INTENT_DISARM))
retaliate(H)
return ..()
/mob/living/simple_animal/bot/secbot/attackby(obj/item/weapon/W, mob/user, params)
..()
if(istype(W, /obj/item/weapon/weldingtool) && user.a_intent != INTENT_HARM) // Any intent but harm will heal, so we shouldn't get angry.
return
if(!istype(W, /obj/item/weapon/screwdriver) && (W.force) && (!target) && (W.damtype != STAMINA) ) // Added check for welding tool to fix #2432. Welding tool behavior is handled in superclass.
retaliate(user)
/mob/living/simple_animal/bot/secbot/emag_act(mob/user)
..()
if(emagged == 2)
if(user)
to_chat(user, "<span class='danger'>You short out [src]'s target assessment circuits.</span>")
oldtarget_name = user.name
audible_message("<span class='danger'>[src] buzzes oddly!</span>")
declare_arrests = 0
icon_state = "secbot[on]"
/mob/living/simple_animal/bot/secbot/bullet_act(obj/item/projectile/Proj)
if(istype(Proj ,/obj/item/projectile/beam)||istype(Proj,/obj/item/projectile/bullet))
if((Proj.damage_type == BURN) || (Proj.damage_type == BRUTE))
if(!Proj.nodamage && Proj.damage < src.health)
retaliate(Proj.firer)
..()
/mob/living/simple_animal/bot/secbot/UnarmedAttack(atom/A)
if(!on)
return
if(iscarbon(A))
var/mob/living/carbon/C = A
if(!C.stunned || arrest_type)
stun_attack(A)
else if(C.canBeHandcuffed() && !C.handcuffed)
cuff(A)
else
..()
/mob/living/simple_animal/bot/secbot/hitby(atom/movable/AM, skipcatch = 0, hitpush = 1, blocked = 0)
if(istype(AM, /obj/item))
var/obj/item/I = AM
if(I.throwforce < src.health && I.thrownby && ishuman(I.thrownby))
var/mob/living/carbon/human/H = I.thrownby
retaliate(H)
..()
/mob/living/simple_animal/bot/secbot/proc/cuff(mob/living/carbon/C)
mode = BOT_ARREST
playsound(loc, 'sound/weapons/cablecuff.ogg', 30, 1, -2)
C.visible_message("<span class='danger'>[src] is trying to put zipties on [C]!</span>",\
"<span class='userdanger'>[src] is trying to put zipties on you!</span>")
spawn(60)
if( !Adjacent(C) || !isturf(C.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
return
if(!C.handcuffed)
C.handcuffed = new /obj/item/weapon/restraints/handcuffs/cable/zipties/used(C)
C.update_handcuffed()
playsound(loc, pick('sound/voice/bgod.ogg', 'sound/voice/biamthelaw.ogg', 'sound/voice/bsecureday.ogg', 'sound/voice/bradio.ogg', 'sound/voice/binsult.ogg', 'sound/voice/bcreep.ogg'), 50, 0)
back_to_idle()
/mob/living/simple_animal/bot/secbot/proc/stun_attack(mob/living/carbon/C)
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
icon_state = "secbot-c"
spawn(2)
icon_state = "secbot[on]"
var/threat = 5
if(ishuman(C))
C.stuttering = 5
C.Stun(5)
C.Weaken(5)
var/mob/living/carbon/human/H = C
threat = H.assess_threat(src)
else
C.Weaken(5)
C.stuttering = 5
C.Stun(5)
threat = C.assess_threat()
add_logs(src,C,"stunned")
if(declare_arrests)
var/area/location = get_area(src)
speak("[arrest_type ? "Detaining" : "Arresting"] level [threat] scumbag <b>[C]</b> in [location].", radio_channel)
C.visible_message("<span class='danger'>[src] has stunned [C]!</span>",\
"<span class='userdanger'>[src] has stunned you!</span>")
/mob/living/simple_animal/bot/secbot/handle_automated_action()
if(!..())
return
switch(mode)
if(BOT_IDLE) // idle
walk_to(src,0)
look_for_perp() // see if any criminals are in range
if(!mode && auto_patrol) // still idle, and set to patrol
mode = BOT_START_PATROL // switch to patrol mode
if(BOT_HUNT) // hunting for perp
// if can't reach perp for long enough, go idle
if(frustration >= 8)
walk_to(src,0)
back_to_idle()
return
if(target) // make sure target exists
if(Adjacent(target) && isturf(target.loc)) // if right next to perp
stun_attack(target)
mode = BOT_PREP_ARREST
anchored = 1
target_lastloc = target.loc
return
else // not next to perp
var/turf/olddist = get_dist(src, target)
walk_to(src, target,1,4)
if((get_dist(src, target)) >= (olddist))
frustration++
else
frustration = 0
else
back_to_idle()
if(BOT_PREP_ARREST) // preparing to arrest target
// see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again.
if( !Adjacent(target) || !isturf(target.loc) || target.weakened < 2 )
back_to_hunt()
return
if(iscarbon(target) && target.canBeHandcuffed())
if(!arrest_type)
if(!target.handcuffed) //he's not cuffed? Try to cuff him!
cuff(target)
else
back_to_idle()
return
else
back_to_idle()
return
if(BOT_ARREST)
if(!target)
anchored = 0
mode = BOT_IDLE
last_found = world.time
frustration = 0
return
if(target.handcuffed) //no target or target cuffed? back to idle.
back_to_idle()
return
if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && target.weakened < 2)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again.
back_to_hunt()
return
else //Try arresting again if the target escapes.
mode = BOT_PREP_ARREST
anchored = 0
if(BOT_START_PATROL)
look_for_perp()
start_patrol()
if(BOT_PATROL)
look_for_perp()
bot_patrol()
return
/mob/living/simple_animal/bot/secbot/proc/back_to_idle()
anchored = 0
mode = BOT_IDLE
target = null
last_found = world.time
frustration = 0
spawn(0)
handle_automated_action() //ensure bot quickly responds
/mob/living/simple_animal/bot/secbot/proc/back_to_hunt()
anchored = 0
frustration = 0
mode = BOT_HUNT
spawn(0)
handle_automated_action() //ensure bot quickly responds
// look for a criminal in view of the bot
/mob/living/simple_animal/bot/secbot/proc/look_for_perp()
anchored = 0
for (var/mob/living/carbon/C in view(7,src)) //Let's find us a criminal
if((C.stat) || (C.handcuffed))
continue
if((C.name == oldtarget_name) && (world.time < last_found + 100))
continue
threatlevel = C.assess_threat(src)
if(!threatlevel)
continue
else if(threatlevel >= 4)
target = C
oldtarget_name = C.name
speak("Level [threatlevel] infraction alert!")
playsound(loc, pick('sound/voice/bcriminal.ogg', 'sound/voice/bjustice.ogg', 'sound/voice/bfreeze.ogg'), 50, 0)
visible_message("<b>[src]</b> points at [C.name]!")
mode = BOT_HUNT
spawn(0)
handle_automated_action() // ensure bot quickly responds to a perp
break
else
continue
/mob/living/simple_animal/bot/secbot/proc/check_for_weapons(var/obj/item/slot_item)
if(slot_item && slot_item.needs_permit)
return 1
return 0
/mob/living/simple_animal/bot/secbot/explode()
walk_to(src,0)
visible_message("<span class='boldannounce'>[src] blows apart!</span>")
var/turf/Tsec = get_turf(src)
var/obj/item/weapon/secbot_assembly/Sa = new /obj/item/weapon/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 baton_type(Tsec)
if(prob(50))
new /obj/item/bodypart/l_arm/robot(Tsec)
do_sparks(3, TRUE, src)
new /obj/effect/decal/cleanable/oil(loc)
..()
/mob/living/simple_animal/bot/secbot/attack_alien(var/mob/living/carbon/alien/user as mob)
..()
if(!isalien(target))
target = user
mode = BOT_HUNT
/mob/living/simple_animal/bot/secbot/Crossed(atom/movable/AM)
if(ismob(AM) && target)
var/mob/living/carbon/C = AM
if(!istype(C) || !C || in_range(src, target))
return
knockOver(C)
return
..()
/obj/machinery/bot_core/secbot
req_access = list(GLOB.access_security)
@@ -1,57 +1,57 @@
/obj/item/projectile/hivebotbullet
damage = 10
damage_type = BRUTE
/mob/living/simple_animal/hostile/hivebot
name = "hivebot"
desc = "A small robot."
icon = 'icons/mob/hivebot.dmi'
icon_state = "basic"
icon_living = "basic"
icon_dead = "basic"
gender = NEUTER
health = 15
maxHealth = 15
healable = 0
melee_damage_lower = 2
melee_damage_upper = 3
attacktext = "claws"
attack_sound = 'sound/weapons/bladeslice.ogg'
projectilesound = 'sound/weapons/Gunshot.ogg'
projectiletype = /obj/item/projectile/hivebotbullet
faction = list("hivebot")
check_friendly_fire = 1
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
speak_emote = list("states")
gold_core_spawnable = 1
del_on_death = 1
loot = list(/obj/effect/decal/cleanable/robot_debris)
/mob/living/simple_animal/hostile/hivebot/Initialize()
..()
deathmessage = "[src] blows apart!"
/mob/living/simple_animal/hostile/hivebot/range
name = "hivebot"
desc = "A smallish robot, this one is armed!"
ranged = 1
retreat_distance = 5
minimum_distance = 5
/mob/living/simple_animal/hostile/hivebot/rapid
ranged = 1
rapid = 1
retreat_distance = 5
minimum_distance = 5
/mob/living/simple_animal/hostile/hivebot/strong
name = "strong hivebot"
desc = "A robot, this one is armed and looks tough!"
health = 80
maxHealth = 80
ranged = 1
/mob/living/simple_animal/hostile/hivebot/death(gibbed)
do_sparks(3, TRUE, src)
/obj/item/projectile/hivebotbullet
damage = 10
damage_type = BRUTE
/mob/living/simple_animal/hostile/hivebot
name = "hivebot"
desc = "A small robot."
icon = 'icons/mob/hivebot.dmi'
icon_state = "basic"
icon_living = "basic"
icon_dead = "basic"
gender = NEUTER
health = 15
maxHealth = 15
healable = 0
melee_damage_lower = 2
melee_damage_upper = 3
attacktext = "claws"
attack_sound = 'sound/weapons/bladeslice.ogg'
projectilesound = 'sound/weapons/Gunshot.ogg'
projectiletype = /obj/item/projectile/hivebotbullet
faction = list("hivebot")
check_friendly_fire = 1
atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
minbodytemp = 0
speak_emote = list("states")
gold_core_spawnable = 1
del_on_death = 1
loot = list(/obj/effect/decal/cleanable/robot_debris)
/mob/living/simple_animal/hostile/hivebot/Initialize()
..()
deathmessage = "[src] blows apart!"
/mob/living/simple_animal/hostile/hivebot/range
name = "hivebot"
desc = "A smallish robot, this one is armed!"
ranged = 1
retreat_distance = 5
minimum_distance = 5
/mob/living/simple_animal/hostile/hivebot/rapid
ranged = 1
rapid = 1
retreat_distance = 5
minimum_distance = 5
/mob/living/simple_animal/hostile/hivebot/strong
name = "strong hivebot"
desc = "A robot, this one is armed and looks tough!"
health = 80
maxHealth = 80
ranged = 1
/mob/living/simple_animal/hostile/hivebot/death(gibbed)
do_sparks(3, TRUE, src)
..(1)