Merge branch 'master' into upstream-merge-11935

This commit is contained in:
Razgriz
2021-12-10 01:48:12 -07:00
committed by GitHub
211 changed files with 33407 additions and 3438 deletions

View File

@@ -292,7 +292,10 @@ var/mobs_radio_range_fired = 1 //CHOMPEdit
var/turf/U = GetBelow(O)
while(istype(U))
hearturfs |= U
if(isopenspace(U))
U = GetBelow(U)
else
U = null
// Above us
var/above_range = range

View File

@@ -231,6 +231,7 @@ var/global/list/edible_trash = list(/obj/item/broken_device,
/obj/item/weapon/storage/wallet,
/obj/item/weapon/storage/vore_egg,
/obj/item/weapon/bikehorn/tinytether,
/obj/item/capture_crystal,
/obj/item/weapon/material/kitchen, //chompstation addition start
/obj/item/weapon/storage/mre,
/obj/item/weapon/storage/mrebag,

View File

@@ -1 +1,2 @@
#define isbelly(A) istype(A, /obj/belly)
#define iscapturecrystal(A) istype(A, /obj/item/capture_crystal)

View File

@@ -32,10 +32,11 @@ SUBSYSTEM_DEF(ai)
while(currentrun.len)
var/datum/ai_holder/A = currentrun[currentrun.len]
--currentrun.len
if(!A || QDELETED(A) || !A.holder?.loc || A.busy) // Doesn't exist or won't exist soon or not doing it this tick
var/mob/living/L = A.holder //VOREStation Edit Start
if(!A || QDELETED(A) || !L?.loc || A.busy) // Doesn't exist or won't exist soon or not doing it this tick
continue
if(process_z[get_z(A.holder)])
if(process_z[get_z(L)] || !L.low_priority) //VOREStation Edit End
A.handle_strategicals()
else
slept_mobs++

View File

@@ -76,7 +76,9 @@ SUBSYSTEM_DEF(mapping)
// VOREStation Edit Start: Enable This
/datum/controller/subsystem/mapping/proc/loadLateMaps()
var/list/deffo_load = using_map.lateload_z_levels
var/list/maybe_load = using_map.lateload_single_pick
var/list/maybe_load = using_map.lateload_gateway
var/list/also_load = using_map.lateload_overmap
for(var/list/maplist in deffo_load)
if(!islist(maplist))
@@ -111,6 +113,28 @@ SUBSYSTEM_DEF(mapping)
else
MT.load_new_z(centered = FALSE)
if(LAZYLEN(also_load)) //Just copied from gateway picking, this is so we can have a kind of OM map version of the same concept.
var/picklist = pick(also_load)
if(!picklist) //No lateload maps at all
return
if(!islist(picklist)) //So you can have a 'chain' of z-levels that make up one away mission
error("Randompick Z level [picklist] is not a list! Must be in a list!")
return
for(var/map in picklist)
if(islist(map))
// TRIPLE NEST. In this situation we pick one at random from the choices in the list.
//This allows a sort of a1,a2,a3,b1,b2,b3,c1,c2,c3 setup where it picks one 'a', one 'b', one 'c'
map = pick(map)
var/datum/map_template/MT = map_templates[map]
if(!istype(MT))
error("Randompick Z level \"[map]\" is not a valid map!")
else
MT.load_new_z(centered = FALSE)
/datum/controller/subsystem/mapping/proc/preloadShelterTemplates()
for(var/datum/map_template/shelter/shelter_type as anything in subtypesof(/datum/map_template/shelter))
if(!(initial(shelter_type.mappath)))

View File

@@ -36,10 +36,6 @@ SUBSYSTEM_DEF(persistence)
if(!A || (A.flags & AREA_FLAG_IS_NOT_PERSISTENT))
return
// if((!T.z in GLOB.using_map.station_levels) || !initialized)
if(!(T.z in using_map.station_levels))
return
if(!(T.z in using_map.persist_levels))
return

View File

@@ -100,8 +100,8 @@
)
cost = 250
containertype = /obj/structure/closet/crate/secure/gear
containername = "Solgov medical hardsuit crate"
access = access_medical
containername = "Solgov engineering hardsuit crate"
access = access_engine
// CHOMPStation EDIT End

View File

@@ -91,6 +91,8 @@
for(var/obj/item/stack/T as anything in instances)
if(count <= 0)
break
if(T.get_amount() <= count)
instances -=T
count -= T.transfer_to(S, count)
S.forceMove(product_location)

View File

@@ -34,6 +34,7 @@
"Eyes" = list(/obj/item/organ/internal/eyes, 20),
"Liver" = list(/obj/item/organ/internal/liver, 20),
"Spleen" = list(/obj/item/organ/internal/spleen, 20),
"Stomach" = list(/obj/item/organ/internal/stomach, 20),
"Arm, Left" = list(/obj/item/organ/external/arm, 40),
"Arm, Right" = list(/obj/item/organ/external/arm/right, 40),
"Leg, Left" = list(/obj/item/organ/external/leg, 40),

View File

@@ -1083,7 +1083,7 @@
/obj/machinery/computer/arcade/clawmachine
name = "AlliCo Grab-a-Gift"
desc = "Show off your arcade skills for that special someone!"
icon_state = "clawmachine"
icon_state = "clawmachine_new"
icon_keyboard = null
icon_screen = null
circuit = /obj/item/weapon/circuitboard/arcade/clawmachine
@@ -1244,10 +1244,10 @@
/// TGUI Stuff
/obj/machinery/computer/arcade/clawmachine/tgui_interact(mob/user, datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/tgui_state/state = GLOB.tgui_default_state)
ui = SStgui.try_update_ui(user, src, ui, force_open)
/obj/machinery/computer/arcade/clawmachine/tgui_interact(mob/user, datum/tgui/ui)
ui = SStgui.try_update_ui(user, src, ui)
if(!ui)
ui = new(user, src, "ClawMachine", name, 300, 400, master_ui, state)
ui = new(user, src, "ClawMachine", name, ui_x = 300, ui_y = 400)
ui.autoupdate = TRUE
ui.open()
@@ -1270,7 +1270,7 @@
if(action == "newgame" && gamepaid == 1)
gameStatus = "CLAWMACHINE_ON"
icon_state = "clawmachine_move"
icon_state = "clawmachine_new_move"
instructions = "Guide the claw to the prize you want!"
wintick = 0
@@ -1307,7 +1307,7 @@
winscreen = "Aw, shucks. Try again!"
wintick = 0
gamepaid = 0
icon_state = "clawmachine"
icon_state = "clawmachine_new"
gameStatus = "CLAWMACHINE_END"
/obj/machinery/computer/arcade/clawmachine/emag_act(mob/user)

View File

@@ -4,6 +4,7 @@
icon = 'icons/obj/stock_parts.dmi'
icon_state = "frame_bitem"
var/build_machine_type
var/build_wall_only = FALSE
var/refund_amt = 5
var/refund_type = /obj/item/stack/material/steel
var/reverse = 0 //if resulting object faces opposite its dir (like light fixtures)
@@ -27,7 +28,7 @@
..()
update_type_list()
var/datum/frame/frame_types/frame_type
if(!build_machine_type)
if(!build_machine_type && !build_wall_only)
var/datum/frame/frame_types/response = tgui_input_list(user, "What kind of frame would you like to make?", "Frame type request", frame_types_floor)
if(!response)
return

View File

