Skip to content

Commit

Permalink
Апгрейд ксенобиологии. Порт slime management console + небольшо… (#4554)
Browse files Browse the repository at this point in the history
* Xenobiology features

* Фиксы и прочее

- Более обобщенный хэндлинг "запрещенных" для просмотра зон. В частности, теперь не важно где построить консоль, глаз будет работать лишь там, где ему разрешено работать по коду.
- Пофиксил экшн "Jump To Camera"
- Общее упорядочивание кода

* Замечания по ревью

* Update monkeyrecycler.dm

Исправил баг при котором не работала возможность вытащить манкикубы наружу

* Вырезана функция перемещения в консоль у рекуклера. Маркер теперь виден только игроку.

* Анимация телепорта слизней by FatFat. К одному утилизатору может теперь подключиться несколько консолей

* Спейрореквест

Co-Authored-By: SpaiR <klimbetoo@gmail.com>

* Замена оператора на точку

Co-Authored-By: SpaiR <klimbetoo@gmail.com>

Co-authored-by: SpaiR <klimbetoo@gmail.com>
  • Loading branch information
Zap-zapper and SpaiR committed Feb 15, 2020
1 parent d97c83b commit 37ad218
Show file tree
Hide file tree
Showing 24 changed files with 926 additions and 159 deletions.
7 changes: 7 additions & 0 deletions code/__DEFINES/components.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,10 @@
// /atom/movable signals
#define COMSIG_MOVABLE_CROSSED "movable_crossed" //from base of atom/movable/Crossed(): (/atom/movable)
#define COMSIG_MOVABLE_MOVED "movable_moved" //from base of atom/movable/Moved(): (/atom, dir)


#define COMSIG_XENO_SLIME_CLICK_CTRL "xeno_slime_click_ctrl" //from slime CtrlClickOn(): (/mob)
#define COMSIG_XENO_SLIME_CLICK_SHIFT "xeno_slime_click_shift" //from slime ShiftClickOn(): (/mob)
#define COMSIG_XENO_TURF_CLICK_SHIFT "xeno_turf_click_shift" //from turf ShiftClickOn(): (/mob)
#define COMSIG_XENO_TURF_CLICK_CTRL "xeno_turf_click_alt" //from turf AltClickOn(): (/mob)
#define COMSIG_XENO_MONKEY_CLICK_CTRL "xeno_monkey_click_ctrl" //from monkey CtrlClickOn(): (/mob)
4 changes: 4 additions & 0 deletions code/__DEFINES/maps.dm
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@
#define ZTRAITS_SPACE list(ZTRAIT_LINKAGE = CROSSLINKED, ZTRAIT_SPACE_RUINS = TRUE)
#define ZTRAITS_ASTEROID list(ZTRAIT_LINKAGE = CROSSLINKED, ZTRAIT_MINING = TRUE)

#define CAMERA_LOCK_STATION 1
#define CAMERA_LOCK_MINING 2
#define CAMERA_LOCK_CENTCOM 4

#define DL_NAME "name"
#define DL_TRAITS "traits"
#define DECLARE_LEVEL(NAME, TRAITS) list(DL_NAME = NAME, DL_TRAITS = TRAITS)
Expand Down
232 changes: 232 additions & 0 deletions code/game/machinery/camera/camera_advanced.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
/obj/machinery/computer/camera_advanced
name = "advanced camera console"
desc = "Used to access the various cameras on the station."
icon_state = "cameras"

circuit = /obj/item/weapon/circuitboard/camera_advanced
light_color = "#a91515"

var/lock_override = NONE
var/list/z_lock = list() // Lock use to these z levels. Do not! set this directly, use lock_override flags

var/mob/camera/Eye/remote/eyeobj
var/mob/living/current_user = null

var/list/networks = list("SS13")

var/list/actions = list()
var/datum/action/camera_off/off_action = new
var/datum/action/camera_jump/jump_action = new

/obj/machinery/computer/camera_advanced/atom_init()
. = ..()
actions += off_action
actions += jump_action
if(lock_override)
if(lock_override & CAMERA_LOCK_STATION)
z_lock |= SSmapping.levels_by_trait(ZTRAIT_STATION)
if(lock_override & CAMERA_LOCK_MINING)
z_lock |= SSmapping.levels_by_trait(ZTRAIT_MINING)
if(lock_override & CAMERA_LOCK_CENTCOM)
z_lock |= SSmapping.levels_by_trait(ZTRAIT_CENTCOM)

/obj/machinery/computer/camera_advanced/Destroy()
if(current_user)
current_user.unset_machine()
current_user = null
QDEL_NULL(eyeobj)
QDEL_NULL(off_action)
QDEL_NULL(jump_action)
actions.Cut()
return ..()

/obj/machinery/computer/camera_advanced/proc/CreateEye()
eyeobj = new()
eyeobj.origin = src

/obj/machinery/computer/camera_advanced/proc/GrantActions(mob/living/user)
if(off_action)
off_action.target = user
off_action.Grant(user)


if(jump_action)
jump_action.target = user
jump_action.Grant(user)


/obj/machinery/computer/camera_advanced/proc/remove_eye_control(mob/living/user)
if(!user)
CRASH("Attempted to call remove_eye_control() proc with null user")
for(var/V in actions)
var/datum/action/A = V
A.Remove(user)
for(var/V in eyeobj.visibleCameraChunks)
var/datum/camerachunk/C = V
C.remove(eyeobj)
if(user.client)
user.reset_view(null)
if(eyeobj.user_camera_icon && user.client)
user.client.images -= eyeobj.user_image
eyeobj.master = null
user.remote_control = null

current_user = null
user.unset_machine()

/obj/machinery/computer/camera_advanced/check_eye(mob/user)
if( (stat & (NOPOWER|BROKEN)) || (!Adjacent(user) && !user.has_unlimited_silicon_privilege) || user.eye_blind || user.incapacitated() )
user.unset_machine()
return FALSE
return TRUE

/obj/machinery/computer/camera_advanced/on_unset_machine(mob/M)
if(M == current_user)
remove_eye_control(M)
..()

/obj/machinery/computer/camera_advanced/interact(mob/user)
user.machine = src
var/mob/living/L = user
if(!eyeobj)
CreateEye()

if(!eyeobj.eye_initialized)
var/camera_location
var/turf/myturf = get_turf(src)
if(z_lock.len && !(myturf.z in z_lock))
to_chat(user, "<span class='warning'>ERROR: system unable to access local camera network.</span>")
else
camera_location = myturf

if(camera_location)
eyeobj.eye_initialized = TRUE
give_eye_control(L)
eyeobj.setLoc(camera_location)
else
user.unset_machine()
else
give_eye_control(L)
eyeobj.setLoc(eyeobj.loc)


/obj/machinery/computer/camera_advanced/attack_hand(mob/user)
if(!is_operational())
return
if(current_user)
to_chat(user, "<span class='warning'>The console is already in use!</span>")
return
..()

/obj/machinery/computer/camera_advanced/attack_robot(mob/user)
return attack_hand(user)

/obj/machinery/computer/camera_advanced/attack_ai(mob/user)
return //AIs would need to disable their own camera procs to use the console safely. Bugs happen otherwise.

/obj/machinery/computer/camera_advanced/proc/give_eye_control(mob/user)
GrantActions(user)
current_user = user
eyeobj.master = user
eyeobj.name = "Camera Eye ([user.name])"
user.remote_control = eyeobj
user.reset_view(eyeobj)
eyeobj.setLoc(eyeobj.loc)
if(eyeobj.user_camera_icon && user.client)
user.client.images += eyeobj.user_image

/mob/camera/Eye/remote
name = "Inactive Camera Eye"
var/obj/machinery/computer/camera_advanced/origin
var/sprint = 10
var/cooldown = 0
var/acceleration = FALSE
var/eye_initialized = FALSE
var/user_camera_icon = null //How icon appears to user. If you want eye to be invisible to anyone but user, use this instead of "icon" variable.
var/image/user_image = null
var/allowed_area_type = null

/mob/camera/Eye/remote/atom_init()
if(!user_image && user_camera_icon)
user_image = image(icon = user_camera_icon,loc = src,icon_state = icon_state,layer = LIGHTING_LAYER+1)
. = ..()

/mob/camera/Eye/remote/Destroy()
if(origin && master)
origin.remove_eye_control(master)
origin = null
master = null
return ..()

/mob/camera/Eye/remote/relaymove(mob/user,direct)
var/initial = initial(sprint)
var/max_sprint = 50

if(cooldown && cooldown < world.timeofday) // 3 seconds
sprint = initial

for(var/i = 0; i < max(sprint, initial); i += 20)
var/turf/movement = get_step(src, direct)
if(movement)
setLoc(movement)

cooldown = world.timeofday + 5
if(acceleration)
sprint = min(sprint + 0.5, max_sprint)
else
sprint = initial

/mob/camera/Eye/remote/setLoc(turf/T)
if (allowed_area_type != null && !istype(get_area(T), allowed_area_type))
return
..()

/datum/action/camera_off
name = "End Camera View"
button_icon = 'icons/mob/actions.dmi'
button_icon_state = "camera_off"
action_type = AB_INNATE

/datum/action/camera_off/Activate()
if(!target || !isliving(target))
return
var/mob/living/C = target
var/mob/camera/Eye/remote/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/console = remote_eye.origin
console.remove_eye_control(target)

/datum/action/camera_jump
name = "Jump To Camera"
button_icon = 'icons/mob/actions.dmi'
button_icon_state = "camera_jump"
action_type = AB_INNATE

/datum/action/camera_jump/Activate()
if(!target || !isliving(target))
return

var/mob/living/C = target
var/mob/camera/Eye/remote/remote_eye = C.remote_control
var/obj/machinery/computer/camera_advanced/origin = remote_eye.origin

var/list/L = list()

for (var/obj/machinery/camera/cam in cameranet.cameras)
if(origin.z_lock.len && !(cam.z in origin.z_lock))
continue
L.Add(cam)

camera_sort(L)

var/list/T = list()

for (var/obj/machinery/camera/netcam in L)
if (length(netcam.network & origin.networks))
if (remote_eye.allowed_area_type != null && !istype(get_area(netcam), remote_eye.allowed_area_type))
continue
T["[netcam.c_tag][netcam.can_use() ? null : " (Deactivated)"]"] = netcam

var/camera = input("Choose which camera you want to view", "Cameras") as null|anything in T
var/obj/machinery/camera/final = T[camera]
if(final)
remote_eye.setLoc(get_turf(final))
8 changes: 8 additions & 0 deletions code/game/machinery/computer/buildandrepair.dm
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@
name = "Circuit board (Message Monitor)"
build_path = /obj/machinery/computer/message_monitor
origin_tech = "programming=3"
/obj/item/weapon/circuitboard/camera_advanced
name = "circuit board (Advanced Camera Console)"
build_path = /obj/machinery/computer/camera_advanced
req_access = list(access_security)
/obj/item/weapon/circuitboard/camera_advanced/xenobio
name = "circuit board (Slime management console)"
build_path = /obj/machinery/computer/camera_advanced/xenobio
origin_tech = "biotech=3;bluespace=3"
/obj/item/weapon/circuitboard/security
name = "Circuit board (Security)"
build_path = /obj/machinery/computer/security
Expand Down
56 changes: 41 additions & 15 deletions code/game/machinery/kitchen/monkeyrecycler.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/obj/machinery/monkey_recycler
name = "Monkey Recycler"
desc = "A machine used for recycling dead monkeys into monkey cubes."
name = "Recycler"
desc = "A machine used for recycling dead monkeys into monkey cubes. Can also quickly extract cores from dead slimes"
icon = 'icons/obj/kitchen.dmi'
icon_state = "grinder"
layer = 2.9
Expand All @@ -12,6 +12,7 @@
var/grinded = 0
var/required_grind = 5
var/cube_production = 1
var/list/connected_consoles = list()

/obj/machinery/monkey_recycler/atom_init()
. = ..()
Expand All @@ -21,18 +22,33 @@
component_parts += new /obj/item/weapon/stock_parts/matter_bin(null)
RefreshParts()

/obj/machinery/monkey_recycler/proc/grind(var/M, mob/user)
user.drop_item()
qdel(M)
to_chat(user, "<span class='notice'>You stuff the monkey in the machine.</span>")
/obj/machinery/monkey_recycler/Destroy()
for(var/obj/machinery/computer/camera_advanced/xenobio/console in connected_consoles)
console.connected_recycler = null
connected_consoles.Cut()
return ..()

/obj/machinery/monkey_recycler/proc/grind(atom/movable/P, mob/user)
playsound(src, 'sound/machines/juicer.ogg', VOL_EFFECTS_MASTER)
var/offset = prob(50) ? -2 : 2
animate(src, pixel_x = pixel_x + offset, time = 0.2, loop = 200) //start shaking
use_power(500)
src.grinded++
sleep(50)
var/atom/movable/M = P
M.forceMove(src) //To hide them from view
addtimer(CALLBACK(src, .proc/finish_processing,M,user), 50)


/obj/machinery/monkey_recycler/proc/finish_processing(atom/movable/M, mob/user)
if(ismonkey(M))
src.grinded++
to_chat(user, "<span class='notice'>The machine now has [grinded/required_grind] monkeys worth of material stored.</span>")
else if(isslime(M))
var/mob/living/carbon/slime/S = M
var/C = S.cores
for(var/i in 1 to (C+cube_production-1)) //Can extract many cores if upgraded
new S.coretype(loc)
qdel(M)
pixel_x = initial(pixel_x)
to_chat(user, "<span class='notice'>The machine now has [grinded] monkeys worth of material stored.</span>")

/obj/machinery/monkey_recycler/RefreshParts()
var/req_grind = 5
Expand All @@ -43,7 +59,7 @@
cubes_made = M.rating
cube_production = cubes_made
required_grind = req_grind
desc = "A machine used for recycling dead monkeys into monkey cubes. It currently produces [cubes_made] cube(s) for every [required_grind] monkey(s) inserted."
desc = "A machine used for recycling dead monkeys into monkey cubes. It currently produces [cubes_made] cube(s) for every [required_grind] monkey(s) inserted. Can also quickly extract cores from dead slimes."

/obj/machinery/monkey_recycler/attackby(obj/item/O, mob/user, params)
if(default_deconstruction_screwdriver(user, "grinder_open", "grinder", O))
Expand All @@ -68,20 +84,30 @@
for (var/mob/living/M in O.contents)
G = M
if (G.stat == CONSCIOUS)
to_chat(user, "<span class='warning'>The monkey is struggling far too much to put it in the recycler.</span>")
to_chat(user, "<span class='warning'>The subject is struggling far too much to put it in the recycler.</span>")
else
user.drop_item()
to_chat(user, "<span class='notice'>You stuff the subject in the machine.</span>")
grind(O, user)
if (istype(O, /obj/item/weapon/grab))
var/obj/item/weapon/grab/G = O
var/grabbed = G.affecting
if(ismonkey(grabbed))
var/mob/living/carbon/monkey/target = grabbed
if(ismonkey(grabbed) || isslime(grabbed))
var/mob/living/carbon/target = grabbed
if(target.stat == CONSCIOUS)
to_chat(user, "<span class='warning'>The monkey is struggling far too much to put it in the recycler.</span>")
to_chat(user, "<span class='warning'>The subject is struggling far too much to put it in the recycler.</span>")
else
user.drop_item()
to_chat(user, "<span class='notice'>You stuff the subject in the machine.</span>")
grind(target, user)
else
to_chat(user, "<span class='warning'>The machine only accepts monkeys!</span>")
to_chat(user, "<span class='warning'>The machine only accepts monkeys and slimes!</span>")

if(panel_open)
if(ismultitool(O))
var/obj/item/device/multitool/M = O
M.buffer = src
to_chat(user, "<span class='notice'>You save the data in the [O.name]'s buffer.</span>")
return

/obj/machinery/monkey_recycler/attack_hand(mob/user)
Expand Down
14 changes: 14 additions & 0 deletions code/game/objects/items/weapons/storage/bags.dm
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,20 @@
w_class = ITEM_SIZE_SMALL
can_hold = list(/obj/item/weapon/reagent_containers/food/snacks/grown,/obj/item/seeds,/obj/item/weapon/grown)

// -----------------------------
// Bio bag
// -----------------------------

/obj/item/weapon/storage/bag/bio
name = "bio bag"
icon = 'icons/obj/chemical.dmi'
icon_state = "biobag"
desc = "A bag for the safe transportation and disposal of biowaste and other biological materials."
max_storage_space = 100
w_class = ITEM_SIZE_NORMAL
max_w_class = ITEM_SIZE_NORMAL
can_hold = list(/obj/item/slime_extract,/obj/item/weapon/reagent_containers/syringe,/obj/item/weapon/reagent_containers/dropper,/obj/item/weapon/reagent_containers/glass/beaker,/obj/item/weapon/reagent_containers/glass/bottle,/obj/item/weapon/reagent_containers/blood,/obj/item/weapon/reagent_containers/food/snacks/monkeycube,/obj/item/organ)


// -----------------------------
// Sheet Snatcher
Expand Down

0 comments on commit 37ad218

Please sign in to comment.