Files
Paradise/code/modules/mob/living/carbon/human/interactive/interactive.dm
T
Tigercat2000 0f70e6810b -tg- OOP Hud Refactor
- Added 4 new HUD styles
 - Humans recreate their hud if they change their UI pref mid-game
 - Refactored how objects are added to the client screen
 - HUD's are now handled by subtype and mob/proc/create_mob_hud()
 - HUD visibility is no longer chained directly to the F12 button, it's a proc on HUD datums now
 - Mobs only create/destroy their HUD when necessary, not every Login()
 - Destroyed aim-mode, it didn't work and I couldn't make it work.
 - Renamed all of the screen1_x.dmi files to screen_x.dmi
 - Removed screen1.dmi, screen_gen.dmi now handles generic icons.
2016-04-21 20:28:08 -07:00

954 lines
28 KiB
Plaintext

/*
NPC VAR EXPLANATIONS (for modules and other things)
doing = their current action, SNPC_INTERACTING, SNPC_TRAVEL or SNPC_FIGHTING
interest = how interested the NPC is in the situation, if they are idle, this drops
timeout = this is internal
TARGET = their current target
LAST_TARGET = their last target
nearby = a list of nearby mobs
best_force = the highest force object, used for checking when to swap items
retal = this is internal
retal_target = this is internal
update_hands = this is a bool (1/0) to determine if the NPC should update what is in his hands
MYID = their ID card
MYPDA = their PDA
main_hand = what is in their "main" hand (chosen from left > right)
TRAITS = the traits assigned to this npc
mymjob = the job assigned to the npc
robustness = the chance for the npc to hit something
smartness = the inverse chance for an npc to do stupid things
attitude = the chance for an npc to do rude or mean things
slyness = the chance for an npc to do naughty things ie thieving
functions = the list of procs that the npc will use for modules
graytide = shitmin var to make them go psycho
*/
/mob/living/carbon/human/interactive
name = "interactive station member"
var/doing = 0
var/interest = 10
var/maxInterest = 10
var/timeout = 0
var/inactivity_period = 0
var/atom/TARGET = null
var/atom/LAST_TARGET = null
var/list/nearby = list()
var/best_force = 0
var/retal = 0
var/mob/retal_target = null
var/update_hands = 0
var/list/blacklistItems = list() // items we should be ignoring
var/maxStepsTick = 6 // step as many times as we can per frame
//Job and mind data
var/obj/item/weapon/card/id/MYID
var/obj/item/weapon/card/id/RPID // the "real" idea they use
var/obj/item/device/pda/MYPDA
var/obj/item/main_hand
var/obj/item/other_hand
var/TRAITS = 0
var/obj/item/weapon/card/id/Path_ID
var/default_job = /datum/job/civilian // the type for the default job
var/datum/job/myjob
var/list/myPath = list()
faction = list("synth")
//trait vars
var/robustness = 50
var/smartness = 50
var/attitude = 50
var/slyness = 50
var/graytide = 0
var/list/favoured_types = list() // allow a mob to favour a type, and hold onto them
var/chattyness = SNPC_CHANCE_TALK
var/targetInterestShift = 5 // how much a good action should "reward" the npc
//modules
var/list/functions = list("nearbyscan","combat","shitcurity","chatter")
var/restrictedJob = 0
var/shouldUseDynamicProc = 0 // switch to make the AI control it's own proccessing
var/alternateProcessing = 0
var/forceProcess = 0
var/processTime = 10
var/speak_file = "npc_chatter.json"
var/list/knownStrings = list()
//snpc traitor variables
var/isTraitor = 0
var/traitorTarget
var/traitorScale = 0 // our ability as a traitor
var/traitorType = 0
/// SNPC voice handling
/mob/living/carbon/human/interactive/proc/loadVoice()
var/savefile/S = new /savefile("data/npc_saves/snpc.sav")
S["knownStrings"] >> knownStrings
if(isnull(knownStrings))
knownStrings = list()
/mob/living/carbon/human/interactive/proc/saveVoice()
var/savefile/S = new /savefile("data/npc_saves/snpc.sav")
S["knownStrings"] << knownStrings
//botPool funcs
/mob/living/carbon/human/interactive/proc/takeDelegate(mob/living/carbon/human/interactive/from,doReset=TRUE)
change_eye_color(255, 0, 0)
if(from == src)
return FALSE
TARGET = from.TARGET
LAST_TARGET = from.LAST_TARGET
retal = from.retal
retal_target = from.retal_target
doing = from.doing
//
timeout = 0
inactivity_period = 0
interest = maxInterest
//
update_icons()
if(doReset)
from.TARGET = null
from.LAST_TARGET = null
from.retal = 0
from.retal_target = null
from.doing = 0
return TRUE
//end pool funcs
/mob/living/carbon/human/interactive/proc/random()
//this is here because this has no client/prefs/brain whatever.
age = rand(AGE_MIN, AGE_MAX)
change_gender(pick("male", "female"))
rename_character(real_name, species.get_random_name(gender))
//job handling
myjob = new default_job()
job = myjob.title
mind.assigned_role = job
myjob.equip(src)
myjob.apply_fingerprints(T)
/mob/living/carbon/human/interactive/proc/reset()
walk(src, 0)
timeout = 100
retal = 0
doing = 0
inactivity_period = 0
/client/proc/resetSNPC(mob/living/carbon/human/interactive/T in npc_master.botPool_l)
set name = "Reset SNPC"
set desc = "Reset the SNPC"
set category = "Debug"
if(!holder)
return
if(istype(T))
T.reset()
/client/proc/toggleSNPC(mob/living/carbon/human/interactive/T in npc_master.botPool_l)
set name = "Toggle SNPC Proccessing Mode"
set desc = "Toggle SNPC Proccessing Mode"
set category = "Debug"
if(!holder)
return
if(istype(T))
T.alternateProcessing = !T.alternateProcessing
T.forceProcess = 1
to_chat(usr, "[T]'s processing has been switched to [T.alternateProcessing ? "High Profile" : "Low Profile"]")
/client/proc/customiseSNPC(mob/living/carbon/human/interactive/T in npc_master.botPool_l)
set name = "Customize SNPC"
set desc = "Customise the SNPC"
set category = "Debug"
if(!holder)
return
if(!istype(T))
return
var/list/jobs[0]
for(var/datum/job/j in job_master.occupations)
if(j.title != "AI" && j.title != "Cyborg")
jobs[j.title] = j
jobs = sortAssoc(jobs)
var/job_name = input("Choose Job") as null|anything in jobs
if(job_name)
var/datum/job/cjob = jobs[job_name]
var/alt_title = input("Choose Alt Title") in (list(job_name) + cjob.alt_titles)
T.myjob = cjob
T.job = cjob.title
T.mind.assigned_role = cjob.title
for(var/obj/item/W in T)
qdel(W)
T.myjob.equip(T)
T.myjob.apply_fingerprints(T)
T.doSetup(alt_title)
var/shouldDoppel = input("Do you want the SNPC to disguise themself as a crewmember?") as anything in list("Yes", "No")
if(shouldDoppel == "Yes")
var/list/validchoices = list()
for(var/mob/living/carbon/human/M in mob_list)
validchoices += M
var/mob/living/carbon/human/chosen = input("Which crewmember?") as null|anything in validchoices
if(chosen)
var/datum/dna/toDoppel = chosen.dna
T.real_name = toDoppel.real_name
T.set_species(chosen.species.name)
T.body_accessory = chosen.body_accessory
T.dna = toDoppel.Clone()
T.UpdateAppearance()
domutcheck(T)
var/doTrait = input("Do you want the SNPC to be a traitor?") as anything in list("Yes", "No")
if(doTrait == "Yes")
var/list/tType = list("Brute" = SNPC_BRUTE, "Stealth" = SNPC_STEALTH, "Martyr" = SNPC_MARTYR, "Psycho" = SNPC_PSYCHO)
var/cType = input("Choose the traitor personality.") as null|anything in tType
if(cType)
var/value = tType[cType]
T.makeTraitor(value)
var/doTele = input("Place the SNPC in their department?") as anything in list("Yes", "No")
if(doTele == "Yes")
T.loc = pick(get_area_turfs(T.job2area(T.myjob)))
T.revive()
/mob/living/carbon/human/interactive/proc/doSetup(alt_title = null)
Path_ID = new /obj/item/weapon/card/id(src)
var/datum/job/captain/C = new/datum/job/captain
Path_ID.access = C.get_access()
if(!alt_title)
alt_title = job
MYID = new(src)
MYID.name = "[real_name]'s ID Card ([alt_title])"
MYID.assignment = "[alt_title]"
MYID.rank = job
MYID.sex = capitalize(gender)
MYID.age = age
MYID.registered_name = real_name
MYID.photo = get_id_photo(src)
MYID.access = Path_ID.access // Automatons have strange powers... strange indeed
RPID = new(src)
RPID.name = "[real_name]'s ID Card ([alt_title])"
RPID.assignment = "[alt_title]"
RPID.rank = job
RPID.sex = capitalize(gender)
RPID.age = age
RPID.registered_name = real_name
RPID.photo = get_id_photo(src)
RPID.access = myjob.get_access()
equip_to_slot_or_del(MYID, slot_wear_id)
MYPDA = new(src)
MYPDA.owner = real_name
MYPDA.ownjob = alt_title
MYPDA.ownrank = job
MYPDA.name = "PDA-[real_name] ([alt_title])"
equip_to_slot_or_del(MYPDA, slot_belt)
zone_sel.selecting = "chest"
//arms
if(prob((SNPC_FUZZY_CHANCE_LOW+SNPC_FUZZY_CHANCE_HIGH)/4))
var/obj/item/organ/external/R = organs_by_name["r_arm"]
if(R)
R.robotize()
else
var/obj/item/organ/external/L = organs_by_name["l_arm"]
if(L)
L.robotize()
//legs
if(prob((SNPC_FUZZY_CHANCE_LOW+SNPC_FUZZY_CHANCE_HIGH)/4))
var/obj/item/organ/external/R = organs_by_name["r_leg"]
if(R)
R.robotize()
else
var/obj/item/organ/external/L = organs_by_name["l_leg"]
if(L)
L.robotize()
UpdateDamageIcon()
regenerate_icons()
hand = 0
functions = list("nearbyscan", "combat", "shitcurity", "chatter") // stop customize adding multiple copies of a function
setup_job(job)
if(TRAITS & TRAIT_ROBUST)
robustness = 75
else if(TRAITS & TRAIT_UNROBUST)
robustness = 25
//modifiers are prob chances, lower = smarter
if(TRAITS & TRAIT_SMART)
smartness = 75
else if(TRAITS & TRAIT_DUMB)
disabilities |= CLUMSY
smartness = 25
if(TRAITS & TRAIT_MEAN)
attitude = 75
else if(TRAITS & TRAIT_FRIENDLY)
attitude = 1
if(TRAITS & TRAIT_THIEVING)
slyness = 75
/mob/living/carbon/human/interactive/proc/setup_job(thejob)
switch(thejob)
if("Civilian")
favoured_types = list(/obj/item/clothing, /obj/item/weapon)
if("Captain", "Head of Personnel")
favoured_types = list(/obj/item/clothing, /obj/item/weapon/stamp/captain,/obj/item/weapon/disk/nuclear)
if("Nanotrasen Representative")
favoured_types = list(/obj/item/clothing, /obj/item/weapon/stamp/centcom, /obj/item/weapon/paper, /obj/item/weapon/melee/baton/loaded/ntcane)
functions += "paperwork"
if("Magistrate", "Internal Affairs Agent")
favoured_types = list(/obj/item/clothing, /obj/item/weapon/stamp/law, /obj/item/weapon/paper)
functions += "paperwork"
if("Quartermaster", "Cargo Technician")
favoured_types = list(/obj/item/clothing, /obj/item/weapon/stamp/granted, /obj/item/weapon/stamp/denied, /obj/item/weapon/paper, /obj/item/weapon/clipboard)
functions += "stamping"
if("Chef")
favoured_types = list(/obj/item/weapon/reagent_containers/food, /obj/item/weapon/kitchen)
functions += "souschef"
restrictedJob = 1
if("Bartender")
favoured_types = list(/obj/item/weapon/reagent_containers/food, /obj/item/weapon/kitchen)
functions += "bartend"
restrictedJob = 1
if("Station Engineer", "Chief Engineer", "Life Support Specialist", "Mechanic")
favoured_types = list(/obj/item/stack, /obj/item/weapon, /obj/item/clothing)
if("Chief Medical Officer", "Medical Doctor", "Chemist", "Virologist", "Geneticist", "Psychiatrist", "Paramedic", "Brig Physician")
favoured_types = list(/obj/item/weapon/reagent_containers/glass/beaker, /obj/item/weapon/storage/firstaid, /obj/item/stack/medical, /obj/item/weapon/reagent_containers/syringe)
functions += "healpeople"
if("Research Director", "Scientist", "Roboticist")
favoured_types = list(/obj/item/weapon/reagent_containers/glass/beaker, /obj/item/stack, /obj/item/weapon/reagent_containers)
if("Head of Security", "Warden", "Security Officer", "Detective", "Security Pod Pilot", "Blueshield")
favoured_types = list(/obj/item/clothing, /obj/item/weapon, /obj/item/weapon/restraints)
if("Janitor")
favoured_types = list(/obj/item/weapon/mop, /obj/item/weapon/reagent_containers/glass/bucket, /obj/item/weapon/reagent_containers/spray/cleaner, /obj/effect/decal/cleanable)
functions += "dojanitor"
if("Clown")
favoured_types = list(/obj/item/weapon/soap, /obj/item/weapon/reagent_containers/food/snacks/grown/banana, /obj/item/weapon/bananapeel)
functions += "clowning"
if("Botanist")
favoured_types = list(/obj/machinery/portable_atmospherics/hydroponics, /obj/item/weapon/reagent_containers, /obj/item/weapon)
functions += "botany"
restrictedJob = 1
else
favoured_types = list(/obj/item/clothing)
/mob/living/carbon/human/interactive/proc/makeTraitor(var/inPers)
isTraitor = 1
traitorScale = (slyness + smartness) + rand(-10,10)
traitorType = inPers
ticker.mode.traitors += mind
mind.special_role = "traitor"
var/datum/mindslaves/slaved = new()
slaved.masters += mind
mind.som = slaved
ticker.mode.update_traitor_icons_added(mind)
switch(traitorType)
if(SNPC_BRUTE) // SMASH KILL RAAARGH
var/datum/objective/assassinate/A = new
A.owner = mind
A.find_target()
mind.objectives += A
traitorTarget = A.target.current
if(SNPC_STEALTH) // Shhh we is sneekies
var/datum/objective/steal/S = new
S.owner = mind
S.find_target()
mind.objectives += S
traitorTarget = locate(S.steal_target.typepath) in world
if(SNPC_MARTYR) // MY LIFE FOR SPESZUL
var/targetType = pick(/obj/structure/particle_accelerator, /obj/machinery/gravity_generator/main, /obj/machinery/power/smes)
traitorTarget = locate(targetType) in world
var/datum/objective/O = new("Destroy \the [traitorTarget].")
O.owner = mind
mind.objectives += O
if(SNPC_PSYCHO) // YOU'RE LIKE A FLESH BICYLE AND I WANT TO DISMANTLE YOU
var/datum/objective/hijack/H = new
H.owner = mind
mind.objectives += H
traitorTarget = null
functions += "traitor"
faction -= "neutral"
faction += "hostile"
/mob/living/carbon/human/interactive/create_mob_hud()
if(!hud_used)
hud_used = new /datum/hud/human(src)
/mob/living/carbon/human/interactive/New()
..()
snpc_list += src
create_mob_hud()
sync_mind()
random()
doSetup()
npc_master.insertBot(src)
loadVoice()
hear_radio_list += src
// a little bit of variation to make individuals more unique
robustness += rand(-10, 10)
smartness += rand(-10, 10)
attitude += rand(-10, 10)
slyness += rand(-10, 10)
doProcess()
/mob/living/carbon/human/interactive/Destroy()
hear_radio_list -= src
snpc_list -= src
return ..()
/mob/living/carbon/human/interactive/proc/retalTarget(mob/living/target)
var/mob/living/M = target
if(istype(M))
if(health > 0)
if(M.a_intent == "help" && !incapacitated())
chatter()
if(istype(target, /mob/living/carbon) && !retal && prob(SNPC_FUZZY_CHANCE_LOW))
var/mob/living/carbon/C = target
if(!Adjacent(target))
tryWalk(target)
else
C.help_shake_act(src)
if(M.a_intent == "harm")
retal = 1
retal_target = target
//Retaliation clauses
/mob/living/carbon/human/interactive/attacked_by(obj/item/I, mob/living/user, def_zone)
..()
retalTarget(user)
/mob/living/carbon/human/interactive/hitby(atom/movable/AM)
..()
var/mob/living/carbon/C = locate(/mob/living/carbon) in view(SNPC_MIN_RANGE_FIND, src)
if(C)
retalTarget(C)
/mob/living/carbon/human/interactive/bullet_act(obj/item/projectile/P)
..()
retalTarget(P.firer)
/mob/living/carbon/human/interactive/attack_hand(mob/living/carbon/human/M)
..()
retalTarget(M)
/mob/living/carbon/human/interactive/show_inv(mob/user)
..()
retalTarget(user)
/mob/living/carbon/human/interactive/can_inject(mob/user, error_msg, target_zone, var/penetrate_thick = 0)
..()
retalTarget(user)
//THESE EXIST FOR DEBUGGING OF THE DOING/INTEREST SYSTEM EASILY
/mob/living/carbon/human/interactive/proc/doing2string(doin)
var/toReturn = ""
if(!doin)
toReturn = "not doing anything"
if(doin & SNPC_INTERACTING)
toReturn += "interacting with something, "
if(doin & SNPC_FIGHTING)
toReturn += "engaging in combat, "
if(doin & SNPC_TRAVEL)
toReturn += "and going somewhere"
return toReturn
/mob/living/carbon/human/interactive/proc/interest2string(inter)
var/toReturn = "Flatlined"
if(inter >= 0 && inter <= 25)
toReturn = "Very Bored"
if(inter >= 26 && inter <= 50)
toReturn = "Bored"
if(inter >= 51 && inter <= 75)
toReturn = "Content"
if(inter >= 76)
toReturn = "Excited"
return toReturn
//END DEBUG
/mob/living/carbon/human/interactive/proc/IsDeadOrIncap(checkDead = TRUE)
if(!canmove)
return 1
if(health <= 0 && checkDead)
return 1
if(restrained())
return 1
if(paralysis)
return 1
if(stunned)
return 1
if(stat)
return 1
if(inactivity_period > 0)
return 1
return 0
/mob/living/carbon/human/interactive/proc/enforce_hands()
if(main_hand)
if(main_hand.loc != src)
main_hand = null
if(other_hand)
if(other_hand.loc != src)
other_hand = null
if(hand)
if(!l_hand)
main_hand = null
if(r_hand)
swap_hands()
else
if(!r_hand)
main_hand = null
if(l_hand)
swap_hands()
/mob/living/carbon/human/interactive/proc/swap_hands()
hand = !hand
var/obj/item/T = other_hand
main_hand = other_hand
other_hand = T
update_hands = 1
/mob/living/carbon/human/interactive/proc/take_to_slot(obj/item/G, var/hands=0)
var/list/slots = list("left pocket" = slot_l_store, "right pocket" = slot_r_store, "left hand" = slot_l_hand, "right hand" = slot_r_hand)
if(hands)
slots = list("left hand" = slot_l_hand, "right hand" = slot_r_hand)
G.loc = src
if(G.force && G.force > best_force)
best_force = G.force
equip_in_one_of_slots(G, slots)
update_hands = 1
/mob/living/carbon/human/interactive/proc/insert_into_backpack()
var/list/slots = list(slot_l_store, slot_r_store, slot_l_hand, slot_r_hand)
var/obj/item/I = get_item_by_slot(pick(slots))
var/obj/item/weapon/storage/BP = get_item_by_slot(slot_back)
if(back && BP && I)
if(BP.can_be_inserted(I))
BP.handle_item_insertion(I)
else
unEquip(I,TRUE)
update_hands = 1
/mob/living/carbon/human/interactive/proc/targetRange(towhere)
return get_dist(get_turf(towhere), get_turf(src))
/mob/living/carbon/human/interactive/death()
saveVoice()
..()
/mob/living/carbon/human/interactive/hear_say(message, verb = "says", datum/language/language = null, alt_name = "", italics = 0, mob/speaker = null, sound/speech_sound, sound_vol)
if(!istype(speaker, /mob/living/carbon/human/interactive))
knownStrings |= html_decode(message)
..()
/mob/living/carbon/human/interactive/hear_radio(message, verb = "says", datum/language/language=null, part_a, part_b, mob/speaker = null, hard_to_hear = 0, vname = "", atom/follow_target)
if(!istype(speaker, /mob/living/carbon/human/interactive))
knownStrings |= html_decode(message)
..()
/mob/living/carbon/human/interactive/proc/doProcess()
forceProcess = 0
if(shouldUseDynamicProc)
var/isSeen = 0
for(var/mob/living/carbon/human/A in orange(12, src))
if(A.client)
isSeen = 1
alternateProcessing = isSeen
if(alternateProcessing)
forceProcess = 1
if(IsDeadOrIncap())
reset()
return
//---------------------------
//---- interest flow control
if(interest < 0 || inactivity_period < 0)
if(interest < 0)
interest = 0
if(inactivity_period < 0)
inactivity_period = 0
if(interest > maxInterest)
interest = maxInterest
//---------------------------
//VIEW FUNCTIONS
//doorscan is now integrated into life and runs before all other procs
var/mistake_chance = (100 - smartness) / 2
spawn(0)
for(var/dir in alldirs)
var/turf/T = get_step(src, dir)
if(T)
for(var/obj/machinery/door/D in T.contents)
if(!istype(D,/obj/machinery/door/poddoor) && D.density)
spawn(0)
if(istype(D,/obj/machinery/door/airlock))
var/obj/machinery/door/airlock/AL = D
if(!AL.CanAStarPass(RPID)) // only crack open doors we can't get through
AL.p_open = 1
AL.update_icon()
AL.shock(src, mistake_chance)
sleep(5)
AL.unlock()
if(prob(mistake_chance))
if(!AL.wires.IsIndexCut(AIRLOCK_WIRE_DOOR_BOLTS))
AL.wires.CutWireIndex(AIRLOCK_WIRE_DOOR_BOLTS)
else
if(AL.wires.IsIndexCut(AIRLOCK_WIRE_DOOR_BOLTS))
AL.wires.CutWireIndex(AIRLOCK_WIRE_DOOR_BOLTS, 1)
if(AL.locked)
AL.wires.UpdatePulsed(AIRLOCK_WIRE_DOOR_BOLTS)
if(!AL.wires.IsIndexCut(AIRLOCK_WIRE_MAIN_POWER1))
AL.wires.CutWireIndex(AIRLOCK_WIRE_MAIN_POWER1)
if(!AL.wires.IsIndexCut(AIRLOCK_WIRE_MAIN_POWER2))
AL.wires.CutWireIndex(AIRLOCK_WIRE_MAIN_POWER2)
if(prob(mistake_chance) && !AL.wires.IsIndexCut(AIRLOCK_WIRE_SAFETY))
AL.wires.CutWireIndex(AIRLOCK_WIRE_SAFETY)
if(prob(mistake_chance) && !AL.wires.IsIndexCut(AIRLOCK_WIRE_ELECTRIFY))
AL.wires.CutWireIndex(AIRLOCK_WIRE_ELECTRIFY)
sleep(5)
AL.p_open = 0
AL.update_icon()
D.open()
if(update_hands)
if(l_hand || r_hand)
if(l_hand)
hand = 1
main_hand = l_hand
if(r_hand)
other_hand = r_hand
else if(r_hand)
hand = 0
main_hand = r_hand
if(l_hand) //this technically shouldnt occur, but its a redundancy
other_hand = l_hand
update_icons()
update_hands = 0
if(grabbed_by.len > 0)
for(var/obj/item/weapon/grab/G in grabbed_by)
if(Adjacent(G))
a_intent = "disarm"
G.assailant.attack_hand(src)
inactivity_period = 10
if(buckled)
resist()
inactivity_period = 10
//proc functions
for(var/Proc in functions)
if(!IsDeadOrIncap())
callfunction(Proc)
//target interaction stays hardcoded
if(TARGET && (TARGET in blacklistItems)) // don't use blacklisted items
TARGET = null
if(TARGET && Adjacent(TARGET))
doing |= SNPC_INTERACTING
//--------DOORS
if(istype(TARGET, /obj/machinery/door))
var/obj/machinery/door/D = TARGET
if(D.check_access(MYID) && !istype(D,/obj/machinery/door/poddoor))
D.open()
sleep(15)
var/turf/T = get_step(get_step(D.loc, dir), dir) //recursion yo
tryWalk(T)
//THIEVING SKILLS
insert_into_backpack() // dump random item into backpack to make space
//---------ITEMS
if(istype(TARGET, /obj/item))
var/obj/item/I = TARGET
if(I.anchored)
TARGET = null
else if(istype(TARGET, /obj/item/weapon))
var/obj/item/weapon/W = TARGET
if(W.force >= best_force || prob((SNPC_FUZZY_CHANCE_LOW + SNPC_FUZZY_CHANCE_HIGH) / 2) || favouredObjIn(list(W)))
if(!l_hand || !r_hand)
put_in_hands(W)
else
insert_into_backpack()
else
if(!l_hand || !r_hand)
put_in_hands(TARGET)
else
insert_into_backpack()
//---------FASHION
if(istype(TARGET, /obj/item/clothing))
var/obj/item/clothing/C = TARGET
drop_item()
spawn(5)
take_to_slot(C,1)
if(!equip_to_appropriate_slot(C))
var/obj/item/I = get_item_by_slot(C)
unEquip(I)
spawn(5)
equip_to_appropriate_slot(C)
update_hands = 1
if(MYPDA in loc)
equip_to_appropriate_slot(MYPDA)
if(MYID in loc)
equip_to_appropriate_slot(MYID)
//THIEVING SKILLS END
//-------------TOUCH ME
if(istype(TARGET, /obj/structure))
var/obj/structure/STR = TARGET
if(main_hand)
var/obj/item/weapon/W = main_hand
STR.attackby(W, src)
else
STR.attack_hand(src)
interest += targetInterestShift
doing = doing & ~SNPC_INTERACTING
timeout = 0
TARGET = null
else
if(TARGET)
tryWalk(TARGET)
timeout++
if(doing == 0)
interest--
else
interest++
if(inactivity_period > 0)
inactivity_period--
if(interest <= 0 || timeout >= 10) // facilitate boredom functions
TARGET = null
doing = 0
timeout = 0
myPath = list()
//this is boring, lets move
if(!doing && !IsDeadOrIncap() && !TARGET)
doing |= SNPC_TRAVEL
if(!isTraitor || !traitorTarget || get_dist(src, traitorTarget) >= SNPC_MAX_RANGE_FIND || get_dist(src, traitorTarget) <= 1)
var/choice = rand(1,50)
switch(choice)
if(1 to 30)
//chance to chase an item
TARGET = locate(/obj/item) in favouredObjIn(oview(SNPC_MIN_RANGE_FIND, src))
if(31 to 40)
TARGET = safepick(get_area_turfs(job2area(myjob)))
if(41 to 45)
TARGET = pick(target_filter(favouredObjIn(urange(SNPC_MAX_RANGE_FIND, src, 1))))
if(46 to 50)
TARGET = pick(target_filter(oview(SNPC_MIN_RANGE_FIND, src)))
else
TARGET = traitorTarget
tryWalk(TARGET)
LAST_TARGET = TARGET
if(alternateProcessing)
spawn(processTime)
doProcess()
/mob/living/carbon/human/interactive/proc/favouredObjIn(list/inList)
var/list/outList = list()
for(var/i in inList)
for(var/path in favoured_types)
if(istype(i, path))
outList += i
if(!outList.len)
outList = inList
return outList
/mob/living/carbon/human/interactive/proc/callfunction(Proc)
spawn(0)
call(src, Proc)(src)
/mob/living/carbon/human/interactive/proc/tryWalk(turf/inTarget)
if(restrictedJob) // we're a job that has to stay in our home
if(!(get_turf(inTarget) in get_area_turfs(job2area(myjob))))
TARGET = null
return
if(!IsDeadOrIncap())
if(!walk2derpless(inTarget))
timeout++
else
timeout++
/mob/living/carbon/human/interactive/proc/getGoodPath(target, maxtries=512)
set background = 1
var/turf/end = get_turf(target)
var/turf/current = get_turf(src)
var/list/path = list()
var/tries = 0
while(current != end && tries < maxtries)
var/turf/shortest = current
for(var/turf/T in view(current,1))
var/foundDense = 0
for(var/atom/A in T)
if(A.density)
foundDense = 1
if(T.density == 0 && !foundDense)
if(get_dist(T, target) < get_dist(shortest,target))
shortest = T
else
tries++
else
tries++
current = shortest
path += shortest
return path
/mob/living/carbon/human/interactive/proc/walk2derpless(target)
set background = 1
if(!target)
return 0
if(myPath.len <= 0)
myPath = get_path_to(src, get_turf(target), /turf/proc/Distance, SNPC_MAX_RANGE_FIND + 1, 250,1, id=Path_ID)
if(myPath)
if(myPath.len > 0)
doing = doing & ~SNPC_TRAVEL
for(var/i = 0; i < maxStepsTick; ++i)
if(!IsDeadOrIncap())
if(myPath.len >= 1)
walk_to(src,myPath[1],0,5)
myPath -= myPath[1]
return 1
return 0
/mob/living/carbon/human/interactive/proc/job2area(target)
var/datum/job/T = target
switch(T.title)
if("Civilian", "Paramedic")
return /area/hallway/primary
if("Captain", "Head of Personnel", "Blueshield")
return /area/bridge
if("Bartender")
return /area/crew_quarters/bar
if("Chef")
return /area/crew_quarters/kitchen
if("Station Engineer", "Chief Engineer", "Mechanic")
return /area/engine
if("Life Support Specialist")
return /area/atmos
if("Chief Medical Officer", "Medical Doctor", "Chemist", "Virologist", "Psychiatrist")
return /area/medical
if("Geneticist")
return /area/medical/genetics
if("Research Director", "Scientist")
return /area/toxins
if("Roboticist")
return /area/assembly/robotics
if("Head of Security", "Warden", "Security Officer", "Detective", "Security Pod Pilot", "Brig Physician", "Magistrate", "Internal Affairs Agent")
return /area/security
if("Botanist")
return /area/hydroponics
else
return pick(/area/hallway, /area/crew_quarters)
/mob/living/carbon/human/interactive/proc/target_filter(target)
var/list/filtered_targets = list(/area, /turf, /obj/machinery/door, /atom/movable/lighting_overlay, /obj/structure/cable, /obj/machinery/atmospherics, /obj/item/device/radio/intercom)
var/list/L = target
for(var/atom/A in target) // added a bunch of "junk" that clogs up the general find procs
if(is_type_in_list(A,filtered_targets))
L -= A
return L
/mob/living/carbon/human/interactive/proc/shouldModulePass() // returns 1 if the npc is in anything "primary"
if(doing & (SNPC_FIGHTING | SNPC_SPECIAL))
return 1
if(retal)
return 1
return 0
/mob/living/carbon/human/interactive/proc/getAllContents()
var/list/allContents = list()
for(var/atom/A in contents)
allContents += A
if(A.contents.len)
for(var/atom/B in A)
allContents += B
return allContents
/mob/living/carbon/human/interactive/proc/enforceHome()
var/list/validHome = get_area_turfs(job2area(myjob))
if(TARGET)
var/atom/tcheck = TARGET
if(tcheck)
if(!(get_turf(tcheck) in validHome))
TARGET = null
return 1
if(!(get_turf(src) in validHome))
tryWalk(pick(get_area_turfs(job2area(myjob))))
return 1
return 0
/mob/living/carbon/human/interactive/proc/npcDrop(obj/item/A, blacklist = 0)
if(blacklist)
blacklistItems += A
unEquip(A)
enforce_hands()
update_icons()
/mob/living/carbon/human/interactive/proc/compareFaction(list/targetFactions)
var/hasSame = 0
for(var/A in targetFactions)
if(A in faction)
hasSame = 1
return hasSame
/mob/living/carbon/human/interactive/proc/nearbyscan(obj)
nearby = list()
for(var/mob/living/M in view(4,src))
if(M != src)
nearby += M
/mob/living/carbon/human/interactive/rename_character(oldname, newname)
if(!..())
return 0
if(oldname)
if(MYID)
MYID.registered_name = newname
MYID.name = "[newname]'s ID Card ([MYID.assignment])"
if(RPID)
RPID.registered_name = MYID.registered_name
RPID.name = MYID.name
return 1