441 lines
14 KiB
Plaintext
441 lines
14 KiB
Plaintext
//These procs handle putting stuff in your hand. It's probably best to use these rather than setting stuff manually
|
|
//as they handle all relevant stuff like adding it to the player's screen and such
|
|
|
|
/**
|
|
* Returns the thing in our active hand (whatever is in our active module-slot, in this case)
|
|
*
|
|
* Arguments
|
|
* * get_gripper - If the active module is a gripper, should we return the gripper or the contained item? (if the gripper contains nothing, returns the gripper anyways)
|
|
*/
|
|
/mob/living/silicon/robot/get_active_held_item(get_gripper = FALSE)
|
|
var/item = module_active
|
|
// snowflake handler for the gripper
|
|
if(istype(item, /obj/item/gripper) && !get_gripper)
|
|
var/obj/item/gripper/G = item
|
|
if(G.wrapped)
|
|
if(G.wrapped.loc != G)
|
|
G.wrapped = null
|
|
return module_active
|
|
item = G.wrapped
|
|
return item
|
|
return module_active
|
|
/**
|
|
* Parent proc - triggers when an item/module is unequipped from a cyborg.
|
|
*/
|
|
/obj/item/proc/cyborg_unequip(mob/user)
|
|
return
|
|
|
|
/**
|
|
* Finds the first available slot and attemps to put item item_module in it.
|
|
*
|
|
* Arguments
|
|
* * item_module - the item being equipped to a slot.
|
|
*/
|
|
/mob/living/silicon/robot/proc/activate_module(obj/item/item_module)
|
|
if(QDELETED(item_module))
|
|
CRASH("activate_module called with improper item_module")
|
|
|
|
if(!(item_module in module.modules))
|
|
CRASH("activate_module called with item_module not in module.modules")
|
|
|
|
if(activated(item_module))
|
|
to_chat(src, "<span class='warning'>That module is already activated.</span>")
|
|
return FALSE
|
|
|
|
if(disabled_modules & BORG_MODULE_ALL_DISABLED)
|
|
to_chat(src, "<span class='warning'>All modules are disabled!</span>")
|
|
return FALSE
|
|
|
|
/// What's the first free slot for the borg?
|
|
var/first_free_slot = !held_items[1] ? 1 : (!held_items[2] ? 2 : (!held_items[3] ? 3 : null))
|
|
|
|
if(!first_free_slot || is_invalid_module_number(first_free_slot))
|
|
to_chat(src, "<span class='warning'>Deactivate a module first!</span>")
|
|
return FALSE
|
|
|
|
return equip_module_to_slot(item_module, first_free_slot)
|
|
|
|
/**
|
|
* Is passed an item and a module slot. Equips the item to that borg slot.
|
|
*
|
|
* Arguments
|
|
* * item_module - the item being equipped to a slot
|
|
* * module_num - the slot number being equipped to.
|
|
*/
|
|
/mob/living/silicon/robot/proc/equip_module_to_slot(obj/item/item_module, module_num)
|
|
var/storage_was_closed = FALSE //Just to be consistant and all
|
|
if(!shown_robot_modules) //Tools may be invisible if the collection is hidden
|
|
hud_used.toggle_show_robot_modules()
|
|
storage_was_closed = TRUE
|
|
switch(module_num)
|
|
if(1)
|
|
item_module.screen_loc = inv1.screen_loc
|
|
if(2)
|
|
item_module.screen_loc = inv2.screen_loc
|
|
if(3)
|
|
item_module.screen_loc = inv3.screen_loc
|
|
|
|
held_items[module_num] = item_module
|
|
item_module.equipped(src, ITEM_SLOT_HANDS)
|
|
item_module.mouse_opacity = initial(item_module.mouse_opacity)
|
|
item_module.layer = ABOVE_HUD_LAYER
|
|
item_module.plane = ABOVE_HUD_PLANE
|
|
item_module.forceMove(src)
|
|
|
|
if(istype(item_module, /obj/item/borg/sight))
|
|
var/obj/item/borg/sight/borg_sight = item_module
|
|
sight_mode |= borg_sight.sight_mode
|
|
update_sight()
|
|
|
|
observer_screen_update(item_module, TRUE)
|
|
|
|
if(storage_was_closed)
|
|
hud_used.toggle_show_robot_modules()
|
|
return TRUE
|
|
|
|
/**
|
|
* Unequips item item_module from slot module_num. Deletes it if delete_after = TRUE.
|
|
*
|
|
* Arguments
|
|
* * item_module - the item being unequipped
|
|
* * module_num - the slot number being unequipped.
|
|
*/
|
|
/mob/living/silicon/robot/proc/unequip_module_from_slot(obj/item/item_module, module_num)
|
|
if(QDELETED(item_module))
|
|
CRASH("unequip_module_from_slot called with improper item_module")
|
|
|
|
if(!(item_module in module.modules))
|
|
CRASH("unequip_module_from_slot called with item_module not in module.modules")
|
|
|
|
item_module.mouse_opacity = MOUSE_OPACITY_OPAQUE
|
|
|
|
if(istype(item_module, /obj/item/storage/bag/tray/))
|
|
SEND_SIGNAL(item_module, COMSIG_TRY_STORAGE_QUICK_EMPTY)
|
|
if(istype(item_module, /obj/item/borg/sight))
|
|
var/obj/item/borg/sight/borg_sight = item_module
|
|
sight_mode &= ~borg_sight.sight_mode
|
|
update_sight()
|
|
//CITADEL EDIT reee proc, Dogborg modules
|
|
if(istype(item_module, /obj/item/gun/energy/laser/cyborg))
|
|
laser = FALSE
|
|
update_icons()
|
|
if(istype(item_module, /obj/item/gun/energy/disabler/cyborg) || istype(item_module, /obj/item/gun/energy/e_gun/advtaser/cyborg))
|
|
disabler = FALSE
|
|
update_icons() //PUT THE GUN AWAY
|
|
if(istype(item_module, /obj/item/dogborg/sleeper))
|
|
sleeper_g = FALSE
|
|
sleeper_r = FALSE
|
|
update_icons()
|
|
var/obj/item/dogborg/sleeper/S = item_module
|
|
S.go_out() //this should stop edgecase deletions
|
|
//END CITADEL EDIT
|
|
|
|
if(client)
|
|
client.screen -= item_module
|
|
|
|
if(module_active == item_module)
|
|
module_active = null
|
|
|
|
switch(module_num)
|
|
if(1)
|
|
if(!(disabled_modules & BORG_MODULE_ALL_DISABLED))
|
|
inv1.icon_state = initial(inv1.icon_state)
|
|
if(2)
|
|
if(!(disabled_modules & BORG_MODULE_TWO_DISABLED))
|
|
inv2.icon_state = initial(inv2.icon_state)
|
|
if(3)
|
|
if(!(disabled_modules & BORG_MODULE_THREE_DISABLED))
|
|
inv3.icon_state = initial(inv3.icon_state)
|
|
|
|
if(item_module.item_flags & DROPDEL)
|
|
item_module.item_flags &= ~DROPDEL //we shouldn't HAVE things with DROPDEL_1 in our modules, but better safe than runtiming horribly
|
|
|
|
held_items[module_num] = null
|
|
item_module.cyborg_unequip(src)
|
|
item_module.forceMove(module) //Return item to module so it appears in its contents, so it can be taken out again.
|
|
|
|
observer_screen_update(item_module, FALSE)
|
|
hud_used.update_robot_modules_display()
|
|
return TRUE
|
|
|
|
/**
|
|
* Breaks the slot number, changing the icon.
|
|
*
|
|
* Arguments
|
|
* * module_num - the slot number being repaired.
|
|
*/
|
|
/mob/living/silicon/robot/proc/break_cyborg_slot(module_num)
|
|
if(is_invalid_module_number(module_num, TRUE))
|
|
return FALSE
|
|
|
|
if(held_items[module_num]) //If there's a held item, unequip it first.
|
|
if(!unequip_module_from_slot(held_items[module_num], module_num)) //If we fail to unequip it, then don't continue
|
|
return FALSE
|
|
|
|
switch(module_num)
|
|
if(1)
|
|
if(disabled_modules & BORG_MODULE_ALL_DISABLED)
|
|
return FALSE
|
|
|
|
inv1.icon_state = "[initial(inv1.icon_state)] +b"
|
|
disabled_modules |= BORG_MODULE_ALL_DISABLED
|
|
|
|
playsound(src, 'sound/machines/warning-buzzer.ogg', 75, TRUE, TRUE)
|
|
audible_message("<span class='warning'>[src] sounds an alarm! \"CRITICAL ERROR: ALL modules OFFLINE.\"</span>")
|
|
|
|
if(builtInCamera)
|
|
builtInCamera.status = FALSE
|
|
to_chat(src, "<span class='userdanger'>CRITICAL ERROR: Built in security camera OFFLINE.</span>")
|
|
|
|
to_chat(src, "<span class='userdanger'>CRITICAL ERROR: ALL modules OFFLINE.</span>")
|
|
|
|
if(2)
|
|
if(disabled_modules & BORG_MODULE_TWO_DISABLED)
|
|
return FALSE
|
|
|
|
inv2.icon_state = "[initial(inv2.icon_state)] +b"
|
|
disabled_modules |= BORG_MODULE_TWO_DISABLED
|
|
|
|
playsound(src, 'sound/machines/warning-buzzer.ogg', 60, TRUE, TRUE)
|
|
audible_message("<span class='warning'>[src] sounds an alarm! \"SYSTEM ERROR: Module [module_num] OFFLINE.\"</span>")
|
|
to_chat(src, "<span class='userdanger'>SYSTEM ERROR: Module [module_num] OFFLINE.</span>")
|
|
|
|
if(3)
|
|
if(disabled_modules & BORG_MODULE_THREE_DISABLED)
|
|
return FALSE
|
|
|
|
inv3.icon_state = "[initial(inv3.icon_state)] +b"
|
|
disabled_modules |= BORG_MODULE_THREE_DISABLED
|
|
|
|
playsound(src, 'sound/machines/warning-buzzer.ogg', 50, TRUE, TRUE)
|
|
audible_message("<span class='warning'>[src] sounds an alarm! \"SYSTEM ERROR: Module [module_num] OFFLINE.\"</span>")
|
|
to_chat(src, "<span class='userdanger'>SYSTEM ERROR: Module [module_num] OFFLINE.</span>")
|
|
|
|
return TRUE
|
|
|
|
/**
|
|
* Breaks all of a cyborg's slots.
|
|
*/
|
|
/mob/living/silicon/robot/proc/break_all_cyborg_slots()
|
|
for(var/cyborg_slot in 1 to 3)
|
|
break_cyborg_slot(cyborg_slot)
|
|
|
|
/**
|
|
* Repairs the slot number, updating the icon.
|
|
*
|
|
* Arguments
|
|
* * module_num - the module number being repaired.
|
|
*/
|
|
/mob/living/silicon/robot/proc/repair_cyborg_slot(module_num)
|
|
if(is_invalid_module_number(module_num, TRUE))
|
|
return FALSE
|
|
|
|
switch(module_num)
|
|
if(1)
|
|
if(!(disabled_modules & BORG_MODULE_ALL_DISABLED))
|
|
return FALSE
|
|
|
|
inv1.icon_state = initial(inv1.icon_state)
|
|
disabled_modules &= ~BORG_MODULE_ALL_DISABLED
|
|
if(builtInCamera)
|
|
builtInCamera.status = TRUE
|
|
to_chat(src, "<span class='notice'>You hear your built in security camera focus adjust as it comes back online!</span>")
|
|
if(2)
|
|
if(!(disabled_modules & BORG_MODULE_TWO_DISABLED))
|
|
return FALSE
|
|
|
|
inv2.icon_state = initial(inv2.icon_state)
|
|
disabled_modules &= ~BORG_MODULE_TWO_DISABLED
|
|
if(3)
|
|
if(!(disabled_modules & BORG_MODULE_THREE_DISABLED))
|
|
return FALSE
|
|
|
|
inv3.icon_state = initial(inv3.icon_state)
|
|
disabled_modules &= ~BORG_MODULE_THREE_DISABLED
|
|
|
|
to_chat(src, "<span class='notice'>ERROR CLEARED: Module [module_num] back online.</span>")
|
|
|
|
return TRUE
|
|
|
|
/**
|
|
* Repairs all slots. Unbroken slots are unaffected.
|
|
*/
|
|
/mob/living/silicon/robot/proc/repair_all_cyborg_slots()
|
|
for(var/cyborg_slot in 1 to 3)
|
|
repair_cyborg_slot(cyborg_slot)
|
|
|
|
/**
|
|
* Updates the observers's screens with cyborg itemss.
|
|
* Arguments
|
|
* * item_module - the item being added or removed from the screen
|
|
* * add - whether or not the item is being added, or removed.
|
|
*/
|
|
/mob/living/silicon/robot/proc/observer_screen_update(obj/item/item_module, add = TRUE)
|
|
if(observers?.len)
|
|
for(var/M in observers)
|
|
var/mob/dead/observe = M
|
|
if(observe.client && observe.client.eye == src)
|
|
if(add)
|
|
observe.client.screen += item_module
|
|
else
|
|
observe.client.screen -= item_module
|
|
else
|
|
observers -= observe
|
|
if(!observers.len)
|
|
observers = null
|
|
break
|
|
|
|
/**
|
|
* Unequips the active held item, if there is one.
|
|
*
|
|
* Will always consider dropping gripper contents first.
|
|
*/
|
|
/mob/living/silicon/robot/proc/uneq_active()
|
|
if(module_active)
|
|
var/obj/item/gripper/gripper = get_active_held_item(TRUE)
|
|
if(istype(gripper) && gripper.drop_held())
|
|
return
|
|
unequip_module_from_slot(module_active, get_selected_module())
|
|
|
|
/**
|
|
* Unequips all held items.
|
|
*/
|
|
/mob/living/silicon/robot/proc/uneq_all()
|
|
for(var/cyborg_slot in 1 to 3)
|
|
if(!held_items[cyborg_slot])
|
|
continue
|
|
unequip_module_from_slot(held_items[cyborg_slot], cyborg_slot)
|
|
|
|
/**
|
|
* Checks if the item is currently in a slot.
|
|
*
|
|
* If the item is found in a slot, this returns TRUE. Otherwise, it returns FALSE
|
|
* Modified to accept items inside of grippers, used for `code\modules\tgui\states\hands.dm:27`
|
|
* Arguments
|
|
* * item_module - the item being checked
|
|
*/
|
|
/mob/living/silicon/robot/proc/activated(obj/item/item_module)
|
|
if(get_active_held_item() == item_module || (item_module in held_items))
|
|
return TRUE
|
|
return FALSE
|
|
|
|
/**
|
|
* Checks if the provided module number is a valid number.
|
|
*
|
|
* If the number is between 1 and 3 (if check_all_slots is true) or between 1 and the number of disabled
|
|
* modules (if check_all_slots is false), then it returns FALSE. Otherwise, it returns TRUE.
|
|
* Arguments
|
|
* * module_num - the passed module num that is checked for validity.
|
|
* * check_all_slots - TRUE = the proc checks all slots | FALSE = the proc only checks un-disabled slots
|
|
*/
|
|
/mob/living/silicon/robot/proc/is_invalid_module_number(module_num, check_all_slots = FALSE)
|
|
if(!module_num)
|
|
return TRUE
|
|
|
|
/// The number of module slots we're checking
|
|
var/max_number = 3
|
|
if(!check_all_slots)
|
|
if(disabled_modules & BORG_MODULE_ALL_DISABLED)
|
|
max_number = 0
|
|
else if(disabled_modules & BORG_MODULE_TWO_DISABLED)
|
|
max_number = 1
|
|
else if(disabled_modules & BORG_MODULE_THREE_DISABLED)
|
|
max_number = 2
|
|
|
|
return module_num < 1 || module_num > max_number
|
|
|
|
/**
|
|
* Returns the slot number of the selected module, or zero if no modules are selected.
|
|
*/
|
|
/mob/living/silicon/robot/proc/get_selected_module()
|
|
if(module_active)
|
|
return held_items.Find(module_active)
|
|
|
|
return FALSE
|
|
|
|
/**
|
|
* Selects the module in the slot module_num.
|
|
* Arguments
|
|
* * module_num - the slot number being selected
|
|
*/
|
|
/mob/living/silicon/robot/proc/select_module(module_num)
|
|
if(is_invalid_module_number(module_num) || !held_items[module_num]) //If the slot number is invalid, or there's nothing there, we have nothing to equip
|
|
return FALSE
|
|
|
|
switch(module_num)
|
|
if(1)
|
|
if(module_active != held_items[module_num])
|
|
inv1.icon_state = "[initial(inv1.icon_state)] +a"
|
|
if(2)
|
|
if(module_active != held_items[module_num])
|
|
inv2.icon_state = "[initial(inv2.icon_state)] +a"
|
|
if(3)
|
|
if(module_active != held_items[module_num])
|
|
inv3.icon_state = "[initial(inv3.icon_state)] +a"
|
|
module_active = held_items[module_num]
|
|
return TRUE
|
|
|
|
/**
|
|
* Deselects the module in the slot module_num.
|
|
* Arguments
|
|
* * module_num - the slot number being de-selected
|
|
*/
|
|
/mob/living/silicon/robot/proc/deselect_module(module_num)
|
|
switch(module_num)
|
|
if(1)
|
|
if(module_active == held_items[module_num])
|
|
inv1.icon_state = initial(inv1.icon_state)
|
|
if(2)
|
|
if(module_active == held_items[module_num])
|
|
inv2.icon_state = initial(inv2.icon_state)
|
|
if(3)
|
|
if(module_active == held_items[module_num])
|
|
inv3.icon_state = initial(inv3.icon_state)
|
|
module_active = null
|
|
return TRUE
|
|
|
|
/**
|
|
* Toggles selection of the module in the slot module_num.
|
|
* Arguments
|
|
* * module_num - the slot number being toggled
|
|
*/
|
|
/mob/living/silicon/robot/proc/toggle_module(module_num)
|
|
if(is_invalid_module_number(module_num))
|
|
return FALSE
|
|
|
|
if(module_num == get_selected_module())
|
|
deselect_module(module_num)
|
|
return TRUE
|
|
|
|
if(module_active != held_items[module_num])
|
|
deselect_module(get_selected_module())
|
|
|
|
return select_module(module_num)
|
|
|
|
/**
|
|
* Cycles through the list of enabled modules, deselecting the current one and selecting the next one.
|
|
*/
|
|
/mob/living/silicon/robot/proc/cycle_modules()
|
|
var/slot_start = get_selected_module()
|
|
var/slot_num
|
|
if(slot_start)
|
|
deselect_module(slot_start) //Only deselect if we have a selected slot.
|
|
slot_num = slot_start + 1
|
|
else
|
|
slot_num = 1
|
|
slot_start = 4
|
|
|
|
while(slot_num != slot_start) //If we wrap around without finding any free slots, just give up.
|
|
if(select_module(slot_num))
|
|
return
|
|
slot_num++
|
|
if(slot_num > 4) // not >3 otherwise cycling with just one item on module 3 wouldn't work
|
|
slot_num = 1 //Wrap around.
|
|
|
|
/mob/living/silicon/robot/swap_hand()
|
|
cycle_modules()
|
|
|
|
/mob/living/silicon/robot/can_hold_items(obj/item/I)
|
|
return (I && (I in module.modules)) //Only if it's part of our module.
|
|
|