@@ -0,0 +1,83 @@
|
||||
/mob/living/carbon
|
||||
var/combatmode = FALSE //literally lifeweb
|
||||
var/lastmousedir
|
||||
var/wrongdirmovedelay
|
||||
var/lastdirchange
|
||||
var/combatmessagecooldown
|
||||
|
||||
//oh no vore time
|
||||
var/voremode = FALSE
|
||||
|
||||
/mob/living/carbon/CanPass(atom/movable/mover, turf/target)
|
||||
. = ..()
|
||||
if(.)
|
||||
var/mob/living/mobdude = mover
|
||||
if(istype(mobdude))
|
||||
if(!resting && mobdude.resting)
|
||||
if(!(mobdude.pass_flags & PASSMOB))
|
||||
return FALSE
|
||||
return .
|
||||
|
||||
/mob/living/carbon/proc/toggle_combat_mode(forced)
|
||||
if(recoveringstam)
|
||||
return TRUE
|
||||
if(!forced)
|
||||
for(var/datum/status_effect/S in status_effects)
|
||||
if(S.blocks_combatmode)
|
||||
return TRUE
|
||||
combatmode = !combatmode
|
||||
if(voremode)
|
||||
toggle_vore_mode()
|
||||
if(combatmode)
|
||||
playsound_local(src, 'sound/misc/ui_toggle.ogg', 50, FALSE, pressure_affected = FALSE) //Sound from interbay!
|
||||
else
|
||||
playsound_local(src, 'sound/misc/ui_toggleoff.ogg', 50, FALSE, pressure_affected = FALSE) //Slightly modified version of the above!
|
||||
if(client)
|
||||
client.show_popup_menus = !combatmode // So we can right-click for alternate actions and all that other good shit. Also moves examine to shift+rightclick to make it possible to attack while sprinting
|
||||
if(hud_used && hud_used.static_inventory)
|
||||
for(var/obj/screen/combattoggle/selector in hud_used.static_inventory)
|
||||
selector.rebasetointerbay(src)
|
||||
if(world.time >= combatmessagecooldown && combatmode)
|
||||
if(a_intent != INTENT_HELP)
|
||||
visible_message("<span class='warning'>[src] [resting ? "tenses up" : (prob(95)? "drops into a combative stance" : (prob(95)? "poses aggressively" : "asserts dominance with their pose"))].</span>")
|
||||
else
|
||||
visible_message("<span class='notice'>[src] [pick("looks","seems","goes")] [pick("alert","attentive","vigilant")].</span>")
|
||||
combatmessagecooldown = 10 SECONDS + world.time //This is set 100% of the time to make sure squeezing regen out of process cycles doesn't result in the combat mode message getting spammed
|
||||
SEND_SIGNAL(src, COMSIG_COMBAT_TOGGLED, src, combatmode)
|
||||
return TRUE
|
||||
|
||||
mob/living/carbon/proc/toggle_vore_mode()
|
||||
voremode = !voremode
|
||||
if(hud_used && hud_used.static_inventory)
|
||||
for(var/obj/screen/voretoggle/selector in hud_used.static_inventory)
|
||||
selector.rebaseintomygut(src)
|
||||
if(combatmode)
|
||||
return FALSE //let's not override the main draw of the game these days
|
||||
SEND_SIGNAL(src, COMSIG_VORE_TOGGLED, src, voremode)
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/Move(atom/newloc, direct = 0)
|
||||
var/currentdirection = dir
|
||||
. = ..()
|
||||
wrongdirmovedelay = FALSE
|
||||
if(combatmode && client && lastmousedir)
|
||||
if(lastmousedir != dir)
|
||||
wrongdirmovedelay = TRUE
|
||||
setDir(lastmousedir, ismousemovement = TRUE)
|
||||
if(currentdirection != dir)
|
||||
lastdirchange = world.time
|
||||
|
||||
|
||||
/mob/living/carbon/onMouseMove(object, location, control, params)
|
||||
if(!combatmode)
|
||||
return
|
||||
mouse_face_atom(object)
|
||||
lastmousedir = dir
|
||||
|
||||
/mob/living/carbon/setDir(newdir, ismousemovement = FALSE)
|
||||
if(!combatmode || ismousemovement)
|
||||
if(dir != newdir)
|
||||
lastdirchange = world.time
|
||||
. = ..()
|
||||
else
|
||||
return
|
||||
@@ -0,0 +1,28 @@
|
||||
/mob/living/proc/resist_embedded()
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/resist_embedded()
|
||||
if(handcuffed || legcuffed || (wear_suit && wear_suit.breakouttime))
|
||||
return
|
||||
if(canmove && !on_fire)
|
||||
for(var/obj/item/bodypart/L in bodyparts)
|
||||
if(istype(L) && L.embedded_objects.len)
|
||||
for(var/obj/item/I in L.embedded_objects)
|
||||
if(istype(I) && I.w_class >= WEIGHT_CLASS_NORMAL) //minimum weight class to insta-ripout via resist
|
||||
remove_embedded_unsafe(L, I, src, 1.5) //forcefully call the remove embedded unsafe proc but with extra pain multiplier. if you want to remove it less painfully, examine and remove it carefully.
|
||||
return TRUE //Hands are occupied
|
||||
return
|
||||
|
||||
/mob/living/carbon/human/proc/remove_embedded_unsafe(obj/item/bodypart/L, obj/item/I, mob/user, painmul = 1)
|
||||
if(!I || !L || I.loc != src || !(I in L.embedded_objects))
|
||||
return
|
||||
L.embedded_objects -= I
|
||||
L.receive_damage(I.embedding.embedded_unsafe_removal_pain_multiplier*I.w_class*painmul)//It hurts to rip it out, get surgery you dingus. And if you're ripping it out quickly via resist, it's gonna hurt even more
|
||||
I.forceMove(get_turf(src))
|
||||
user.put_in_hands(I)
|
||||
user.emote("scream")
|
||||
user.visible_message("[user] rips [I] out of [user.p_their()] [L.name]!","<span class='notice'>You remove [I] from your [L.name].</span>")
|
||||
if(!has_embedded_objects())
|
||||
clear_alert("embeddedobject")
|
||||
SEND_SIGNAL(user, COMSIG_CLEAR_MOOD_EVENT, "embedded")
|
||||
return
|
||||
@@ -0,0 +1,37 @@
|
||||
/mob/living/carbon/human
|
||||
var/sprinting = FALSE
|
||||
|
||||
/mob/living/carbon/human/Move(NewLoc, direct)
|
||||
var/oldpseudoheight = pseudo_z_axis
|
||||
. = ..()
|
||||
if(. && sprinting && !(movement_type & FLYING) && canmove && !resting && m_intent == MOVE_INTENT_RUN && has_gravity(loc) && !pulledby)
|
||||
doSprintLossTiles(1)
|
||||
if((oldpseudoheight - pseudo_z_axis) >= 8)
|
||||
to_chat(src, "<span class='warning'>You trip off of the elevated surface!</span>")
|
||||
for(var/obj/item/I in held_items)
|
||||
accident(I)
|
||||
Knockdown(80)
|
||||
|
||||
/mob/living/carbon/human/movement_delay()
|
||||
. = 0
|
||||
if(!resting && m_intent == MOVE_INTENT_RUN && !sprinting)
|
||||
. += 1
|
||||
if(wrongdirmovedelay)
|
||||
. += 1
|
||||
. += ..()
|
||||
|
||||
/mob/living/carbon/human/proc/togglesprint() // If you call this proc outside of hotkeys or clicking the HUD button, I'll be disappointed in you.
|
||||
sprinting = !sprinting
|
||||
if(!resting && m_intent == MOVE_INTENT_RUN && canmove)
|
||||
if(sprinting)
|
||||
playsound_local(src, 'sound/misc/sprintactivate.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
else
|
||||
playsound_local(src, 'sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
if(hud_used && hud_used.static_inventory)
|
||||
for(var/obj/screen/sprintbutton/selector in hud_used.static_inventory)
|
||||
selector.insert_witty_toggle_joke_here(src)
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/human/proc/sprint_hotkey(targetstatus)
|
||||
if(targetstatus ? !sprinting : sprinting)
|
||||
togglesprint()
|
||||
@@ -0,0 +1,132 @@
|
||||
/mob/living
|
||||
var/recoveringstam = FALSE
|
||||
var/incomingstammult = 1
|
||||
var/bufferedstam = 0
|
||||
var/stambuffer = 20
|
||||
var/stambufferregentime
|
||||
var/attemptingstandup = FALSE
|
||||
var/intentionalresting = FALSE
|
||||
var/attemptingcrawl = FALSE
|
||||
|
||||
//Sprint buffer---
|
||||
var/sprint_buffer = 42 //Tiles
|
||||
var/sprint_buffer_max = 42
|
||||
var/sprint_buffer_regen_ds = 0.3 //Tiles per world.time decisecond
|
||||
var/sprint_buffer_regen_last = 0 //last world.time this was regen'd for math.
|
||||
var/sprint_stamina_cost = 0.70 //stamina loss per tile while insufficient sprint buffer.
|
||||
//---End
|
||||
|
||||
/mob/living/movement_delay(ignorewalk = 0)
|
||||
. = ..()
|
||||
if(resting)
|
||||
. += 6
|
||||
|
||||
/atom
|
||||
var/pseudo_z_axis
|
||||
|
||||
/atom/proc/get_fake_z()
|
||||
return pseudo_z_axis
|
||||
|
||||
/obj/structure/table
|
||||
pseudo_z_axis = 8
|
||||
|
||||
/turf/open/get_fake_z()
|
||||
var/objschecked
|
||||
for(var/obj/structure/structurestocheck in contents)
|
||||
objschecked++
|
||||
if(structurestocheck.pseudo_z_axis)
|
||||
return structurestocheck.pseudo_z_axis
|
||||
if(objschecked >= 25)
|
||||
break
|
||||
return pseudo_z_axis
|
||||
|
||||
/mob/living/Move(atom/newloc, direct)
|
||||
. = ..()
|
||||
if(.)
|
||||
pseudo_z_axis = newloc.get_fake_z()
|
||||
pixel_z = pseudo_z_axis
|
||||
|
||||
/mob/living/proc/lay_down()
|
||||
set name = "Rest"
|
||||
set category = "IC"
|
||||
|
||||
if(client && client.prefs && client.prefs.autostand)
|
||||
intentionalresting = !intentionalresting
|
||||
to_chat(src, "<span class='notice'>You are now attempting to [intentionalresting ? "[!resting ? "lay down and ": ""]stay down" : "[resting ? "get up and ": ""]stay up"].</span>")
|
||||
if(intentionalresting && !resting)
|
||||
resting = TRUE
|
||||
update_canmove()
|
||||
else
|
||||
resist_a_rest()
|
||||
else
|
||||
if(!resting)
|
||||
resting = TRUE
|
||||
to_chat(src, "<span class='notice'>You are now laying down.</span>")
|
||||
update_canmove()
|
||||
else
|
||||
resist_a_rest()
|
||||
|
||||
/mob/living/proc/resist_a_rest(automatic = FALSE, ignoretimer = FALSE) //Lets mobs resist out of resting. Major QOL change with combat reworks.
|
||||
if(!resting || stat || attemptingstandup)
|
||||
return FALSE
|
||||
if(ignoretimer)
|
||||
resting = FALSE
|
||||
update_canmove()
|
||||
return TRUE
|
||||
else
|
||||
var/totaldelay = 3 //A little bit less than half of a second as a baseline for getting up from a rest
|
||||
if(getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
to_chat(src, "<span class='warning'>You're too exhausted to get up!")
|
||||
return FALSE
|
||||
attemptingstandup = TRUE
|
||||
var/health_deficiency = max((maxHealth - (health - getStaminaLoss()))*0.5, 0)
|
||||
if(!has_gravity())
|
||||
health_deficiency = health_deficiency*0.2
|
||||
totaldelay += health_deficiency
|
||||
var/standupwarning = "[src] and everyone around them should probably yell at the dev team"
|
||||
switch(health_deficiency)
|
||||
if(-INFINITY to 10)
|
||||
standupwarning = "[src] stands right up!"
|
||||
if(10 to 35)
|
||||
standupwarning = "[src] tries to stand up."
|
||||
if(35 to 60)
|
||||
standupwarning = "[src] slowly pushes [p_them()]self upright."
|
||||
if(60 to 80)
|
||||
standupwarning = "[src] weakly attempts to stand up."
|
||||
if(80 to INFINITY)
|
||||
standupwarning = "[src] struggles to stand up."
|
||||
var/usernotice = automatic ? "<span class='notice'>You are now getting up. (Auto)</span>" : "<span class='notice'>You are now getting up.</span>"
|
||||
visible_message("<span class='notice'>[standupwarning]</span>", usernotice, vision_distance = 5)
|
||||
if(do_after(src, totaldelay, target = src))
|
||||
resting = FALSE
|
||||
attemptingstandup = FALSE
|
||||
update_canmove()
|
||||
return TRUE
|
||||
else
|
||||
visible_message("<span class='notice'>[src] falls right back down.</span>", "<span class='notice'>You fall right back down.</span>")
|
||||
attemptingstandup = FALSE
|
||||
if(has_gravity())
|
||||
playsound(src, "bodyfall", 20, 1)
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/update_stamina()
|
||||
var/total_health = getStaminaLoss()
|
||||
if(total_health)
|
||||
if(!recoveringstam && total_health >= STAMINA_CRIT && !stat)
|
||||
to_chat(src, "<span class='notice'>You're too exhausted to keep going...</span>")
|
||||
resting = TRUE
|
||||
if(combatmode)
|
||||
toggle_combat_mode(TRUE)
|
||||
recoveringstam = TRUE
|
||||
filters += CIT_FILTER_STAMINACRIT
|
||||
update_canmove()
|
||||
if(recoveringstam && total_health <= STAMINA_SOFTCRIT)
|
||||
to_chat(src, "<span class='notice'>You don't feel nearly as exhausted anymore.</span>")
|
||||
recoveringstam = FALSE
|
||||
filters -= CIT_FILTER_STAMINACRIT
|
||||
update_canmove()
|
||||
update_health_hud()
|
||||
|
||||
/mob/living/proc/update_hud_sprint_bar()
|
||||
if(hud_used && hud_used.sprint_buffer)
|
||||
hud_used.sprint_buffer.update_to_mob(src)
|
||||
@@ -0,0 +1,466 @@
|
||||
/*
|
||||
DOG BORG EQUIPMENT HERE
|
||||
SLEEPER CODE IS IN game/objects/items/devices/dogborg_sleeper.dm !
|
||||
*/
|
||||
|
||||
/obj/item/dogborg/jaws
|
||||
name = "Dogborg jaws"
|
||||
desc = "The jaws of the debug errors oh god."
|
||||
icon = 'icons/mob/dogborg.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
force = 1
|
||||
throwforce = 0
|
||||
w_class = 3
|
||||
hitsound = 'sound/weapons/bite.ogg'
|
||||
sharpness = IS_SHARP
|
||||
var/stamtostunconversion = 0.1 //Total stamloss gets multiplied by this value for the help intent hard stun. Resting adds an additional 2x multiplier on top. Keep this low or so help me god.
|
||||
var/stuncooldown = 4 SECONDS //How long it takes before you're able to attempt to stun a target again
|
||||
var/nextstuntime
|
||||
|
||||
/obj/item/dogborg/jaws/examine(mob/user)
|
||||
. = ..()
|
||||
if(!CONFIG_GET(flag/weaken_secborg))
|
||||
to_chat(user, "<span class='notice'>Use help intent to attempt to non-lethally incapacitate the target by latching on with your maw. This is more effective against exhausted and resting targets.</span>")
|
||||
|
||||
/obj/item/dogborg/jaws/big
|
||||
name = "combat jaws"
|
||||
desc = "The jaws of the law. Very sharp."
|
||||
icon_state = "jaws"
|
||||
force = 15 //Chomp chomp. Crew harm.
|
||||
attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
|
||||
stamtostunconversion = 0.2 // 100*0.2*2=40. Stun's just long enough to slap on cuffs with click delay if the target is near hard stamcrit.
|
||||
stuncooldown = 6 SECONDS
|
||||
|
||||
|
||||
/obj/item/dogborg/jaws/small
|
||||
name = "puppy jaws"
|
||||
desc = "Rubberized teeth designed to protect accidental harm. Sharp enough for specialized tasks however."
|
||||
icon_state = "smalljaws"
|
||||
force = 6
|
||||
attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed")
|
||||
var/status = 0
|
||||
|
||||
/obj/item/dogborg/jaws/attack(atom/A, mob/living/silicon/robot/user)
|
||||
if(!istype(user))
|
||||
return
|
||||
if(!CONFIG_GET(flag/weaken_secborg) && user.a_intent != INTENT_HARM && istype(A, /mob/living))
|
||||
if(A == user.pulling)
|
||||
to_chat(user, "<span class='warning'>You already have [A] in your jaws.</span>")
|
||||
return
|
||||
if(nextstuntime >= world.time)
|
||||
to_chat(user, "<span class='warning'>Your jaw servos are still recharging.</span>")
|
||||
return
|
||||
nextstuntime = world.time + stuncooldown
|
||||
var/mob/living/M = A
|
||||
var/cachedstam = M.getStaminaLoss()
|
||||
var/totalstuntime = cachedstam * stamtostunconversion * (M.lying ? 2 : 1)
|
||||
if(!M.resting)
|
||||
M.Knockdown(cachedstam*2) //BORK BORK. GET DOWN.
|
||||
M.Stun(totalstuntime)
|
||||
user.do_attack_animation(A, ATTACK_EFFECT_BITE)
|
||||
user.start_pulling(M, TRUE) //Yip yip. Come with.
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
M.visible_message("<span class='danger'>[user] clamps [user.p_their()] [src] onto [M] and latches on!</span>", "<span class='userdanger'>[user] clamps [user.p_their()] [src] onto you and latches on!</span>")
|
||||
if(totalstuntime >= 4 SECONDS)
|
||||
playsound(usr, 'sound/effects/k9_jaw_strong.ogg', 75, FALSE, 2) //Wuff wuff. Big stun.
|
||||
else
|
||||
playsound(usr, 'sound/effects/k9_jaw_weak.ogg', 50, TRUE, -1) //Arf arf. Pls buff.
|
||||
else
|
||||
. = ..()
|
||||
user.do_attack_animation(A, ATTACK_EFFECT_BITE)
|
||||
|
||||
/obj/item/dogborg/jaws/small/attack_self(mob/user)
|
||||
var/mob/living/silicon/robot/R = user
|
||||
if(R.cell && R.cell.charge > 100)
|
||||
if(R.emagged && status == 0)
|
||||
name = "combat jaws"
|
||||
icon_state = "jaws"
|
||||
desc = "The jaws of the law."
|
||||
force = 12
|
||||
attack_verb = list("chomped", "bit", "ripped", "mauled", "enforced")
|
||||
stamtostunconversion = 0.15
|
||||
stuncooldown = 5 SECONDS
|
||||
status = 1
|
||||
to_chat(user, "<span class='notice'>Your jaws are now [status ? "Combat" : "Pup'd"].</span>")
|
||||
else
|
||||
name = "puppy jaws"
|
||||
icon_state = "smalljaws"
|
||||
desc = "The jaws of a small dog."
|
||||
force = initial(force)
|
||||
attack_verb = list("nibbled", "bit", "gnawed", "chomped", "nommed")
|
||||
stamtostunconversion = initial(stamtostunconversion)
|
||||
stuncooldown = initial(stuncooldown)
|
||||
status = 0
|
||||
if(R.emagged)
|
||||
to_chat(user, "<span class='notice'>Your jaws are now [status ? "Combat" : "Pup'd"].</span>")
|
||||
update_icon()
|
||||
|
||||
//Boop
|
||||
|
||||
/obj/item/analyzer/nose
|
||||
name = "boop module"
|
||||
icon = 'icons/mob/dogborg.dmi'
|
||||
icon_state = "nose"
|
||||
desc = "The BOOP module"
|
||||
flags_1 = CONDUCT_1
|
||||
force = 0
|
||||
throwforce = 0
|
||||
attack_verb = list("nuzzles", "pushes", "boops")
|
||||
w_class = 1
|
||||
|
||||
/obj/item/analyzer/nose/attack_self(mob/user)
|
||||
user.visible_message("[user] sniffs around the air.", "<span class='warning'>You sniff the air for gas traces.</span>")
|
||||
|
||||
var/turf/location = user.loc
|
||||
if(!istype(location))
|
||||
return
|
||||
|
||||
var/datum/gas_mixture/environment = location.return_air()
|
||||
|
||||
var/pressure = environment.return_pressure()
|
||||
var/total_moles = environment.total_moles()
|
||||
|
||||
to_chat(user, "<span class='info'><B>Results:</B></span>")
|
||||
if(abs(pressure - ONE_ATMOSPHERE) < 10)
|
||||
to_chat(user, "<span class='info'>Pressure: [round(pressure,0.1)] kPa</span>")
|
||||
else
|
||||
to_chat(user, "<span class='alert'>Pressure: [round(pressure,0.1)] kPa</span>")
|
||||
if(total_moles)
|
||||
var/list/env_gases = environment.gases
|
||||
|
||||
var/o2_concentration = env_gases[/datum/gas/oxygen]/total_moles
|
||||
var/n2_concentration = env_gases[/datum/gas/nitrogen]/total_moles
|
||||
var/co2_concentration = env_gases[/datum/gas/carbon_dioxide]/total_moles
|
||||
var/plasma_concentration = env_gases[/datum/gas/plasma]/total_moles
|
||||
GAS_GARBAGE_COLLECT(environment.gases)
|
||||
|
||||
if(abs(n2_concentration - N2STANDARD) < 20)
|
||||
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] %</span>")
|
||||
else
|
||||
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] %</span>")
|
||||
|
||||
if(abs(o2_concentration - O2STANDARD) < 2)
|
||||
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] %</span>")
|
||||
else
|
||||
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] %</span>")
|
||||
|
||||
if(co2_concentration > 0.01)
|
||||
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] %</span>")
|
||||
else
|
||||
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] %</span>")
|
||||
|
||||
if(plasma_concentration > 0.005)
|
||||
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] %</span>")
|
||||
else
|
||||
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] %</span>")
|
||||
|
||||
|
||||
for(var/id in env_gases)
|
||||
if(id in GLOB.hardcoded_gases)
|
||||
continue
|
||||
var/gas_concentration = env_gases[id]/total_moles
|
||||
to_chat(user, "<span class='alert'>[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] %</span>")
|
||||
to_chat(user, "<span class='info'>Temperature: [round(environment.temperature-T0C)] °C</span>")
|
||||
|
||||
/obj/item/analyzer/nose/AltClick(mob/user) //Barometer output for measuring when the next storm happens
|
||||
. = ..()
|
||||
|
||||
/obj/item/analyzer/nose/afterattack(atom/target, mob/user, proximity)
|
||||
. = ..()
|
||||
if(!proximity)
|
||||
return
|
||||
do_attack_animation(target, null, src)
|
||||
user.visible_message("<span class='notice'>[user] [pick(attack_verb)] \the [target.name] with their nose!</span>")
|
||||
|
||||
//Delivery
|
||||
/obj/item/storage/bag/borgdelivery
|
||||
name = "fetching storage"
|
||||
desc = "Fetch the thing!"
|
||||
icon = 'icons/mob/dogborg.dmi'
|
||||
icon_state = "dbag"
|
||||
w_class = WEIGHT_CLASS_BULKY
|
||||
|
||||
/obj/item/storage/bag/borgdelivery/ComponentInitialize()
|
||||
. = ..()
|
||||
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
|
||||
STR.max_w_class = WEIGHT_CLASS_BULKY
|
||||
STR.max_combined_w_class = 5
|
||||
STR.max_items = 1
|
||||
STR.cant_hold = typecacheof(list(/obj/item/disk/nuclear, /obj/item/radio/intercom))
|
||||
|
||||
//Tongue stuff
|
||||
/obj/item/soap/tongue
|
||||
name = "synthetic tongue"
|
||||
desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face."
|
||||
icon = 'icons/mob/dogborg.dmi'
|
||||
icon_state = "synthtongue"
|
||||
hitsound = 'sound/effects/attackblob.ogg'
|
||||
cleanspeed = 80
|
||||
var/status = 0
|
||||
|
||||
/obj/item/soap/tongue/scrubpup
|
||||
cleanspeed = 25 //slightly faster than a mop.
|
||||
|
||||
/obj/item/soap/tongue/New()
|
||||
..()
|
||||
item_flags |= NOBLUDGEON //No more attack messages
|
||||
|
||||
/obj/item/soap/tongue/attack_self(mob/user)
|
||||
var/mob/living/silicon/robot/R = user
|
||||
if(R.cell && R.cell.charge > 100)
|
||||
if(R.emagged && status == 0)
|
||||
status = !status
|
||||
name = "energized tongue"
|
||||
desc = "Your tongue is energized for dangerously maximum efficency."
|
||||
icon_state = "syndietongue"
|
||||
to_chat(user, "<span class='notice'>Your tongue is now [status ? "Energized" : "Normal"].</span>")
|
||||
cleanspeed = 10 //(nerf'd)tator soap stat
|
||||
else
|
||||
status = 0
|
||||
name = "synthetic tongue"
|
||||
desc = "Useful for slurping mess off the floor before affectionally licking the crew members in the face."
|
||||
icon_state = "synthtongue"
|
||||
cleanspeed = initial(cleanspeed)
|
||||
if(R.emagged)
|
||||
to_chat(user, "<span class='notice'>Your tongue is now [status ? "Energized" : "Normal"].</span>")
|
||||
update_icon()
|
||||
|
||||
/obj/item/soap/tongue/afterattack(atom/target, mob/user, proximity)
|
||||
var/mob/living/silicon/robot/R = user
|
||||
if(!proximity || !check_allowed_items(target))
|
||||
return
|
||||
if(R.client && (target in R.client.screen))
|
||||
to_chat(R, "<span class='warning'>You need to take that [target.name] off before cleaning it!</span>")
|
||||
else if(is_cleanable(target))
|
||||
R.visible_message("[R] begins to lick off \the [target.name].", "<span class='warning'>You begin to lick off \the [target.name]...</span>")
|
||||
if(do_after(R, src.cleanspeed, target = target))
|
||||
if(!in_range(src, target)) //Proximity is probably old news by now, do a new check.
|
||||
return //If they moved away, you can't eat them.
|
||||
to_chat(R, "<span class='notice'>You finish licking off \the [target.name].</span>")
|
||||
qdel(target)
|
||||
R.cell.give(50)
|
||||
else if(isobj(target)) //hoo boy. danger zone man
|
||||
if(istype(target,/obj/item/trash))
|
||||
R.visible_message("[R] nibbles away at \the [target.name].", "<span class='warning'>You begin to nibble away at \the [target.name]...</span>")
|
||||
if(!do_after(R, src.cleanspeed, target = target))
|
||||
return //If they moved away, you can't eat them.
|
||||
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
|
||||
qdel(target)
|
||||
R.cell.give(250)
|
||||
return
|
||||
if(istype(target,/obj/item/stock_parts/cell))
|
||||
R.visible_message("[R] begins cramming \the [target.name] down its throat.", "<span class='warning'>You begin cramming \the [target.name] down your throat...</span>")
|
||||
if(!do_after(R, 50, target = target))
|
||||
return //If they moved away, you can't eat them.
|
||||
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
|
||||
var/obj/item/stock_parts/cell.C = target
|
||||
R.cell.charge = R.cell.charge + (C.charge / 3) //Instant full cell upgrades op idgaf
|
||||
qdel(target)
|
||||
return
|
||||
var/obj/item/I = target //HAHA FUCK IT, NOT LIKE WE ALREADY HAVE A SHITTON OF WAYS TO REMOVE SHIT
|
||||
if(!I.anchored && R.emagged)
|
||||
R.visible_message("[R] begins chewing up \the [target.name]. Looks like it's trying to loophole around its diet restriction!", "<span class='warning'>You begin chewing up \the [target.name]...</span>")
|
||||
if(!do_after(R, 100, target = I)) //Nerf dat time yo
|
||||
return //If they moved away, you can't eat them.
|
||||
visible_message("<span class='warning'>[R] chews up \the [target.name] and cleans off the debris!</span>")
|
||||
to_chat(R, "<span class='notice'>You finish off \the [target.name].</span>")
|
||||
qdel(I)
|
||||
R.cell.give(500)
|
||||
return
|
||||
R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
|
||||
else if(ishuman(target))
|
||||
var/mob/living/L = target
|
||||
if(status == 0 && check_zone(R.zone_selected) == "head")
|
||||
R.visible_message("<span class='warning'>\the [R] affectionally licks \the [L]'s face!</span>", "<span class='notice'>You affectionally lick \the [L]'s face!</span>")
|
||||
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
|
||||
if(istype(L) && L.fire_stacks > 0)
|
||||
L.adjust_fire_stacks(-10)
|
||||
return
|
||||
else if(status == 0)
|
||||
R.visible_message("<span class='warning'>\the [R] affectionally licks \the [L]!</span>", "<span class='notice'>You affectionally lick \the [L]!</span>")
|
||||
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
|
||||
if(istype(L) && L.fire_stacks > 0)
|
||||
L.adjust_fire_stacks(-10)
|
||||
return
|
||||
else
|
||||
if(R.cell.charge <= 800)
|
||||
to_chat(R, "Insufficent Power!")
|
||||
return
|
||||
L.Stun(4) // normal stunbaton is force 7 gimme a break good sir!
|
||||
L.Knockdown(80)
|
||||
L.apply_effect(EFFECT_STUTTER, 4)
|
||||
L.visible_message("<span class='danger'>[R] has shocked [L] with its tongue!</span>", \
|
||||
"<span class='userdanger'>[R] has shocked you with its tongue!</span>")
|
||||
playsound(loc, 'sound/weapons/Egloves.ogg', 50, 1, -1)
|
||||
R.cell.use(666)
|
||||
log_combat(R, L, "tongue stunned")
|
||||
|
||||
else if(istype(target, /obj/structure/window))
|
||||
R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
|
||||
if(do_after(user, src.cleanspeed, target = target))
|
||||
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
|
||||
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
|
||||
target.set_opacity(initial(target.opacity))
|
||||
else
|
||||
R.visible_message("[R] begins to lick \the [target.name] clean...", "<span class='notice'>You begin to lick \the [target.name] clean...</span>")
|
||||
if(do_after(user, src.cleanspeed, target = target))
|
||||
to_chat(user, "<span class='notice'>You clean \the [target.name].</span>")
|
||||
var/obj/effect/decal/cleanable/C = locate() in target
|
||||
qdel(C)
|
||||
target.remove_atom_colour(WASHABLE_COLOUR_PRIORITY)
|
||||
SEND_SIGNAL(target, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_MEDIUM)
|
||||
target.wash_cream()
|
||||
return
|
||||
|
||||
//Nerfed tongue for flavour reasons (haha geddit?). Used for aux skins for regular borgs
|
||||
/obj/item/soap/tongue/flavour
|
||||
desc = "For giving affectionate kisses."
|
||||
|
||||
/obj/item/soap/tongue/flavour/attack_self(mob/user)
|
||||
return
|
||||
|
||||
/obj/item/soap/tongue/flavour/afterattack(atom/target, mob/user, proximity)
|
||||
if(!proximity)
|
||||
return
|
||||
var/mob/living/silicon/robot.R = user
|
||||
if(ishuman(target))
|
||||
var/mob/living/L = target
|
||||
if(status == 0 && check_zone(R.zone_selected) == "head")
|
||||
R.visible_message("<span class='warning'>\the [R] affectionally licks \the [L]'s face!</span>", "<span class='notice'>You affectionally lick \the [L]'s face!</span>")
|
||||
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
|
||||
return
|
||||
else if(status == 0)
|
||||
R.visible_message("<span class='warning'>\the [R] affectionally licks \the [L]!</span>", "<span class='notice'>You affectionally lick \the [L]!</span>")
|
||||
playsound(src.loc, 'sound/effects/attackblob.ogg', 50, 1)
|
||||
return
|
||||
|
||||
//Same as above but for noses
|
||||
/obj/item/analyzer/nose/flavour/AltClick(mob/user)
|
||||
return
|
||||
|
||||
/obj/item/analyzer/nose/flavour/attack_self(mob/user)
|
||||
return
|
||||
|
||||
/obj/item/analyzer/nose/flavour/afterattack(atom/target, mob/user, proximity)
|
||||
if(!proximity)
|
||||
return
|
||||
do_attack_animation(target, null, src)
|
||||
user.visible_message("<span class='notice'>[user] [pick(attack_verb)] \the [target.name] with their nose!</span>")
|
||||
|
||||
|
||||
//Dogfood
|
||||
|
||||
/obj/item/trash/rkibble
|
||||
name = "robo kibble"
|
||||
desc = "A novelty bowl of assorted mech fabricator byproducts. Mockingly feed this to the sec-dog to help it recharge."
|
||||
icon = 'icons/mob/dogborg.dmi'
|
||||
icon_state= "kibble"
|
||||
|
||||
//Defibs
|
||||
|
||||
/obj/item/twohanded/shockpaddles/cyborg/hound
|
||||
name = "Paws of Life"
|
||||
desc = "MediHound specific shock paws."
|
||||
icon = 'icons/mob/dogborg.dmi'
|
||||
icon_state = "defibpaddles0"
|
||||
item_state = "defibpaddles0"
|
||||
|
||||
// Pounce stuff for K-9
|
||||
|
||||
/obj/item/dogborg/pounce
|
||||
name = "pounce"
|
||||
icon = 'icons/mob/dogborg.dmi'
|
||||
icon_state = "pounce"
|
||||
desc = "Leap at your target to momentarily stun them."
|
||||
force = 0
|
||||
throwforce = 0
|
||||
|
||||
/obj/item/dogborg/pounce/New()
|
||||
..()
|
||||
item_flags |= NOBLUDGEON
|
||||
|
||||
/mob/living/silicon/robot
|
||||
var/leaping = 0
|
||||
var/pounce_cooldown = 0
|
||||
var/pounce_cooldown_time = 30 //Time in deciseconds between pounces
|
||||
var/pounce_spoolup = 5 //Time in deciseconds for the pounce to happen after clicking
|
||||
var/pounce_stamloss_cap = 120 //How much staminaloss pounces alone are capable of bringing a spaceman to
|
||||
var/pounce_stamloss = 80 //Base staminaloss value of the pounce
|
||||
var/leap_at
|
||||
var/disabler
|
||||
var/laser
|
||||
var/sleeper_g
|
||||
var/sleeper_r
|
||||
var/sleeper_nv
|
||||
|
||||
#define MAX_K9_LEAP_DIST 4 //because something's definitely borked the pounce functioning from a distance.
|
||||
|
||||
/obj/item/dogborg/pounce/afterattack(atom/A, mob/user)
|
||||
var/mob/living/silicon/robot/R = user
|
||||
if(R && (world.time >= R.pounce_cooldown))
|
||||
R.pounce_cooldown = world.time + R.pounce_cooldown_time
|
||||
to_chat(R, "<span class ='warning'>Your targeting systems lock on to [A]...</span>")
|
||||
playsound(R, 'sound/effects/servostep.ogg', 100, TRUE)
|
||||
addtimer(CALLBACK(R, /mob/living/silicon/robot.proc/leap_at, A), R.pounce_spoolup)
|
||||
else if(R && (world.time < R.pounce_cooldown))
|
||||
to_chat(R, "<span class='danger'>Your leg actuators are still recharging!</span>")
|
||||
|
||||
/mob/living/silicon/robot/proc/leap_at(atom/A)
|
||||
if(leaping || stat || buckled || lying)
|
||||
return
|
||||
|
||||
if(!has_gravity(src) || !has_gravity(A))
|
||||
to_chat(src,"<span class='danger'>It is unsafe to leap without gravity!</span>")
|
||||
//It's also extremely buggy visually, so it's balance+bugfix
|
||||
return
|
||||
|
||||
if(cell.charge <= 750)
|
||||
to_chat(src,"<span class='danger'>Insufficent reserves for jump actuators!</span>")
|
||||
return
|
||||
|
||||
else
|
||||
leaping = 1
|
||||
weather_immunities += "lava"
|
||||
pixel_y = 10
|
||||
update_icons()
|
||||
throw_at(A, MAX_K9_LEAP_DIST, 1, spin=0, diagonals_first = 1)
|
||||
cell.use(750) //Less than a stunbaton since stunbatons hit everytime.
|
||||
playsound(src, 'sound/effects/stealthoff.ogg', 25, TRUE, -1)
|
||||
weather_immunities -= "lava"
|
||||
|
||||
/mob/living/silicon/robot/throw_impact(atom/A)
|
||||
|
||||
if(!leaping)
|
||||
return ..()
|
||||
|
||||
if(A)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
var/blocked = 0
|
||||
if(ishuman(A))
|
||||
var/mob/living/carbon/human/H = A
|
||||
if(H.check_shields(0, "the [name]", src, attack_type = LEAP_ATTACK))
|
||||
blocked = 1
|
||||
if(!blocked)
|
||||
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
|
||||
L.Knockdown(iscarbon(L) ? 60 : 45, override_stamdmg = CLAMP(pounce_stamloss, 0, pounce_stamloss_cap-L.getStaminaLoss())) // Temporary. If someone could rework how dogborg pounces work to accomodate for combat changes, that'd be nice.
|
||||
playsound(src, 'sound/weapons/Egloves.ogg', 50, 1)
|
||||
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
|
||||
step_towards(src,L)
|
||||
log_combat(src, L, "borg pounced")
|
||||
else
|
||||
Knockdown(15, 1, 1)
|
||||
|
||||
pounce_cooldown = !pounce_cooldown
|
||||
spawn(pounce_cooldown_time) //3s by default
|
||||
pounce_cooldown = !pounce_cooldown
|
||||
else if(A.density && !A.CanPass(src))
|
||||
visible_message("<span class ='danger'>[src] smashes into [A]!</span>", "<span class ='userdanger'>You smash into [A]!</span>")
|
||||
playsound(src, 'sound/items/trayhit1.ogg', 50, 1)
|
||||
Knockdown(15, 1, 1)
|
||||
|
||||
if(leaping)
|
||||
leaping = 0
|
||||
pixel_y = initial(pixel_y)
|
||||
update_icons()
|
||||
update_canmove()
|
||||
@@ -11,6 +11,7 @@
|
||||
. = ..()
|
||||
if(!resting && !sprinting)
|
||||
. += 1
|
||||
. += speed
|
||||
|
||||
/mob/living/silicon/robot/proc/togglesprint(shutdown = FALSE) //Basically a copypaste of the proc from /mob/living/carbon/human
|
||||
if(!shutdown && (!cell || cell.charge < 25))
|
||||
@@ -18,11 +19,11 @@
|
||||
sprinting = shutdown ? FALSE : !sprinting
|
||||
if(!resting && canmove)
|
||||
if(sprinting)
|
||||
playsound_local(src, 'modular_citadel/sound/misc/sprintactivate.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
playsound_local(src, 'sound/misc/sprintactivate.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
else
|
||||
if(shutdown)
|
||||
playsound_local(src, 'sound/effects/light_flicker.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
playsound_local(src, 'modular_citadel/sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
playsound_local(src, 'sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
if(hud_used && hud_used.static_inventory)
|
||||
for(var/obj/screen/sprintbutton/selector in hud_used.static_inventory)
|
||||
selector.insert_witty_toggle_joke_here(src)
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
/obj/item/seeds/banana/Initialize()
|
||||
. = ..()
|
||||
mutatelist += /obj/item/seeds/banana/exotic_banana
|
||||
|
||||
|
||||
/obj/item/seeds/banana/exotic_banana
|
||||
name = "pack of exotic banana seeds"
|
||||
desc = "They're seeds that grow into banana trees. However, those bananas might be alive."
|
||||
icon = 'modular_citadel/icons/mob/BananaSpider.dmi'
|
||||
icon_state = "seed_ExoticBanana"
|
||||
species = "banana"
|
||||
plantname = "Exotic Banana Tree"
|
||||
product = /obj/item/reagent_containers/food/snacks/grown/banana/banana_spider_spawnable
|
||||
growing_icon = 'modular_citadel/icons/mob/BananaSpider.dmi'
|
||||
icon_dead = "banana-dead"
|
||||
mutatelist = list()
|
||||
genes = list(/datum/plant_gene/trait/slip)
|
||||
reagents_add = list("banana" = 0.1, "potassium" = 0.1, "vitamin" = 0.04, "nutriment" = 0.02)
|
||||
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/banana/banana_spider_spawnable
|
||||
seed = /obj/item/seeds/banana/exotic_banana
|
||||
name = "banana spider"
|
||||
desc = "You do not know what it is, but you can bet the clown would love it."
|
||||
icon = 'modular_citadel/icons/mob/BananaSpider.dmi'
|
||||
icon_state = "banana"
|
||||
item_state = "banana"
|
||||
filling_color = "#FFFF00"
|
||||
list_reagents = list("nutriment" = 3, "vitamin" = 2)
|
||||
foodtype = GROSS | MEAT | RAW | FRUIT
|
||||
grind_results = list("blood" = 20, "liquidgibs" = 5)
|
||||
juice_results = list("banana" = 0)
|
||||
var/awakening = 0
|
||||
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/grown/banana/banana_spider_spawnable/attack_self(mob/user)
|
||||
if(awakening || isspaceturf(user.loc))
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You decide to wake up the banana spider...</span>")
|
||||
awakening = 1
|
||||
|
||||
spawn(30)
|
||||
if(!QDELETED(src))
|
||||
var/mob/living/simple_animal/banana_spider/S = new /mob/living/simple_animal/banana_spider(get_turf(src.loc))
|
||||
S.speed += round(10 / seed.potency)
|
||||
S.visible_message("<span class='notice'>The banana spider chitters as it stretches its legs.</span>")
|
||||
qdel(src)
|
||||
|
||||
|
||||
/mob/living/simple_animal/banana_spider
|
||||
icon = 'modular_citadel/icons/mob/BananaSpider.dmi'
|
||||
name = "banana spider"
|
||||
desc = "What the fuck is this abomination?"
|
||||
icon_state = "banana"
|
||||
icon_dead = "banana_peel"
|
||||
health = 1
|
||||
maxHealth = 1
|
||||
turns_per_move = 5 //this isn't player speed =|
|
||||
speed = 2 //this is player speed
|
||||
loot = list(/obj/item/reagent_containers/food/snacks/deadbanana_spider)
|
||||
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 = 270
|
||||
maxbodytemp = INFINITY
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
mob_size = MOB_SIZE_TINY
|
||||
response_help = "pokes"
|
||||
response_disarm = "shoos"
|
||||
response_harm = "splats"
|
||||
speak_emote = list("chitters")
|
||||
mouse_opacity = 2
|
||||
density = TRUE
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
verb_say = "chitters"
|
||||
verb_ask = "chitters inquisitively"
|
||||
verb_exclaim = "chitters loudly"
|
||||
verb_yell = "chitters loudly"
|
||||
var/squish_chance = 50
|
||||
var/projectile_density = TRUE //griffons get shot
|
||||
del_on_death = TRUE
|
||||
|
||||
/mob/living/simple_animal/banana_spider/Initialize()
|
||||
. = ..()
|
||||
var/area/A = get_area(src)
|
||||
if(A)
|
||||
notify_ghosts("A banana spider has been created in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE)
|
||||
|
||||
/mob/living/simple_animal/banana_spider/attack_ghost(mob/user)
|
||||
if(key) //please stop using src. without a good reason.
|
||||
return
|
||||
if(CONFIG_GET(flag/use_age_restriction_for_jobs))
|
||||
if(!isnum(user.client.player_age))
|
||||
return
|
||||
if(!SSticker.mode)
|
||||
to_chat(user, "Can't become a banana spider before the game has started.")
|
||||
return
|
||||
var/be_spider = alert("Become a banana spider? (Warning, You can no longer be cloned!)",,"Yes","No")
|
||||
if(be_spider == "No" || QDELETED(src) || !isobserver(user))
|
||||
return
|
||||
sentience_act()
|
||||
user.transfer_ckey(src, FALSE)
|
||||
density = TRUE
|
||||
|
||||
/mob/living/simple_animal/banana_spider/ComponentInitialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/slippery, 40)
|
||||
|
||||
/mob/living/simple_animal/banana_spider/Crossed(atom/movable/AM) //no /var in proc headers
|
||||
. = ..()
|
||||
if(istype(AM, /obj/item/projectile) && projectile_density) //forced projectile density
|
||||
var/obj/item/projectile/P = AM
|
||||
P.Bump(src)
|
||||
if(ismob(AM))
|
||||
if(isliving(AM))
|
||||
var/mob/living/A = AM
|
||||
if(A.mob_size > MOB_SIZE_SMALL && !(A.movement_type & FLYING))
|
||||
if(prob(squish_chance))
|
||||
A.visible_message("<span class='notice'>[A] squashed [src].</span>", "<span class='notice'>You squashed [src] under your weight as you fell.</span>")
|
||||
adjustBruteLoss(1)
|
||||
else
|
||||
visible_message("<span class='notice'>[src] avoids getting crushed.</span>")
|
||||
else
|
||||
if(isstructure(AM))
|
||||
if(prob(squish_chance))
|
||||
AM.visible_message("<span class='notice'>[src] was crushed under [AM]'s weight as they fell.</span>")
|
||||
adjustBruteLoss(1)
|
||||
else
|
||||
visible_message("<span class='notice'>[src] avoids getting crushed.</span>")
|
||||
|
||||
/mob/living/simple_animal/banana_spider/ex_act()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/banana_spider/start_pulling()
|
||||
return FALSE //No.
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/deadbanana_spider
|
||||
name = "dead banana spider"
|
||||
desc = "Thank god it's gone...but it does look slippery."
|
||||
icon = 'modular_citadel/icons/mob/BananaSpider.dmi'
|
||||
icon_state = "banana_peel"
|
||||
bitesize = 3
|
||||
eatverb = "devours"
|
||||
list_reagents = list("nutriment" = 3, "vitamin" = 2)
|
||||
foodtype = GROSS | MEAT | RAW
|
||||
grind_results = list("blood" = 20, "liquidgibs" = 5)
|
||||
juice_results = list("banana" = 0)
|
||||
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/deadbanana_spider/Initialize()
|
||||
. = ..()
|
||||
AddComponent(/datum/component/slippery, 20)
|
||||
@@ -1,134 +0,0 @@
|
||||
/mob/living/simple_animal/kiwi
|
||||
name = "space kiwi"
|
||||
desc = "Exposure to low gravity made them grow larger."
|
||||
gender = FEMALE
|
||||
icon = 'modular_citadel/icons/mob/kiwi.dmi'
|
||||
icon_state = "kiwi"
|
||||
icon_living = "kiwi"
|
||||
icon_dead = "dead"
|
||||
speak = list("Chirp!","Cheep cheep chirp!!","Cheep.")
|
||||
speak_emote = list("chirps","trills")
|
||||
emote_hear = list("chirps.")
|
||||
emote_see = list("pecks at the ground.","jumps in place.")
|
||||
density = FALSE
|
||||
speak_chance = 2
|
||||
turns_per_move = 3
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3)
|
||||
var/egg_type = /obj/item/reagent_containers/food/snacks/egg/kiwiEgg
|
||||
var/food_type = /obj/item/reagent_containers/food/snacks/grown/wheat
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
attacktext = "kicks"
|
||||
health = 25
|
||||
maxHealth = 25
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
var/eggsleft = 0
|
||||
var/eggsFertile = TRUE
|
||||
pass_flags = PASSTABLE | PASSMOB
|
||||
mob_size = MOB_SIZE_SMALL
|
||||
var/list/feedMessages = list("It chirps happily.","It chirps happily.")
|
||||
var/list/layMessage = list("lays an egg.","squats down and croons.","begins making a huge racket.","begins chirping raucously.")
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
var/static/kiwi_count = 0
|
||||
|
||||
/mob/living/simple_animal/kiwi/Destroy()
|
||||
--kiwi_count
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/kiwi/Initialize()
|
||||
. = ..()
|
||||
++kiwi_count
|
||||
|
||||
|
||||
/mob/living/simple_animal/kiwi/Life()
|
||||
. =..()
|
||||
if(!.)
|
||||
return
|
||||
if((!stat && prob(3) && eggsleft > 0) && egg_type)
|
||||
visible_message("[src] [pick(layMessage)]")
|
||||
eggsleft--
|
||||
var/obj/item/E = new egg_type(get_turf(src))
|
||||
E.pixel_x = rand(-6,6)
|
||||
E.pixel_y = rand(-6,6)
|
||||
if(eggsFertile)
|
||||
if(kiwi_count < MAX_CHICKENS && prob(25))
|
||||
START_PROCESSING(SSobj, E)
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/egg/kiwiEgg/process()
|
||||
if(isturf(loc))
|
||||
amount_grown += rand(1,2)
|
||||
if(amount_grown >= 100)
|
||||
visible_message("[src] hatches with a quiet cracking sound.")
|
||||
new /mob/living/simple_animal/babyKiwi(get_turf(src))
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
qdel(src)
|
||||
else
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
|
||||
|
||||
/mob/living/simple_animal/kiwi/attackby(obj/item/O, mob/user, params)
|
||||
if(istype(O, food_type)) //feedin' dem kiwis
|
||||
if(!stat && eggsleft < 8)
|
||||
var/feedmsg = "[user] feeds [O] to [name]! [pick(feedMessages)]"
|
||||
user.visible_message(feedmsg)
|
||||
qdel(O)
|
||||
eggsleft += rand(1, 4)
|
||||
else
|
||||
to_chat(user, "<span class='warning'>[name] doesn't seem hungry!</span>")
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/mob/living/simple_animal/babyKiwi
|
||||
name = "baby space kiwi"
|
||||
desc = "So huggable."
|
||||
icon = 'modular_citadel/icons/mob/kiwi.dmi'
|
||||
icon_state = "babyKiwi"
|
||||
icon_living = "babyKiwi"
|
||||
icon_dead = "deadBaby"
|
||||
icon_gib = "chick_gib"
|
||||
gender = FEMALE
|
||||
speak = list("Cherp.","Cherp?","Chirrup.","Cheep!")
|
||||
speak_emote = list("chirps")
|
||||
emote_hear = list("chirps.")
|
||||
emote_see = list("pecks at the ground.","Happily bounces in place.")
|
||||
density = FALSE
|
||||
speak_chance = 2
|
||||
turns_per_move = 2
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 2)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
attacktext = "kicks"
|
||||
health = 10
|
||||
maxHealth = 10
|
||||
ventcrawler = VENTCRAWLER_ALWAYS
|
||||
var/amount_grown = 0
|
||||
pass_flags = PASSTABLE | PASSGRILLE | PASSMOB
|
||||
mob_size = MOB_SIZE_TINY
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
|
||||
/mob/living/simple_animal/babyKiwi/Initialize()
|
||||
. = ..()
|
||||
pixel_x = rand(-6, 6)
|
||||
pixel_y = rand(0, 10)
|
||||
|
||||
/mob/living/simple_animal/babyKiwi/Life()
|
||||
. =..()
|
||||
if(!.)
|
||||
return
|
||||
if(!stat && !ckey)
|
||||
amount_grown += rand(1,2)
|
||||
if(amount_grown >= 100)
|
||||
new /mob/living/simple_animal/kiwi(src.loc)
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/item/reagent_containers/food/snacks/egg/kiwiEgg
|
||||
name = "kiwi egg"
|
||||
icon = 'modular_citadel/icons/mob/kiwi.dmi'
|
||||
desc = "A slightly bigger egg!"
|
||||
icon_state = "egg"
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
//CARBON MOBS
|
||||
/mob/living/carbon/alien
|
||||
devourable = TRUE
|
||||
digestable = TRUE
|
||||
feeding = TRUE
|
||||
|
||||
/mob/living/carbon/monkey
|
||||
devourable = TRUE
|
||||
digestable = TRUE
|
||||
feeding = TRUE
|
||||
|
||||
|
||||
/*
|
||||
REFER TO code/modules/mob/living/simple_animal/simple_animal_vr.dm for Var information!
|
||||
*/
|
||||
|
||||
|
||||
//NUETRAL MOBS
|
||||
/mob/living/simple_animal/crab
|
||||
devourable = TRUE
|
||||
digestable = TRUE
|
||||
feeding = TRUE
|
||||
|
||||
/mob/living/simple_animal/cow
|
||||
devourable = TRUE
|
||||
digestable = TRUE
|
||||
feeding = TRUE
|
||||
vore_active = TRUE
|
||||
isPredator = TRUE
|
||||
vore_default_mode = DM_HOLD
|
||||
|
||||
/mob/living/simple_animal/chick
|
||||
devourable = TRUE
|
||||
digestable = TRUE
|
||||
|
||||
/mob/living/simple_animal/chicken
|
||||
devourable = TRUE
|
||||
digestable = TRUE
|
||||
|
||||
/mob/living/simple_animal/mouse
|
||||
devourable = TRUE
|
||||
digestable = TRUE
|
||||
|
||||
/mob/living/simple_animal/kiwi
|
||||
devourable = TRUE
|
||||
digestable = TRUE
|
||||
|
||||
//STATION PETS
|
||||
/mob/living/simple_animal/pet
|
||||
devourable = TRUE
|
||||
digestable = TRUE
|
||||
feeding = TRUE
|
||||
|
||||
/mob/living/simple_animal/pet/fox
|
||||
vore_active = TRUE
|
||||
isPredator = TRUE
|
||||
vore_default_mode = DM_HOLD
|
||||
|
||||
/mob/living/simple_animal/pet/cat
|
||||
vore_active = TRUE
|
||||
isPredator = TRUE
|
||||
vore_default_mode = DM_HOLD
|
||||
|
||||
/mob/living/simple_animal/pet/dog
|
||||
vore_active = TRUE
|
||||
isPredator = TRUE
|
||||
vore_default_mode = DM_HOLD
|
||||
|
||||
/mob/living/simple_animal/sloth
|
||||
devourable = TRUE
|
||||
digestable = TRUE
|
||||
|
||||
/mob/living/simple_animal/parrot
|
||||
devourable = TRUE
|
||||
digestable = TRUE
|
||||
|
||||
//HOSTILE MOBS
|
||||
/mob/living/simple_animal/hostile/retaliate/goat
|
||||
devourable = TRUE
|
||||
digestable = TRUE
|
||||
feeding = TRUE
|
||||
vore_active = TRUE
|
||||
isPredator = TRUE
|
||||
vore_stomach_flavor = "You find yourself squeezed into the hollow of the goat, the smell of oats and hay thick in the tight space, all of which grinds in on you. Harmless for now..."
|
||||
vore_default_mode = DM_HOLD
|
||||
|
||||
/mob/living/simple_animal/hostile/lizard
|
||||
devourable = TRUE
|
||||
digestable = TRUE
|
||||
feeding = TRUE
|
||||
vore_active = TRUE
|
||||
isPredator = TRUE
|
||||
vore_default_mode = DM_DIGEST
|
||||
|
||||
/mob/living/simple_animal/hostile/alien
|
||||
feeding = TRUE
|
||||
vore_active = TRUE
|
||||
isPredator = TRUE
|
||||
vore_default_mode = DM_DIGEST
|
||||
|
||||
/mob/living/simple_animal/hostile/bear
|
||||
feeding = TRUE
|
||||
vore_active = TRUE
|
||||
isPredator = TRUE
|
||||
vore_default_mode = DM_DIGEST
|
||||
|
||||
/mob/living/simple_animal/hostile/poison/giant_spider
|
||||
feeding = TRUE
|
||||
vore_active = TRUE
|
||||
isPredator = TRUE
|
||||
vore_default_mode = DM_DIGEST
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/poison/snake
|
||||
feeding = TRUE
|
||||
vore_active = TRUE
|
||||
isPredator = TRUE
|
||||
vore_default_mode = DM_DIGEST
|
||||
|
||||
/mob/living/simple_animal/hostile/gorilla
|
||||
feeding = TRUE
|
||||
vore_active = TRUE
|
||||
isPredator = TRUE
|
||||
vore_default_mode = DM_DIGEST
|
||||
|
||||
/mob/living/simple_animal/hostile/asteroid/goliath
|
||||
feeding = TRUE //for pet Goliaths I guess or something.
|
||||
vore_active = TRUE
|
||||
isPredator = TRUE
|
||||
vore_default_mode = DM_DIGEST
|
||||
|
||||
/mob/living/simple_animal/hostile/carp
|
||||
feeding = TRUE
|
||||
vore_active = TRUE
|
||||
isPredator = TRUE
|
||||
vore_default_mode = DM_DIGEST
|
||||
@@ -3,9 +3,11 @@
|
||||
|
||||
/mob/say_mod(input, message_mode)
|
||||
var/customsayverb = findtext(input, "*")
|
||||
if(customsayverb)
|
||||
if(customsayverb && message_mode != MODE_WHISPER_CRIT)
|
||||
message_mode = MODE_CUSTOM_SAY
|
||||
return lowertext(copytext(input, 1, customsayverb))
|
||||
. = ..()
|
||||
else
|
||||
return ..()
|
||||
|
||||
/atom/movable/proc/attach_spans(input, list/spans)
|
||||
var/customsayverb = findtext(input, "*")
|
||||
|
||||
Reference in New Issue
Block a user