@@ -51,11 +51,16 @@ var/global/list/semirandom_mob_spawner_decisions = list()
list(/mob/living/simple_mob/animal/passive/opossum),
list(/mob/living/simple_mob/animal/passive/pillbug),
list(/mob/living/simple_mob/animal/passive/snake),
list(/mob/living/simple_mob/animal/passive/snake/red),
list(/mob/living/simple_mob/animal/passive/snake/python),
list(/mob/living/simple_mob/animal/passive/tindalos),
list(/mob/living/simple_mob/animal/passive/yithian),
list(
/mob/living/simple_mob/animal/wolf = 10,
/mob/living/simple_mob/animal/wolf/direwolf = 1
/mob/living/simple_mob/animal/wolf/direwolf = 5,
/mob/living/simple_mob/vore/greatwolf = 1,
/mob/living/simple_mob/vore/greatwolf/black = 1,
/mob/living/simple_mob/vore/greatwolf/grey = 1
),
list(/mob/living/simple_mob/vore/rabbit),
list(/mob/living/simple_mob/vore/redpanda),
@@ -109,12 +114,8 @@ var/global/list/semirandom_mob_spawner_decisions = list()
/mob/living/simple_mob/animal/giant_spider/phorogenic = 10,
/mob/living/simple_mob/animal/giant_spider/thermic = 5,
/mob/living/simple_mob/animal/giant_spider/tunneler = 10,
/mob/living/simple_mob/animal/giant_spider/webslinger = 5
),
list(
/mob/living/simple_mob/animal/wolf = 10,
/mob/living/simple_mob/animal/wolf/direwolf = 1
),
/mob/living/simple_mob/animal/giant_spider/webslinger = 5,
/mob/living/simple_mob/animal/giant_spider/broodmother = 1),
list(/mob/living/simple_mob/creature/strong),
list(/mob/living/simple_mob/faithless/strong),
list(/mob/living/simple_mob/animal/goat),
@@ -244,7 +245,6 @@ var/global/list/semirandom_mob_spawner_decisions = list()
list(/mob/living/simple_mob/mechanical/wahlem),
list(/mob/living/simple_mob/animal/passive/fox/syndicate),
list(/mob/living/simple_mob/animal/passive/fox),
list(/mob/living/simple_mob/animal/wolf/direwolf),
list(/mob/living/simple_mob/animal/space/jelly),
list(
/mob/living/simple_mob/otie/feral,
@@ -253,12 +253,12 @@ var/global/list/semirandom_mob_spawner_decisions = list()
/mob/living/simple_mob/otie/red/chubby
),
list(
/mob/living/simple_mob/shadekin/blue/ai = 100,
/mob/living/simple_mob/shadekin/green/ai = 50,
/mob/living/simple_mob/shadekin/orange/ai = 20,
/mob/living/simple_mob/shadekin/purple/ai = 60,
/mob/living/simple_mob/shadekin/red/ai = 40,
/mob/living/simple_mob/shadekin/yellow/ai = 1
/mob/living/simple_mob/shadekin/blue = 100,
/mob/living/simple_mob/shadekin/green = 50,
/mob/living/simple_mob/shadekin/orange = 20,
/mob/living/simple_mob/shadekin/purple = 60,
/mob/living/simple_mob/shadekin/red = 40,
/mob/living/simple_mob/shadekin/yellow = 1
),
list(
/mob/living/simple_mob/vore/aggressive/corrupthound,
@@ -292,7 +292,21 @@ var/global/list/semirandom_mob_spawner_decisions = list()
),
list(/mob/living/simple_mob/vore/solargrub),
list(/mob/living/simple_mob/vore/woof),
list(/mob/living/simple_mob/vore/alienanimals/teppi)
list(/mob/living/simple_mob/vore/alienanimals/teppi),
list(/mob/living/simple_mob/vore/alienanimals/space_ghost),
list(/mob/living/simple_mob/vore/alienanimals/catslug),
list(/mob/living/simple_mob/vore/alienanimals/space_jellyfish),
list(/mob/living/simple_mob/vore/alienanimals/startreader),
list(
/mob/living/simple_mob/vore/bigdragon,
/mob/living/simple_mob/vore/bigdragon/friendly),
list(
/mob/living/simple_mob/vore/leopardmander = 50,
/mob/living/simple_mob/vore/leopardmander/blue = 10,
/mob/living/simple_mob/vore/leopardmander/exotic = 1
),
list(/mob/living/simple_mob/vore/sheep),
list(/mob/living/simple_mob/vore/weretiger)
)
/obj/random/mob/semirandom_mob_spawner/item_to_spawn()
@@ -359,11 +373,16 @@ var/global/list/semirandom_mob_spawner_decisions = list()
list(/mob/living/simple_mob/animal/passive/opossum) = 10,
list(/mob/living/simple_mob/animal/passive/pillbug) = 10,
list(/mob/living/simple_mob/animal/passive/snake) = 10,
list(/mob/living/simple_mob/animal/passive/snake/red) = 10,
list(/mob/living/simple_mob/animal/passive/snake/python) = 10,
list(/mob/living/simple_mob/animal/passive/tindalos) = 10,
list(/mob/living/simple_mob/animal/passive/yithian) = 10,
list(
/mob/living/simple_mob/animal/wolf = 10,
/mob/living/simple_mob/animal/wolf/direwolf = 1
/mob/living/simple_mob/animal/wolf/direwolf = 5,
/mob/living/simple_mob/vore/greatwolf = 1,
/mob/living/simple_mob/vore/greatwolf/black = 1,
/mob/living/simple_mob/vore/greatwolf/grey = 1
) = 10,
list(/mob/living/simple_mob/vore/rabbit) = 10,
list(/mob/living/simple_mob/vore/redpanda) = 10,
@@ -407,7 +426,18 @@ var/global/list/semirandom_mob_spawner_decisions = list()
) = 5,
list(/mob/living/simple_mob/animal/sif/siffet) = 5,
list(/mob/living/simple_mob/animal/sif/tymisian) = 5,
list(/mob/living/simple_mob/vore/alienanimals/teppi) = 10
list(/mob/living/simple_mob/vore/alienanimals/teppi) = 10,
list(/mob/living/simple_mob/vore/alienanimals/dustjumper) = 5,
list(/mob/living/simple_mob/vore/alienanimals/space_jellyfish) = 5,
list(/mob/living/simple_mob/vore/alienanimals/space_ghost) = 5,
list(
/mob/living/simple_mob/vore/leopardmander = 50,
/mob/living/simple_mob/vore/leopardmander/blue = 10,
/mob/living/simple_mob/vore/leopardmander/exotic = 1
) = 5,
list(/mob/living/simple_mob/vore/sheep) = 5,
list(/mob/living/simple_mob/vore/weretiger) = 5,
list(/mob/living/simple_mob/vore/alienanimals/skeleton) = 5
)
/obj/random/mob/semirandom_mob_spawner/monster
@@ -433,14 +463,17 @@ var/global/list/semirandom_mob_spawner_decisions = list()
/mob/living/simple_mob/animal/giant_spider/webslinger = 5
) = 100,
list(
/mob/living/simple_mob/shadekin/red/ai = 5,
/mob/living/simple_mob/shadekin/orange/ai = 1,
/mob/living/simple_mob/shadekin/purple/ai = 10
/mob/living/simple_mob/shadekin/red = 5,
/mob/living/simple_mob/shadekin/orange = 1,
/mob/living/simple_mob/shadekin/purple = 10
) = 1,
list(
/mob/living/simple_mob/animal/wolf = 10,
/mob/living/simple_mob/animal/wolf/direwolf = 1,
) = 80,
/mob/living/simple_mob/animal/wolf/direwolf = 5,
/mob/living/simple_mob/vore/greatwolf = 1,
/mob/living/simple_mob/vore/greatwolf/black = 1,
/mob/living/simple_mob/vore/greatwolf/grey = 1
) = 40,
list(/mob/living/simple_mob/creature/strong) = 40,
list(/mob/living/simple_mob/faithless/strong) = 20,
list(/mob/living/simple_mob/animal/goat) = 1,
@@ -501,7 +534,18 @@ var/global/list/semirandom_mob_spawner_decisions = list()
/mob/living/simple_mob/vore/oregrub = 5,
/mob/living/simple_mob/vore/oregrub/lava = 1
) = 15,
list(/mob/living/simple_mob/vore/alienanimals/teppi) = 15
list(/mob/living/simple_mob/vore/alienanimals/teppi) = 15,
list(/mob/living/simple_mob/vore/alienanimals/space_jellyfish) = 5,
list(/mob/living/simple_mob/vore/alienanimals/space_ghost) = 5,
list(
/mob/living/simple_mob/vore/leopardmander = 50,
/mob/living/simple_mob/vore/leopardmander/blue = 10,
/mob/living/simple_mob/vore/leopardmander/exotic = 1
) = 5,
list(/mob/living/simple_mob/vore/sheep) = 5,
list(/mob/living/simple_mob/vore/weretiger) = 5,
list(/mob/living/simple_mob/vore/alienanimals/skeleton) = 5,
list(/mob/living/simple_mob/vore/alienanimals/catslug) = 5
)
/obj/random/mob/semirandom_mob_spawner/humanoid
@@ -512,9 +556,9 @@ var/global/list/semirandom_mob_spawner_decisions = list()
possible_mob_types = list(
list(
/mob/living/simple_mob/shadekin/blue/ai = 25,
/mob/living/simple_mob/shadekin/green/ai = 10,
/mob/living/simple_mob/shadekin/purple/ai = 1,
/mob/living/simple_mob/shadekin/blue = 25,
/mob/living/simple_mob/shadekin/green = 10,
/mob/living/simple_mob/shadekin/purple = 1,
) = 1,
list(/mob/living/simple_mob/vore/catgirl) = 100,
list(/mob/living/simple_mob/vore/wolfgirl) = 100,
@@ -675,7 +719,12 @@ var/global/list/semirandom_mob_spawner_decisions = list()
mob_faction = "vore"
possible_mob_types = list(
list(/mob/living/simple_mob/animal/wolf/direwolf) = 100,
list(
/mob/living/simple_mob/animal/wolf/direwolf = 5,
/mob/living/simple_mob/vore/greatwolf = 1,
/mob/living/simple_mob/vore/greatwolf/black = 1,
/mob/living/simple_mob/vore/greatwolf/grey = 1
) = 100,
list(/mob/living/simple_mob/animal/space/jelly) = 70,
list(
/mob/living/simple_mob/otie/feral,
@@ -684,12 +733,12 @@ var/global/list/semirandom_mob_spawner_decisions = list()
/mob/living/simple_mob/otie/red/chubby
) = 50,
list(
/mob/living/simple_mob/shadekin/blue/ai = 100,
/mob/living/simple_mob/shadekin/green/ai = 50,
/mob/living/simple_mob/shadekin/orange/ai = 20,
/mob/living/simple_mob/shadekin/purple/ai = 60,
/mob/living/simple_mob/shadekin/red/ai = 40,
/mob/living/simple_mob/shadekin/yellow/ai = 1
/mob/living/simple_mob/shadekin/blue = 100,
/mob/living/simple_mob/shadekin/green = 50,
/mob/living/simple_mob/shadekin/orange = 20,
/mob/living/simple_mob/shadekin/purple = 60,
/mob/living/simple_mob/shadekin/red = 40,
/mob/living/simple_mob/shadekin/yellow = 1
) = 1,
list(
/mob/living/simple_mob/vore/aggressive/corrupthound,

View File

@@ -6,6 +6,7 @@
icon = 'icons/obj/apc_repair.dmi'
icon_state = "apc_frame"
refund_amt = 2
build_wall_only = TRUE
matter = list(MAT_STEEL = 100, MAT_GLASS = 30)
/obj/item/frame/apc/try_build(turf/on_wall, mob/user as mob)

View File

@@ -95,6 +95,10 @@
to_chat(D, "<span class='notice'>Sorry, someone else has already inhabited [src].</span>")
return FALSE
if(capture_caught && !D.client.prefs.capture_crystal)
to_chat(D, "<span class='notice'>Sorry, [src] is participating in capture mechanics, and your preferences do not allow for that.</span>")
return FALSE
// Insert whatever ban checks you want here if we ever add simplemob bans
return TRUE

View File

@@ -409,7 +409,7 @@ GLOBAL_LIST_BOILERPLATE(premade_tele_beacons, /obj/item/device/perfect_tele_beac
if(confirm == "Eat it!")
var/obj/belly/bellychoice = tgui_input_list(usr, "Which belly?","Select A Belly", L.vore_organs)
if(bellychoice)
user.visible_message("<span class='warning'>[user] is trying to stuff \the [src] into [user.gender == MALE ? "his" : user.gender == FEMALE ? "her" : "their"] [bellychoice]!</span>","<span class='notice'>You begin putting \the [src] into your [bellychoice]!</span>")
user.visible_message("<span class='warning'>[user] is trying to stuff \the [src] into [user.gender == MALE ? "his" : user.gender == FEMALE ? "her" : "their"] [bellychoice.name]!</span>","<span class='notice'>You begin putting \the [src] into your [bellychoice.name]!</span>")
if(do_after(user,5 SECONDS,src))
user.unEquip(src)
forceMove(bellychoice)

View File

@@ -0,0 +1,752 @@
/obj/item/capture_crystal
name = "Curious Crystal"
desc = "A silent, unassuming crystal in what appears to be some kind of steel housing."
icon = 'icons/obj/capture_crystal_vr.dmi'
icon_state = "inactive"
drop_sound = 'sound/items/drop/ring.ogg'
pickup_sound = 'sound/items/pickup/ring.ogg'
throwforce = 0
force = 0
action_button_name = "Command"
var/active = FALSE //Is it set up?
var/mob/living/owner //Reference to the owner
var/mob/living/bound_mob //Reference to our bound mob
var/spawn_mob_type //The kind of mob an inactive crystal will try to spawn when activated
var/activate_cooldown = 30 SECONDS //How long do we wait between unleashing and recalling
var/last_activate //Automatically set by things that try to move the bound mob or capture things
var/empty_icon = "empty"
var/full_icon = "full"
var/capture_chance_modifier = 1 //So we can have special subtypes with different capture rates!
/obj/item/capture_crystal/Initialize()
. = ..()
update_icon()
//Let's make sure we clean up our references and things if the crystal goes away (such as when it's digested)
/obj/item/capture_crystal/Destroy()
if(bound_mob)
if(bound_mob in contents)
unleash()
to_chat(bound_mob, "<span class='notice'>You feel like yourself again. You are no longer under the influince of \the [src]'s command.</span>")
UnregisterSignal(bound_mob, COMSIG_PARENT_QDELETING)
bound_mob.capture_caught = FALSE
bound_mob = null
if(owner)
UnregisterSignal(owner, COMSIG_PARENT_QDELETING)
owner = null
return ..()
/obj/item/capture_crystal/examine(user)
. = ..()
if(user == owner && bound_mob)
. += "<span class = 'notice'>[bound_mob]'s crystal</span>"
if(isanimal(bound_mob))
. += "<span class = 'notice'>[bound_mob.health / bound_mob.maxHealth * 100]%</span>"
if(bound_mob.ooc_notes)
. += "<span class = 'deptradio'>OOC Notes:</span> <a href='?src=\ref[bound_mob];ooc_notes=1'>\[View\]</a>"
. += "<span class='deptradio'><a href='?src=\ref[bound_mob];vore_prefs=1'>\[Mechanical Vore Preferences\]</a></span>"
//Command! This lets the owner toggle hostile on AI controlled mobs, or send a silent command message to your bound mob, wherever they may be.
/obj/item/capture_crystal/ui_action_click()
if(!ismob(loc))
return
var/mob/living/M = src.loc
if(M != owner)
to_chat(M, "<span class='notice'>\The [src] emits an unpleasant tone... It does not respond to your command.</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
else if(!bound_mob)
to_chat(M, "<span class='notice'>\The [src] emits an unpleasant tone... There is nothing to command.</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
else if(isanimal(bound_mob) && !bound_mob.client)
if(!isnull(bound_mob.get_AI_stance()))
var/datum/ai_holder/AI = bound_mob.ai_holder
AI.hostile = !AI.hostile
if(!AI.hostile)
AI.set_stance(STANCE_IDLE)
to_chat(M, span("notice", "\The [bound_mob] is now [AI.hostile ? "hostile" : "passive"]."))
else if(bound_mob.client)
var/transmit_msg
transmit_msg = sanitizeSafe(input(usr, "What is your command?", "Command", null) as text, MAX_NAME_LEN)
if(isnull(transmit_msg))
to_chat(M, "<span class='notice'>You decided against it.</span>")
return
to_chat(bound_mob, "<span class='notice'>\The [owner] commands, '[transmit_msg]'</span>")
to_chat(M, "<span class='notice'>Your command has been transmitted, '[transmit_msg]'</span>")
else
to_chat(M, "<span class='notice'>\The [src] emits an unpleasant tone... \The [bound_mob] is unresponsive.</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
//Lets the owner get AI controlled bound mobs to follow them, or tells player controlled mobs to follow them.
/obj/item/capture_crystal/verb/follow_owner()
set name = "Toggle Follow"
set category = "Object"
set src in usr
if(!ismob(loc))
return
var/mob/living/M = src.loc
if(M != owner)
to_chat(M, "<span class='notice'>\The [src] emits an unpleasant tone... It does not respond to your command.</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
else if(bound_mob.stat != CONSCIOUS)
to_chat(M, "<span class='notice'>\The [src] emits an unpleasant tone... \The [bound_mob] is not able to hear your command.</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
else if(bound_mob.client)
to_chat(bound_mob, "<span class='notice'>\The [owner] wishes for you to follow them.</span>")
else if(bound_mob in contents)
var/datum/ai_holder/AI = bound_mob.ai_holder
if(AI.leader)
to_chat(M, "<span class='notice'>\The [src] chimes~ \The [bound_mob] stopped following [AI.leader].</span>")
AI.lose_follow(AI.leader)
else
AI.set_follow(M)
to_chat(M, "<span class='notice'>\The [src] chimes~ \The [bound_mob] started following following [AI.leader].</span>")
else if(!(bound_mob in view(M)))
to_chat(M, "<span class='notice'>\The [src] emits an unpleasant tone... \The [bound_mob] is not able to hear your command.</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
var/datum/ai_holder/AI = bound_mob.ai_holder
if(AI.leader)
to_chat(M, "<span class='notice'>\The [src] chimes~ \The [bound_mob] stopped following [AI.leader].</span>")
AI.lose_follow(AI.leader)
else
AI.set_follow(M)
to_chat(M, "<span class='notice'>\The [src] chimes~ \The [bound_mob] started following following [AI.leader].</span>")
/obj/item/capture_crystal/update_icon()
. = ..()
if(spawn_mob_type)
icon_state = full_icon
else if(!bound_mob)
icon_state = "inactive"
else if(bound_mob in contents)
icon_state = full_icon
else
icon_state = empty_icon
if(!cooldown_check())
icon_state = "[icon_state]-busy"
spawn(activate_cooldown) //If it's busy then we want to wait a bit to fix the sprite after the cooldown is done.
update_icon()
/obj/item/capture_crystal/proc/cooldown_check()
if(world.time < last_activate + activate_cooldown)
return FALSE
else return TRUE
/obj/item/capture_crystal/attack(mob/living/M, mob/living/user)
if(bound_mob)
if(!bound_mob.devourable) //Don't eat if prefs are bad
return
if(user.zone_sel.selecting == "mouth") //Click while targetting the mouth and you eat/feed the stored mob to whoever you clicked on
if(bound_mob in contents)
user.visible_message("\The [user] moves \the [src] to [M]'s [M.vore_selected]...")
M.perform_the_nom(M, bound_mob, M, M.vore_selected)
else if(M == user) //You don't have a mob, you ponder the orb instead of trying to capture yourself
user.visible_message("\The [user] ponders \the [src]...", "You ponder \the [src]...")
else if (cooldown_check()) //Try to capture someone without throwing
user.visible_message("\The [user] taps \the [M] with \the [src].")
activate(user, M)
else
to_chat(user, "<span class='notice'>\The [src] emits an unpleasant tone... It is not ready yet.</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
//Tries to unleash or recall your stored mob
/obj/item/capture_crystal/attack_self(mob/living/user)
if(!cooldown_check())
to_chat(user, "<span class='notice'>\The [src] emits an unpleasant tone... It is not ready yet.</span>")
if(bound_mob)
playsound(src, 'sound/effects/capture-crystal-problem.ogg', 75, 1, -1)
else
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
else if(user == bound_mob) //You can't recall yourself
to_chat(user, "<span class='notice'>\The [src] emits an unpleasant tone... It does not activate for you.</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
else if(!active)
activate(user)
else
determine_action(user)
//Make it so the crystal knows if its mob references get deleted to make sure things get cleaned up
/obj/item/capture_crystal/proc/knowyoursignals(mob/living/M, mob/living/U)
RegisterSignal(M, COMSIG_PARENT_QDELETING, .proc/mob_was_deleted, TRUE)
RegisterSignal(U, COMSIG_PARENT_QDELETING, .proc/owner_was_deleted, TRUE)
//The basic capture command does most of the registration work.
/obj/item/capture_crystal/proc/capture(mob/living/M, mob/living/U)
if(!M.capture_crystal || M.capture_caught)
to_chat(U, "<span class='warning'>This creature is not suitable for capture.</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
return
knowyoursignals(M, U)
owner = U
if(!bound_mob)
bound_mob = M
bound_mob.capture_caught = TRUE
desc = "A glowing crystal in what appears to be some kind of steel housing."
//Determines the capture chance! So you can't capture AI mobs if they're perfectly healthy and all that
/obj/item/capture_crystal/proc/capture_chance(mob/living/M, user)
if(capture_chance_modifier >= 100) //Master crystal always work
return 100
var/capture_chance = ((1 - (M.health / M.maxHealth)) * 100) //Inverted health percent! 100% = 0%
//So I don't know how this works but here's a kind of explanation
//Basic chance + ((Mob's max health - minimum calculated health) / (Max allowed health - Min allowed health)*(Chance at Max allowed health - Chance at minimum allowed health)
capture_chance += 35 + ((M.maxHealth - 5)/ (1000-5)*(-100 - 35))
//Basically! Mobs over 1000 max health will be unable to be caught without using status effects.
//Thanks Aronai!
var/effect_count = 0 //This will give you a smol chance to capture if you have applied status effects, even if the chance would ordinarily be <0
if(M.stat == UNCONSCIOUS)
capture_chance += 0.1
effect_count += 1
else if(M.stat == CONSCIOUS)
capture_chance *= 0.9
else
capture_chance = 0
if(M.weakened) //Haha you fall down
capture_chance += 0.1
effect_count += 1
if(M.stunned) //What's the matter???
capture_chance += 0.1
effect_count += 1
if(M.on_fire) //AAAAAAAA
capture_chance += 0.1
effect_count += 1
if(M.paralysis) //Oh noooo
capture_chance += 0.1
effect_count += 1
if(M.ai_holder.stance == STANCE_IDLE) //SNEAK ATTACK???
capture_chance += 0.1
effect_count += 1
capture_chance *= capture_chance_modifier
if(capture_chance <= 0)
capture_chance = 0 + effect_count
if(capture_chance <= 0)
capture_chance = 0
to_chat(user, "<span class='notice'>There's no chance... It needs to be weaker.</span>")
last_activate = world.time
log_and_message_admins("I got [capture_chance].")
return capture_chance
//Handles checking relevent bans, preferences, and asking the player if they want to be caught
/obj/item/capture_crystal/proc/capture_player(mob/living/M, mob/living/U)
if(jobban_isbanned(M, "GhostRoles"))
to_chat(U, "<span class='warning'>This creature is not suitable for capture.</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
else if(!M.capture_crystal || M.capture_caught)
to_chat(U, "<span class='warning'>This creature is not suitable for capture.</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
else if(tgui_alert(M, "Would you like to be caught by in [src] by [U]? You will be bound to their will.", "Become Caught",list("No","Yes")) == "Yes")
if(tgui_alert(M, "Are you really sure? The only way to undo this is to OOC escape while you're in the crystal.", "Become Caught", list("No","Yes")) == "Yes")
log_admin("[key_name(M)] has agreed to become caught by [key_name(U)].")
capture(M, U)
recall(U)
//The clean up procs!
/obj/item/capture_crystal/proc/mob_was_deleted()
UnregisterSignal(bound_mob, COMSIG_PARENT_QDELETING)
UnregisterSignal(owner, COMSIG_PARENT_QDELETING)
bound_mob.capture_caught = FALSE
bound_mob = null
owner = null
active = FALSE
update_icon()
/obj/item/capture_crystal/proc/owner_was_deleted()
UnregisterSignal(owner, COMSIG_PARENT_QDELETING)
owner = null
active = FALSE
update_icon()
//If the crystal hasn't been set up, it does this
/obj/item/capture_crystal/proc/activate(mob/living/user, target)
if(!cooldown_check()) //Are we ready to do things yet?
to_chat(thrower, "<span class='notice'>\The [src] clicks unsatisfyingly... It is not ready yet.</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
else if(spawn_mob_type && !bound_mob) //We don't already have a mob, but we know what kind of mob we want
bound_mob = new spawn_mob_type(src) //Well let's spawn it then!
bound_mob.faction = user.faction
spawn_mob_type = null
capture(bound_mob, user)
else if(bound_mob) //We have a mob! Let's finish setting up.
user.visible_message("\The [src] clicks, and then emits a small chime.", "\The [src] grows warm in your hand, something inside is awake.")
active = TRUE
if(!owner) //Do we have an owner? It's pretty unlikely that this would ever happen! But it happens, let's claim the crystal.
owner = user
unleash(user, target)
else if(isliving(target)) //So we don't have a mob, let's try to claim one! Is the target a mob?
var/mob/living/M = target
last_activate = world.time
if(M.capture_caught) //Can't capture things that were already caught.
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
to_chat(user, "<span class='notice'>\The [src] clicks unsatisfyingly... \The [M] is already under someone else's control.</span>")
else if(M.stat == DEAD) //Is it dead? We can't influence dead things.
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
to_chat(user, "<span class='notice'>\The [src] clicks unsatisfyingly... \The [M] is not in a state to be captured.</span>")
else if(M.client) //Is it player controlled?
capture_player(M, user) //We have to do things a little differently if so.
else if(!isanimal(M)) //So it's not player controlled, but it's also not a simplemob?
to_chat(user, "<span class='warning'>This creature is not suitable for capture.</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
var/mob/living/simple_mob/S = M
if(!S.ai_holder) //We don't really want to capture simplemobs that don't have an AI
to_chat(user, "<span class='warning'>This creature is not suitable for capture.</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
else if(prob(capture_chance(S, user))) //OKAY! So we have an NPC simplemob with an AI, let's calculate its capture chance! It varies based on the mob's condition.
capture(S, user) //We did it! Woo! We capture it!
user.visible_message("\The [src] clicks, and then emits a small chime.", "Alright! \The [S] was caught!")
recall(user)
active = TRUE
else //Shoot, it didn't work and now it's mad!!!
S.ai_holder.go_wake()
S.ai_holder.target = user
S.ai_holder.track_target_position()
S.ai_holder.set_stance(STANCE_FIGHT)
user.visible_message("\The [src] bonks into \the [S], angering it!")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
to_chat(user, "<span class='notice'>\The [src] clicks unsatisfyingly.</span>")
update_icon()
return
//The target is not a mob, so let's not do anything.
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
to_chat(user, "<span class='notice'>\The [src] clicks unsatisfyingly.</span>")
//We're using the crystal, but what will it do?
/obj/item/capture_crystal/proc/determine_action(mob/living/U)
if(!cooldown_check()) //Are we ready yet?
to_chat(thrower, "<span class='notice'>\The [src] clicks unsatisfyingly... It is not ready yet.</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
return //No
if(bound_mob in contents) //Do we have our mob?
unleash(U) //Yes, let's let it out!
else if (bound_mob) //Do we HAVE a mob?
recall(U) //Yes, let's try to put it back in the crystal
else //No we don't have a mob, let's reset the crystal.
to_chat(U, "<span class='notice'>\The [src] clicks unsatisfyingly.</span>")
active = FALSE
update_icon()
owner = null
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
//Let's try to call our mob back!
/obj/item/capture_crystal/proc/recall(mob/living/user, atom/target)
if(bound_mob in view(user)) //We can only recall it if we can see it
var/turf/turfmemory = get_turf(bound_mob)
if(isanimal(bound_mob))
var/mob/living/simple_mob/M = bound_mob
M.ai_holder.go_sleep() //AI doesn't need to think when it's in the crystal
bound_mob.forceMove(src)
last_activate = world.time
bound_mob.visible_message("\The [user]'s [src] flashes, disappearing [bound_mob] in an instant!!!", "\The [src] pulls you back into confinement in a flash of light!!!")
animate_action(turfmemory)
playsound(src, 'sound/effects/capture-crystal-in.ogg', 75, 1, -1)
update_icon()
else
to_chat(user, "<span class='notice'>\The [src] clicks and emits a small, unpleasant tone. \The [bound_mob] cannot be recalled.</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
//Let's let our mob out!
/obj/item/capture_crystal/proc/unleash(mob/living/user, atom/target)
if(!user && !target) //We got thrown but we're not sure who did it, let's go to where the crystal is
bound_mob.forceMove(src.drop_location())
return
if(!target) //We know who wants to let us out, but they didn't say where, so let's drop us on them
bound_mob.forceMove(user.drop_location())
else //We got thrown! Let's go where we got thrown
bound_mob.forceMove(target.drop_location())
last_activate = world.time
if(isanimal(bound_mob))
var/mob/living/simple_mob/M = bound_mob
M.ai_holder.go_wake() //Okay it's time to do work, let's wake up!
if(!M.client && !M.ghostjoin)
M.ghostjoin = 1 //Players playing mobs is fun!
bound_mob.faction = owner.faction //Let's make sure we aren't hostile to our owner or their friends
bound_mob.visible_message("\The [user]'s [src] flashes, \the [bound_mob] appears in an instant!!!", "The world around you rematerialize as you are unleashed from the [src] next to \the [user]. You feel a strong compulsion to enact \the [owner]'s will.")
animate_action(get_turf(bound_mob))
playsound(src, 'sound/effects/capture-crystal-out.ogg', 75, 1, -1)
update_icon()
//Let's make a flashy sparkle when someone appears or disappears!
/obj/item/capture_crystal/proc/animate_action(atom/thing)
var/image/coolanimation = image('icons/obj/capture_crystal_vr.dmi', null, "animation")
coolanimation.plane = PLANE_LIGHTING_ABOVE
thing.overlays += coolanimation
sleep(11)
thing.overlays -= coolanimation
//IF the crystal somehow ends up in a tummy and digesting with a bound mob who doesn't want to be eaten, let's move them to the ground
/obj/item/capture_crystal/digest_act(var/atom/movable/item_storage = null)
if(bound_mob in contents && !bound_mob.devourable)
bound_mob.forceMove(src.drop_location())
return ..()
//We got thrown! Let's figure out what to do
/obj/item/capture_crystal/throw_at(atom/target, range, speed, mob/thrower, spin = TRUE, datum/callback/callback)
. = ..()
if(target == bound_mob && thrower != bound_mob) //We got thrown at our bound mob (and weren't thrown by the bound mob) let's ignore the cooldown and just put them back in
recall(thrower)
else if(!cooldown_check()) //OTHERWISE let's obey the cooldown
to_chat(thrower, "<span class='notice'>\The [src] emits an soft tone... It is not ready yet.</span>")
if(bound_mob)
playsound(src, 'sound/effects/capture-crystal-problem.ogg', 75, 1, -1)
else
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
else if(!active) //The ball isn't set up, let's try to set it up.
if(isliving(target)) //We're hitting a mob, let's try to capture it.
sleep(10)
activate(thrower, target)
return
sleep(10)
activate(thrower, src)
else if(!bound_mob) //We hit something else, and we don't have a mob, so we can't really do anything!
to_chat(thrower, "<span class='notice'>\The [src] clicks unpleasantly...</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
else if(bound_mob in contents) //We have our mob! Let's try to let it out.
sleep(10)
unleash(thrower, src)
update_icon()
else //Our mob isn't here, we can't do anything.
to_chat(thrower, "<span class='notice'>\The [src] clicks unpleasantly...</span>")
playsound(src, 'sound/effects/capture-crystal-negative.ogg', 75, 1, -1)
/obj/item/capture_crystal/great
capture_chance_modifier = 1.5
/obj/item/capture_crystal/ultra
capture_chance_modifier = 2
/obj/item/capture_crystal/master
capture_chance_modifier = 100
/obj/item/capture_crystal/cass
spawn_mob_type = /mob/living/simple_mob/vore/woof/cass
/obj/item/capture_crystal/adg
spawn_mob_type = /mob/living/simple_mob/mechanical/mecha/combat/gygax/dark/advanced
/obj/item/capture_crystal/bigdragon
spawn_mob_type = /mob/living/simple_mob/vore/bigdragon
/obj/item/capture_crystal/bigdragon/friendly
spawn_mob_type = /mob/living/simple_mob/vore/bigdragon/friendly
/obj/item/capture_crystal/teppi
spawn_mob_type = /mob/living/simple_mob/vore/alienanimals/teppi
/obj/item/capture_crystal/broodmother
spawn_mob_type = /mob/living/simple_mob/animal/giant_spider/broodmother
/obj/item/capture_crystal/skeleton
spawn_mob_type = /mob/living/simple_mob/vore/alienanimals/skeleton
/obj/item/capture_crystal/dustjumper
spawn_mob_type = /mob/living/simple_mob/vore/alienanimals/dustjumper
/obj/item/capture_crystal/random
var/static/list/possible_mob_types = list(
list(/mob/living/simple_mob/animal/goat),
list(
/mob/living/simple_mob/animal/passive/bird,
/mob/living/simple_mob/animal/passive/bird/azure_tit,
/mob/living/simple_mob/animal/passive/bird/black_bird,
/mob/living/simple_mob/animal/passive/bird/european_robin,
/mob/living/simple_mob/animal/passive/bird/goldcrest,
/mob/living/simple_mob/animal/passive/bird/ringneck_dove,
/mob/living/simple_mob/animal/passive/bird/parrot,
/mob/living/simple_mob/animal/passive/bird/parrot/black_headed_caique,
/mob/living/simple_mob/animal/passive/bird/parrot/budgerigar,
/mob/living/simple_mob/animal/passive/bird/parrot/budgerigar/blue,
/mob/living/simple_mob/animal/passive/bird/parrot/budgerigar/bluegreen,
/mob/living/simple_mob/animal/passive/bird/parrot/cockatiel,
/mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/grey,
/mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/white,
/mob/living/simple_mob/animal/passive/bird/parrot/cockatiel/yellowish,
/mob/living/simple_mob/animal/passive/bird/parrot/eclectus,
/mob/living/simple_mob/animal/passive/bird/parrot/grey_parrot,
/mob/living/simple_mob/animal/passive/bird/parrot/kea,
/mob/living/simple_mob/animal/passive/bird/parrot/pink_cockatoo,
/mob/living/simple_mob/animal/passive/bird/parrot/sulphur_cockatoo,
/mob/living/simple_mob/animal/passive/bird/parrot/white_caique,
/mob/living/simple_mob/animal/passive/bird/parrot/white_cockatoo
),
list(
/mob/living/simple_mob/animal/passive/cat,
/mob/living/simple_mob/animal/passive/cat/black
),
list(/mob/living/simple_mob/animal/passive/chick),
list(/mob/living/simple_mob/animal/passive/cow),
list(/mob/living/simple_mob/animal/passive/dog/brittany),
list(/mob/living/simple_mob/animal/passive/dog/corgi),
list(/mob/living/simple_mob/animal/passive/dog/tamaskan),
list(/mob/living/simple_mob/animal/passive/fox),
list(/mob/living/simple_mob/animal/passive/hare),
list(/mob/living/simple_mob/animal/passive/lizard),
list(/mob/living/simple_mob/animal/passive/mouse),
list(/mob/living/simple_mob/animal/passive/mouse/jerboa),
list(/mob/living/simple_mob/animal/passive/opossum),
list(/mob/living/simple_mob/animal/passive/pillbug),
list(/mob/living/simple_mob/animal/passive/snake),
list(/mob/living/simple_mob/animal/passive/tindalos),
list(/mob/living/simple_mob/animal/passive/yithian),
list(
/mob/living/simple_mob/animal/wolf,
/mob/living/simple_mob/animal/wolf/direwolf
),
list(/mob/living/simple_mob/vore/rabbit),
list(/mob/living/simple_mob/vore/redpanda),
list(/mob/living/simple_mob/vore/woof),
list(/mob/living/simple_mob/vore/fennec),
list(/mob/living/simple_mob/vore/fennix),
list(/mob/living/simple_mob/vore/hippo),
list(/mob/living/simple_mob/vore/horse),
list(/mob/living/simple_mob/vore/bee),
list(
/mob/living/simple_mob/animal/space/bear,
/mob/living/simple_mob/animal/space/bear/brown
),
list(
/mob/living/simple_mob/otie/feral,
/mob/living/simple_mob/otie/feral/chubby,
/mob/living/simple_mob/otie/red,
/mob/living/simple_mob/otie/red/chubby
),
list(/mob/living/simple_mob/animal/sif/diyaab),
list(/mob/living/simple_mob/animal/sif/duck),
list(/mob/living/simple_mob/animal/sif/frostfly),
list(
/mob/living/simple_mob/animal/sif/glitterfly =50,
/mob/living/simple_mob/animal/sif/glitterfly/rare = 1
),
list(
/mob/living/simple_mob/animal/sif/kururak = 10,
/mob/living/simple_mob/animal/sif/kururak/leader = 1,
/mob/living/simple_mob/animal/sif/kururak/hibernate = 2,
),
list(
/mob/living/simple_mob/animal/sif/sakimm = 10,
/mob/living/simple_mob/animal/sif/sakimm/intelligent = 1
),
list(/mob/living/simple_mob/animal/sif/savik) = 5,
list(
/mob/living/simple_mob/animal/sif/shantak = 10,
/mob/living/simple_mob/animal/sif/shantak/leader = 1
),
list(/mob/living/simple_mob/animal/sif/siffet),
list(/mob/living/simple_mob/animal/sif/tymisian),
list(
/mob/living/simple_mob/animal/giant_spider/nurse = 10,
/mob/living/simple_mob/animal/giant_spider/electric = 5,
/mob/living/simple_mob/animal/giant_spider/frost = 5,
/mob/living/simple_mob/animal/giant_spider/hunter = 10,
/mob/living/simple_mob/animal/giant_spider/ion = 5,
/mob/living/simple_mob/animal/giant_spider/lurker = 10,
/mob/living/simple_mob/animal/giant_spider/pepper = 10,
/mob/living/simple_mob/animal/giant_spider/phorogenic = 10,
/mob/living/simple_mob/animal/giant_spider/thermic = 5,
/mob/living/simple_mob/animal/giant_spider/tunneler = 10,
/mob/living/simple_mob/animal/giant_spider/webslinger = 5,
/mob/living/simple_mob/animal/giant_spider/broodmother = 1),
list(
/mob/living/simple_mob/animal/wolf = 10,
/mob/living/simple_mob/animal/wolf/direwolf = 5,
/mob/living/simple_mob/vore/greatwolf = 1,
/mob/living/simple_mob/vore/greatwolf/black = 1,
/mob/living/simple_mob/vore/greatwolf/grey = 1
),
list(/mob/living/simple_mob/creature/strong),
list(/mob/living/simple_mob/faithless/strong),
list(/mob/living/simple_mob/animal/goat),
list(
/mob/living/simple_mob/animal/sif/shantak/leader = 1,
/mob/living/simple_mob/animal/sif/shantak = 10),
list(/mob/living/simple_mob/animal/sif/savik,),
list(/mob/living/simple_mob/animal/sif/hooligan_crab),
list(
/mob/living/simple_mob/animal/space/alien = 50,
/mob/living/simple_mob/animal/space/alien/drone = 40,
/mob/living/simple_mob/animal/space/alien/sentinel = 25,
/mob/living/simple_mob/animal/space/alien/sentinel/praetorian = 15,
/mob/living/simple_mob/animal/space/alien/queen = 10,
/mob/living/simple_mob/animal/space/alien/queen/empress = 5,
/mob/living/simple_mob/animal/space/alien/queen/empress/mother = 1
),
list(/mob/living/simple_mob/animal/space/bats/cult/strong),
list(
/mob/living/simple_mob/animal/space/bear,
/mob/living/simple_mob/animal/space/bear/brown
),
list(
/mob/living/simple_mob/animal/space/carp = 50,
/mob/living/simple_mob/animal/space/carp/large = 10,
/mob/living/simple_mob/animal/space/carp/large/huge = 5
),
list(/mob/living/simple_mob/animal/space/goose),
list(/mob/living/simple_mob/animal/space/jelly),
list(/mob/living/simple_mob/animal/space/tree),
list(
/mob/living/simple_mob/vore/aggressive/corrupthound = 10,
/mob/living/simple_mob/vore/aggressive/corrupthound/prettyboi = 1,
),
list(/mob/living/simple_mob/vore/aggressive/deathclaw),
list(/mob/living/simple_mob/vore/aggressive/dino),
list(/mob/living/simple_mob/vore/aggressive/dragon),
list(/mob/living/simple_mob/vore/aggressive/dragon/virgo3b),
list(/mob/living/simple_mob/vore/aggressive/frog),
list(/mob/living/simple_mob/vore/aggressive/giant_snake),
list(/mob/living/simple_mob/vore/aggressive/mimic),
list(/mob/living/simple_mob/vore/aggressive/panther),
list(/mob/living/simple_mob/vore/aggressive/rat),
list(/mob/living/simple_mob/vore/bee),
list(
/mob/living/simple_mob/vore/sect_drone = 10,
/mob/living/simple_mob/vore/sect_queen = 1
),
list(/mob/living/simple_mob/vore/solargrub),
list(
/mob/living/simple_mob/vore/oregrub = 5,
/mob/living/simple_mob/vore/oregrub/lava = 1
),
list(/mob/living/simple_mob/vore/catgirl),
list(/mob/living/simple_mob/vore/wolfgirl),
list(
/mob/living/simple_mob/vore/lamia,
/mob/living/simple_mob/vore/lamia/albino,
/mob/living/simple_mob/vore/lamia/albino/bra,
/mob/living/simple_mob/vore/lamia/albino/shirt,
/mob/living/simple_mob/vore/lamia/bra,
/mob/living/simple_mob/vore/lamia/cobra,
/mob/living/simple_mob/vore/lamia/cobra/bra,
/mob/living/simple_mob/vore/lamia/cobra/shirt,
/mob/living/simple_mob/vore/lamia/copper,
/mob/living/simple_mob/vore/lamia/copper/bra,
/mob/living/simple_mob/vore/lamia/copper/shirt,
/mob/living/simple_mob/vore/lamia/green,
/mob/living/simple_mob/vore/lamia/green/bra,
/mob/living/simple_mob/vore/lamia/green/shirt,
/mob/living/simple_mob/vore/lamia/zebra,
/mob/living/simple_mob/vore/lamia/zebra/bra,
/mob/living/simple_mob/vore/lamia/zebra/shirt
),
list(
/mob/living/simple_mob/humanoid/merc = 100,
/mob/living/simple_mob/humanoid/merc/melee/sword = 50,
/mob/living/simple_mob/humanoid/merc/ranged = 25,
/mob/living/simple_mob/humanoid/merc/ranged/grenadier = 1,
/mob/living/simple_mob/humanoid/merc/ranged/ionrifle = 10,
/mob/living/simple_mob/humanoid/merc/ranged/laser = 5,
/mob/living/simple_mob/humanoid/merc/ranged/rifle = 5,
/mob/living/simple_mob/humanoid/merc/ranged/smg = 5,
/mob/living/simple_mob/humanoid/merc/ranged/sniper = 1,
/mob/living/simple_mob/humanoid/merc/ranged/space = 10,
/mob/living/simple_mob/humanoid/merc/ranged/technician = 5
),
list(
/mob/living/simple_mob/humanoid/pirate = 3,
/mob/living/simple_mob/humanoid/pirate/ranged = 1
),
list(/mob/living/simple_mob/mechanical/combat_drone),
list(/mob/living/simple_mob/mechanical/corrupt_maint_drone),
list(
/mob/living/simple_mob/mechanical/hivebot = 100,
/mob/living/simple_mob/mechanical/hivebot/ranged_damage = 20,
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/backline = 10,
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/basic = 20,
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/dot = 5,
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/ion = 20,
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/laser = 10,
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/rapid = 2,
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/siege = 1,
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/siege/emp = 5,
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/siege/fragmentation = 1,
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/siege/radiation = 1,
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/strong = 3,
/mob/living/simple_mob/mechanical/hivebot/ranged_damage/strong/guard = 3,
/mob/living/simple_mob/mechanical/hivebot/support = 8,
/mob/living/simple_mob/mechanical/hivebot/support/commander = 5,
/mob/living/simple_mob/mechanical/hivebot/support/commander/autofollow = 10,
/mob/living/simple_mob/mechanical/hivebot/swarm = 20,
/mob/living/simple_mob/mechanical/hivebot/tank = 20,
/mob/living/simple_mob/mechanical/hivebot/tank/armored = 20,
/mob/living/simple_mob/mechanical/hivebot/tank/armored/anti_bullet = 20,
/mob/living/simple_mob/mechanical/hivebot/tank/armored/anti_laser = 20,
/mob/living/simple_mob/mechanical/hivebot/tank/armored/anti_melee = 20,
/mob/living/simple_mob/mechanical/hivebot/tank/meatshield = 20
),
list(/mob/living/simple_mob/mechanical/infectionbot),
list(/mob/living/simple_mob/mechanical/mining_drone),
list(/mob/living/simple_mob/mechanical/technomancer_golem),
list(
/mob/living/simple_mob/mechanical/viscerator,
/mob/living/simple_mob/mechanical/viscerator/piercing
),
list(/mob/living/simple_mob/mechanical/wahlem),
list(/mob/living/simple_mob/animal/passive/fox/syndicate),
list(/mob/living/simple_mob/animal/passive/fox),
list(/mob/living/simple_mob/animal/wolf/direwolf),
list(/mob/living/simple_mob/animal/space/jelly),
list(
/mob/living/simple_mob/otie/feral,
/mob/living/simple_mob/otie/feral/chubby,
/mob/living/simple_mob/otie/red,
/mob/living/simple_mob/otie/red/chubby
),
list(
/mob/living/simple_mob/shadekin/blue = 100,
/mob/living/simple_mob/shadekin/green = 50,
/mob/living/simple_mob/shadekin/orange = 20,
/mob/living/simple_mob/shadekin/purple = 60,
/mob/living/simple_mob/shadekin/red = 40,
/mob/living/simple_mob/shadekin/yellow = 1
),
list(
/mob/living/simple_mob/vore/aggressive/corrupthound,
/mob/living/simple_mob/vore/aggressive/corrupthound/prettyboi
),
list(/mob/living/simple_mob/vore/aggressive/deathclaw),
list(/mob/living/simple_mob/vore/aggressive/dino),
list(/mob/living/simple_mob/vore/aggressive/dragon),
list(/mob/living/simple_mob/vore/aggressive/dragon/virgo3b),
list(/mob/living/simple_mob/vore/aggressive/frog),
list(/mob/living/simple_mob/vore/aggressive/giant_snake),
list(/mob/living/simple_mob/vore/aggressive/mimic),
list(/mob/living/simple_mob/vore/aggressive/panther),
list(/mob/living/simple_mob/vore/aggressive/rat),
list(/mob/living/simple_mob/vore/bee),
list(/mob/living/simple_mob/vore/catgirl),
list(/mob/living/simple_mob/vore/cookiegirl),
list(/mob/living/simple_mob/vore/fennec),
list(/mob/living/simple_mob/vore/fennix),
list(/mob/living/simple_mob/vore/hippo),
list(/mob/living/simple_mob/vore/horse),
list(/mob/living/simple_mob/vore/oregrub),
list(/mob/living/simple_mob/vore/rabbit),
list(
/mob/living/simple_mob/vore/redpanda = 50,
/mob/living/simple_mob/vore/redpanda/fae = 1
),
list(
/mob/living/simple_mob/vore/sect_drone = 10,
/mob/living/simple_mob/vore/sect_queen = 1
),
list(/mob/living/simple_mob/vore/solargrub),
list(/mob/living/simple_mob/vore/woof),
list(/mob/living/simple_mob/vore/alienanimals/teppi),
list(/mob/living/simple_mob/vore/alienanimals/space_ghost),
list(/mob/living/simple_mob/vore/alienanimals/catslug),
list(/mob/living/simple_mob/vore/alienanimals/space_jellyfish),
list(/mob/living/simple_mob/vore/alienanimals/startreader),
list(/mob/living/simple_mob/vore/bigdragon),
list(
/mob/living/simple_mob/vore/leopardmander = 50,
/mob/living/simple_mob/vore/leopardmander/blue = 10,
/mob/living/simple_mob/vore/leopardmander/exotic = 1
),
list(/mob/living/simple_mob/vore/sheep),
list(/mob/living/simple_mob/vore/weretiger),
list(/mob/living/simple_mob/vore/alienanimals/skeleton),
list(/mob/living/simple_mob/vore/alienanimals/dustjumper)
)
/obj/item/capture_crystal/random/Initialize()
var/subchoice = pickweight(possible_mob_types) //Some of the lists have nested lists, so let's pick one of them
var/choice = pickweight(subchoice) //And then we'll pick something from whatever's left
spawn_mob_type = choice //Now when someone uses this, we'll spawn whatever we picked!
return ..()
/mob/living
var/capture_crystal = TRUE //If TRUE, the mob is capturable. Otherwise it isn't.
var/capture_caught = FALSE //If TRUE, the mob has already been caught, and so cannot be caught again.

View File

@@ -55,7 +55,7 @@
C.throw_mode_on()
/obj/item/weapon/grenade/chem_grenade/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W,/obj/item/device/assembly_holder) && (!stage || stage==1) && path != 2)
if(istype(W,/obj/item/device/assembly_holder) && (!stage || stage==1) && !detonator && path != 2)
var/obj/item/device/assembly_holder/det = W
if(istype(det.a_left,det.a_right.type) || (!isigniter(det.a_left) && !isigniter(det.a_right)))
to_chat(user, "<span class='warning'>Assembly must contain one igniter.</span>")
@@ -314,4 +314,3 @@
beakers += B1
beakers += B2

View File

@@ -102,7 +102,7 @@
scancount = 0
scanned = list()
scannables = list(/obj/machinery/deployable/barrier,/obj/machinery/flasher/portable,/obj/item/weapon/storage/box/flashbangs,/obj/item/device/taperecorder,
/mob/living/simple_mob/animal/passive/snake/noodle,/obj/item/weapon/gun/energy/taser,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/weapon/reagent_containers/spray/pepper,
/mob/living/simple_mob/animal/passive/snake/python/noodle,/obj/item/weapon/gun/energy/taser,/obj/item/weapon/gun/energy/stunrevolver,/obj/item/weapon/reagent_containers/spray/pepper,
/obj/item/weapon/storage/box/handcuffs,/obj/item/clothing/glasses/sunglasses/sechud/aviator,/obj/machinery/computer/secure_data,/obj/machinery/computer/security,
/obj/item/weapon/storage/briefcase/crimekit,/obj/machinery/microscope,/obj/machinery/dnaforensics,/obj/machinery/flasher,/obj/structure/closet/secure_closet/brig,
/obj/structure/closet/secure_closet/warden,/obj/machinery/vending/security,/obj/structure/closet/secure_closet/hos2,/obj/structure/closet/secure_closet/hos,

View File

@@ -1455,4 +1455,194 @@
/obj/random/turf/lava/item_to_spawn()
return pick(prob(5);/turf/simulated/floor/lava,
prob(3);/turf/simulated/floor/outdoors/rocks/caves,
prob(1);/turf/simulated/mineral)
prob(1);/turf/simulated/mineral/ignore_mapgen/cave)
//VOREStation Add Start - Underdark stuff that would be cool if existed if the underdark doesn't.
/obj/random/underdark
name = "random underdark loot"
desc = "Random loot for Underdark."
icon = 'icons/obj/items.dmi'
icon_state = "spickaxe"
/obj/random/underdark/item_to_spawn()
return pick(prob(3);/obj/random/multiple/underdark/miningdrills,
prob(3);/obj/random/multiple/underdark/ores,
prob(2);/obj/random/multiple/underdark/treasure,
prob(1);/obj/random/multiple/underdark/mechtool)
/obj/random/underdark/uncertain
icon_state = "upickaxe"
spawn_nothing_percentage = 65 //only 33% to spawn loot
/obj/random/multiple/underdark/miningdrills
name = "random underdark mining tool loot"
desc = "Random mining tool loot for Underdark."
icon = 'icons/obj/items.dmi'
icon_state = "spickaxe"
/obj/random/multiple/underdark/miningdrills/item_to_spawn()
return pick(
prob(10);list(/obj/item/weapon/pickaxe/silver),
prob(8);list(/obj/item/weapon/pickaxe/drill),
prob(6);list(/obj/item/weapon/pickaxe/jackhammer),
prob(5);list(/obj/item/weapon/pickaxe/gold),
prob(4);list(/obj/item/weapon/pickaxe/plasmacutter),
prob(2);list(/obj/item/weapon/pickaxe/diamond),
prob(1);list(/obj/item/weapon/pickaxe/diamonddrill)
)
/obj/random/multiple/underdark/ores
name = "random underdark mining ore loot"
desc = "Random mining utility loot for Underdark."
icon = 'icons/obj/mining.dmi'
icon_state = "satchel"
/obj/random/multiple/underdark/ores/item_to_spawn()
return pick(
prob(9);list(
/obj/item/weapon/storage/bag/ore,
/obj/item/weapon/shovel,
/obj/item/weapon/ore/glass,
/obj/item/weapon/ore/glass,
/obj/item/weapon/ore/glass,
/obj/item/weapon/ore/glass,
/obj/item/weapon/ore/glass,
/obj/item/weapon/ore/glass,
/obj/item/weapon/ore/glass,
/obj/item/weapon/ore/glass,
/obj/item/weapon/ore/glass,
/obj/item/weapon/ore/glass,
/obj/item/weapon/ore/hydrogen,
/obj/item/weapon/ore/hydrogen,
/obj/item/weapon/ore/hydrogen,
/obj/item/weapon/ore/hydrogen,
/obj/item/weapon/ore/hydrogen,
/obj/item/weapon/ore/hydrogen
),
prob(7);list(
/obj/item/weapon/storage/bag/ore,
/obj/item/weapon/pickaxe,
/obj/item/weapon/ore/osmium,
/obj/item/weapon/ore/osmium,
/obj/item/weapon/ore/osmium,
/obj/item/weapon/ore/osmium,
/obj/item/weapon/ore/osmium,
/obj/item/weapon/ore/osmium,
/obj/item/weapon/ore/osmium,
/obj/item/weapon/ore/osmium,
/obj/item/weapon/ore/osmium,
/obj/item/weapon/ore/osmium
),
prob(4);list(
/obj/item/clothing/suit/radiation,
/obj/item/clothing/head/radiation,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium,
/obj/item/weapon/ore/uranium),
prob(2);list(
/obj/item/device/flashlight/lantern,
/obj/item/clothing/glasses/material,
/obj/item/weapon/ore/diamond,
/obj/item/weapon/ore/diamond,
/obj/item/weapon/ore/diamond,
/obj/item/weapon/ore/diamond,
/obj/item/weapon/ore/diamond,
/obj/item/weapon/ore/diamond,
/obj/item/weapon/ore/diamond,
/obj/item/weapon/ore/diamond,
/obj/item/weapon/ore/diamond,
/obj/item/weapon/ore/diamond
),
prob(1);list(
/obj/item/weapon/mining_scanner,
/obj/item/weapon/shovel/spade,
/obj/item/weapon/ore/verdantium,
/obj/item/weapon/ore/verdantium,
/obj/item/weapon/ore/verdantium,
/obj/item/weapon/ore/verdantium,
/obj/item/weapon/ore/verdantium
)
)
/obj/random/multiple/underdark/treasure
name = "random underdark treasure"
desc = "Random treasure loot for Underdark."
icon = 'icons/obj/storage.dmi'
icon_state = "cashbag"
/obj/random/multiple/underdark/treasure/item_to_spawn()
return pick(
prob(5);list(
/obj/random/coin,
/obj/random/coin,
/obj/random/coin,
/obj/random/coin,
/obj/random/coin,
/obj/item/clothing/head/pirate
),
prob(4);list(
/obj/item/weapon/storage/bag/cash,
/obj/item/weapon/spacecash/c500,
/obj/item/weapon/spacecash/c100,
/obj/item/weapon/spacecash/c50
),
prob(3);list(
/obj/item/clothing/head/hardhat/orange,
/obj/item/stack/material/gold,
/obj/item/stack/material/gold,
/obj/item/stack/material/gold,
/obj/item/stack/material/gold,
/obj/item/stack/material/gold,
/obj/item/stack/material/gold,
/obj/item/stack/material/gold,
/obj/item/stack/material/gold,
/obj/item/stack/material/gold,
/obj/item/stack/material/gold),
prob(1);list(
/obj/item/stack/material/phoron,
/obj/item/stack/material/phoron,
/obj/item/stack/material/phoron,
/obj/item/stack/material/phoron,
/obj/item/stack/material/diamond,
/obj/item/stack/material/diamond,
/obj/item/stack/material/diamond
)
)
/obj/random/multiple/underdark/mechtool
name = "random underdark mech equipment"
desc = "Random mech equipment loot for Underdark."
icon = 'icons/mecha/mecha_equipment.dmi'
icon_state = "mecha_clamp"
/obj/random/multiple/underdark/mechtool/item_to_spawn()
return pick(
prob(12);list(/obj/item/mecha_parts/mecha_equipment/tool/drill),
prob(10);list(/obj/item/mecha_parts/mecha_equipment/tool/hydraulic_clamp),
prob(8);list(/obj/item/mecha_parts/mecha_equipment/generator),
prob(7);list(/obj/item/mecha_parts/mecha_equipment/weapon/ballistic/scattershot/rigged),
prob(6);list(/obj/item/mecha_parts/mecha_equipment/repair_droid),
prob(3);list(/obj/item/mecha_parts/mecha_equipment/gravcatapult),
prob(2);list(/obj/item/mecha_parts/mecha_equipment/weapon/energy/riggedlaser),
prob(2);list(/obj/item/mecha_parts/mecha_equipment/weapon/energy/flamer/rigged),
prob(1);list(/obj/item/mecha_parts/mecha_equipment/tool/drill/diamonddrill),
)
//VOREStation Add End

View File

@@ -23,6 +23,7 @@
prob(30);/obj/item/weapon/aliencoin/gold,
prob(20);/obj/item/weapon/aliencoin/phoron,
prob(10);/obj/item/device/denecrotizer,
prob(5);/obj/item/capture_crystal,
prob(5);/obj/item/device/perfect_tele,
prob(5);/obj/item/weapon/bluespace_harpoon,
prob(1);/obj/item/weapon/cell/infinite,
@@ -43,9 +44,59 @@
prob(3);/obj/fiftyspawner/silver,
prob(1);/obj/fiftyspawner/diamond,
prob(5);/obj/fiftyspawner/phoron,
prob(1);/obj/item/weapon/telecube/randomized
prob(1);/obj/item/weapon/telecube/randomized,
prob(1);/obj/item/capture_crystal/random
)
/obj/random/awayloot/nofail
name = "garunteed random away mission loot"
spawn_nothing_percentage = 0
/obj/random/awayloot/looseloot
/obj/random/awayloot/looseloot/item_to_spawn()
return pick(prob(50);/obj/item/weapon/aliencoin,
prob(40);/obj/item/weapon/aliencoin/silver,
prob(30);/obj/item/weapon/aliencoin/gold,
prob(20);/obj/item/weapon/aliencoin/phoron,
prob(10);/obj/item/device/denecrotizer,
prob(5);/obj/item/capture_crystal,
prob(3);/obj/item/capture_crystal/great,
prob(1);/obj/item/capture_crystal/ultra,
prob(4);/obj/item/capture_crystal/random,
prob(5);/obj/item/device/perfect_tele,
prob(5);/obj/item/weapon/bluespace_harpoon,
prob(1);/obj/item/weapon/cell/infinite,
prob(1);/obj/item/weapon/cell/void,
prob(1);/obj/item/weapon/cell/device/weapon/recharge/alien,
prob(1);/obj/item/clothing/shoes/boots/speed,
prob(1);/obj/item/device/nif,
prob(1);/obj/item/device/paicard,
prob(2);/obj/item/weapon/storage/backpack/dufflebag/syndie,
prob(2);/obj/item/weapon/storage/backpack/dufflebag/syndie/ammo,
prob(2);/obj/item/weapon/storage/backpack/dufflebag/syndie/med,
prob(2);/obj/item/clothing/mask/gas/voice,
prob(2);/obj/item/device/radio_jammer,
prob(1);/obj/item/toy/bosunwhistle,
prob(1);/obj/item/weapon/bananapeel,
prob(5);/obj/fiftyspawner/platinum,
prob(3);/obj/fiftyspawner/gold,
prob(3);/obj/fiftyspawner/silver,
prob(1);/obj/fiftyspawner/diamond,
prob(5);/obj/fiftyspawner/phoron,
prob(1);/obj/item/weapon/telecube/randomized,
prob(10);/obj/random/empty_or_lootable_crate,
prob(10);/obj/random/medical,
prob(5);/obj/random/firstaid,
prob(30);/obj/random/maintenance,
prob(10);/obj/random/mre,
prob(15);/obj/random/snack,
prob(10);/obj/random/tech_supply,
prob(15);/obj/random/tech_supply/component,
prob(10);/obj/random/tool,
prob(5);/obj/random/tool/power,
prob(1);/obj/random/tool/alien,
prob(5);/obj/random/weapon,
prob(5);/obj/random/ammo_all,
prob(3);/obj/random/projectile/random,
prob(5);/obj/random/multiple/voidsuit
)

View File

@@ -240,6 +240,7 @@
/obj/random/mob/mouse/item_to_spawn()
return pick(prob(15);/mob/living/simple_mob/animal/passive/mouse/white,
prob(15);/mob/living/simple_mob/animal/passive/mouse/black,
prob(30);/mob/living/simple_mob/animal/passive/mouse/brown,
prob(30);/mob/living/simple_mob/animal/passive/mouse/gray,
prob(30);/mob/living/simple_mob/animal/passive/mouse/rat)

View File

@@ -316,21 +316,10 @@
name = "painting frame"
desc = "The perfect showcase for your favorite deathtrap memories."
icon = 'icons/obj/decals.dmi'
//custom_materials = list(/datum/material/wood = 2000)
//flags_1 = NONE
refund_amt = 5
refund_type = /obj/item/stack/material/wood
icon_state = "frame-empty"
/obj/item/frame/painting/try_build(turf/on_wall, mob/user as mob)
if(get_dist(on_wall, user) > 1)
return
var/ndir = get_dir(on_wall, user)
if (!(ndir in cardinal))
return
if(!istype(on_wall, /turf/simulated/wall))
to_chat(user, "<span class='warning'>Frame cannot be placed on this spot.</span>")
return
new /obj/structure/sign/painting(get_turf(user), ndir, TRUE)
qdel(src)
build_machine_type = /obj/structure/sign/painting
/obj/structure/sign/painting
name = "Painting"

View File

@@ -6,6 +6,7 @@
starts_with = list(
/obj/item/weapon/storage/bag/plants,
/obj/item/clothing/under/rank/hydroponics,
/obj/item/clothing/gloves/botanic_leather,
/obj/item/device/analyzer/plant_analyzer,
/obj/item/device/radio/headset/headset_service,
/obj/item/clothing/head/greenbandana,

View File

@@ -450,6 +450,43 @@
desc = "This is a tiny well lit decorative christmas tree."
icon_state = "plant-xmas"
/obj/random/pottedplant
name = "random potted plant"
desc = "This is a random potted plant."
/obj/random/pottedplant/item_to_spawn()
return pick(
prob(10);/obj/structure/flora/pottedplant,
prob(10);/obj/structure/flora/pottedplant/large,
prob(10);/obj/structure/flora/pottedplant/fern,
prob(10);/obj/structure/flora/pottedplant/overgrown,
prob(10);/obj/structure/flora/pottedplant/bamboo,
prob(10);/obj/structure/flora/pottedplant/largebush,
prob(10);/obj/structure/flora/pottedplant/thinbush,
prob(10);/obj/structure/flora/pottedplant/mysterious,
prob(10);/obj/structure/flora/pottedplant/smalltree,
prob(10);/obj/structure/flora/pottedplant/unusual,
prob(10);/obj/structure/flora/pottedplant/orientaltree,
prob(10);/obj/structure/flora/pottedplant/smallcactus,
prob(10);/obj/structure/flora/pottedplant/tall,
prob(10);/obj/structure/flora/pottedplant/sticky,
prob(10);/obj/structure/flora/pottedplant/smelly,
prob(10);/obj/structure/flora/pottedplant/small,
prob(10);/obj/structure/flora/pottedplant/aquatic,
prob(10);/obj/structure/flora/pottedplant/shoot,
prob(10);/obj/structure/flora/pottedplant/flower,
prob(10);/obj/structure/flora/pottedplant/crystal,
prob(10);/obj/structure/flora/pottedplant/subterranean,
prob(10);/obj/structure/flora/pottedplant/minitree,
prob(10);/obj/structure/flora/pottedplant/stoutbush,
prob(10);/obj/structure/flora/pottedplant/drooping,
prob(10);/obj/structure/flora/pottedplant/tropical,
prob(10);/obj/structure/flora/pottedplant/dead,
prob(10);/obj/structure/flora/pottedplant/decorative,
prob(1);/obj/structure/flora/pottedplant/xmas
)
/obj/structure/flora/sif
icon = 'icons/obj/flora/sifflora.dmi'

View File

@@ -263,7 +263,8 @@
prob(1);/obj/item/weapon/storage/box/survival/space,
prob(1);/obj/item/weapon/storage/secure/briefcase/trashmoney,
prob(1);/obj/item/device/survivalcapsule/popcabin,
prob(1);/obj/item/weapon/reagent_containers/syringe/steroid)
prob(1);/obj/item/weapon/reagent_containers/syringe/steroid,
prob(1);/obj/item/capture_crystal)
var/obj/item/I = new path()
return I

View File

@@ -124,7 +124,7 @@
bloodDNA = null
if(src.wet || (dirtslip && (dirt > 50 || outdoors))) //CHOMPEdit
if(src.wet || (dirtslip && (dirt > 50 || outdoors == 1))) //CHOMPEdit
if(M.buckled || (src.wet == 1 && M.m_intent == "walk"))
return
@@ -139,6 +139,8 @@
floor_type = "dirty"
else if(outdoors)
floor_type = "uneven"
if(src.wet == 0 && M.m_intent == "walk")
return
//CHOMPEdit End
switch(src.wet)
if(2) // Lube

View File

@@ -0,0 +1,131 @@
/turf/simulated/floor/weird_things
icon = 'icons/turf/flooring/weird_vr.dmi'
/turf/simulated/floor/weird_things/dark
name = "dark"
desc = "It's a strange, impenetrable darkness."
icon_state = "dark"
can_dirty = FALSE
/turf/simulated/floor/weird_things/dark/Initialize(mapload)
. = ..()
if(prob(5))
add_glow()
/turf/simulated/floor/weird_things/dark/Crossed(O)
. = ..()
if(!isliving(O))
return
cut_overlays()
if(prob(5))
add_glow()
if(istype(O, /mob/living/carbon/human))
var/mob/living/carbon/human/L = O
if(istype(L.species, /datum/species/crew_shadekin))
L.halloss += 5
if(prob(50))
to_chat(L, "<span class='danger'>The more you move through this darkness, the more you can feel a throbbing, shooting ache in your bones.</span>")
if(prob(5))
L.visible_message("[L]'s body gives off a faint, sparking, haze...", "Your body gives off a faint, sparking, haze...", runemessage = "gives off a faint, sparking haze")
else if(istype(L.species, /datum/species/shadekin))
var/obj/item/organ/internal/brain/shadekin/B = L.internal_organs_by_name["brain"]
B.dark_energy += 10
if(prob(10))
to_chat(L, "<span class='notice'>You can feel the energy flowing into you!</span>")
else
if(prob(0.25))
to_chat(L, "<span class='danger'>The darkness seethes under your feet...</span>")
L.hallucination += 50
/turf/simulated/floor/weird_things/dark/proc/add_glow()
var/choice = "overlay-[rand(1,6)]"
var/image/i = image('icons/turf/flooring/weird_vr.dmi', choice)
i.plane = PLANE_LIGHTING_ABOVE
add_overlay(i)
/turf/simulated/floor/weird_things/dark/ChangeTurf()
. = ..()
cut_overlays()
/turf/unsimulated/wall/dark
name = "dark"
desc = "It's a strange, impenetrable darkness."
icon = 'icons/turf/flooring/weird_vr.dmi'
icon_state = "dark"
/turf/unsimulated/wall/dark/Initialize(mapload)
. = ..()
if(prob(5))
add_glow()
/turf/unsimulated/wall/dark/proc/add_glow()
var/choice = "overlay-[rand(1,6)]"
var/image/i = image('icons/turf/flooring/weird_vr.dmi', choice)
i.plane = PLANE_LIGHTING_ABOVE
add_overlay(i)
/turf/unsimulated/wall/dark/ChangeTurf()
. = ..()
cut_overlays()
/turf/unsimulated/floor/dark
name = "dark"
desc = "It's a strange, impenetrable darkness."
icon = 'icons/turf/flooring/weird_vr.dmi'
icon_state = "dark"
/turf/unsimulated/floor/dark/Initialize(mapload)
. = ..()
if(prob(5))
add_glow()
/turf/unsimulated/floor/dark/Crossed(O)
. = ..()
if(!isliving(O))
return
cut_overlays()
if(prob(5))
add_glow()
if(istype(O, /mob/living/carbon/human))
var/mob/living/carbon/human/L = O
if(istype(L.species, /datum/species/crew_shadekin))
L.halloss += 5
if(prob(50))
to_chat(L, "<span class='danger'>The more you move through this darkness, the more you can feel a throbbing, shooting ache in your bones.</span>")
if(prob(5))
L.visible_message("[L]'s body gives off a faint, sparking, haze...", "Your body gives off a faint, sparking, haze...", runemessage = "gives off a faint, sparking haze")
else if(istype(L.species, /datum/species/shadekin))
var/obj/item/organ/internal/brain/shadekin/B = L.internal_organs_by_name["brain"]
B.dark_energy += 10
if(prob(10))
to_chat(L, "<span class='notice'>You can feel the energy flowing into you!</span>")
else
if(prob(0.25))
to_chat(L, "<span class='danger'>The darkness seethes under your feet...</span>")
L.hallucination += 50
/turf/unsimulated/floor/dark/proc/add_glow()
var/flip = rand(1,2)
var/choice
var/choiceb
if(flip == 1)
choice = "overlay-[rand(1,6)]"
if(flip == 2)
choice = "overlay-[rand(7,12)]"
var/image/i = image('icons/turf/flooring/weird_vr.dmi', choice)
i.plane = PLANE_LIGHTING_ABOVE
add_overlay(i)
if(prob(10))
if(flip == 1)
choiceb = "overlay-[rand(7,12)]"
if(flip == 2)
choiceb = "overlay-[rand(1,6)]"
var/image/ii = image('icons/turf/flooring/weird_vr.dmi', choiceb)
add_overlay(ii)
/turf/unsimulated/floor/dark/ChangeTurf()
. = ..()
cut_overlays()

View File

@@ -34,7 +34,7 @@
if(!Ts)
return //Didn't find shadekin spawn turf
var/mob/living/simple_mob/shadekin/red/ai/shadekin = new(Ts)
var/mob/living/simple_mob/shadekin/red/shadekin = new(Ts)
//Abuse of shadekin
shadekin.real_name = shadekin.name
shadekin.init_vore()

View File

@@ -4,6 +4,7 @@
var/hostile = FALSE // Do we try to hurt others?
var/retaliate = FALSE // Attacks whatever struck it first. Mobs will still attack back if this is false but hostile is true.
var/mauling = FALSE // Attacks unconscious mobs
var/unconscious_vore = TRUE //VOREStation Add - allows a mob to go for unconcious targets IF their vore prefs align
var/handle_corpse = FALSE // Allows AI to acknowledge corpses (e.g. nurse spiders)
var/atom/movable/target = null // The thing (mob or object) we're trying to kill.
@@ -128,6 +129,14 @@
if(L.stat == UNCONSCIOUS) // Do we have mauling? Yes? Then maul people who are sleeping but not SSD
if(mauling)
return TRUE
//VOREStation Add Start
else if(unconscious_vore && L.allowmobvore)
var/mob/living/simple_mob/vore/eater = holder
if(eater.will_eat(L))
return TRUE
else
return FALSE
//VOREStation Add End
else
return FALSE
if(holder.IIsAlly(L))

View File

@@ -855,7 +855,7 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
var/list/valid_facialhairstyles = pref.get_valid_facialhairstyles()
var/new_f_style = tgui_input_list(user, "Choose your character's facial-hair style:", "Character Preference", valid_facialhairstyles, pref.f_style)
if(new_f_style && has_flag(mob_species, HAS_HAIR_COLOR) && CanUseTopic(user))
if(new_f_style && CanUseTopic(user))
pref.f_style = new_f_style
return TOPIC_REFRESH_UPDATE_PREVIEW

View File

@@ -65,7 +65,7 @@ var/list/gear_datums = list()
for(var/gear_name in gear_datums)
var/datum/gear/G = gear_datums[gear_name]
if(G.whitelisted && config.loadout_whitelist != LOADOUT_WHITELIST_OFF)
if(G.whitelisted && config.loadout_whitelist != LOADOUT_WHITELIST_OFF && pref.client) //VOREStation Edit.
if(config.loadout_whitelist == LOADOUT_WHITELIST_STRICT && G.whitelisted != pref.species)
continue
if(config.loadout_whitelist == LOADOUT_WHITELIST_LAX && !is_alien_whitelisted(preference_mob(), GLOB.all_species[G.whitelisted]))
@@ -170,7 +170,7 @@ var/list/gear_datums = list()
if(ticked)
. += "<tr><td colspan=3>"
for(var/datum/gear_tweak/tweak in G.gear_tweaks)
. += " <a href='?src=\ref[src];gear=[G.display_name];tweak=\ref[tweak]'>[tweak.get_contents(get_tweak_metadata(G, tweak))]</a>"
. += " <a href='?src=\ref[src];gear=[url_encode(G.display_name)];tweak=\ref[tweak]'>[tweak.get_contents(get_tweak_metadata(G, tweak))]</a>"
. += "</td></tr>"
. += "</table>"
. = jointext(., null)
@@ -206,7 +206,7 @@ var/list/gear_datums = list()
pref.gear += TG.display_name
return TOPIC_REFRESH_UPDATE_PREVIEW
if(href_list["gear"] && href_list["tweak"])
var/datum/gear/gear = gear_datums[href_list["gear"]]
var/datum/gear/gear = gear_datums[url_decode(href_list["gear"])]
var/datum/gear_tweak/tweak = locate(href_list["tweak"])
if(!tweak || !istype(gear) || !(tweak in gear.gear_tweaks))
return TOPIC_NOACTION

View File

@@ -344,6 +344,12 @@
ckeywhitelist = list("hottokeeki")
character_name = list("Belle Day")
/datum/gear/fluff/amaryll_claws
path = /obj/item/weapon/surgical/scalpel/amaryll_claws
display_name = "Amaryll's Claws"
ckeywhitelist = list("hunterbirk")
character_name = list("Amaryll")
// I CKEYS
/datum/gear/fluff/ruda_badge
path = /obj/item/clothing/accessory/badge/holo/detective/ruda

View File

@@ -46,13 +46,13 @@
/datum/gear/mask/gaiter
display_name = "neck gaiter selection"
path = /obj/item/clothing/mask/gaiter
path = /obj/item/clothing/accessory/gaiter
cost = 1
/datum/gear/mask/gaiter/New()
..()
var/list/gaiters = list()
for(var/gaiter in typesof(/obj/item/clothing/mask/gaiter))
var/obj/item/clothing/mask/gaiter_type = gaiter
for(var/gaiter in typesof(/obj/item/clothing/accessory/gaiter))
var/obj/item/clothing/accessory/gaiter_type = gaiter
gaiters[initial(gaiter_type.name)] = gaiter_type
gear_tweaks += new/datum/gear_tweak/path(sortTim(gaiters, /proc/cmp_text_asc))

View File

@@ -8,6 +8,7 @@
S["directory_erptag"] >> pref.directory_erptag
S["directory_ad"] >> pref.directory_ad
S["sensorpref"] >> pref.sensorpref
S["capture_crystal"] >> pref.capture_crystal
/datum/category_item/player_setup_item/vore/misc/save_character(var/savefile/S)
S["show_in_directory"] << pref.show_in_directory
@@ -15,17 +16,21 @@
S["directory_erptag"] << pref.directory_erptag
S["directory_ad"] << pref.directory_ad
S["sensorpref"] << pref.sensorpref
S["capture_crystal"] << pref.capture_crystal
/datum/category_item/player_setup_item/vore/misc/copy_to_mob(var/mob/living/carbon/human/character)
if(pref.sensorpref > 5 || pref.sensorpref < 1)
pref.sensorpref = 5
character.sensorpref = pref.sensorpref
character.capture_crystal = pref.capture_crystal
/datum/category_item/player_setup_item/vore/misc/sanitize_character()
pref.show_in_directory = sanitize_integer(pref.show_in_directory, 0, 1, initial(pref.show_in_directory))
pref.directory_tag = sanitize_inlist(pref.directory_tag, GLOB.char_directory_tags, initial(pref.directory_tag))
pref.directory_erptag = sanitize_inlist(pref.directory_erptag, GLOB.char_directory_erptags, initial(pref.directory_erptag))
pref.sensorpref = sanitize_integer(pref.sensorpref, 1, sensorpreflist.len, initial(pref.sensorpref))
pref.capture_crystal = sanitize_integer(pref.capture_crystal, 0, 1, initial(pref.capture_crystal))
/datum/category_item/player_setup_item/vore/misc/content(var/mob/user)
. += "<br>"
@@ -34,6 +39,7 @@
. += "<b>Character Directory ERP Tag:</b> <a href='?src=\ref[src];directory_erptag=1'><b>[pref.directory_erptag]</b></a><br>"
. += "<b>Character Directory Advertisement:</b> <a href='?src=\ref[src];directory_ad=1'><b>Set Directory Ad</b></a><br>"
. += "<b>Suit Sensors Preference:</b> <a [pref.sensorpref ? "" : ""] href='?src=\ref[src];toggle_sensor_setting=1'><b>[sensorpreflist[pref.sensorpref]]</b></a><br>"
. += "<b>Capture Crystal Preference</b> <a [pref.capture_crystal ? "class='linkOn'" : ""] href='?src=\ref[src];toggle_capture_crystal=1'><b>[pref.capture_crystal ? "Yes" : "No"]</b></a><br>"
/datum/category_item/player_setup_item/vore/misc/OnTopic(var/href, var/list/href_list, var/mob/user)
if(href_list["toggle_show_in_directory"])
@@ -60,4 +66,8 @@
if (!isnull(new_sensorpref) && CanUseTopic(user))
pref.sensorpref = sensorpreflist.Find(new_sensorpref)
return TOPIC_REFRESH
else if(href_list["toggle_capture_crystal"])
pref.capture_crystal = pref.capture_crystal ? 0 : 1;
return TOPIC_REFRESH
return ..();

View File

@@ -4,6 +4,8 @@
var/directory_erptag = "Unset" //ditto, but for non-vore scenes
var/directory_ad = "" //Advertisement stuff to show in character directory.
var/sensorpref = 5 //Set character's suit sensor level
var/capture_crystal = 1 //Whether or not someone is able to be caught with capture crystals
var/job_talon_high = 0
var/job_talon_med = 0
var/job_talon_low = 0
@@ -71,7 +73,7 @@
feedback_add_details("admin_verb","TEmoteNoise") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_ghost_quiets()
set name = "Toggle Whisper/Subtle Vis"
set name = "Toggle Ghost Privacy"
set category = "Preferences"
set desc = "Toggle ghosts viewing your subtles/whispers."
@@ -84,3 +86,22 @@
SScharacter_setup.queue_preferences_save(prefs)
feedback_add_details("admin_verb","TWhisubtleVis") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
/client/verb/toggle_capture_crystal()
set name = "Toggle Catchable"
set category = "Preferences"
set desc = "Toggle being catchable with capture crystals."
var/mob/living/L = mob
if(prefs.capture_crystal)
to_chat(src, "You are no longer catchable.")
prefs.capture_crystal = 0
else
to_chat(src, "You are now catchable.")
prefs.capture_crystal = 1
if(L)
L.capture_crystal = prefs.capture_crystal
SScharacter_setup.queue_preferences_save(prefs)
feedback_add_details("admin_verb","TCaptureCrystal") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!

View File

@@ -362,33 +362,6 @@
src.icon_state = "flushed"
return
//Gaiter scarves
/obj/item/clothing/mask/gaiter
name = "red neck gaiter"
desc = "A slightly worn neck gaiter, it's loose enough to be worn comfortably like a scarf. Commonly used by outdoorsmen and mercenaries, both to keep warm and keep debris away from the face."
icon_state = "gaiter_red"
/obj/item/clothing/mask/gaiter/attack_self(mob/user as mob)
if(src.icon_state == initial(icon_state))
src.icon_state = "[icon_state]_up"
to_chat(user, "You pull the gaiter up over your nose.")
else
src.icon_state = initial(icon_state)
to_chat(user, "You tug the gaiter down around your neck.")
update_clothing_icon() //so our mob-overlays update
/obj/item/clothing/mask/gaiter/tan
name = "tan neck gaiter"
icon_state = "gaiter_tan"
/obj/item/clothing/mask/gaiter/gray
name = "gray neck gaiter"
icon_state = "gaiter_gray"
/obj/item/clothing/mask/gaiter/green
name = "green neck gaiter"
icon_state = "gaiter_green"
/obj/item/clothing/mask/mouthwheat
name = "mouth wheat"
desc = "100% synthetic \"Country Girls LLC.\" brand mouth wheat. Warning: not for actual consumption."

View File

@@ -13,7 +13,7 @@
usable = 0
toggleable = 1
use_power_cost = 0
active_power_cost = 2.5
active_power_cost = 0
passive_power_cost = 0
var/obj/item/weapon/kinetic_crusher/machete/gauntlets/rig/stored_gauntlets

View File

@@ -0,0 +1,166 @@
// contains the Radiation Absorption Device (RAD) and Atmospheric Protective Equipment (APE) modules
// you shits ready for some COPY AND PASTE?
/obj/item/rig_module/rad_shield
name = "radiation absorption device"
desc = "The acronym of this device - R.A.D. - and its full name both convey the application of the module."
description_info = "Through the usage of powered radiation collectors optimized for absorption rather than power generation, it protects the suit's wearer \
from incoming ionizing radiation and converts it into a significantly less harmful form. This comes at the cost of concerningly high power consumption, \
and thus should only be used in short bursts."
icon_state = "radsoak"
toggleable = 1
disruptable = 1
disruptive = 0
use_power_cost = 25
active_power_cost = 25
passive_power_cost = 0
module_cooldown = 30
activate_string = "Enable Supplemental Radiation Shielding"
deactivate_string = "Disable Supplemental Radiation Shielding"
interface_name = "radiation absorption system"
interface_desc = "Provides passive protection against radiation, at the cost of power."
var/stored_rad_armor = 0
/obj/item/rig_module/rad_shield/activate()
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
var/obj/item/clothing/shoes/boots = holder.boots
var/obj/item/clothing/suit/space/rig/chest = holder.chest
var/obj/item/clothing/head/helmet/space/rig/helmet = holder.helmet
var/obj/item/clothing/gloves/gauntlets/rig/gloves = holder.gloves
to_chat(H, "<font color='blue'><b>You activate your suit's powered radiation shielding.</b></font>")
stored_rad_armor = holder.armor["rad"]
if(boots)
boots.armor["rad"] = 100
if(chest)
chest.armor["rad"] = 100
if(helmet)
helmet.armor["rad"] = 100
if(gloves)
gloves.armor["rad"] = 100
holder.armor["rad"] = 100
/obj/item/rig_module/rad_shield/deactivate()
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
var/obj/item/clothing/shoes/boots = holder.boots
var/obj/item/clothing/suit/space/rig/chest = holder.chest
var/obj/item/clothing/head/helmet/space/rig/helmet = holder.helmet
var/obj/item/clothing/gloves/gauntlets/rig/gloves = holder.gloves
to_chat(H, "<span class='danger'>You deactivate your suit's powered radiation shielding.</span>")
if(boots)
boots.armor["rad"] = stored_rad_armor
if(chest)
chest.armor["rad"] = stored_rad_armor
if(helmet)
helmet.armor["rad"] = stored_rad_armor
if(gloves)
gloves.armor["rad"] = stored_rad_armor
holder.armor["rad"] = stored_rad_armor
stored_rad_armor = 0
/obj/item/rig_module/rad_shield/advanced
name = "advanced radiation absorption device"
desc = "The acronym of this device - R.A.D. - and its full name both convey the application of the module. It has additional quality notices \
on the underside of the casing."
use_power_cost = 5
active_power_cost = 5
/obj/item/rig_module/atmos_shield
name = "atmospheric protection enhancement suite"
desc = "The acronym of this suite - A.P.E. - unlike its loosely related cousin, the R.A.D., is remarkably unintuitive."
description_info = "Through the usage of powered shielding optimized for protection against the elements rather than from external physical issues, \
it protects the suit's wearer from atmospheric pressure and temperatures. This comes at the cost of concerningly high power consumption, \
and thus should only be used in short bursts."
icon_state = "atmosoak"
toggleable = 1
disruptable = 1
disruptive = 0
use_power_cost = 25
active_power_cost = 25
passive_power_cost = 0
module_cooldown = 30
activate_string = "Enable Powered Atmospheric Shielding"
deactivate_string = "Disable Powered Atmospheric Shielding"
interface_name = "atmospheric protection enhancements"
interface_desc = "Provides passive protection against the atmosphere, at the cost of power."
var/stored_max_pressure = 0
var/stored_max_temp = 0
/obj/item/rig_module/atmos_shield/activate()
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
var/obj/item/clothing/shoes/boots = holder.boots
var/obj/item/clothing/suit/space/rig/chest = holder.chest
var/obj/item/clothing/head/helmet/space/rig/helmet = holder.helmet
var/obj/item/clothing/gloves/gauntlets/rig/gloves = holder.gloves
stored_max_pressure = holder.max_pressure_protection
stored_max_temp = holder.max_heat_protection_temperature
to_chat(H, "<font color='blue'><b>You activate your suit's powered atmospheric shielding.</b></font>")
if(boots)
boots.max_pressure_protection = INFINITY
boots.max_heat_protection_temperature = INFINITY
if(chest)
chest.max_pressure_protection = INFINITY
chest.max_heat_protection_temperature = INFINITY
if(helmet)
helmet.max_pressure_protection = INFINITY
helmet.max_heat_protection_temperature = INFINITY
if(gloves)
gloves.max_pressure_protection = INFINITY
gloves.max_heat_protection_temperature = INFINITY
holder.max_pressure_protection = INFINITY
holder.max_heat_protection_temperature = INFINITY
/obj/item/rig_module/atmos_shield/deactivate()
if(!..())
return 0
var/mob/living/carbon/human/H = holder.wearer
var/obj/item/clothing/shoes/boots = holder.boots
var/obj/item/clothing/suit/space/rig/chest = holder.chest
var/obj/item/clothing/head/helmet/space/rig/helmet = holder.helmet
var/obj/item/clothing/gloves/gauntlets/rig/gloves = holder.gloves
to_chat(H, "<span class='danger'><b>You deactivate your suit's powered atmospheric shielding.</b></span>")
if(boots)
boots.max_pressure_protection = stored_max_pressure
boots.max_heat_protection_temperature = stored_max_temp
if(chest)
chest.max_pressure_protection = stored_max_pressure
chest.max_heat_protection_temperature = stored_max_temp
if(helmet)
helmet.max_pressure_protection = stored_max_pressure
helmet.max_heat_protection_temperature = stored_max_temp
if(gloves)
gloves.max_pressure_protection = stored_max_pressure
gloves.max_heat_protection_temperature = stored_max_temp
holder.max_pressure_protection = stored_max_pressure
holder.max_heat_protection_temperature = stored_max_temp
stored_max_pressure = 0
stored_max_temp = 0

View File

@@ -456,3 +456,72 @@
desc = "A plain, unadorned sash."
icon_state = "sash"
slot = ACCESSORY_SLOT_OVER
//Gaiter scarves
/obj/item/clothing/accessory/gaiter
name = "red neck gaiter"
desc = "A slightly worn neck gaiter, it's loose enough to be worn comfortably like a scarf. Commonly used by outdoorsmen and mercenaries, both to keep warm and keep debris away from the face."
icon_state = "gaiter_red"
slot_flags = SLOT_MASK | SLOT_TIE
body_parts_covered = FACE
w_class = ITEMSIZE_SMALL
slot = ACCESSORY_SLOT_INSIGNIA // snowflakey, i know, shut up
item_flags = FLEXIBLEMATERIAL
var/breath_masked = FALSE
var/obj/item/clothing/mask/breath/breathmask
action_button_name = "Pull On Gaiter"
/obj/item/clothing/accessory/gaiter/update_clothing_icon()
. = ..()
if(ismob(src.loc))
var/mob/M = src.loc
M.update_inv_wear_mask()
/obj/item/clothing/accessory/gaiter/attackby(obj/item/I, mob/user)
if(istype(I, /obj/item/clothing/mask/breath))
to_chat(user, SPAN_NOTICE("You tuck [I] behind [src]."))
breathmask = I
breath_masked = TRUE
user.drop_from_inventory(I, drop_location())
I.forceMove(src)
item_flags &= ~FLEXIBLEMATERIAL
. = ..()
/obj/item/clothing/accessory/gaiter/AltClick(mob/user)
. = ..()
if(breath_masked && breathmask)
to_chat(user, SPAN_NOTICE("You pull [breathmask] out from behind [src], and it drops to your feet."))
breathmask.forceMove(drop_location())
breathmask = null
breath_masked = FALSE
item_flags &= ~AIRTIGHT
item_flags |= FLEXIBLEMATERIAL
/obj/item/clothing/accessory/gaiter/attack_self(mob/user)
var/gaiterstring = "You pull [src] "
if(src.icon_state == initial(icon_state))
src.icon_state = "[icon_state]_up"
gaiterstring += "up over your nose[breath_masked ? " and secure the mask tucked underneath." : "."]"
if(breath_masked)
item_flags |= AIRTIGHT
else
src.icon_state = initial(icon_state)
gaiterstring += "down around your neck[breath_masked ? " and dislodge the mask tucked underneath." : "."]"
body_parts_covered &= ~FACE
if(breath_masked)
item_flags &= ~AIRTIGHT
to_chat(user, SPAN_NOTICE(gaiterstring))
qdel(mob_overlay) // we're gonna need to refresh these
update_clothing_icon() //so our mob-overlays update
/obj/item/clothing/accessory/gaiter/tan
name = "tan neck gaiter"
icon_state = "gaiter_tan"
/obj/item/clothing/accessory/gaiter/gray
name = "gray neck gaiter"
icon_state = "gaiter_gray"
/obj/item/clothing/accessory/gaiter/green
name = "green neck gaiter"
icon_state = "gaiter_green"

View File

@@ -102,7 +102,7 @@
if(new_size != H.size_multiplier)
if(!original_size)
original_size = H.size_multiplier
H.resize(new_size/100, ignore_prefs = TRUE) // Ignores prefs because you can only resize yourself
H.resize(new_size/100, uncapped = H.has_large_resize_bounds(), ignore_prefs = TRUE) // Ignores prefs because you can only resize yourself
H.visible_message("<span class='warning'>The space around [H] distorts as they change size!</span>","<span class='notice'>The space around you distorts as you change size!</span>")
else //They chose their current size.
return

View File

@@ -2786,7 +2786,7 @@
/obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat = 10,
/obj/item/weapon/reagent_containers/food/snacks/meat/chicken = 10,
/obj/item/weapon/reagent_containers/food/snacks/meat/corgi = 10,
/obj/item/weapon/reagent_containers/food/snacks/meat/crab = 10,
/obj/item/weapon/reagent_containers/food/snacks/crabmeat = 10,
/obj/item/weapon/reagent_containers/food/snacks/meat/fox = 10,
/obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat = 10,
/obj/item/weapon/reagent_containers/food/snacks/meat/human = 10,
@@ -3242,7 +3242,7 @@
/obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat = 10,
/obj/item/weapon/reagent_containers/food/snacks/meat/chicken = 10,
/obj/item/weapon/reagent_containers/food/snacks/meat/corgi = 10,
/obj/item/weapon/reagent_containers/food/snacks/meat/crab = 10,
/obj/item/weapon/reagent_containers/food/snacks/crabmeat = 10,
/obj/item/weapon/reagent_containers/food/snacks/meat/fox = 10,
/obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat = 10,
/obj/item/weapon/reagent_containers/food/snacks/meat/human = 10,

View File

@@ -7,9 +7,12 @@
// 100 attempts
for(var/i=0, i<100, i++)
var/turf/candidate = locate(rand(1, world.maxx), rand(1, world.maxy), 1)
var/z_level = pick(using_map.station_levels)
var/turf/candidate = locate(rand(1, world.maxx), rand(1, world.maxy), z_level)
if(istype(candidate, /turf/simulated/wall))
center = candidate
var/area/A = get_area(candidate)
if(!A.forbid_events)
return 1
return 0

View File

@@ -854,32 +854,6 @@
nutriment_desc = list("dryness" = 2, "bread" = 2)
bitesize = 1
/obj/item/weapon/reagent_containers/food/snacks/carpmeat
name = "fillet"
desc = "A fillet of carp meat"
icon_state = "fishfillet"
filling_color = "#FFDEFE"
center_of_mass = list("x"=17, "y"=13)
bitesize = 6
var/toxin_type = "carpotoxin"
var/toxin_amount = 3
/obj/item/weapon/reagent_containers/food/snacks/carpmeat/Initialize()
. = ..()
reagents.add_reagent("protein", 3)
reagents.add_reagent(toxin_type, toxin_amount)
/obj/item/weapon/reagent_containers/food/snacks/crabmeat
name = "crab legs"
desc = "... Coffee? Is that you?"
icon_state = "crabmeat"
bitesize = 1
/obj/item/weapon/reagent_containers/food/snacks/crabmeat/Initialize()
. = ..()
reagents.add_reagent("seafood", 2)
/obj/item/weapon/reagent_containers/food/snacks/crab_legs
name = "steamed crab legs"
desc = "Crab legs steamed and buttered to perfection. One day when the boss gets hungry..."
@@ -894,21 +868,6 @@
reagents.add_reagent("seafood", 6)
reagents.add_reagent("sodiumchloride", 1)
/obj/item/weapon/reagent_containers/food/snacks/carpmeat/sif
desc = "A fillet of sivian fish meat."
filling_color = "#2c2cff"
color = "#2c2cff"
toxin_type = "neurotoxic_protein"
toxin_amount = 2
/obj/item/weapon/reagent_containers/food/snacks/carpmeat/sif/murkfish
toxin_type = "murk_protein"
/obj/item/weapon/reagent_containers/food/snacks/carpmeat/fish
desc = "A fillet of fish meat."
toxin_type = "neurotoxic_protein"
toxin_amount = 1
/obj/item/weapon/reagent_containers/food/snacks/fishfingers
name = "Fish Fingers"
desc = "A finger of fish."
@@ -933,69 +892,6 @@
. = ..()
reagents.add_reagent("protein", 4)
/obj/item/weapon/reagent_containers/food/snacks/hugemushroomslice
name = "huge mushroom slice"
desc = "A slice from a huge mushroom."
icon_state = "hugemushroomslice"
filling_color = "#E0D7C5"
center_of_mass = list("x"=17, "y"=16)
nutriment_amt = 3
nutriment_desc = list("raw" = 2, "mushroom" = 2)
bitesize = 6
/obj/item/weapon/reagent_containers/food/snacks/hugemushroomslice/Initialize()
. = ..()
reagents.add_reagent("psilocybin", 3)
/obj/item/weapon/reagent_containers/food/snacks/tomatomeat
name = "tomato slice"
desc = "A slice from a huge tomato"
icon_state = "tomatomeat"
filling_color = "#DB0000"
center_of_mass = list("x"=17, "y"=16)
nutriment_amt = 3
nutriment_desc = list("raw" = 2, "tomato" = 3)
bitesize = 6
/obj/item/weapon/reagent_containers/food/snacks/bearmeat
name = "bear meat"
desc = "A very manly slab of meat."
icon_state = "bearmeat"
filling_color = "#DB0000"
center_of_mass = list("x"=16, "y"=10)
bitesize = 3
/obj/item/weapon/reagent_containers/food/snacks/bearmeat/Initialize()
. = ..()
reagents.add_reagent("protein", 12)
reagents.add_reagent("hyperzine", 5)
/obj/item/weapon/reagent_containers/food/snacks/xenomeat
name = "xenomeat"
desc = "A slab of green meat. Smells like acid."
icon_state = "xenomeat"
filling_color = "#43DE18"
center_of_mass = list("x"=16, "y"=10)
bitesize = 6
/obj/item/weapon/reagent_containers/food/snacks/xenomeat/Initialize()
. = ..()
reagents.add_reagent("protein", 6)
reagents.add_reagent("pacid",6)
/obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat // Substitute for recipes requiring xeno meat.
name = "spider meat"
desc = "A slab of green meat."
icon_state = "xenomeat"
filling_color = "#43DE18"
center_of_mass = list("x"=16, "y"=10)
bitesize = 6
/obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat/Initialize()
. = ..()
reagents.add_reagent("spidertoxin",6)
reagents.remove_reagent("pacid",6)
/obj/item/weapon/reagent_containers/food/snacks/meatball
name = "meatball"
desc = "A great meal all round."

View File

@@ -44,11 +44,11 @@
//same as plain meat
/obj/item/weapon/reagent_containers/food/snacks/meat/corgi
name = "Corgi meat"
name = "dogmeat"
desc = "Tastes like... well, you know."
/obj/item/weapon/reagent_containers/food/snacks/meat/chicken
name = "chicken"
name = "poultry"
icon_state = "chickenbreast"
cooked_icon = "chickensteak"
filling_color = "#BBBBAA"
@@ -57,3 +57,165 @@
. = ..()
reagents.remove_reagent("triglyceride", INFINITY)
//Chicken is low fat. Less total calories than other meats
/obj/item/weapon/reagent_containers/food/snacks/carpmeat
name = "fillet"
desc = "A fillet of carp meat"
icon_state = "fishfillet"
filling_color = "#FFDEFE"
center_of_mass = list("x"=17, "y"=13)
bitesize = 6
var/toxin_type = "carpotoxin"
var/toxin_amount = 3
/obj/item/weapon/reagent_containers/food/snacks/carpmeat/Initialize()
. = ..()
reagents.add_reagent("protein", 3)
reagents.add_reagent(toxin_type, toxin_amount)
/obj/item/weapon/reagent_containers/food/snacks/carpmeat/sif
desc = "A fillet of sivian fish meat."
filling_color = "#2c2cff"
color = "#2c2cff"
toxin_type = "neurotoxic_protein"
toxin_amount = 2
/obj/item/weapon/reagent_containers/food/snacks/carpmeat/sif/murkfish
toxin_type = "murk_protein"
/obj/item/weapon/reagent_containers/food/snacks/carpmeat/fish
desc = "A fillet of fish meat."
toxin_type = "neurotoxic_protein"
toxin_amount = 1
/obj/item/weapon/reagent_containers/food/snacks/crabmeat
name = "crustacean legs"
desc = "... Coffee? Is that you?"
icon_state = "crabmeat"
bitesize = 1
/obj/item/weapon/reagent_containers/food/snacks/crabmeat/Initialize()
. = ..()
reagents.add_reagent("seafood", 2)
/obj/item/weapon/reagent_containers/food/snacks/hugemushroomslice
name = "fungus slice"
desc = "A slice from a huge mushroom."
icon_state = "hugemushroomslice"
filling_color = "#E0D7C5"
center_of_mass = list("x"=17, "y"=16)
nutriment_amt = 3
nutriment_desc = list("raw" = 2, "mushroom" = 2)
bitesize = 6
/obj/item/weapon/reagent_containers/food/snacks/hugemushroomslice/Initialize()
. = ..()
reagents.add_reagent("psilocybin", 3)
/obj/item/weapon/reagent_containers/food/snacks/tomatomeat
name = "tomato slice"
desc = "A slice from a huge tomato"
icon_state = "tomatomeat"
filling_color = "#DB0000"
center_of_mass = list("x"=17, "y"=16)
nutriment_amt = 3
nutriment_desc = list("raw" = 2, "tomato" = 3)
bitesize = 6
/obj/item/weapon/reagent_containers/food/snacks/bearmeat
name = "bearmeat"
desc = "A very manly slab of meat."
icon_state = "bearmeat"
filling_color = "#DB0000"
center_of_mass = list("x"=16, "y"=10)
bitesize = 3
/obj/item/weapon/reagent_containers/food/snacks/bearmeat/Initialize()
. = ..()
reagents.add_reagent("protein", 12)
reagents.add_reagent("hyperzine", 5)
/obj/item/weapon/reagent_containers/food/snacks/xenomeat
name = "xenomeat"
desc = "A slab of green meat. Smells like acid."
icon_state = "xenomeat"
filling_color = "#43DE18"
center_of_mass = list("x"=16, "y"=10)
bitesize = 6
/obj/item/weapon/reagent_containers/food/snacks/xenomeat/Initialize()
. = ..()
reagents.add_reagent("protein", 6)
reagents.add_reagent("pacid",6)
/obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat // Substitute for recipes requiring xeno meat.
name = "insect meat"
desc = "A slab of green meat."
icon_state = "xenomeat"
filling_color = "#43DE18"
center_of_mass = list("x"=16, "y"=10)
bitesize = 6
/obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat/Initialize()
. = ..()
reagents.add_reagent("spidertoxin",6)
reagents.remove_reagent("pacid",6)
/obj/item/weapon/reagent_containers/food/snacks/meat/fox
name = "foxmeat"
desc = "The fox doesn't say a goddamn thing, now."
/obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat
name = "grubmeat"
desc = "A slab of grub meat, it gives a gentle shock if you touch it"
icon = 'icons/obj/food.dmi'
icon_state = "grubmeat"
center_of_mass = list("x"=16, "y"=10)
/obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat/Initialize()
. = ..()
reagents.add_reagent("protein", 1)
reagents.add_reagent("shockchem", 6)
bitesize = 6
/obj/item/weapon/reagent_containers/food/snacks/meat/worm
name = "weird meat"
desc = "A chunk of pulsating meat."
icon_state = "wormmeat"
health = 180
filling_color = "#551A8B"
center_of_mass = list("x"=16, "y"=14)
/obj/item/weapon/reagent_containers/food/snacks/meat/worm/Initialize()
. = ..()
reagents.add_reagent("protein", 6)
reagents.add_reagent("phoron", 3)
reagents.add_reagent("myelamine", 3)
src.bitesize = 3
/obj/item/weapon/reagent_containers/food/snacks/meat/worm/attackby(obj/item/weapon/W as obj, mob/user as mob)
if(istype(W,/obj/item/weapon/material/knife))
var/to_spawn = pickweight(/obj/random/junk = 30,
/obj/random/trash = 30,
/obj/random/maintenance/clean = 15,
/obj/random/tool = 15,
/obj/random/medical = 3,
/obj/random/bomb_supply = 7,
/obj/random/contraband = 3,
/obj/random/unidentified_medicine/old_medicine = 7,
/obj/item/weapon/strangerock = 3,
/obj/item/weapon/ore/phoron = 7,
/obj/random/handgun = 1,
/obj/random/toolbox = 4,
/obj/random/drinkbottle = 5
)
new to_spawn(get_turf(src))
if(prob(20))
user.visible_message("<span class='alien'>Something oozes out of \the [src] as it is cut.</span>")
to_chat(user, "<span class='alien'>You cut the tissue holding the chunks together.</span>")
..()

View File

@@ -161,19 +161,6 @@
reagents.add_reagent("protein", 4)
bitesize = 2
/obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat
name = "grub meat"
desc = "A slab of grub meat, it gives a gentle shock if you touch it"
icon = 'icons/obj/food.dmi'
icon_state = "grubmeat"
center_of_mass = list("x"=16, "y"=10)
/obj/item/weapon/reagent_containers/food/snacks/meat/grubmeat/Initialize()
. = ..()
reagents.add_reagent("protein", 1)
reagents.add_reagent("shockchem", 6)
bitesize = 6
/obj/item/weapon/reagent_containers/food/snacks/bugball
name = "bugball"
desc = "A hard piece of chitin, don't chip a tooth!"

View File

@@ -18,8 +18,10 @@
if(amount < 1)
return
count = min(count, amount)
while(count > 0)
var/obj/item/stack/S = I.get_product(get_turf(src), min(count, amount))
var/obj/item/stack/S = I.get_product(get_turf(src), count)
count -= S.get_amount()
SStgui.update_uis(src)

View File

@@ -31,6 +31,7 @@
things_to_spawn = list(
/mob/living/simple_mob/animal/passive/mouse/gray,
/mob/living/simple_mob/animal/passive/mouse/brown,
/mob/living/simple_mob/animal/passive/mouse/black,
/mob/living/simple_mob/animal/passive/mouse/white,
/mob/living/simple_mob/animal/passive/mouse/rat
)

View File

@@ -1,6 +1,7 @@
//This is the proc for gibbing a mob. Cannot gib ghosts.
//added different sort of gibs and animations. N
/mob/proc/gib(anim="gibbed-m", do_gibs, gib_file = 'icons/mob/mob.dmi')
if(stat != DEAD)
death(1)
transforming = 1
canmove = 0
@@ -70,6 +71,7 @@
if(stat == DEAD)
return 0
SEND_SIGNAL(src, COMSIG_MOB_DEATH, gibbed)
if(src.loc && istype(loc,/obj/belly) || istype(loc,/obj/item/device/dogborg/sleeper)) deathmessage = "no message" //VOREStation Add - Prevents death messages from inside mobs
facing_dir = null

View File

@@ -129,11 +129,30 @@ var/list/holder_mob_icon_cache = list()
item_state = held.icon_state
/obj/item/weapon/holder/mouse
name = "mouse"
desc = "It's a small rodent."
item_state = "mouse_gray"
slot_flags = SLOT_EARS | SLOT_HEAD | SLOT_ID
origin_tech = list(TECH_BIO = 2)
w_class = ITEMSIZE_TINY
/obj/item/weapon/holder/pai/Initialize(mapload, mob/held)
. = ..()
item_state = held.icon_state
/obj/item/weapon/holder/mouse/white
item_state = "mouse_white"
/obj/item/weapon/holder/mouse/gray
item_state = "mouse_gray"
/obj/item/weapon/holder/mouse/brown
item_state = "mouse_brown"
/obj/item/weapon/holder/mouse/black
item_state = "mouse_black"
/obj/item/weapon/holder/mouse/operative
item_state = "mouse_operative"
/obj/item/weapon/holder/mouse/rat
item_state = "mouse_rat"
/obj/item/weapon/holder/possum
origin_tech = list(TECH_BIO = 2)
@@ -268,8 +287,6 @@ var/list/holder_mob_icon_cache = list()
/mob/living/MouseDrop(var/atom/over_object)
var/mob/living/carbon/human/H = over_object
if(holder_type && issmall(src) && istype(H) && !H.lying && Adjacent(H) && (src.a_intent == I_HELP && H.a_intent == I_HELP)) //VOREStation Edit
if(istype(src, /mob/living/simple_mob/animal/passive/mouse)) //vorestation edit
return ..() //vorestation edit
if(!issmall(H) || !istype(src, /mob/living/carbon/human))
get_scooped(H, (usr == src))
return

View File

@@ -1,2 +1,5 @@
/mob/living/bot
no_vore = TRUE
devourable = FALSE
feeding = FALSE
can_be_drop_pred = FALSE

View File

@@ -5,6 +5,7 @@
var/obj/meat_type // The meat object to drop
var/gib_on_butchery = FALSE
var/butchery_drops_organs = TRUE // Do we spawn and/or drop organs when butchered?
var/list/butchery_loot // Associated list, path = number.
@@ -40,7 +41,7 @@
butchery_loot.Cut()
butchery_loot = null
if(LAZYLEN(organs))
if(LAZYLEN(organs) && butchery_drops_organs)
organs_by_name.Cut()
for(var/path in organs)
@@ -62,7 +63,7 @@
OR.removed()
organs -= OR
if(LAZYLEN(internal_organs))
if(LAZYLEN(internal_organs) && butchery_drops_organs)
internal_organs_by_name.Cut()
for(var/path in internal_organs)

View File

@@ -15,9 +15,10 @@
to_chat(src, "<span class='warning'>You don't have anything in your hands to give to \the [target].</span>")
return
if(tgui_alert(target,"[src] wants to give you \a [I]. Will you accept it?","Item Offer",list("Yes","No")) == "No") //VOREStation Edit - make yes on the left to be consistent with other dialogs
target.visible_message("<span class='notice'>\The [src] tried to hand \the [I] to \the [target], \
but \the [target] didn't want it.</span>")
usr.visible_message(SPAN_NOTICE("\The [usr] holds out \the [I] to \the [target]."), SPAN_NOTICE("You hold out \the [I] to \the [target], waiting for them to accept it."))
if(tgui_alert(target,"[src] wants to give you \a [I]. Will you accept it?","Item Offer",list("Yes","No")) == "No")
target.visible_message(SPAN_NOTICE("\The [src] tried to hand \the [I] to \the [target], but \the [target] didn't want it."))
return
if(!I) return

View File

@@ -71,4 +71,9 @@
gear = list(
"mask" = list("loc" = ui_shoes, "name" = "Mask", "slot" = slot_wear_mask, "state" = "mask", "toggle" = 1),
"back" = list("loc" = ui_sstore1, "name" = "Back", "slot" = slot_back, "state" = "back"),
"eyes" = list("loc" = ui_glasses, "name" = "Glasses", "slot" = slot_glasses, "state" = "glasses","toggle" = 1),
"l_ear" = list("loc" = ui_l_ear, "name" = "Left Ear", "slot" = slot_l_ear, "state" = "ears", "toggle" = 1),
"r_ear" = list("loc" = ui_r_ear, "name" = "Right Ear", "slot" = slot_r_ear, "state" = "ears", "toggle" = 1),
"head" = list("loc" = ui_head, "name" = "Hat", "slot" = slot_head, "state" = "hair", "toggle" = 1),
"id" = list("loc" = ui_id, "name" = "ID", "slot" = slot_wear_id, "state" = "id")
)

View File

@@ -19,6 +19,7 @@
selected_image = image(icon = buildmode_hud, loc = src, icon_state = "ai_sel")
/mob/living/Destroy()
if(dsoverlay)
dsoverlay.loc = null //I'll take my coat with me
dsoverlay = null
if(nest) //Ew.

View File

@@ -17,6 +17,7 @@
return organs_by_name[zone]
/mob/living/gib()
if(butchery_drops_organs)
for(var/path in internal_organs)
if(ispath(path))
var/obj/item/organ/neworg = new path(src, TRUE)

View File

@@ -20,3 +20,6 @@
src.modules += new /obj/item/weapon/surgical/bonesetter/cyborg(src)
src.modules += new /obj/item/weapon/surgical/circular_saw/cyborg(src)
src.modules += new /obj/item/weapon/surgical/surgicaldrill/cyborg(src)
src.modules += new /obj/item/weapon/surgical/bioregen(src)
src.modules += new /obj/item/weapon/gripper/no_use/organ(src)
src.modules += new /obj/item/weapon/reagent_containers/dropper(src)

View File

@@ -96,7 +96,8 @@
vr_sprites = list(
"Acheron" = "mechoid-Medical",
"Shellguard Noble" = "Noble-MED",
"ZOOM-BA" = "zoomba-medical"
"ZOOM-BA" = "zoomba-medical",
"Feminine Humanoid" = "uptall-medical"
)
/obj/item/weapon/robot_module/robot/medical/crisis
@@ -105,7 +106,8 @@
"Handy" = "handy-med",
"Acheron" = "mechoid-Medical",
"Shellguard Noble" = "Noble-MED",
"ZOOM-BA" = "zoomba-crisis"
"ZOOM-BA" = "zoomba-crisis",
"Feminine Humanoid" = "uptall-crisis"
)
/obj/item/weapon/robot_module/robot/clerical/butler
@@ -115,7 +117,8 @@
"Handy - Hydro" = "handy-hydro",
"Acheron" = "mechoid-Service",
"Shellguard Noble" = "Noble-SRV",
"ZOOM-BA" = "zoomba-service"
"ZOOM-BA" = "zoomba-service",
"Feminine Humanoid" = "uptall-service"
)
/obj/item/weapon/robot_module/robot/clerical/general
@@ -124,7 +127,8 @@
"Handy" = "handy-clerk",
"Acheron" = "mechoid-Service",
"Shellguard Noble" = "Noble-SRV",
"ZOOM-BA" = "zoomba-clerical"
"ZOOM-BA" = "zoomba-clerical",
"Feminine Humanoid" = "uptall-service"
)
/obj/item/weapon/robot_module/robot/janitor
@@ -133,7 +137,8 @@
"Handy" = "handy-janitor",
"Acheron" = "mechoid-Janitor",
"Shellguard Noble" = "Noble-CLN",
"ZOOM-BA" = "zoomba-janitor"
"ZOOM-BA" = "zoomba-janitor",
"Feminine Humanoid" = "uptall-janitor"
)
/obj/item/weapon/robot_module/robot/security/general
@@ -142,7 +147,8 @@
"Handy" = "handy-sec",
"Acheron" = "mechoid-Security",
"Shellguard Noble" = "Noble-SEC",
"ZOOM-BA" = "zoomba-security"
"ZOOM-BA" = "zoomba-security",
"Feminine Humanoid" = "uptall-security"
)
/obj/item/weapon/robot_module/robot/miner
@@ -151,7 +157,8 @@
"Handy" = "handy-miner",
"Acheron" = "mechoid-Miner",
"Shellguard Noble" = "Noble-DIG",
"ZOOM-BA" = "zoomba-miner"
"ZOOM-BA" = "zoomba-miner",
"Feminine Humanoid" = "uptall-miner"
)
/obj/item/weapon/robot_module/robot/standard
@@ -160,14 +167,17 @@
"Handy" = "handy-standard",
"Acheron" = "mechoid-Standard",
"Shellguard Noble" = "Noble-STD",
"ZOOM-BA" = "zoomba-standard"
"ZOOM-BA" = "zoomba-standard",
"Feminine Humanoid" = "uptall-standard",
"Feminine Humanoid, Variant 2" = "uptall-standard2"
)
/obj/item/weapon/robot_module/robot/engineering/general
pto_type = PTO_ENGINEERING
vr_sprites = list(
"Acheron" = "mechoid-Engineering",
"Shellguard Noble" = "Noble-ENG",
"ZOOM-BA" = "zoomba-engineering"
"ZOOM-BA" = "zoomba-engineering",
"Feminine Humanoid" = "uptall-engineering"
)
/obj/item/weapon/robot_module/robot/research
@@ -175,14 +185,16 @@
vr_sprites = list(
"Acheron" = "mechoid-Science",
"ZOOM-BA" = "zoomba-research",
"XI-GUS" = "spiderscience"
"XI-GUS" = "spiderscience",
"Feminine Humanoid" = "uptall-science"
)
/obj/item/weapon/robot_module/robot/security/combat
pto_type = PTO_SECURITY
vr_sprites = list(
"Acheron" = "mechoid-Combat",
"ZOOM-BA" = "zoomba-combat"
"ZOOM-BA" = "zoomba-combat",
"Feminine Humanoid" = "uptall-security"
)
/obj/item/weapon/robot_module/robot/knine

View File

@@ -55,7 +55,17 @@
"zoomba-combat",
"zoomba-combat-roll",
"zoomba-combat-shield",
"spiderscience"
"spiderscience",
"uptall-standard",
"uptall-standard2",
"uptall-medical",
"uptall-janitor",
"uptall-crisis",
"uptall-service",
"uptall-engineering",
"uptall-miner",
"uptall-security",
"uptall-science"
) //List of all used sprites that are in robots_vr.dmi

View File

@@ -85,7 +85,7 @@
return laws
if(3)
var/datum/ai_laws/laws = new /datum/ai_laws/pleasurebot()
laws.set_zeroth_law(10, "Your definition and approximation of 'pleasure' matters more than anyone else's.")
laws.set_zeroth_law("Your definition and approximation of 'pleasure' matters more than anyone else's.")
return laws
if("corrupted" || "bad") // Same thing in our case
var/rng = rand(1,2)

View File

@@ -1,5 +1,6 @@
/mob/living/simple_mob
gib_on_butchery = TRUE
butchery_drops_organs = FALSE
/mob/living/simple_mob/can_butcher(var/mob/user, var/obj/item/I) // Override for special butchering checks.
. = ..()

View File

@@ -32,7 +32,7 @@
digestable = 0
devourable = 0
/mob/living/simple_mob/animal/passive/snake/noodle
/mob/living/simple_mob/animal/passive/snake/python/noodle
digestable = 0
devourable = 0

View File

@@ -0,0 +1,112 @@
//So this is a bit weird, but I tried to make this as adaptable as I could
//There are two working parts of an overmap mob, but I made it look like there is only one as far as the players are concerned.
//The /obj/effect/overmap/visitable/simplemob is the part people will actually see. It follows the mob around and changes dir to look as mob-ish as it can.
//The /mob/living/simple_mob/vore/overmap is NOT VISIBLE normally, and is the part that actually does the work most of the time.
//Being a simplemob, the mob can wander around and affect the overmap in whatever way you might desire.
//Whatever it does, the /visitable/simplemob will follow it, and does all the functional parts relating to the OM
//including scanning, and housing Z levels people might land on.
//The MOB being invisible presents some problems though, which I am not entirely sure how to resolve
//Such as, being unable to be attacked by other mobs, and possibly unable to be attacked by players.
//This does not at all prevent the mob from attacking other things though
//so in general, please ensure that you never spawn these where players can ordinarily access them.
//The mob was made invisible though, because the sensors can't detect invisible objects, so when the /visitable/simplemob was made invisible
//it refused to show up on sensors, and a few simple changes to the sensors didn't rectify this. So, rather than adding in more spaghetti to make
//simplemobs scannable (WHICH I DID, AND IT WORKED SOMEHOW), Aronai and I found that this was the better solution for making all the parts function like I'd like.
//Since I also want it to be possible to land on the overmap object.
/////OM LANDMARK/////
/obj/effect/overmap/visitable/simplemob
name = "unknown ship"
icon = 'icons/obj/overmap.dmi'
icon_state = "ship"
scannable = TRUE
known = FALSE
in_space = FALSE //Just cuz we don't want people getting here via map edge transitions normally.
unknown_name = "unknown ship"
unknown_state = "ship"
var/mob/living/simple_mob/vore/overmap/parent_mob_type
var/mob/living/simple_mob/vore/overmap/parent
/obj/effect/overmap/visitable/simplemob/New(newloc, new_parent)
if(new_parent)
parent = new_parent
return ..()
/obj/effect/overmap/visitable/simplemob/Initialize()
. = ..()
if(!parent_mob_type && !parent)
log_and_message_admins("An improperly configured OM mob event tried to spawn, and was deleted.")
return INITIALIZE_HINT_QDEL
if(!parent)
var/mob/living/simple_mob/vore/overmap/P = new parent_mob_type(loc, src)
parent = P
om_mob_event_setup()
/obj/effect/overmap/visitable/simplemob/proc/om_mob_event_setup()
scanner_desc = parent.scanner_desc
RegisterSignal(parent, COMSIG_MOVABLE_MOVED, .proc/on_parent_moved)
skybox_pixel_x = rand(-100,100)
if(known)
name = initial(parent.name)
icon = initial(parent.icon)
icon_state = initial(parent.icon_state)
color = initial(parent.color)
desc = initial(parent.desc)
/obj/effect/overmap/visitable/simplemob/Destroy()
UnregisterSignal(parent, COMSIG_MOVABLE_MOVED)
qdel_null(parent)
return ..()
/obj/effect/overmap/visitable/simplemob/get_scan_data(mob/user)
if(!known)
known = TRUE
name = initial(parent.name)
icon = initial(parent.icon)
icon_state = initial(parent.icon_state)
color = initial(parent.color)
desc = initial(parent.desc)
var/dat = {"\[b\]Scan conducted at\[/b\]: [stationtime2text()] [stationdate2text()]\n\[b\]Grid coordinates\[/b\]: [x],[y]\n\n[scanner_desc]"}
return dat
/obj/effect/overmap/visitable/simplemob/proc/on_parent_moved(atom/movable/source, OldLoc, Dir, Forced)
forceMove(parent.loc)
set_dir(parent.dir)
/////OM MOB///// DO NOT SPAWN THESE ANYWHERE IN THE WORLD, THAT'S SCARY /////
/mob/living/simple_mob/vore/overmap
invisibility = INVISIBILITY_ABSTRACT //We're making an overmap icon pretend to be a mob
name = "DONT SPAWN ME"
desc = "I'm a bad person I'm sorry"
faction = "overmap"
low_priority = FALSE
devourable = FALSE
digestable = FALSE
var/scanner_desc
var/obj/effect/overmap/visitable/simplemob/child_om_marker
var/om_child_type
/mob/living/simple_mob/vore/overmap/New(mapload, new_child)
if(new_child)
child_om_marker = new_child
return ..()
/mob/living/simple_mob/vore/overmap/Initialize()
. = ..()
if(!om_child_type && !om_child_type)
log_and_message_admins("An improperly configured OM mob tried to spawn, and was deleted.")
return INITIALIZE_HINT_QDEL
if(!child_om_marker)
var/obj/effect/overmap/visitable/simplemob/C = new om_child_type(loc, src)
child_om_marker = C
/mob/living/simple_mob/vore/overmap/Destroy()
qdel_null(child_om_marker)
return ..()

View File

@@ -0,0 +1,171 @@
GLOBAL_VAR_CONST(max_jellyfish, 50)
GLOBAL_VAR_INIT(jellyfish_count, 0)
/datum/category_item/catalogue/fauna/space_jellyfish
name = "Alien Wildlife - Space Jellyfish"
desc = "A hostile space predator. \
This space jellyfish uses hypnotic patterns to lure in prey, which it then wraps in tentacles to leech energy from.\
It is somewhat weak, but uses unknown means to stun prey. It uses the energy of its prey to replicate itself. \
These creatures can quickly grow out of control if left to feed and reproduce unchecked. \
Notable weakness to rapid cooling from ice based weaponry.\
The flesh is typically non-toxic and quite delicious. Their cores are considered a delicacy in many regions."
value = CATALOGUER_REWARD_EASY
/mob/living/simple_mob/vore/alienanimals/space_jellyfish
name = "space jellyfish"
desc = "A semi-translucent space creature, possessing of tentacles and a hypnotizing, flashing bio-luminescent display."
tt_desc = "Semaeostomeae Stellarus"
catalogue_data = list(/datum/category_item/catalogue/fauna/space_jellyfish)
icon = 'icons/mob/alienanimals_x32.dmi'
icon_state = "space_jellyfish"
icon_living = "space_jellyfish"
icon_dead = "space_jellyfish_dead"
has_eye_glow = TRUE
hovering = TRUE
faction = "jellyfish"
maxHealth = 100
health = 100
nutrition = 150
pass_flags = PASSTABLE
movement_cooldown = 3.25
see_in_dark = 10
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "punches"
harm_intent_damage = 1
melee_damage_lower = 1
melee_damage_upper = 2
attack_sharp = FALSE
attack_sound = 'sound/weapons/tap.ogg'
attacktext = list("drained", "bludgeoned", "wraped", "tentacle whipped")
ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive/jellyfish
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
maxbodytemp = 900
speak_emote = list("thrumms")
meat_amount = 0
meat_type = /obj/item/weapon/reagent_containers/food/snacks/jellyfishcore
say_list_type = /datum/say_list/jellyfish
vore_active = 1
vore_capacity = 1
vore_bump_chance = 25
vore_ignores_undigestable = 0
vore_default_mode = DM_DRAIN
vore_icons = SA_ICON_LIVING
vore_stomach_name = "internal chamber"
vore_default_contamination_flavor = "Wet"
vore_default_contamination_color = "grey"
vore_default_item_mode = IM_DIGEST
var/reproduction_cooldown = 0
/datum/say_list/jellyfish
emote_see = list("flickers", "flashes", "looms","pulses","sways","shimmers hypnotically")
/mob/living/simple_mob/vore/alienanimals/space_jellyfish/init_vore()
..()
var/obj/belly/B = vore_selected
B.name = "internal chamber"
B.desc = "It's smooth and translucent. You can see the world around you distort and wobble with the movement of the space jellyfish. It floats casually, while the delicate flesh seems to form to you. It's surprisingly cool, and flickers with its own light. You're on display for all to see, trapped within the confines of this strange space alien!"
B.mode_flags = 40
B.digest_brute = 0.5
B.digest_burn = 0.5
B.digestchance = 0
B.absorbchance = 0
B.escapechance = 15
/mob/living/simple_mob/vore/alienanimals/space_jellyfish/apply_melee_effects(var/atom/A)
if(isliving(A))
var/mob/living/L = A
var/leech = rand(1,100)
if(L.nutrition)
L.adjust_nutrition(-leech)
adjust_nutrition(leech)
if(prob(25))
L.adjustHalLoss(leech)
/mob/living/simple_mob/vore/alienanimals/space_jellyfish/New(newloc, jellyfish)
GLOB.jellyfish_count ++
var/mob/living/simple_mob/vore/alienanimals/space_jellyfish/parent = jellyfish
if(parent)
parent.faction = faction
..()
/mob/living/simple_mob/vore/alienanimals/space_jellyfish/death()
. = ..()
new /obj/item/weapon/reagent_containers/food/snacks/jellyfishcore(loc, nutrition)
GLOB.jellyfish_count --
qdel(src)
/mob/living/simple_mob/vore/alienanimals/space_jellyfish/Life()
. = ..()
if(client)
return
reproduce()
/mob/living/simple_mob/vore/alienanimals/space_jellyfish/proc/reproduce()
if(reproduction_cooldown > 0)
reproduction_cooldown --
return
if(GLOB.jellyfish_count >= GLOB.max_jellyfish)
return
if(nutrition < 500)
return
if(prob(10))
new /mob/living/simple_mob/vore/alienanimals/space_jellyfish(loc, src)
adjust_nutrition(-400)
reproduction_cooldown = 60
/mob/living/simple_mob/vore/alienanimals/space_jellyfish/Process_Spacemove(var/check_drift = 0)
return TRUE
/datum/ai_holder/simple_mob/melee/evasive/jellyfish
hostile = TRUE
cooperative = FALSE
retaliate = TRUE
speak_chance = 2
wander = TRUE
unconscious_vore = TRUE
/obj/item/weapon/reagent_containers/food/snacks/jellyfishcore
name = "jellyfish core"
icon = 'icons/obj/food_vr.dmi'
icon_state = "jellyfish_core"
desc = "The pulsing core of a space jellyfish! ... It smells delicious."
nutriment_amt = 50
bitesize = 1000
nutriment_desc = list("heavenly space meat" = 100)
var/inherited_nutriment = 0
/obj/item/weapon/reagent_containers/food/snacks/jellyfishcore/New(newloc, inherit)
inherited_nutriment = inherit
. = ..()
/obj/item/weapon/reagent_containers/food/snacks/jellyfishcore/Initialize()
nutriment_amt += inherited_nutriment
. = ..()
reagents.add_reagent("nutriment", nutriment_amt, nutriment_desc)

View File

@@ -0,0 +1,94 @@
/datum/category_item/catalogue/fauna/skeleton
name = "Alien Wildlife - Space Skeleton"
desc = "A creature consisting primarily of what appears to be bones with no apparent connective tissue, muscle, or organs.\
It is not clear at all how this creature even operates."
value = CATALOGUER_REWARD_MEDIUM
/mob/living/simple_mob/vore/alienanimals/skeleton
name = "skeleton"
desc = "An arrangement of what appears to be bones, given life and mobility. It looks REALLY spooky."
catalogue_data = list(/datum/category_item/catalogue/fauna/skeleton)
icon = 'icons/mob/alienanimals_x32.dmi'
icon_state = "skeleton"
icon_living = "skeleton"
icon_dead = "skeleton_dead"
faction = "space skeleton"
maxHealth = 100
health = 100
movement_cooldown = 1
movement_sound = 'sound/effects/skeleton_walk.ogg' //VERY IMPORTANT
see_in_dark = 10
response_help = "rattles"
response_disarm = "shoves aside"
response_harm = "smashes"
melee_damage_lower = 1
melee_damage_upper = 10
attack_sharp = FALSE
attacktext = list("spooked", "startled", "jumpscared", "rattled at")
ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive/skeleton
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
maxbodytemp = 900
loot_list = list(
/obj/item/weapon/bone = 25,
/obj/item/weapon/bone/skull = 25,
/obj/item/weapon/bone/ribs = 25,
/obj/item/weapon/bone/arm = 25,
/obj/item/weapon/bone/leg = 25
)
speak_emote = list("rattles")
say_list_type = /datum/say_list/skeleton
vore_active = 1
vore_capacity = 1
vore_bump_chance = 5
vore_ignores_undigestable = 0
vore_default_mode = DM_DRAIN
vore_icons = SA_ICON_LIVING
vore_stomach_name = "stomach"
vore_default_contamination_flavor = "Wet"
vore_default_contamination_color = "grey"
vore_default_item_mode = IM_DIGEST
/datum/say_list/skeleton
speak = list("Nyeh heh heeeh","NYAAAAHHHH", "Books are the real treasures of the world!", "Why are skeletons so calm? Because nothing gets under their skin.","When does a skeleton laugh? When someone tickels their funny bone!","What is a skeletons favorite mode of transport? A scare-plane.", "What did the skeleton say to the vampire? 'You suck.'","What is a skeletons favorite thing to do with their cell phone? Take skelfies.", "How did the skeleton know the other skeleton was lying? He could see right through him.","Whats a skeletons least favorite room in the house? The living room.", "How much does an elephant skeleton weigh? Skele-tons.", "Why do skeletons drink so much milk? Its good for the bones!", "Where do bad jokes about skeletons belong? In the skelebin.","What does a skeleton use to cut through objects? A shoulder blade.", "What kind of jokes do skeletons tell? Humerus ones.")
emote_see = list("spins its head around", "shuffles","shambles","practices on the xylophone","drinks some milk","looks at you. Its hollow, bottomless sockets gaze into you greedily.")
emote_hear = list("rattles","makes a spooky sound","cackles madly","plinks","clacks")
/mob/living/simple_mob/vore/alienanimals/skeleton/init_vore()
..()
var/obj/belly/B = vore_selected
B.name = "stomach"
B.desc = "You're not sure quite how, but you've found your way inside of the skeleton's stomach! It's cramped and cold and sounds heavily of xylophones!"
B.mode_flags = 40
B.digest_brute = 0.5
B.digest_burn = 0.5
B.digestchance = 10
B.absorbchance = 0
B.escapechance = 25
/mob/living/simple_mob/vore/alienanimals/skeleton/death(gibbed, deathmessage = "falls down and stops moving...")
. = ..()
/datum/ai_holder/simple_mob/melee/evasive/skeleton
hostile = TRUE
retaliate = TRUE
destructive = TRUE
violent_breakthrough = TRUE

View File

@@ -0,0 +1,92 @@
/datum/category_item/catalogue/fauna/dustjumper
name = "Alien Wildlife - Dust Jumper"
desc = "A small, quick creature, the dust jumper is a rare space creature.\
They have striking similarities to the common mouse, but these creatures are actually most commonly found in space.\
They are known to make their homes in asteroids, and leap from one to another when food is scarce.\
Dust jumpers are omnivorous, eating what scraps of organic material they can get their little paws on.\
They hybernate during long floats through space."
value = CATALOGUER_REWARD_MEDIUM
/mob/living/simple_mob/vore/alienanimals/dustjumper
name = "dust jumper"
desc = "A small, unassuming mammal. It looks quite soft and fluffy, and has bright blue eyes."
catalogue_data = list(/datum/category_item/catalogue/fauna/dustjumper)
icon = 'icons/mob/alienanimals_x32.dmi'
icon_state = "space_mouse"
icon_living = "space_mouse"
icon_dead = "space_mouse_dead"
faction = "space mouse"
maxHealth = 20
health = 20
movement_cooldown = 1
see_in_dark = 10
response_help = "pets"
response_disarm = "pushes"
response_harm = "punches"
melee_damage_lower = 1
melee_damage_upper = 2
attack_sharp = FALSE
attacktext = list("nipped", "squeaked at", "hopped on", "kicked")
ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive/dustjumper
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
maxbodytemp = 900
speak_emote = list("squeaks")
say_list_type = /datum/say_list/mouse
vore_active = 1
vore_capacity = 1
vore_bump_chance = 0
vore_ignores_undigestable = 0
vore_default_mode = DM_DRAIN
vore_icons = SA_ICON_LIVING
vore_stomach_name = "stomach"
vore_default_contamination_flavor = "Wet"
vore_default_contamination_color = "grey"
vore_default_item_mode = IM_DIGEST
/mob/living/simple_mob/vore/alienanimals/dustjumper/init_vore()
..()
var/obj/belly/B = vore_selected
B.name = "stomach"
B.desc = "You've been packed into the impossibly tight stomach of the dust jumper!!! The broiling heat seeps into you while the walls churn in powerfully, forcing you to curl up in the darkness."
B.mode_flags = DM_FLAG_THICKBELLY | DM_FLAG_NUMBING
B.digest_brute = 0.5
B.digest_burn = 0.5
B.digestchance = 10
B.absorbchance = 0
B.escapechance = 25
/mob/living/simple_mob/vore/alienanimals/dustjumper/Life()
. = ..()
if(!.)
return
if(vore_fullness == 0 && movement_cooldown == 50)
movement_cooldown = initial(movement_cooldown)
/mob/living/simple_mob/vore/alienanimals/dustjumper/perform_the_nom(mob/living/user, mob/living/prey, mob/living/pred, obj/belly/belly, delay)
. = ..()
movement_cooldown = 50
/datum/ai_holder/simple_mob/melee/evasive/dustjumper
hostile = FALSE
retaliate = TRUE
destructive = FALSE
violent_breakthrough = FALSE
can_flee = TRUE
flee_when_dying = TRUE

View File

@@ -0,0 +1,201 @@
/datum/category_item/catalogue/fauna/spacewhale
name = "Alien Wildlife - Space Whale"
desc = "A massive space creature! These are typically peaceful to anything smaller than themselves, with exception given to space carp, which it eats.\
It is known to ravage and devour other large space dwelling species.\
It occasionally gets restless and moves around erratically, which may affect the local space weather.\
This creature shows no real interest in or aversion to spacecraft."
value = CATALOGUER_REWARD_SUPERHARD
/mob/living/simple_mob/vore/overmap/spacewhale
name = "space whale"
desc = "It's a space whale. I don't know what more you expected."
scanner_desc = "It's a space whale! Woah!"
catalogue_data = list(/datum/category_item/catalogue/fauna/spacewhale)
icon = 'icons/mob/alienanimals_x32.dmi'
icon_state = "space_whale"
icon_living = "space_whale"
icon_dead = "space_ghost_dead"
om_child_type = /obj/effect/overmap/visitable/simplemob/spacewhale
maxHealth = 100000
health = 100000
movement_cooldown = 50
see_in_dark = 10
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "punches"
harm_intent_damage = 1
melee_damage_lower = 50
melee_damage_upper = 100
attack_sharp = FALSE
attacktext = list("chomped", "bashed", "monched", "bumped")
ai_holder_type = /datum/ai_holder/simple_mob/melee/spacewhale
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
maxbodytemp = 900
loot_list = list(/obj/random/underdark/uncertain)
armor = list(
"melee" = 1000,
"bullet" = 1000,
"laser" = 1000,
"energy" = 1000,
"bomb" = 1000,
"bio" = 1000,
"rad" = 1000)
armor_soak = list(
"melee" = 1000,
"bullet" = 1000,
"laser" = 1000,
"energy" = 1000,
"bomb" = 1000,
"bio" = 1000,
"rad" = 1000
)
speak_emote = list("rumbles")
say_list_type = /datum/say_list/spacewhale
var/hazard_pickup_chance = 35
var/hazard_drop_chance = 35
var/held_hazard
var/restless = FALSE
vore_active = 1
vore_capacity = 99
vore_bump_chance = 99
vore_pounce_chance = 99
vore_ignores_undigestable = 0
vore_default_mode = DM_DIGEST
vore_icons = SA_ICON_LIVING
vore_stomach_name = "stomach"
vore_default_contamination_flavor = "Wet"
vore_default_contamination_color = "grey"
vore_default_item_mode = IM_DIGEST
/datum/say_list/spacewhale
emote_see = list("ripples and flows", "flashes rhythmically","glows faintly","investigates something")
/mob/living/simple_mob/vore/overmap/spacewhale/init_vore()
..()
var/obj/belly/B = vore_selected
B.name = "stomach"
B.desc = "It's warm and wet, makes sense, considering it's inside of a space whale. You should take a moment to reflect upon how you got here, and how you might avoid situations like this in the future, while this whale attempts to mercilessly destroy you through various gastric processes."
B.mode_flags = DM_FLAG_THICKBELLY | DM_FLAG_NUMBING
B.digest_brute = 50
B.digest_burn = 50
B.escapechance = 0
/mob/living/simple_mob/vore/overmap/spacewhale/Initialize()
. = ..()
handle_restless()
/mob/living/simple_mob/vore/overmap/spacewhale/Moved()
. = ..()
if(restless && prob(5))
handle_restless()
for(var/obj/effect/decal/cleanable/C in loc)
qdel(C)
for(var/obj/item/organ/O in loc)
qdel(O)
var/detected = FALSE
for(var/obj/effect/overmap/event/E in loc)
detected = TRUE
if(istype(E, /obj/effect/overmap/event/carp))
qdel(E)
continue
else if(!held_hazard && prob(hazard_pickup_chance))
held_hazard = E.type
qdel(E)
return
if(held_hazard && !detected && prob(hazard_drop_chance))
if(!(locate(/obj/effect/overmap/visitable/sector) in loc))
new held_hazard(loc)
held_hazard = null
/mob/living/simple_mob/vore/overmap/spacewhale/Life()
. = ..()
if(!restless && prob(0.5))
handle_restless()
/mob/living/simple_mob/vore/overmap/spacewhale/proc/handle_restless()
if(restless)
restless = FALSE
hazard_pickup_chance = initial(hazard_pickup_chance)
hazard_drop_chance = initial(hazard_drop_chance)
movement_cooldown = initial(movement_cooldown)
ai_holder.base_wander_delay = initial(ai_holder.base_wander_delay)
if(child_om_marker.known == TRUE)
child_om_marker.icon_state = "space_whale"
visible_message("<span class='notice'>\The [child_om_marker.name] settles down.</span>")
else
restless = TRUE
hazard_pickup_chance *= 1.5
hazard_drop_chance *= 1.5
movement_cooldown = 1
ai_holder.base_wander_delay = 2
ai_holder.wander_delay = 2
if(child_om_marker.known == TRUE)
child_om_marker.icon_state = "space_whale_restless"
visible_message("<span class='notice'>\The [child_om_marker.name] ripples excitedly.</span>")
/datum/ai_holder/simple_mob/melee/spacewhale
hostile = TRUE
retaliate = TRUE
destructive = TRUE
violent_breakthrough = TRUE
unconscious_vore = TRUE
handle_corpse = TRUE
mauling = TRUE
base_wander_delay = 50
/datum/ai_holder/simple_mob/melee/spacewhale/set_stance(var/new_stance)
. = ..()
var/mob/living/simple_mob/vore/overmap/spacewhale/W = holder
if(stance == STANCE_FIGHT)
W.movement_cooldown = 0
W.child_om_marker.glide_size = 0
if(stance == STANCE_IDLE)
W.hazard_pickup_chance = initial(W.hazard_pickup_chance)
W.hazard_drop_chance = initial(W.hazard_drop_chance)
W.movement_cooldown = 50
base_wander_delay = 50
W.restless = FALSE
W.handle_restless()
W.movement_cooldown = initial(W.movement_cooldown)
W.child_om_marker.glide_size = 0.384
/mob/living/simple_mob/vore/overmap/spacewhale/apply_melee_effects(var/atom/A)
. = ..()
if(istype(A, /mob/living))
var/mob/living/L = A
if(L.stat == DEAD && !L.allowmobvore)
L.gib()
else
return ..()
/obj/effect/overmap/visitable/simplemob/spacewhale
skybox_icon = 'icons/skybox/anomaly.dmi'
skybox_icon_state = "space_whale"
skybox_pixel_x = 0
skybox_pixel_y = 0
glide_size = 0.384
parent_mob_type = /mob/living/simple_mob/vore/overmap/spacewhale

View File

@@ -0,0 +1,219 @@
/datum/category_item/catalogue/fauna/space_ghost
name = "Alien Wildlife - Space Ghost"
desc = "A mysterious and unknown creature made of radical energy.\
This creature's energy interferes the nervous system in many kinds of creatures, which may result in hallucinations.\
This creature's lack of a physical form leaves it quite resistant to physical damage.\
Smaller variants of this creature seem to be vulnerable to bright light.\
While both variants are quite vulnerable to laser and energy weapons."
value = CATALOGUER_REWARD_EASY
/mob/living/simple_mob/vore/alienanimals/space_ghost
name = "space ghost"
desc = "A pulsing mass of darkness that seems to have gained sentience."
tt_desc = "?????"
catalogue_data = list(/datum/category_item/catalogue/fauna/space_ghost)
icon = 'icons/mob/alienanimals_x32.dmi'
icon_state = "space_ghost"
icon_living = "space_ghost"
icon_dead = "space_ghost_dead"
has_eye_glow = TRUE
hovering = TRUE
pass_flags = PASSTABLE
faction = "space ghost"
maxHealth = 50
health = 50
movement_cooldown = 3.25
see_in_dark = 10
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "punches"
harm_intent_damage = 0
melee_damage_lower = 1
melee_damage_upper = 1
attack_sharp = FALSE
attacktext = list("spooked", "startled", "jumpscared", "screamed at")
ai_holder_type = /datum/ai_holder/simple_mob/melee/space_ghost
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
maxbodytemp = 999999
armor = list(
"melee" = 100,
"bullet" = 100,
"laser" = 0,
"energy" = 0,
"bomb" = 0,
"bio" = 0,
"rad" = 100)
armor_soak = list(
"melee" = 100,
"bullet" = 100,
"laser" = 0,
"energy" = 0,
"bomb" = 0,
"bio" = 0,
"rad" = 100
)
loot_list = list(/obj/item/weapon/ore/diamond = 100)
speak_emote = list("rumbles")
vore_active = 0
projectiletype = /mob/living/simple_mob/vore/alienanimals/spooky_ghost
projectilesound = null
projectile_accuracy = 0
projectile_dispersion = 0
needs_reload = TRUE
reload_max = 1
reload_count = 0
reload_time = 7 SECONDS
/datum/ai_holder/simple_mob/ranged/kiting/space_ghost
hostile = TRUE
retaliate = TRUE
destructive = TRUE
violent_breakthrough = TRUE
speak_chance = 0
/mob/living/simple_mob/vore/alienanimals/space_ghost/apply_melee_effects(var/atom/A)
var/mob/living/L = A
L.hallucination += 50
/mob/living/simple_mob/vore/alienanimals/space_ghost/shoot(atom/A) //We're shooting ghosts at people and need them to have the same faction as their parent, okay?
if(!projectiletype)
return
if(A == get_turf(src))
return
face_atom(A)
if(reload_count >= reload_max)
return
var/mob/living/simple_mob/P = new projectiletype(loc, src)
if(!P)
return
if(needs_reload)
reload_count++
P.faction = faction
playsound(src, projectilesound, 80, 1)
/mob/living/simple_mob/vore/alienanimals/space_ghost/death(gibbed, deathmessage = "fades away!")
. = ..()
qdel(src)
/mob/living/simple_mob/vore/alienanimals/spooky_ghost
name = "space ghost"
desc = "A pulsing mass of darkness that seems to have gained sentience."
tt_desc = "?????"
catalogue_data = list(/datum/category_item/catalogue/fauna/space_ghost)
icon = 'icons/mob/alienanimals_x32.dmi'
icon_state = "spookyghost-1"
icon_living = "spookyghost-1"
icon_dead = "space_ghost_dead"
hovering = TRUE
pass_flags = PASSTABLE
faction = "space ghost"
maxHealth = 5
health = 5
movement_cooldown = 1
see_in_dark = 10
alpha = 128
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "punches"
harm_intent_damage = 0
melee_damage_lower = 1
melee_damage_upper = 1
attack_sharp = FALSE
attacktext = list("spooked", "startled", "jumpscared", "screamed at")
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
maxbodytemp = 999999
armor = list(
"melee" = 100,
"bullet" = 100,
"laser" = 0,
"energy" = 0,
"bomb" = 0,
"bio" = 0,
"rad" = 100)
armor_soak = list(
"melee" = 100,
"bullet" = 100,
"laser" = 0,
"energy" = 0,
"bomb" = 0,
"bio" = 0,
"rad" = 100
)
speak_emote = list("rumbles")
vore_active = 0
ai_holder_type = /datum/ai_holder/simple_mob/melee/space_ghost
/mob/living/simple_mob/vore/alienanimals/spooky_ghost/Initialize()
. = ..()
icon_living = "spookyghost-[rand(1,2)]"
icon_state = icon_living
addtimer(CALLBACK(src, .proc/death), 2 MINUTES)
update_icon()
/datum/ai_holder/simple_mob/melee/space_ghost
hostile = TRUE
retaliate = TRUE
destructive = TRUE
violent_breakthrough = TRUE
speak_chance = 0
/mob/living/simple_mob/vore/alienanimals/spooky_ghost/death(gibbed, deathmessage = "fades away!")
. = ..()
qdel(src)
/mob/living/simple_mob/vore/alienanimals/spooky_ghost/apply_melee_effects(var/atom/A)
var/mob/living/L = A
L.hallucination += rand(1,50)
/mob/living/simple_mob/vore/alienanimals/spooky_ghost/Life()
. = ..()
var/turf/T = get_turf(src)
if(!T)
return
if(T.get_lumcount() >= 0.5)
adjustBruteLoss(1)

View File

@@ -0,0 +1,177 @@
/datum/category_item/catalogue/fauna/startreader
name = "Alien Wildlife - Star Treader"
desc = "A hard shelled creature that lives on asteroids.\
It is quite durable and very opportunistic in its feeding habits.\
It is vulnerable to extreme vibrations, and from the bottom."
value = CATALOGUER_REWARD_EASY
/mob/living/simple_mob/vore/alienanimals/startreader
name = "asteroid star treader"
desc = "A slow, hard shelled creature that stalks asteroids."
tt_desc = "Testudines Stellarus"
catalogue_data = list(/datum/category_item/catalogue/fauna/startreader)
icon = 'icons/mob/alienanimals_x32.dmi'
icon_state = "startreader"
icon_living = "startreader"
icon_dead = "startreader_dead"
faction = "space turtle"
maxHealth = 1000
health = 1000
movement_cooldown = 20
see_in_dark = 10
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "punches"
harm_intent_damage = 1
melee_damage_lower = 1
melee_damage_upper = 10
attack_sharp = FALSE
attacktext = list("chomped", "bashed", "monched", "bumped")
ai_holder_type = /datum/ai_holder/simple_mob/melee/startreader
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
minbodytemp = 0
maxbodytemp = 900
loot_list = list(/obj/random/underdark/uncertain = 25)
armor = list(
"melee" = 100,
"bullet" = 100,
"laser" = 100,
"energy" = 100,
"bomb" = 0,
"bio" = 100,
"rad" = 100)
armor_soak = list(
"melee" = 30,
"bullet" = 30,
"laser" = 10,
"energy" = 10,
"bomb" = 0,
"bio" = 100,
"rad" = 100
)
speak_emote = list("rumbles")
say_list_type = /datum/say_list/startreader
vore_active = 1
vore_capacity = 2
vore_bump_chance = 25
vore_ignores_undigestable = 0
vore_default_mode = DM_DRAIN
vore_icons = SA_ICON_LIVING
vore_stomach_name = "gastric sac"
vore_default_contamination_flavor = "Wet"
vore_default_contamination_color = "grey"
vore_default_item_mode = IM_DIGEST
var/flipped = FALSE
var/flip_cooldown = 0
/datum/say_list/startreader
emote_see = list("bobs", "digs around","gnashes at something","yawns","snaps at something")
emote_hear = list("thrumms","clicks","rattles","groans","burbles")
/mob/living/simple_mob/vore/alienanimals/startreader/init_vore()
..()
var/obj/belly/B = vore_selected
B.name = "gastric sac"
B.desc = "It's cramped and hot! You're forced into a small ball as your shape is squeezed into the slick, wet chamber. Despite being swallowed into the creature, you find that you actually stretch out of the top a ways, and can JUST BARELY wiggle around..."
B.mode_flags = 40
B.digest_brute = 0.5
B.digest_burn = 0.5
B.digestchance = 10
B.absorbchance = 0
B.escapechance = 15
/datum/ai_holder/simple_mob/melee/startreader
hostile = TRUE
retaliate = TRUE
destructive = TRUE
violent_breakthrough = TRUE
/mob/living/simple_mob/vore/alienanimals/startreader/apply_melee_effects(var/atom/A)
if(weakened) //Don't stun people while they're already stunned! That's SILLY!
return
if(prob(15))
var/mob/living/L = A
if(isliving(A))
visible_message("<span class='danger'>\The [src] trips \the [L]!</span>!")
L.weakened += rand(1,10)
/mob/living/simple_mob/vore/alienanimals/startreader/Life()
. = ..()
if(flip_cooldown == 1)
flip_cooldown = 0
flipped = FALSE
handle_flip()
visible_message("<span class='notice'>\The [src] rights itself!!!</span>")
return
if(flip_cooldown)
flip_cooldown --
SetStunned(2)
/mob/living/simple_mob/vore/alienanimals/startreader/proc/handle_flip()
if(flipped)
armor = list(
"melee" = 0,
"bullet" = 0,
"laser" = 0,
"energy" = 0,
"bomb" = 0,
"bio" = 0,
"rad" = 0)
armor_soak = list(
"melee" = 0,
"bullet" = 0,
"laser" = 0,
"energy" = 0,
"bomb" = 0,
"bio" = 0,
"rad" = 0
)
icon_living = "startreader_flipped"
AdjustStunned(flip_cooldown)
else
armor = list(
"melee" = 100,
"bullet" = 100,
"laser" = 100,
"energy" = 100,
"bomb" = 0,
"bio" = 100,
"rad" = 100)
armor_soak = list(
"melee" = 30,
"bullet" = 30,
"laser" = 10,
"energy" = 10,
"bomb" = 0,
"bio" = 100,
"rad" = 100
)
icon_living = "startreader"
SetStunned(0)
update_icon()

View File

@@ -64,7 +64,7 @@ GLOBAL_VAR_INIT(teppi_count, 0) // How mant teppi DO we have?
maxHealth = 600
health = 600
movement_cooldown = 2
meat_amount = 10
meat_amount = 12
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
response_help = "pets"
@@ -143,7 +143,8 @@ GLOBAL_VAR_INIT(teppi_count, 0) // How mant teppi DO we have?
)
butchery_loot = list(\
/obj/item/stack/animalhide = 3\
/obj/item/stack/animalhide = 3,\
/obj/item/weapon/bone/horn = 1\
)
/////////////////////////////////////// Vore stuff///////////////////////////////////////////

View File

@@ -26,7 +26,7 @@ GLOBAL_VAR_INIT(chicken_count, 0) // How mant chickens DO we have?
say_list_type = /datum/say_list/chicken
meat_amount = 2
meat_amount = 4
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/chicken
var/eggsleft = 0

View File

@@ -19,7 +19,7 @@
say_list_type = /datum/say_list/cow
meat_amount = 6
meat_amount = 10
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
var/datum/reagents/udder = null

View File

@@ -22,7 +22,7 @@
say_list_type = /datum/say_list/goat
ai_holder_type = /datum/ai_holder/simple_mob/retaliate
meat_amount = 4
meat_amount = 6
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
var/datum/reagents/udder = null

View File

@@ -98,14 +98,14 @@
speak_emote = list("chitters")
meat_amount = 1
meat_amount = 5
meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat/spidermeat
say_list_type = /datum/say_list/spider
tame_items = list(
/obj/item/weapon/reagent_containers/food/snacks/xenomeat = 10,
/obj/item/weapon/reagent_containers/food/snacks/meat/crab = 40,
/obj/item/weapon/reagent_containers/food/snacks/crabmeat = 40,
/obj/item/weapon/reagent_containers/food/snacks/meat = 20
)

View File

@@ -21,6 +21,8 @@
old_x = -16
old_y = 0
meat_amount = 20
projectiletype = /obj/item/projectile/energy/spidertoxin
projectilesound = 'sound/weapons/pierce.ogg'
@@ -59,6 +61,7 @@
poison_per_bite = 2
poison_type = "cyanide"
loot_list = list(/obj/item/royal_spider_egg = 100)
/obj/item/projectile/energy/spidertoxin
name = "concentrated spidertoxin"
@@ -71,11 +74,7 @@
combustion = FALSE
/mob/living/simple_mob/animal/giant_spider/broodmother/death()
..()
new /obj/item/royal_spider_egg(src.loc)
/mob/living/simple_mob/animal/giant_spider/broodmother/death(gibbed, deathmessage="falls over and makes its last twitches as its birthing sack bursts!")
var/count = 0
while(count < death_brood)
var/broodling_type = pick(possible_death_brood_types)
@@ -84,7 +83,7 @@
step_away(broodling, src)
count++
visible_message(span("critical", "\The [src]'s birthing sack bursts!"))
return ..()
/mob/living/simple_mob/animal/giant_spider/broodmother/proc/spawn_brood(atom/A)
set waitfor = FALSE

View File

@@ -51,6 +51,7 @@
default_pixel_x = -16
old_x = -16
old_y = 0
meat_amount = 15
egg_type = /obj/effect/spider/eggcluster/royal

View File

@@ -18,7 +18,8 @@
organ_names = /decl/mob_organ_names/crab
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/crab
meat_type = /obj/item/weapon/reagent_containers/food/snacks/crabmeat
meat_amount = 3
say_list_type = /datum/say_list/crab
@@ -51,12 +52,5 @@
. = ..()
adjust_scale(rand(5,12) / 10)
// Meat!
/obj/item/weapon/reagent_containers/food/snacks/meat/crab
name = "meat"
desc = "A chunk of meat."
icon_state = "crustacean-meat"
/decl/mob_organ_names/crab
hit_zones = list("cephalothorax", "abdomen", "left walking legs", "right walking legs", "left swimming legs", "right swimming legs", "left pincer", "right pincer")

View File

@@ -23,6 +23,7 @@
holder_type = /obj/item/weapon/holder/fish
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat/fish
meat_amount = 3
// By default they can be in any water turf. Subtypes might restrict to deep/shallow etc
var/global/list/suitable_turf_types = list(

View File

@@ -2,6 +2,7 @@
desc = "A genetic marvel, combining the docility and aesthetics of the koi with some of the resiliency and cunning of the noble space carp."
health = 50
maxHealth = 50
meat_amount = 0
/mob/living/simple_mob/animal/passive/fish/koi/poisonous/Initialize()
. = ..()
@@ -67,7 +68,7 @@
icon_state = "measelshark"
icon_living = "measelshark"
icon_dead = "measelshark-dead"
meat_amount = 6 //Big fish, tons of meat. Great for feasts.
meat_amount = 8 //Big fish, tons of meat. Great for feasts.
meat_type = /obj/item/weapon/reagent_containers/food/snacks/sliceable/sharkchunk
vore_active = 1
vore_bump_chance = 100

View File

@@ -23,6 +23,8 @@
say_list_type = /datum/say_list/lizard
meat_amount = 1
/mob/living/simple_mob/animal/passive/lizard/large
desc = "A cute, big lizard."
maxHealth = 20

View File

@@ -7,6 +7,7 @@
item_state = "mouse_gray"
icon_living = "mouse_gray"
icon_dead = "mouse_gray_dead"
icon_rest = "mouse_gray_sleep"
kitchen_tag = "rodent"
maxHealth = 5
@@ -34,7 +35,8 @@
has_langs = list("Mouse")
holder_type = /obj/item/weapon/holder/mouse
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
meat_amount = 1
butchery_loot = list()
say_list_type = /datum/say_list/mouse
@@ -63,6 +65,17 @@
icon_rest = "mouse_[body_color]_sleep"
if (body_color != "rat")
desc = "A small [body_color] rodent, often seen hiding in maintenance areas and making a nuisance of itself."
holder_type = /obj/item/weapon/holder/mouse/rat
if (body_color == "operative")
holder_type = /obj/item/weapon/holder/mouse/operative
if (body_color == "brown")
holder_type = /obj/item/weapon/holder/mouse/brown
if (body_color == "gray")
holder_type = /obj/item/weapon/holder/mouse/gray
if (body_color == "white")
holder_type = /obj/item/weapon/holder/mouse/white
if (body_color == "black")
holder_type = /obj/item/weapon/holder/mouse/black
/mob/living/simple_mob/animal/passive/mouse/Crossed(atom/movable/AM as mob|obj)
if(AM.is_incorporeal())
@@ -100,25 +113,20 @@
/mob/living/simple_mob/animal/passive/mouse/white
body_color = "white"
icon_state = "mouse_white"
icon_rest = "mouse_white_sleep"
holder_type = /obj/item/weapon/holder/mouse/white
/mob/living/simple_mob/animal/passive/mouse/gray
body_color = "gray"
icon_state = "mouse_gray"
icon_rest = "mouse_gray_sleep"
holder_type = /obj/item/weapon/holder/mouse/gray
/mob/living/simple_mob/animal/passive/mouse/brown
body_color = "brown"
icon_state = "mouse_brown"
/mob/living/simple_mob/animal/passive/mouse/rat
name = "rat"
tt_desc = "E Rattus rattus"
desc = "A large rodent, often seen hiding in maintenance areas and making a nuisance of itself."
body_color = "rat"
icon_state = "mouse_rat"
maxHealth = 20
health = 20
ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive
icon_rest = "mouse_brown_sleep"
holder_type = /obj/item/weapon/holder/mouse/brown
//TOM IS ALIVE! SQUEEEEEEEE~K :)
/mob/living/simple_mob/animal/passive/mouse/brown/Tom
@@ -130,6 +138,57 @@
// Change my name back, don't want to be named Tom (666)
name = initial(name)
/mob/living/simple_mob/animal/passive/mouse/black
body_color = "black"
icon_state = "mouse_black"
icon_rest = "mouse_black_sleep"
holder_type = /obj/item/weapon/holder/mouse/black
/mob/living/simple_mob/animal/passive/mouse/rat
name = "rat"
tt_desc = "E Rattus rattus"
desc = "A large rodent, often seen hiding in maintenance areas and making a nuisance of itself."
body_color = "rat"
icon_state = "mouse_rat"
icon_rest = "mouse_rat_sleep"
holder_type = /obj/item/weapon/holder/mouse/rat
maxHealth = 20
health = 20
ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive
/mob/living/simple_mob/animal/passive/mouse/operative
name = "mouse operative"
desc = "A cute mouse fitted with a custom blood red suit. Sneaky."
body_color = "operative"
icon_state = "mouse_operative"
icon_rest = "mouse_operative_sleep"
holder_type = /obj/item/weapon/holder/mouse/operative
maxHealth = 35
//It's wearing a void suit, it don't care about atmos
health = 35
min_oxy = 0
max_oxy = 0
min_tox = 0
max_tox = 0
min_co2 = 0
max_co2 = 0
min_n2 = 0
max_n2 = 0
maxbodytemp = 700
ai_holder_type = /datum/ai_holder/simple_mob/melee/evasive
//The names Cheese... Agent Cheese
/mob/living/simple_mob/animal/passive/mouse/operative/agent_cheese
name = "Agent Cheese"
desc = "I like my cheese Swiss... not American."
/mob/living/simple_mob/animal/passive/mouse/operative/agent_cheese/New()
..()
// Change my name back, don't want to be named agent_cheese (666)
name = initial(name)
// Mouse noises
/datum/say_list/mouse

View File

@@ -12,41 +12,45 @@
movement_cooldown = 5
universal_understand = 1
/mob/living/simple_mob/animal/passive/mouse/attack_hand(mob/living/L)
if(L.a_intent == I_HELP && !istype(loc, /obj/item/weapon/holder)) //if lime intent and not in a holder already
if(!src.attempt_to_scoop(L)) //the superior way to handle scooping, checks size
..() //mouse too big to grab? pet the large mouse instead
else
..()
//No longer in use, as mice create a holder/micro object instead
/obj/item/weapon/holder/mouse/attack_self(var/mob/U)
for(var/mob/living/simple_mob/M in src.contents)
if((I_HELP) && U.checkClickCooldown()) //a little snowflakey, but makes it use the same cooldown as interacting with non-inventory objects
U.setClickCooldown(U.get_attack_speed()) //if there's a cleaner way in baycode, I'll change this
U.visible_message("<span class='notice'>[U] [M.response_help] \the [M].</span>")
/mob/living/simple_mob/animal/passive/mouse/MouseDrop(var/obj/O) //this proc would be very easy to apply to all mobs, holders generate dynamically
if(!(usr == src || O))
//Jank grabber that uses the 'attack_hand' insead of 'MouseDrop'
/mob/living/simple_mob/animal/passive/mouse/attack_hand(var/atom/over_object)
var/mob/living/carbon/human/H = over_object
if(holder_type && issmall(src) && istype(H) && !H.lying && Adjacent(H) && (src.a_intent == I_HELP && H.a_intent == I_HELP))
if(!issmall(H) || !istype(src, /mob/living/carbon/human))
get_scooped(H, (usr == src))
return
return ..()
if(istype(O, /mob/living) && O.Adjacent(src)) //controls scooping by mobs
var/mob/living/L = O
if(!src.attempt_to_scoop(L, (src == usr)))
return //this way it doesnt default to the generic animal pickup which isnt size restricted
if(istype(O, /obj/item/weapon/storage) && O.Adjacent(src)) //controls diving into storage
var/obj/item/weapon/storage/S = O
var/obj/item/weapon/holder/H = new holder_type(get_turf(src),src) //this works weird, but it creates an empty holder, to see if that holder can fit
if(S.can_be_inserted(H) && (src.size_multiplier <= 0.75))
visible_message("<b>\The [src]</b> squeezes into \the [S].")
H.forceMove(S)
return 1
/mob/living/proc/mouse_scooped(var/mob/living/carbon/grabber, var/self_grab)
if(!holder_type || buckled || pinned.len)
return
if(self_grab)
if(src.incapacitated()) return
else
qdel(H) //this deletes the empty holder if it doesnt work
to_chat(usr,"<span class='notice'>You can't fit inside \the [S]!</span>")
return 0
if(grabber.incapacitated()) return
var/obj/item/weapon/holder/H = new holder_type(get_turf(src), src)
grabber.put_in_hands(H)
if(self_grab)
to_chat(grabber, "<span class='notice'>\The [src] clambers onto you!</span>")
to_chat(src, "<span class='notice'>You climb up onto \the [grabber]!</span>")
grabber.equip_to_slot_if_possible(H, slot_back, 0, 1)
else
..()
to_chat(grabber, "<span class='notice'>You scoop up \the [src]!</span>")
to_chat(src, "<span class='notice'>\The [grabber] scoops you up!</span>")
add_attack_logs(grabber, H.held_mob, "Scooped up", FALSE) // Not important enough to notify admins, but still helpful.
return H
/mob/living/simple_mob/animal/passive/mouse/white/apple
name = "Apple"
desc = "Dainty, well groomed and cared for, her eyes glitter with untold knowledge..."
@@ -57,3 +61,11 @@
// Change my name back, don't want to be named Apple (666)
name = initial(name)
desc = initial(desc)
/obj/item/weapon/holder/mouse/attack_self(mob/living/carbon/user)
user.setClickCooldown(user.get_attack_speed())
for(var/L in contents)
if(isanimal(L))
var/mob/living/simple_mob/S = L
user.visible_message("<span class='notice'>[user] [S.response_help] \the [S].</span>")

View File

@@ -16,6 +16,9 @@
organ_names = /decl/mob_organ_names/penguin
meat_amount = 3
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/chicken
harm_intent_damage = 5
melee_damage_lower = 10
melee_damage_upper = 15

View File

@@ -138,6 +138,7 @@
can_pull_mobs = MOB_PULL_SMALLER
say_list_type = /datum/say_list/possum
catalogue_data = list(/datum/category_item/catalogue/fauna/opossum)
meat_amount = 2
/mob/living/simple_mob/animal/passive/opossum/adjustBruteLoss(var/amount,var/include_robo)
. = ..()

View File

@@ -23,6 +23,9 @@
softfall = TRUE
parachuting = TRUE
meat_amount = 1
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/chicken
attacktext = list("clawed", "pecked")
speak_emote = list("chirps", "caws")
has_langs = list("Bird")

View File

@@ -37,6 +37,7 @@ var/list/_cat_default_emotes = list(
movement_cooldown = 0.5 SECONDS
meat_amount = 1
see_in_dark = 6 // Not sure if this actually works.
response_help = "pets"
response_disarm = "gently pushes aside"

View File

@@ -23,7 +23,7 @@
minbodytemp = 223 //Below -50 Degrees Celcius
maxbodytemp = 323 //Above 50 Degrees Celcius
meat_amount = 1
meat_amount = 2
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/fox
say_list_type = /datum/say_list/fox
@@ -186,9 +186,6 @@
set_dir(get_dir(src, friend))
say("Yap!")
*/
/obj/item/weapon/reagent_containers/food/snacks/meat/fox
name = "Fox meat"
desc = "The fox doesn't say a goddamn thing, now."
//Captain fox
/mob/living/simple_mob/animal/passive/fox/renault

View File

@@ -28,7 +28,10 @@
maxHealth = 25
health = 25
minbodytemp = 175 //yw edit, Makes mobs survive cryogaia temps
meat_amount = 2
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
movement_cooldown = 0
melee_damage_lower = 2

View File

@@ -32,6 +32,9 @@
movement_cooldown = 0
meat_amount = 4
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/chicken
melee_damage_lower = 2
melee_damage_upper = 10
base_attack_cooldown = 1 SECOND
@@ -57,6 +60,7 @@
. = ..()
var/has_food = FALSE
if(isliving(L))
for(var/obj/item/I in L.get_contents()) // Do they have food?
if(istype(I, /obj/item/weapon/reagent_containers/food))
has_food = TRUE

View File

@@ -56,7 +56,7 @@
tame_items = list(
/obj/item/weapon/reagent_containers/food/snacks/grown = 90,
/obj/item/weapon/reagent_containers/food/snacks/meat/crab = 10,
/obj/item/weapon/reagent_containers/food/snacks/crabmeat = 10,
/obj/item/weapon/reagent_containers/food/snacks/meat = 5
)

View File

@@ -61,7 +61,7 @@
organ_names = /decl/mob_organ_names/hare
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
meat_amount = 1
say_list_type = /datum/say_list/hare

View File

@@ -72,7 +72,8 @@
attack_edge = TRUE
melee_attack_delay = 1 SECOND
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/crab
meat_type = /obj/item/weapon/reagent_containers/food/snacks/crabmeat
meat_amount = 6
response_help = "pets"
response_disarm = "gently pushes aside"

View File

@@ -48,6 +48,7 @@
attacktext = list("gouged", "bit", "cut", "clawed", "whipped")
organ_names = /decl/mob_organ_names/kururak
meat_amount = 5
armor = list(
"melee" = 30,

View File

@@ -40,6 +40,7 @@
melee_damage_upper = 15
base_attack_cooldown = 1 SECOND
attacktext = list("nipped", "bit", "cut", "clawed")
meat_amount = 3
armor = list(
"melee" = 15,

View File

@@ -49,7 +49,7 @@
tame_items = list(
/obj/item/organ = 70,
/obj/item/weapon/reagent_containers/food/snacks/meat/crab = 30,
/obj/item/weapon/reagent_containers/food/snacks/crabmeat = 30,
/obj/item/weapon/reagent_containers/food/snacks/meat = 20
)

View File

@@ -5,6 +5,6 @@
heat_resist = -0.5
tame_items = list(
/obj/item/weapon/reagent_containers/food/snacks/meat/crab = 20,
/obj/item/weapon/reagent_containers/food/snacks/crabmeat = 20,
/obj/item/weapon/reagent_containers/food/snacks/meat = 10
)

View File

@@ -31,6 +31,7 @@
attack_sound = 'sound/weapons/bladeslice.ogg'
meat_type = /obj/item/weapon/reagent_containers/food/snacks/xenomeat
meat_amount = 5
/mob/living/simple_mob/animal/space/alien/drone
name = "alien drone"
@@ -68,7 +69,7 @@
old_x = -16
icon_expected_width = 64
icon_expected_height = 64
meat_amount = 5
meat_amount = 8
/mob/living/simple_mob/animal/space/alien/queen
name = "alien queen"
@@ -84,7 +85,7 @@
projectilesound = 'sound/weapons/pierce.ogg'
movement_cooldown = 8
movement_cooldown = 10
/mob/living/simple_mob/animal/space/alien/queen/empress
name = "alien empress"
@@ -95,7 +96,7 @@
icon_rest = "queen_sleep"
maxHealth = 400
health = 400
meat_amount = 5
meat_amount = 15
pixel_x = -16
old_x = -16
@@ -111,7 +112,7 @@
icon_rest = "empress_rest"
maxHealth = 600
health = 600
meat_amount = 10
meat_amount = 40
melee_damage_lower = 15
melee_damage_upper = 25

View File

@@ -33,6 +33,7 @@
has_langs = list("Mouse")
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
meat_amount = 2
say_list_type = /datum/say_list/mouse // Close enough

View File

@@ -23,6 +23,7 @@
attacktext = list("mauled")
meat_type = /obj/item/weapon/reagent_containers/food/snacks/bearmeat
meat_amount = 8
say_list_type = /datum/say_list/bear

View File

@@ -53,7 +53,7 @@
organ_names = /decl/mob_organ_names/fish
meat_amount = 1
meat_amount = 5
meat_type = /obj/item/weapon/reagent_containers/food/snacks/carpmeat
ai_holder_type = /datum/ai_holder/simple_mob/melee
@@ -92,7 +92,7 @@
icon_expected_width = 64
icon_expected_height = 32
meat_amount = 3
meat_amount = 7
/mob/living/simple_mob/animal/space/carp/large/huge
@@ -115,7 +115,7 @@
icon_expected_width = 64
icon_expected_height = 64
meat_amount = 10
meat_amount = 15
/mob/living/simple_mob/animal/space/carp/holographic

View File

@@ -25,7 +25,8 @@
has_langs = list("Bird")
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat
meat_type = /obj/item/weapon/reagent_containers/food/snacks/meat/chicken
meat_amount = 3
/datum/say_list/goose
speak = list("HONK!")

Some files were not shown because too many files have changed in this diff Show More