mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-07-19 03:55:11 +01:00
Merge branch 'master' of https://github.com/tgstation/-tg-station into reflectivejugs
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
// Camera mob, used by AI camera and blob.
|
||||
|
||||
/mob/camera
|
||||
name = "camera mob"
|
||||
density = 0
|
||||
status_flags = GODMODE // You can't damage it.
|
||||
mouse_opacity = 0
|
||||
see_in_dark = 7
|
||||
invisibility = 101 // No one can see us
|
||||
|
||||
move_on_shuttle = 0
|
||||
|
||||
/mob/camera/experience_pressure_difference()
|
||||
return
|
||||
@@ -71,6 +71,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set name = "Ghost"
|
||||
set desc = "Relinquish your life and enter the land of the dead."
|
||||
|
||||
if(stat != DEAD)
|
||||
succumb()
|
||||
if(stat == DEAD)
|
||||
ghostize(1)
|
||||
else
|
||||
|
||||
@@ -1,258 +0,0 @@
|
||||
/mob/living/blob
|
||||
name = "blob fragment"
|
||||
real_name = "blob fragment"
|
||||
icon = 'icons/mob/blob.dmi'
|
||||
icon_state = "blob_spore_temp"
|
||||
pass_flags = PASSBLOB
|
||||
see_in_dark = 8
|
||||
see_invisible = SEE_INVISIBLE_LEVEL_TWO
|
||||
var/ghost_name = "Unknown"
|
||||
var/creating_blob = 0
|
||||
faction = "blob"
|
||||
|
||||
|
||||
New()
|
||||
real_name += " [pick(rand(1, 99))]"
|
||||
name = real_name
|
||||
..()
|
||||
|
||||
|
||||
say(var/message)
|
||||
return//No talking for you
|
||||
|
||||
|
||||
emote(var/act,var/m_type=1,var/message = null)
|
||||
return
|
||||
|
||||
|
||||
Life()
|
||||
set invisibility = 0
|
||||
set background = 1
|
||||
|
||||
clamp_values()
|
||||
UpdateDamage()
|
||||
if(health < 0)
|
||||
src.dust()
|
||||
|
||||
|
||||
proc/clamp_values()
|
||||
AdjustStunned(0)
|
||||
AdjustParalysis(0)
|
||||
AdjustWeakened(0)
|
||||
sleeping = 0
|
||||
if(stat)
|
||||
stat = CONSCIOUS
|
||||
return
|
||||
|
||||
|
||||
proc/UpdateDamage()
|
||||
health = 60 - (getOxyLoss() + getToxLoss() + getFireLoss() + getBruteLoss() + getCloneLoss())
|
||||
return
|
||||
|
||||
|
||||
death(gibbed)
|
||||
if(key)
|
||||
var/mob/dead/observer/ghost = new(src)
|
||||
ghost.name = ghost_name
|
||||
ghost.real_name = ghost_name
|
||||
ghost.key = key
|
||||
if (ghost.client)
|
||||
ghost.client.eye = ghost
|
||||
return ..(gibbed)
|
||||
|
||||
|
||||
blob_act()
|
||||
src << "The blob attempts to reabsorb you."
|
||||
adjustToxLoss(20)
|
||||
return
|
||||
|
||||
|
||||
Process_Spacemove()
|
||||
if(locate(/obj/effect/blob) in oview(1,src))
|
||||
return 1
|
||||
return (..())
|
||||
|
||||
|
||||
/mob/living/blob/verb/create_node()
|
||||
set category = "Blob"
|
||||
set name = "Create Node"
|
||||
set desc = "Create a Node."
|
||||
if(creating_blob) return
|
||||
var/turf/T = get_turf(src)
|
||||
creating_blob = 1
|
||||
if(!T)
|
||||
creating_blob = 0
|
||||
return
|
||||
var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
|
||||
if(!B)//We are on a blob
|
||||
usr << "There is no blob here!"
|
||||
creating_blob = 0
|
||||
return
|
||||
if(istype(B,/obj/effect/blob/node)||istype(B,/obj/effect/blob/core)||istype(B,/obj/effect/blob/factory))
|
||||
usr << "Unable to use this blob, find a normal one."
|
||||
creating_blob = 0
|
||||
return
|
||||
for(var/obj/effect/blob/node/blob in orange(5))
|
||||
usr << "There is another node nearby, move more than 5 tiles away from it!"
|
||||
creating_blob = 0
|
||||
return
|
||||
for(var/obj/effect/blob/factory/blob in orange(2))
|
||||
usr << "There is a porus blob nearby, move more than 2 tiles away from it!"
|
||||
creating_blob = 0
|
||||
B.change_to("Node")
|
||||
src.dust()
|
||||
return
|
||||
|
||||
|
||||
/mob/living/blob/verb/create_factory()
|
||||
set category = "Blob"
|
||||
set name = "Create Defense"
|
||||
set desc = "Create a Spore producing blob."
|
||||
if(creating_blob) return
|
||||
var/turf/T = get_turf(src)
|
||||
creating_blob = 1
|
||||
if(!T)
|
||||
creating_blob = 0
|
||||
return
|
||||
var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
|
||||
if(!B)
|
||||
usr << "You must be on a blob!"
|
||||
creating_blob = 0
|
||||
return
|
||||
if(istype(B,/obj/effect/blob/node)||istype(B,/obj/effect/blob/core)||istype(B,/obj/effect/blob/factory))
|
||||
usr << "Unable to use this blob, find a normal one."
|
||||
creating_blob = 0
|
||||
return
|
||||
for(var/obj/effect/blob/blob in orange(2))//Not right next to nodes/cores
|
||||
if(istype(B,/obj/effect/blob/node))
|
||||
usr << "There is a node nearby, move away from it!"
|
||||
creating_blob = 0
|
||||
return
|
||||
if(istype(B,/obj/effect/blob/core))
|
||||
usr << "There is a core nearby, move away from it!"
|
||||
creating_blob = 0
|
||||
return
|
||||
if(istype(B,/obj/effect/blob/factory))
|
||||
usr << "There is another porous blob nearby, move away from it!"
|
||||
creating_blob = 0
|
||||
return
|
||||
B.change_to("Factory")
|
||||
src.dust()
|
||||
return
|
||||
|
||||
|
||||
/mob/living/blob/verb/revert()
|
||||
set category = "Blob"
|
||||
set name = "Purge Defense"
|
||||
set desc = "Removes a porous blob."
|
||||
if(creating_blob) return
|
||||
var/turf/T = get_turf(src)
|
||||
creating_blob = 1
|
||||
if(!T)
|
||||
creating_blob = 0
|
||||
return
|
||||
var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
|
||||
if(!B)
|
||||
usr << "You must be on a blob!"
|
||||
creating_blob = 0
|
||||
return
|
||||
if(!istype(B,/obj/effect/blob/factory))
|
||||
usr << "Unable to use this blob, find another one."
|
||||
creating_blob = 0
|
||||
return
|
||||
B.change_to("Normal")
|
||||
src.dust()
|
||||
return
|
||||
|
||||
|
||||
/mob/living/blob/verb/spawn_blob()
|
||||
set category = "Blob"
|
||||
set name = "Create new blob"
|
||||
set desc = "Attempts to create a new blob in this tile."
|
||||
if(creating_blob) return
|
||||
var/turf/T = get_turf(src)
|
||||
creating_blob = 1
|
||||
if(!T)
|
||||
creating_blob = 0
|
||||
return
|
||||
var/obj/effect/blob/B = (locate(/obj/effect/blob) in T)
|
||||
if(B)
|
||||
usr << "There is a blob here!"
|
||||
creating_blob = 0
|
||||
return
|
||||
new/obj/effect/blob(src.loc)
|
||||
src.dust()
|
||||
return
|
||||
|
||||
|
||||
/mob/proc/Blobize()
|
||||
/client/proc/Blobcount()
|
||||
set category = "Debug"
|
||||
set name = "blobreport"
|
||||
set desc = "blob report."
|
||||
set hidden = 1
|
||||
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
return
|
||||
if(ticker && ticker.mode)
|
||||
src << "blobs: [blobs.len]"
|
||||
src << "cores: [blob_cores.len]"
|
||||
src << "nodes: [blob_nodes.len]"
|
||||
return
|
||||
|
||||
|
||||
/client/proc/Blobize()//Mostly stolen from the respawn command
|
||||
set category = "Debug"
|
||||
set name = "Ghostblob"
|
||||
set desc = "Ghost into blobthing."
|
||||
set hidden = 1
|
||||
|
||||
if(!holder)
|
||||
src << "Only administrators may use this command."
|
||||
return
|
||||
var/input = input(src, "Please specify which key will be turned into a bloby.", "Key", "")
|
||||
|
||||
var/mob/dead/observer/G_found
|
||||
if(!input)
|
||||
var/list/ghosts = list()
|
||||
for(var/mob/dead/observer/G in player_list)
|
||||
ghosts += G
|
||||
if(ghosts.len)
|
||||
G_found = pick(ghosts)
|
||||
|
||||
else
|
||||
for(var/mob/dead/observer/G in player_list)
|
||||
if(G.client&&ckey(G.key)==ckey(input))
|
||||
G_found = G
|
||||
break
|
||||
|
||||
if(!G_found)//If a ghost was not found.
|
||||
alert("There is no active key like that in the game or the person is not currently a ghost. Aborting command.")
|
||||
return
|
||||
|
||||
if(G_found.client)
|
||||
G_found.client.screen.len = null
|
||||
var/mob/living/blob/B = new/mob/living/blob(locate(0,0,1))//temp area also just in case should do this better but tired
|
||||
if(blob_cores.len > 0)
|
||||
var/obj/effect/blob/core/core = pick(blob_cores)
|
||||
if(core)
|
||||
B.loc = core.loc
|
||||
B.ghost_name = G_found.real_name
|
||||
if (G_found.client)
|
||||
G_found.client.mob = B
|
||||
B.verbs += /mob/living/blob/verb/create_node
|
||||
B.verbs += /mob/living/blob/verb/create_factory
|
||||
B << "<B>You are now a blob fragment.</B>"
|
||||
B << "You are a weak bit that has temporarily broken off of the blob."
|
||||
B << "If you stay on the blob for too long you will likely be reabsorbed."
|
||||
B << "If you stray from the blob you will likely be killed by other organisms."
|
||||
B << "You have the power to create a new blob node that will help expand the blob."
|
||||
B << "To create this node you will have to be on a normal blob tile and far enough away from any other node."
|
||||
B << "Check your Blob verbs and hit Create Node to build a node."
|
||||
spawn(10)
|
||||
del(G_found)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -395,10 +395,10 @@ In all, this is a lot like the monkey code. /N
|
||||
|
||||
dat += {"
|
||||
<BR>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
user << browse(dat, "window=mob[name];size=325x500")
|
||||
onclose(user, "mob[name]")
|
||||
user << browse(dat, "window=mob\ref[src];size=325x500")
|
||||
onclose(user, "mob\ref[src]")
|
||||
|
||||
|
||||
/mob/living/carbon/alien/humanoid/Topic(href, href_list)
|
||||
|
||||
@@ -45,9 +45,9 @@
|
||||
usr << "This one seems particularly lifeless. Perhaps it will regain some of it's luster later.."
|
||||
|
||||
|
||||
/obj/item/organ/brain/attack(mob/living/carbon/M, mob/living/carbon/user)
|
||||
if(!istype(M, /mob))
|
||||
return
|
||||
/obj/item/organ/brain/attack(mob/living/carbon/M, mob/user)
|
||||
if(!istype(M))
|
||||
return ..()
|
||||
|
||||
add_fingerprint(user)
|
||||
|
||||
|
||||
@@ -495,10 +495,10 @@
|
||||
|
||||
dat += {"
|
||||
<BR>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
user << browse(dat, "window=mob[name];size=325x500")
|
||||
onclose(user, "mob[name]")
|
||||
user << browse(dat, "window=mob\ref[src];size=325x500")
|
||||
onclose(user, "mob\ref[src]")
|
||||
|
||||
/mob/living/carbon/Topic(href, href_list)
|
||||
..()
|
||||
|
||||
@@ -275,6 +275,13 @@
|
||||
mymob.pullin.screen_loc = ui_pull_resist
|
||||
hotkeybuttons += mymob.pullin
|
||||
|
||||
lingchemdisplay = new /obj/screen()
|
||||
lingchemdisplay.name = "chemical storage"
|
||||
lingchemdisplay.icon_state = "power_display"
|
||||
lingchemdisplay.screen_loc = ui_lingchemdisplay
|
||||
lingchemdisplay.layer = 20
|
||||
lingchemdisplay.invisibility = 101
|
||||
|
||||
mymob.blind = new /obj/screen()
|
||||
mymob.blind.icon = 'icons/mob/screen_full.dmi'
|
||||
mymob.blind.icon_state = "blackimageoverlay"
|
||||
@@ -303,7 +310,7 @@
|
||||
|
||||
mymob.client.screen = null
|
||||
|
||||
mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.pressure, mymob.toxin, mymob.bodytemp, mymob.internals, mymob.fire, mymob.healths, mymob.nutrition_icon, mymob.pullin, mymob.blind, mymob.flash, mymob.damageoverlay) //, mymob.hands, mymob.rest, mymob.sleep) //, mymob.mach )
|
||||
mymob.client.screen += list( mymob.throw_icon, mymob.zone_sel, mymob.oxygen, mymob.pressure, mymob.toxin, mymob.bodytemp, mymob.internals, mymob.fire, mymob.healths, mymob.nutrition_icon, mymob.pullin, mymob.blind, mymob.flash, mymob.damageoverlay, lingchemdisplay) //, mymob.hands, mymob.rest, mymob.sleep) //, mymob.mach )
|
||||
mymob.client.screen += adding + hotkeybuttons
|
||||
inventory_shown = 0;
|
||||
|
||||
@@ -330,23 +337,29 @@
|
||||
return
|
||||
|
||||
client.screen -= hud_used.item_action_list
|
||||
hud_used.item_action_list = list()
|
||||
|
||||
for(var/obj/item/I in src)
|
||||
if(I.action_button_name)
|
||||
var/obj/screen/item_action/A = new(hud_used)
|
||||
if(hud_used.item_action_list.len < num)
|
||||
var/obj/screen/item_action/N = new(hud_used)
|
||||
hud_used.item_action_list += N
|
||||
|
||||
var/obj/screen/item_action/A = hud_used.item_action_list[num]
|
||||
|
||||
A.icon = ui_style2icon(client.prefs.UI_style)
|
||||
A.icon_state = "template"
|
||||
var/image/img = image(I.icon, I.icon_state)
|
||||
|
||||
A.overlays = list()
|
||||
var/image/img = image(I.icon, A, I.icon_state)
|
||||
img.pixel_x = 0
|
||||
img.pixel_y = 0
|
||||
A.overlays += img
|
||||
if(I.action_button_name)
|
||||
A.name = I.action_button_name
|
||||
else
|
||||
A.name = "Use [I.name]"
|
||||
|
||||
A.name = I.action_button_name
|
||||
A.owner = I
|
||||
hud_used.item_action_list += A
|
||||
|
||||
client.screen += hud_used.item_action_list[num]
|
||||
|
||||
switch(num)
|
||||
if(1)
|
||||
A.screen_loc = ui_action_slot1
|
||||
@@ -359,6 +372,4 @@
|
||||
if(5)
|
||||
A.screen_loc = ui_action_slot5
|
||||
break //5 slots available, so no more can be added.
|
||||
num++
|
||||
|
||||
client.screen += hud_used.item_action_list
|
||||
num++
|
||||
|
||||
@@ -120,8 +120,8 @@
|
||||
stat("Distribution Pressure", internal.distribute_pressure)
|
||||
if(mind)
|
||||
if(mind.changeling)
|
||||
stat("Chemical Storage", mind.changeling.chem_charges)
|
||||
stat("Genetic Damage Time", mind.changeling.geneticdamage)
|
||||
stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]")
|
||||
stat("Absorbed DNA", mind.changeling.absorbedcount)
|
||||
if (istype(wear_suit, /obj/item/clothing/suit/space/space_ninja)&&wear_suit:s_initialized)
|
||||
stat("Energy Charge", round(wear_suit:cell:charge/100))
|
||||
|
||||
@@ -374,15 +374,16 @@
|
||||
if(legcuffed)
|
||||
dat += "<BR><A href='?src=\ref[src];item=[slot_legcuffed]'>Legcuffed</A>"
|
||||
if(w_uniform)
|
||||
dat += "<BR><A href='?src=\ref[src];pockets=1'>Empty Pockets</A>"
|
||||
dat += "<BR><BR><A href='?src=\ref[src];pockets=left'>Left Pocket ([l_store ? "Full" : "Empty"])</A>"
|
||||
dat += " - <A href='?src=\ref[src];pockets=right'>Right Pocket ([r_store ? "Full" : "Empty"])</A>"
|
||||
|
||||
dat += {"
|
||||
<BR>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
|
||||
user << browse(dat, "window=mob[name];size=340x480")
|
||||
onclose(user, "mob[name]")
|
||||
user << browse(dat, "window=mob\ref[src];size=340x480")
|
||||
onclose(user, "mob\ref[src]")
|
||||
|
||||
|
||||
// called when something steps onto a human
|
||||
@@ -478,15 +479,38 @@
|
||||
//strip panel
|
||||
if(!usr.stat && usr.canmove && !usr.restrained() && in_range(src, usr))
|
||||
if(href_list["pockets"])
|
||||
|
||||
var/pocket_side = href_list["pockets"]
|
||||
var/pocket_id = (pocket_side == "right" ? slot_r_store : slot_l_store)
|
||||
var/obj/item/pocket_item = (pocket_id == slot_r_store ? src.r_store : src.l_store)
|
||||
var/obj/item/place_item = usr.get_active_hand() // Item to place in the pocket, if it's empty
|
||||
|
||||
//visible_message("<span class='danger'>[usr] tries to empty [src]'s pockets.</span>", \
|
||||
"<span class='userdanger'>[usr] tries to empty [src]'s pockets.</span>") // Pickpocketing!
|
||||
usr << "<span class='notice'>You try to empty [src]'s pockets.</span>"
|
||||
if(do_mob(usr, src, STRIP_DELAY * 0.5))
|
||||
u_equip(r_store)
|
||||
u_equip(l_store)
|
||||
if(pocket_item)
|
||||
usr << "<span class='notice'>You try to empty [src]'s [pocket_side] pocket.</span>"
|
||||
else if(place_item && place_item.mob_can_equip(src, pocket_id, 1))
|
||||
usr << "<span class='notice'>You try to place [place_item] into [src]'s [pocket_side] pocket.</span>"
|
||||
else
|
||||
return
|
||||
|
||||
if(do_mob(usr, src, STRIP_DELAY))
|
||||
if(pocket_item)
|
||||
u_equip(pocket_item)
|
||||
else
|
||||
if(place_item)
|
||||
usr.u_equip(place_item)
|
||||
equip_to_slot_if_possible(place_item, pocket_id, 0, 1)
|
||||
|
||||
// Update strip window
|
||||
if(usr.machine == src && in_range(src, usr))
|
||||
show_inv(usr)
|
||||
|
||||
|
||||
|
||||
else
|
||||
// Display a warning if the user mocks up
|
||||
src << "<span class='warning'>You feel your pockets being fumbled with!</span>"
|
||||
src << "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>"
|
||||
|
||||
if(href_list["criminal"])
|
||||
if(istype(usr, /mob/living/carbon/human))
|
||||
|
||||
@@ -1022,6 +1022,12 @@
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
seer = 0
|
||||
|
||||
if(mind && mind.changeling)
|
||||
hud_used.lingchemdisplay.invisibility = 0
|
||||
hud_used.lingchemdisplay.maptext = "<div align='center' valign='middle' style='position:relative; top:0px; left:6px'> <font color='#dd66dd'>[src.mind.changeling.chem_charges]</font></div>"
|
||||
else
|
||||
hud_used.lingchemdisplay.invisibility = 101
|
||||
|
||||
if(istype(wear_mask, /obj/item/clothing/mask/gas/voice/space_ninja))
|
||||
var/obj/item/clothing/mask/gas/voice/space_ninja/O = wear_mask
|
||||
switch(O.mode)
|
||||
|
||||
@@ -142,6 +142,13 @@
|
||||
mymob.pullin.name = "pull"
|
||||
mymob.pullin.screen_loc = ui_pull_resist
|
||||
|
||||
lingchemdisplay = new /obj/screen()
|
||||
lingchemdisplay.name = "chemical storage"
|
||||
lingchemdisplay.icon_state = "power_display"
|
||||
lingchemdisplay.screen_loc = ui_lingchemdisplay
|
||||
lingchemdisplay.layer = 20
|
||||
lingchemdisplay.invisibility = 101
|
||||
|
||||
mymob.blind = new /obj/screen()
|
||||
mymob.blind.icon = 'icons/mob/screen_full.dmi'
|
||||
mymob.blind.icon_state = "blackimageoverlay"
|
||||
|
||||
@@ -345,8 +345,8 @@
|
||||
if(client && mind)
|
||||
if (client.statpanel == "Status")
|
||||
if(mind.changeling)
|
||||
stat("Chemical Storage", mind.changeling.chem_charges)
|
||||
stat("Genetic Damage Time", mind.changeling.geneticdamage)
|
||||
stat("Chemical Storage", "[mind.changeling.chem_charges]/[mind.changeling.chem_storage]")
|
||||
stat("Absorbed DNA", mind.changeling.absorbedcount)
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
src.adjustOxyLoss(src.health + 200)
|
||||
src.health = 100 - src.getOxyLoss() - src.getToxLoss() - src.getFireLoss() - src.getBruteLoss()
|
||||
src << "\blue You have given up life and succumbed to death."
|
||||
|
||||
death()
|
||||
|
||||
|
||||
/mob/living/proc/updatehealth()
|
||||
|
||||
@@ -31,7 +31,7 @@ var/list/ai_list = list()
|
||||
var/obj/item/device/multitool/aiMulti = null
|
||||
|
||||
//MALFUNCTION
|
||||
var/datum/AI_Module/module_picker/malf_picker
|
||||
var/datum/module_picker/malf_picker
|
||||
var/processing_time = 100
|
||||
var/list/datum/AI_Module/current_modules = list()
|
||||
var/fire_res_on_core = 0
|
||||
@@ -48,6 +48,7 @@ var/list/ai_list = list()
|
||||
var/datum/trackable/track = null
|
||||
|
||||
var/last_paper_seen = null
|
||||
var/can_shunt = 1
|
||||
|
||||
/mob/living/silicon/ai/New(loc, var/datum/ai_laws/L, var/obj/item/device/mmi/B, var/safety = 0)
|
||||
var/list/possibleNames = ai_names
|
||||
|
||||
@@ -33,7 +33,7 @@ var/datum/cameranet/cameranet = new()
|
||||
|
||||
// Updates what the aiEye can see. It is recommended you use this when the aiEye moves or it's location is set.
|
||||
|
||||
/datum/cameranet/proc/visibility(mob/aiEye/ai)
|
||||
/datum/cameranet/proc/visibility(mob/camera/aiEye/ai)
|
||||
// 0xf = 15
|
||||
var/x1 = max(0, ai.x - 16) & ~(CHUNK_SIZE - 1)
|
||||
var/y1 = max(0, ai.y - 16) & ~(CHUNK_SIZE - 1)
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
// Add an AI eye to the chunk, then update if changed.
|
||||
|
||||
/datum/camerachunk/proc/add(mob/aiEye/ai)
|
||||
/datum/camerachunk/proc/add(mob/camera/aiEye/ai)
|
||||
if(!ai.ai)
|
||||
return
|
||||
ai.visibleCameraChunks += src
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
// Remove an AI eye from the chunk, then update if changed.
|
||||
|
||||
/datum/camerachunk/proc/remove(mob/aiEye/ai)
|
||||
/datum/camerachunk/proc/remove(mob/camera/aiEye/ai)
|
||||
if(!ai.ai)
|
||||
return
|
||||
ai.visibleCameraChunks -= src
|
||||
@@ -105,7 +105,7 @@
|
||||
if(t.obscured)
|
||||
obscured -= t.obscured
|
||||
for(var/eye in seenby)
|
||||
var/mob/aiEye/m = eye
|
||||
var/mob/camera/aiEye/m = eye
|
||||
if(!m || !m.ai)
|
||||
continue
|
||||
if(m.ai.client)
|
||||
@@ -119,7 +119,7 @@
|
||||
|
||||
obscured += t.obscured
|
||||
for(var/eye in seenby)
|
||||
var/mob/aiEye/m = eye
|
||||
var/mob/camera/aiEye/m = eye
|
||||
if(!m || !m.ai)
|
||||
seenby -= m
|
||||
continue
|
||||
|
||||
@@ -3,40 +3,17 @@
|
||||
// An invisible (no icon) mob that the AI controls to look around the station with.
|
||||
// It streams chunks as it moves around, which will show it what the AI can and cannot see.
|
||||
|
||||
/mob/aiEye
|
||||
/mob/camera/aiEye
|
||||
name = "Inactive AI Eye"
|
||||
icon = 'icons/obj/status_display.dmi' // For AI friend secret shh :o
|
||||
|
||||
var/list/visibleCameraChunks = list()
|
||||
var/mob/living/silicon/ai/ai = null
|
||||
density = 0
|
||||
status_flags = GODMODE // You can't damage it.
|
||||
mouse_opacity = 0
|
||||
see_in_dark = 7
|
||||
|
||||
// Movement code. Returns 0 to stop air movement from moving it.
|
||||
/mob/aiEye/Move()
|
||||
return 0
|
||||
|
||||
// Hide popout menu verbs
|
||||
/mob/aiEye/examine()
|
||||
set popup_menu = 0
|
||||
set src = usr.contents
|
||||
return 0
|
||||
|
||||
/mob/aiEye/pull()
|
||||
set popup_menu = 0
|
||||
set src = usr.contents
|
||||
return 0
|
||||
|
||||
/mob/aiEye/point()
|
||||
set popup_menu = 0
|
||||
set src = usr.contents
|
||||
return 0
|
||||
|
||||
// Use this when setting the aiEye's location.
|
||||
// It will also stream the chunk that the new loc is in.
|
||||
|
||||
/mob/aiEye/proc/setLoc(var/T)
|
||||
/mob/camera/aiEye/proc/setLoc(var/T)
|
||||
|
||||
if(ai)
|
||||
if(!isturf(ai.loc))
|
||||
@@ -51,13 +28,16 @@
|
||||
var/obj/machinery/hologram/holopad/H = ai.current
|
||||
H.move_hologram()
|
||||
|
||||
/mob/camera/aiEye/Move()
|
||||
return 0
|
||||
|
||||
|
||||
// AI MOVEMENT
|
||||
|
||||
// The AI's "eye". Described on the top of the page.
|
||||
|
||||
/mob/living/silicon/ai
|
||||
var/mob/aiEye/eyeobj = new()
|
||||
var/mob/camera/aiEye/eyeobj = new()
|
||||
var/sprint = 10
|
||||
var/cooldown = 0
|
||||
var/acceleration = 1
|
||||
|
||||
@@ -238,6 +238,9 @@
|
||||
adjustBruteLoss(60)
|
||||
updatehealth()
|
||||
return 1
|
||||
else
|
||||
gib()
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/robot/Stat()
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
stop_automated_movement = 1
|
||||
stance_step++
|
||||
if(stance_step >= 10) //rests for 10 ticks
|
||||
if(target_mob && target_mob in ListTargets())
|
||||
if(target && target in ListTargets())
|
||||
stance = HOSTILE_STANCE_ATTACK //If the mob he was chasing is still nearby, resume the attack, otherwise go idle.
|
||||
else
|
||||
stance = HOSTILE_STANCE_IDLE
|
||||
@@ -72,15 +72,15 @@
|
||||
if(HOSTILE_STANCE_ALERT)
|
||||
stop_automated_movement = 1
|
||||
var/found_mob = 0
|
||||
if(target_mob && target_mob in ListTargets())
|
||||
if(!(SA_attackable(target_mob)))
|
||||
if(target && target in ListTargets())
|
||||
if(!(SA_attackable(target)))
|
||||
stance_step = max(0, stance_step) //If we have not seen a mob in a while, the stance_step will be negative, we need to reset it to 0 as soon as we see a mob again.
|
||||
stance_step++
|
||||
found_mob = 1
|
||||
src.dir = get_dir(src,target_mob) //Keep staring at the mob
|
||||
src.dir = get_dir(src,target) //Keep staring at the mob
|
||||
|
||||
if(stance_step in list(1,4,7)) //every 3 ticks
|
||||
var/action = pick( list( "growls at [target_mob]", "stares angrily at [target_mob]", "prepares to attack [target_mob]", "closely watches [target_mob]" ) )
|
||||
var/action = pick( list( "growls at [target]", "stares angrily at [target]", "prepares to attack [target]", "closely watches [target]" ) )
|
||||
if(action)
|
||||
emote(action)
|
||||
if(!found_mob)
|
||||
@@ -105,14 +105,14 @@
|
||||
if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING)
|
||||
stance = HOSTILE_STANCE_ALERT
|
||||
stance_step = 6
|
||||
target_mob = user
|
||||
target = user
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/attack_hand(mob/living/carbon/human/M as mob)
|
||||
if(stance != HOSTILE_STANCE_ATTACK && stance != HOSTILE_STANCE_ATTACKING)
|
||||
stance = HOSTILE_STANCE_ALERT
|
||||
stance_step = 6
|
||||
target_mob = M
|
||||
target = M
|
||||
..()
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/Process_Spacemove(var/check_drift = 0)
|
||||
@@ -128,22 +128,22 @@
|
||||
..(5)
|
||||
|
||||
/mob/living/simple_animal/hostile/bear/AttackingTarget()
|
||||
emote( pick( list("slashes at [target_mob]", "bites [target_mob]") ) )
|
||||
emote( pick( list("slashes at [target]", "bites [target]") ) )
|
||||
|
||||
var/damage = rand(20,30)
|
||||
|
||||
if(ishuman(target_mob))
|
||||
var/mob/living/carbon/human/H = target_mob
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
var/dam_zone = pick("chest", "l_hand", "r_hand", "l_leg", "r_leg")
|
||||
var/datum/limb/affecting = H.get_organ(ran_zone(dam_zone))
|
||||
H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"))
|
||||
return H
|
||||
else if(isliving(target_mob))
|
||||
var/mob/living/L = target_mob
|
||||
else if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
L.adjustBruteLoss(damage)
|
||||
return L
|
||||
else if(istype(target_mob,/obj/mecha))
|
||||
var/obj/mecha/M = target_mob
|
||||
else if(istype(target,/obj/mecha))
|
||||
var/obj/mecha/M = target
|
||||
M.attack_animal(src)
|
||||
return M
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/giant_spider/AttackingTarget()
|
||||
..()
|
||||
if(isliving(target_mob))
|
||||
var/mob/living/L = target_mob
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.reagents)
|
||||
L.reagents.add_reagent("toxin", poison_per_bite)
|
||||
if(prob(poison_per_bite))
|
||||
@@ -82,7 +82,7 @@
|
||||
for(var/turf/T in orange(20, src))
|
||||
move_targets.Add(T)*/
|
||||
stop_automated_movement = 1
|
||||
walk_to(src, pick(orange(20, src)), 1, move_to_delay)
|
||||
Goto(pick(orange(20, src)), move_to_delay)
|
||||
spawn(50)
|
||||
stop_automated_movement = 0
|
||||
walk(src,0)
|
||||
@@ -107,7 +107,7 @@
|
||||
if(C.stat && !istype(C,/mob/living/simple_animal/hostile/giant_spider))
|
||||
cocoon_target = C
|
||||
busy = MOVING_TO_TARGET
|
||||
walk_to(src, C, 1, move_to_delay)
|
||||
Goto(C, move_to_delay)
|
||||
//give up if we can't reach them after 10 seconds
|
||||
GiveUp(C)
|
||||
return
|
||||
@@ -149,7 +149,7 @@
|
||||
cocoon_target = O
|
||||
busy = MOVING_TO_TARGET
|
||||
stop_automated_movement = 1
|
||||
walk_to(src, O, 1, move_to_delay)
|
||||
Goto(O, move_to_delay)
|
||||
//give up if we can't reach them after 10 seconds
|
||||
GiveUp(O)
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
damage_type = BRUTE
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot
|
||||
name = "Hivebot"
|
||||
desc = "A small robot"
|
||||
name = "hivebot"
|
||||
desc = "A small robot."
|
||||
icon = 'icons/mob/hivebot.dmi'
|
||||
icon_state = "basic"
|
||||
icon_living = "basic"
|
||||
@@ -28,7 +28,7 @@
|
||||
minbodytemp = 0
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot/range
|
||||
name = "Hivebot"
|
||||
name = "hivebot"
|
||||
desc = "A smallish robot, this one is armed!"
|
||||
ranged = 1
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
rapid = 1
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot/strong
|
||||
name = "Strong Hivebot"
|
||||
name = "strong hivebot"
|
||||
desc = "A robot, this one is armed and looks tough!"
|
||||
health = 80
|
||||
ranged = 1
|
||||
@@ -54,8 +54,8 @@
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/hivebot/tele//this still needs work
|
||||
name = "Beacon"
|
||||
desc = "Some odd beacon thing"
|
||||
name = "beacon"
|
||||
desc = "Some odd beacon thing."
|
||||
icon = 'icons/mob/hivebot.dmi'
|
||||
icon_state = "def_radar-off"
|
||||
icon_living = "def_radar-off"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/mob/living/simple_animal/hostile
|
||||
faction = "hostile"
|
||||
var/stance = HOSTILE_STANCE_IDLE //Used to determine behavior
|
||||
var/mob/living/target_mob
|
||||
var/target
|
||||
var/attack_same = 0
|
||||
var/ranged = 0
|
||||
var/rapid = 0
|
||||
@@ -32,63 +32,68 @@
|
||||
continue
|
||||
else
|
||||
if(!L.stat)
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
T = L
|
||||
break
|
||||
|
||||
else if(istype(A, /obj/mecha)) // Our line of sight stuff was already done in ListTargets().
|
||||
var/obj/mecha/M = A
|
||||
if (M.occupant)
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
T = M
|
||||
break
|
||||
|
||||
return T
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/GiveTarget(var/new_target)
|
||||
target = new_target
|
||||
stance = HOSTILE_STANCE_ATTACK
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/Goto(var/target, var/delay)
|
||||
walk_to(src, target, 1, delay)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/Found(var/atom/A)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/MoveToTarget()
|
||||
stop_automated_movement = 1
|
||||
if(!target_mob || SA_attackable(target_mob))
|
||||
stance = HOSTILE_STANCE_IDLE
|
||||
if(target_mob in ListTargets())
|
||||
if(!target || SA_attackable(target))
|
||||
LoseTarget()
|
||||
if(target in ListTargets())
|
||||
if(ranged)
|
||||
if(get_dist(src, target_mob) <= 6)
|
||||
OpenFire(target_mob)
|
||||
if(get_dist(src, target) <= 6)
|
||||
OpenFire(target)
|
||||
else
|
||||
walk_to(src, target_mob, 1, move_to_delay)
|
||||
Goto(target, move_to_delay)
|
||||
else
|
||||
stance = HOSTILE_STANCE_ATTACKING
|
||||
walk_to(src, target_mob, 1, move_to_delay)
|
||||
Goto(target, move_to_delay)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/AttackTarget()
|
||||
|
||||
stop_automated_movement = 1
|
||||
if(!target_mob || SA_attackable(target_mob))
|
||||
if(!target || SA_attackable(target))
|
||||
LoseTarget()
|
||||
return 0
|
||||
if(!(target_mob in ListTargets()))
|
||||
if(!(target in ListTargets()))
|
||||
LostTarget()
|
||||
return 0
|
||||
if(get_dist(src, target_mob) <= 1) //Attacking
|
||||
if(get_dist(src, target) <= 1) //Attacking
|
||||
AttackingTarget()
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/AttackingTarget()
|
||||
if(isliving(target_mob))
|
||||
var/mob/living/L = target_mob
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
L.attack_animal(src)
|
||||
return L
|
||||
if(istype(target_mob,/obj/mecha))
|
||||
var/obj/mecha/M = target_mob
|
||||
if(istype(target,/obj/mecha))
|
||||
var/obj/mecha/M = target
|
||||
M.attack_animal(src)
|
||||
return M
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/LoseTarget()
|
||||
stance = HOSTILE_STANCE_IDLE
|
||||
target_mob = null
|
||||
target = null
|
||||
walk(src, 0)
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/LostTarget()
|
||||
@@ -125,7 +130,8 @@
|
||||
if(!stat)
|
||||
switch(stance)
|
||||
if(HOSTILE_STANCE_IDLE)
|
||||
target_mob = FindTarget()
|
||||
var/new_target = FindTarget()
|
||||
GiveTarget(new_target)
|
||||
|
||||
if(HOSTILE_STANCE_ATTACK)
|
||||
DestroySurroundings()
|
||||
@@ -135,8 +141,8 @@
|
||||
DestroySurroundings()
|
||||
AttackTarget()
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/OpenFire(target_mob)
|
||||
var/target = target_mob
|
||||
/mob/living/simple_animal/hostile/proc/OpenFire(var/the_target)
|
||||
var/target = the_target
|
||||
visible_message("\red <b>[src]</b> fires at [target]!", 1)
|
||||
|
||||
var/tturf = get_turf(target)
|
||||
@@ -159,7 +165,7 @@
|
||||
new casingtype
|
||||
|
||||
stance = HOSTILE_STANCE_IDLE
|
||||
target_mob = null
|
||||
target = null
|
||||
return
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,12 @@
|
||||
* Sub-types
|
||||
*/
|
||||
|
||||
/*So you want to delete parrots eh?
|
||||
heres the locations of their snowflake code:
|
||||
lines 294-301 in living/say.dm (speech buffer)
|
||||
135 in living/say.dm (parrots talking into headsets)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Defines
|
||||
*/
|
||||
@@ -42,19 +48,25 @@
|
||||
speak_chance = 1 //1% (1 in 100) chance every tick; So about once per 150 seconds, assuming an average tick is 1.5s
|
||||
turns_per_move = 5
|
||||
meat_type = /obj/item/weapon/reagent_containers/food/snacks/cracker/
|
||||
melee_damage_upper = 10
|
||||
melee_damage_lower = 5
|
||||
|
||||
response_help = "pets"
|
||||
response_disarm = "gently moves aside"
|
||||
response_harm = "swats"
|
||||
stop_automated_movement = 1
|
||||
a_intent = "harm" //parrots now start "aggressive" since only player parrots will nuzzle.
|
||||
attacktext = "chomps"
|
||||
friendly = "grooms"
|
||||
|
||||
var/parrot_damage_upper = 10
|
||||
var/parrot_state = PARROT_WANDER //Hunt for a perch when created
|
||||
var/parrot_sleep_max = 25 //The time the parrot sits while perched before looking around. Mosly a way to avoid the parrot's AI in life() being run every single tick.
|
||||
var/parrot_sleep_dur = 25 //Same as above, this is the var that physically counts down
|
||||
var/parrot_dam_zone = list("chest", "head", "l_arm", "l_leg", "r_arm", "r_leg") //For humans, select a bodypart to attack
|
||||
|
||||
var/parrot_speed = 5 //"Delay in world ticks between movement." according to byond. Yeah, that's BS but it does directly affect movement. Higher number = slower.
|
||||
var/parrot_been_shot = 0 //Parrots get a speed bonus after being shot. This will deincrement every Life() and at 0 the parrot will return to regular speed.
|
||||
//var/parrot_been_shot = 0 this wasn't working right, and parrots don't survive bullets.((Parrots get a speed bonus after being shot. This will deincrement every Life() and at 0 the parrot will return to regular speed.))
|
||||
|
||||
var/parrot_lastmove = null //Updates/Stores position of the parrot while it's moving
|
||||
var/parrot_stuck = 0 //If parrot_lastmove hasnt changed, this will increment until it reaches parrot_stuck_threshold
|
||||
@@ -100,7 +112,8 @@
|
||||
verbs.Add(/mob/living/simple_animal/parrot/proc/steal_from_ground, \
|
||||
/mob/living/simple_animal/parrot/proc/steal_from_mob, \
|
||||
/mob/living/simple_animal/parrot/verb/drop_held_item_player, \
|
||||
/mob/living/simple_animal/parrot/proc/perch_player)
|
||||
/mob/living/simple_animal/parrot/proc/perch_player, \
|
||||
/mob/living/simple_animal/parrot/proc/toggle_mode)
|
||||
|
||||
|
||||
/mob/living/simple_animal/parrot/Die()
|
||||
@@ -113,6 +126,7 @@
|
||||
/mob/living/simple_animal/parrot/Stat()
|
||||
..()
|
||||
stat("Held Item", held_item)
|
||||
stat("Mode",a_intent)
|
||||
|
||||
/*
|
||||
* Inventory
|
||||
@@ -144,10 +158,11 @@
|
||||
switch(remove_from)
|
||||
if("ears")
|
||||
if(ears)
|
||||
if(available_channels.len)
|
||||
src.say("[pick(available_channels)] BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
|
||||
else
|
||||
src.say("BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
|
||||
if(!stat)
|
||||
if(available_channels.len)
|
||||
src.say("[pick(available_channels)] BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
|
||||
else
|
||||
src.say("BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
|
||||
ears.loc = src.loc
|
||||
ears = null
|
||||
for(var/possible_phrase in speak)
|
||||
@@ -197,10 +212,10 @@
|
||||
available_channels.Add(":n")
|
||||
if("Medical")
|
||||
available_channels.Add(":m")
|
||||
if("Mining")
|
||||
available_channels.Add(":d")
|
||||
if("Cargo")
|
||||
available_channels.Add(":q")
|
||||
if("Supply")
|
||||
available_channels.Add(":u")
|
||||
if("Service")
|
||||
available_channels.Add(":v")
|
||||
|
||||
if(headset_to_add.translate_binary)
|
||||
available_channels.Add(":b")
|
||||
@@ -240,29 +255,41 @@
|
||||
|
||||
//Simple animals
|
||||
/mob/living/simple_animal/parrot/attack_animal(mob/living/simple_animal/M as mob)
|
||||
..() //goodbye immortal parrots
|
||||
|
||||
if(client) return
|
||||
|
||||
|
||||
if(parrot_state == PARROT_PERCH)
|
||||
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
|
||||
|
||||
if(M.melee_damage_upper > 0)
|
||||
if(M.melee_damage_upper > 0 && !stat)
|
||||
parrot_interest = M
|
||||
parrot_state = PARROT_SWOOP | PARROT_ATTACK //Attack other animals regardless
|
||||
icon_state = "parrot_fly"
|
||||
|
||||
//Mobs with objects
|
||||
/mob/living/simple_animal/parrot/attackby(var/obj/item/O as obj, var/mob/user as mob)
|
||||
..()
|
||||
if(!stat && !client && !istype(O, /obj/item/stack/medical))
|
||||
/mob/living/simple_animal/parrot/attackby(var/obj/item/O as obj, var/mob/living/user as mob)
|
||||
if(!stat && !client && !istype(O, /obj/item/stack/medical) && !istype(O,/obj/item/weapon/reagent_containers/food/snacks/cracker))
|
||||
if(O.force)
|
||||
if(parrot_state == PARROT_PERCH)
|
||||
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
|
||||
|
||||
parrot_interest = user
|
||||
parrot_state = PARROT_SWOOP | PARROT_FLEE
|
||||
parrot_state = PARROT_SWOOP
|
||||
if (user.health < 50)
|
||||
parrot_state |= PARROT_ATTACK //weakened mob? fight back!
|
||||
else
|
||||
parrot_state |= PARROT_FLEE
|
||||
icon_state = "parrot_fly"
|
||||
drop_held_item(0)
|
||||
else if(istype(O,/obj/item/weapon/reagent_containers/food/snacks/cracker)) //Poly wants a cracker.
|
||||
del(O)
|
||||
user.drop_item()
|
||||
if(health < maxHealth)
|
||||
adjustBruteLoss(-10)
|
||||
user << "\blue [src] eagerly devours the cracker."
|
||||
..()
|
||||
return
|
||||
|
||||
//Bullets
|
||||
@@ -273,8 +300,8 @@
|
||||
parrot_sleep_dur = parrot_sleep_max //Reset it's sleep timer if it was perched
|
||||
|
||||
parrot_interest = null
|
||||
parrot_state = PARROT_WANDER //OWFUCK, Been shot! RUN LIKE HELL!
|
||||
parrot_been_shot += 5
|
||||
parrot_state = PARROT_WANDER | PARROT_FLEE //Been shot and survived! RUN LIKE HELL!
|
||||
//parrot_been_shot += 5
|
||||
icon_state = "parrot_fly"
|
||||
drop_held_item(0)
|
||||
return
|
||||
@@ -462,8 +489,9 @@
|
||||
if(!parrot_interest || !isliving(parrot_interest)) //Sanity
|
||||
parrot_state = PARROT_WANDER
|
||||
|
||||
walk_away(src, parrot_interest, 1, parrot_speed-parrot_been_shot)
|
||||
parrot_been_shot--
|
||||
walk_away(src, parrot_interest, 1, parrot_speed)
|
||||
/*if(parrot_been_shot > 0)
|
||||
parrot_been_shot-- didn't work anyways, and besides, any bullet poly survives isn't worth the speed boost.*/
|
||||
if(isStuck()) return
|
||||
|
||||
return
|
||||
@@ -478,6 +506,9 @@
|
||||
return
|
||||
|
||||
var/mob/living/L = parrot_interest
|
||||
if(melee_damage_upper == 0)
|
||||
melee_damage_upper = parrot_damage_upper
|
||||
a_intent = "harm"
|
||||
|
||||
//If the mob is close enough to interact with
|
||||
if(in_range(src, parrot_interest))
|
||||
@@ -495,21 +526,8 @@
|
||||
parrot_state = PARROT_WANDER
|
||||
return
|
||||
|
||||
//Time for the hurt to begin!
|
||||
var/damage = rand(5,10)
|
||||
|
||||
if(ishuman(parrot_interest))
|
||||
var/mob/living/carbon/human/H = parrot_interest
|
||||
var/datum/limb/affecting = H.get_organ(ran_zone(pick(parrot_dam_zone)))
|
||||
|
||||
H.apply_damage(damage, BRUTE, affecting, H.run_armor_check(affecting, "melee"))
|
||||
emote(pick("pecks [H]'s [affecting]", "cuts [H]'s [affecting] with its talons"))
|
||||
|
||||
else
|
||||
L.adjustBruteLoss(damage)
|
||||
emote(pick("pecks at [L]", "claws [L]"))
|
||||
return
|
||||
|
||||
attacktext = pick("claws at", "chomps")
|
||||
L.attack_animal(src)//Time for the hurt to begin!
|
||||
//Otherwise, fly towards the mob!
|
||||
else
|
||||
walk_to(src, parrot_interest, 1, parrot_speed)
|
||||
@@ -683,6 +701,17 @@
|
||||
src << "\red You have nothing to drop!"
|
||||
return 0
|
||||
|
||||
|
||||
//parrots will eat crackers instead of dropping them
|
||||
if(istype(held_item,/obj/item/weapon/reagent_containers/food/snacks/cracker) && (drop_gently))
|
||||
del(held_item)
|
||||
held_item = null
|
||||
if(health < maxHealth)
|
||||
adjustBruteLoss(-10)
|
||||
emote("[src] eagerly downs the cracker")
|
||||
return 1
|
||||
|
||||
|
||||
if(!drop_gently)
|
||||
if(istype(held_item, /obj/item/weapon/grenade))
|
||||
var/obj/item/weapon/grenade/G = held_item
|
||||
@@ -716,6 +745,22 @@
|
||||
src << "\red There is no perch nearby to sit on."
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/parrot/proc/toggle_mode()
|
||||
set name = "Toggle mode"
|
||||
set category = "Parrot"
|
||||
set desc = "Time to bear those claws!"
|
||||
|
||||
if(stat || !client)
|
||||
return
|
||||
|
||||
if(melee_damage_upper)
|
||||
melee_damage_upper = 0
|
||||
a_intent = "help"
|
||||
else
|
||||
melee_damage_upper = parrot_damage_upper
|
||||
a_intent = "harm"
|
||||
return
|
||||
|
||||
/*
|
||||
* Sub-types
|
||||
*/
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
var/stop_automated_movement_when_pulled = 1 //When set to 1 this stops the animal from moving when someone is pulling it.
|
||||
|
||||
//Interaction
|
||||
var/response_help = "You try to help"
|
||||
var/response_disarm = "You try to disarm"
|
||||
var/response_harm = "You try to hurt"
|
||||
var/response_help = "pokes"
|
||||
var/response_disarm = "shoves"
|
||||
var/response_harm = "hits"
|
||||
var/harm_intent_damage = 3
|
||||
|
||||
//Temperature effect
|
||||
@@ -217,6 +217,11 @@
|
||||
new meat_type(src.loc)
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/blob_act()
|
||||
adjustBruteLoss(20)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/say_quote(var/text)
|
||||
if(speak_emote && speak_emote.len)
|
||||
var/emote = pick(speak_emote)
|
||||
@@ -225,6 +230,8 @@
|
||||
return "says, \"[text]\"";
|
||||
|
||||
/mob/living/simple_animal/emote(var/act)
|
||||
if(stat)
|
||||
return
|
||||
if(act)
|
||||
if(act == "scream") act = "makes a loud and pained whimper" //ugly hack to stop animals screaming when crushed :P
|
||||
for (var/mob/O in viewers(src, null))
|
||||
@@ -368,22 +375,32 @@
|
||||
var/obj/item/stack/medical/MED = O
|
||||
if(health < maxHealth)
|
||||
if(MED.amount >= 1)
|
||||
adjustBruteLoss(-MED.heal_brute)
|
||||
MED.amount -= 1
|
||||
if(MED.amount <= 0)
|
||||
del(MED)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\blue [user] applies [MED] on [src]")
|
||||
if(MED.heal_brute >= 1)
|
||||
adjustBruteLoss(-MED.heal_brute)
|
||||
MED.amount -= 1
|
||||
if(MED.amount <= 0)
|
||||
del(MED)
|
||||
for(var/mob/M in viewers(src, null))
|
||||
if ((M.client && !( M.blinded )))
|
||||
M.show_message("\blue [user] applies [MED] on [src]")
|
||||
return
|
||||
else
|
||||
user << "\blue [MED] won't help at all."
|
||||
return
|
||||
else
|
||||
user << "\blue [src] is at full health."
|
||||
return
|
||||
else
|
||||
user << "\blue [src] is dead, medical items won't bring it back to life."
|
||||
if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead.
|
||||
return
|
||||
else if(meat_type && (stat == DEAD)) //if the animal has a meat, and if it is dead.
|
||||
if(istype(O, /obj/item/weapon/kitchenknife) || istype(O, /obj/item/weapon/butch))
|
||||
new meat_type (get_turf(src))
|
||||
if(prob(95))
|
||||
del(src)
|
||||
return
|
||||
gib()
|
||||
return
|
||||
else
|
||||
if(O.force)
|
||||
var/damage = O.force
|
||||
@@ -440,14 +457,16 @@
|
||||
|
||||
/mob/living/simple_animal/adjustBruteLoss(damage)
|
||||
health = Clamp(health - damage, 0, maxHealth)
|
||||
if(health < 1)
|
||||
Die()
|
||||
|
||||
/mob/living/simple_animal/proc/SA_attackable(target_mob)
|
||||
if (isliving(target_mob))
|
||||
var/mob/living/L = target_mob
|
||||
/mob/living/simple_animal/proc/SA_attackable(target)
|
||||
if (isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(!L.stat)
|
||||
return (0)
|
||||
if (istype(target_mob,/obj/mecha))
|
||||
var/obj/mecha/M = target_mob
|
||||
return 0
|
||||
if (istype(target,/obj/mecha))
|
||||
var/obj/mecha/M = target
|
||||
if (M.occupant)
|
||||
return (0)
|
||||
return (1)
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -238,10 +238,10 @@ var/list/slot_equipment_priority = list( \
|
||||
<HR>
|
||||
<BR><B>Left Hand:</B> <A href='?src=\ref[src];item=[slot_l_hand]'> [l_hand ? l_hand : "Nothing"]</A>
|
||||
<BR><B>Right Hand:</B> <A href='?src=\ref[src];item=[slot_r_hand]'> [r_hand ? r_hand : "Nothing"]</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob[name]'>Close</A>
|
||||
<BR><A href='?src=\ref[user];mach_close=mob\ref[src]'>Close</A>
|
||||
"}
|
||||
user << browse(dat, "window=mob[name];size=325x500")
|
||||
onclose(user, "mob[name]")
|
||||
user << browse(dat, "window=mob\ref[src];size=325x500")
|
||||
onclose(user, "mob\ref[src]")
|
||||
|
||||
|
||||
/mob/verb/mode()
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
var/say_message = null // When you are understood by others. Currently only used by aliens and monkeys in their say_quote procs
|
||||
|
||||
var/faction = "neutral" //Used for checking whether hostile simple animals will attack you, possibly more stuff later
|
||||
var/move_on_shuttle = 1 // Can move on the shuttle.
|
||||
|
||||
//The last mob/living/carbon to push/drag/grab this mob (mostly used by slimes friend recognition)
|
||||
var/mob/living/carbon/LAssailant = null
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
//Used by throw code to hand over the mob, instead of throwing the grab. The grab is then deleted by the throw code.
|
||||
/obj/item/weapon/grab/proc/throw()
|
||||
if(affecting)
|
||||
if(affecting.buckled)
|
||||
return null
|
||||
if(state >= GRAB_AGGRESSIVE)
|
||||
return affecting
|
||||
return null
|
||||
@@ -78,6 +80,7 @@
|
||||
affecting.drop_item()
|
||||
affecting.hand = h
|
||||
for(var/obj/item/weapon/grab/G in affecting.grabbed_by)
|
||||
if(G == src) continue
|
||||
if(G.state == GRAB_AGGRESSIVE)
|
||||
allow_upgrade = 0
|
||||
if(allow_upgrade)
|
||||
@@ -106,7 +109,7 @@
|
||||
return
|
||||
if(assailant.next_move > world.time)
|
||||
return
|
||||
if(last_upgrade > world.time + UPGRADE_COOLDOWN)
|
||||
if(world.time < (last_upgrade + UPGRADE_COOLDOWN))
|
||||
return
|
||||
if(!assailant.canmove || assailant.lying)
|
||||
del(src)
|
||||
|
||||
@@ -115,6 +115,11 @@ proc/isobserver(A)
|
||||
return 1
|
||||
return 0
|
||||
|
||||
proc/isovermind(A)
|
||||
if(istype(A, /mob/camera/blob))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
proc/isorgan(A)
|
||||
if(istype(A, /datum/limb))
|
||||
return 1
|
||||
|
||||
@@ -211,16 +211,16 @@
|
||||
return 0 //This is sota the goto stop mobs from moving var
|
||||
if(mob.control_object)
|
||||
return Move_object(direct)
|
||||
if(isobserver(mob))
|
||||
return mob.Move(n,direct)
|
||||
if(moving)
|
||||
return 0
|
||||
if(world.time < move_delay)
|
||||
return 0
|
||||
if(mob.stat == DEAD)
|
||||
return 0
|
||||
if(isAI(mob))
|
||||
return AIMove(n,direct,mob)
|
||||
if(!isliving(mob))
|
||||
return mob.Move(n,direct)
|
||||
if(moving)
|
||||
return 0
|
||||
if(mob.stat == DEAD)
|
||||
return 0
|
||||
if(isliving(mob))
|
||||
var/mob/living/L = mob
|
||||
if(L.incorporeal_move) //Move though walls
|
||||
|
||||
@@ -389,27 +389,6 @@
|
||||
. = new_corgi
|
||||
del(src)
|
||||
|
||||
/mob/living/carbon/human/proc/blobize() // Oh boy, this is for you Int - Summoner
|
||||
if (monkeyizing)
|
||||
return
|
||||
for(var/obj/item/W in src)
|
||||
drop_from_inventory(W)
|
||||
regenerate_icons()
|
||||
monkeyizing = 1
|
||||
canmove = 0
|
||||
icon = null
|
||||
invisibility = 101
|
||||
for(var/t in organs)
|
||||
del(t)
|
||||
|
||||
var/mob/living/blob/new_blob = new /mob/living/blob (loc)
|
||||
new_blob.a_intent = "harm"
|
||||
new_blob.key = key
|
||||
|
||||
new_blob << "<B>You are now a Blob Fragment. You can now sacrifice yourself to spawn blobs!</B>"
|
||||
. = new_blob
|
||||
del(src)
|
||||
|
||||
/mob/living/carbon/human/Animalize()
|
||||
|
||||
var/list/mobtypes = typesof(/mob/living/simple_animal)
|
||||
|
||||
Reference in New Issue
Block a user