Porting flying robots from Bay. [IDB IGNORE] (#8885)

* Semiport of Allow_Spacemove from Bay.

* Porting flying robots from Bay.

* Converting platforms to an alt title of Robot.

* Converting existing modules to new proc flow.

* Cleaning up jetpack code for robots.

* Making flyers and platforms buildable.

* Debugging/refining robots port.

* Reverting some unneeded spacemove changes.

* Refining/debugging bots.

* Removing Bay subtypes, adding flying subtypes of existing modules.

* Icon rework for flying robots.

* Working commit for flying borgs PR.
This commit is contained in:
MistakeNot4892
2023-07-31 22:22:12 -08:00
committed by GitHub
parent 0941bbacae
commit 658e19e734
75 changed files with 2004 additions and 1621 deletions
+5
View File
@@ -351,6 +351,11 @@
#define SA_ROBOTIC 3
#define SA_HUMANOID 4
// Robot module categorization
#define ROBOT_MODULE_TYPE_GROUNDED "grounded"
#define ROBOT_MODULE_TYPE_FLYING "flying"
#define ROBOT_MODULE_TYPE_PLATFORM "platform"
// More refined version of SA_* ""intelligence"" separators.
// Now includes bitflags, so to target two classes you just do 'MOB_CLASS_ANIMAL|MOB_CLASS_HUMANOID'
#define MOB_CLASS_NONE 0 // Default value, and used to invert for _ALL.
+62
View File
@@ -0,0 +1,62 @@
SUBSYSTEM_DEF(robots)
name = "Robots"
init_order = INIT_ORDER_MISC_EARLY
flags = SS_NO_FIRE
var/list/modules_by_category = list()
var/list/crisis_modules_by_category = list()
var/list/upgrade_modules_by_category = list()
var/list/all_module_names = list()
var/list/mob_types_by_title = list(
"cyborg, flying" = /mob/living/silicon/robot/flying,
"robot, flying" = /mob/living/silicon/robot/flying,
"drone, flying" = /mob/living/silicon/robot/flying,
"drone, platform" = /mob/living/silicon/robot/platform
)
var/list/mmi_types_by_title = list(
"robot" = /obj/item/mmi/digital/posibrain,
"robot, flying" = /obj/item/mmi/digital/posibrain,
"drone" = /obj/item/mmi/digital/robot,
"drone, flying" = /obj/item/mmi/digital/robot,
"drone, platform" = /obj/item/mmi/digital/robot
)
/datum/controller/subsystem/robots/Initialize(start_uptime)
for(var/module_type in subtypesof(/obj/item/robot_module))
var/obj/item/robot_module/module = module_type
if(initial(module.unavailable_by_default))
continue
var/module_category = initial(module.module_category)
var/module_name = initial(module.display_name)
if(module_name && module_category)
if(initial(module.upgrade_locked))
LAZYINITLIST(upgrade_modules_by_category[module_category])
LAZYSET(upgrade_modules_by_category[module_category], module_name, module)
else if(initial(module.crisis_locked))
LAZYINITLIST(crisis_modules_by_category[module_category])
LAZYSET(crisis_modules_by_category[module_category], module_name, module)
else
LAZYINITLIST(modules_by_category[module_category])
LAZYSET(modules_by_category[module_category], module_name, module)
all_module_names |= module_name
all_module_names = sortTim(all_module_names, /proc/cmp_text_asc)
/datum/controller/subsystem/robots/proc/get_available_modules(module_category, crisis_mode, include_override)
. = list()
if(modules_by_category[module_category])
. += modules_by_category[module_category]
if(crisis_mode && crisis_modules_by_category[module_category])
. |= crisis_modules_by_category[module_category]
if(include_override && upgrade_modules_by_category[module_category])
var/list/modules = upgrade_modules_by_category[module_category]
if(modules[include_override])
.[include_override] = modules[include_override]
/datum/controller/subsystem/robots/proc/get_mmi_type_by_title(check_title)
. = mmi_types_by_title[lowertext(trim(check_title))] || /obj/item/mmi
/datum/controller/subsystem/robots/proc/get_mob_type_by_title(check_title)
. = mob_types_by_title[lowertext(trim(check_title))] || /mob/living/silicon/robot
+2 -3
View File
@@ -205,6 +205,5 @@
/datum/job/proc/handle_nonhuman_mob(var/mob/living/carbon/human/player, var/alt_title)
if(mob_type & JOB_SILICON_ROBOT)
return player.Robotize()
if(mob_type & JOB_SILICON_AI)
return player
return player.Robotize(SSrobots.get_mob_type_by_title(alt_title || title))
return player
+9 -1
View File
@@ -57,9 +57,17 @@
assignable = FALSE
mob_type = JOB_SILICON_ROBOT
outfit_type = /decl/hierarchy/outfit/job/silicon/cyborg
substitute_announce_title = "Stationbound Synthetic"
job_description = "A Cyborg is a mobile station synthetic, piloted by a cybernetically preserved brain. It is considered a person, but is still required \
to follow its Laws."
alt_titles = list("Robot" = /datum/alt_title/robot, "Drone" = /datum/alt_title/drone)
alt_titles = list(
"Cyborg, Flying",
"Robot" = /datum/alt_title/robot,
"Robot, Flying" = /datum/alt_title/robot,
"Drone" = /datum/alt_title/drone,
"Drone, Flying" = /datum/alt_title/drone,
"Drone, Platform" = /datum/alt_title/drone
)
// Cyborg Alt Titles
/datum/alt_title/robot
+10 -11
View File
@@ -71,55 +71,54 @@ Please wait until completion...</TT><BR>
if(!operating)
var/part_type = text2num(href_list["make"])
var/build_type = ""
var/build_type
var/build_time = 200
var/build_cost = 25000
switch (part_type)
if(1)
build_type = "/obj/item/robot_parts/l_arm"
build_type = /obj/item/robot_parts/l_arm
build_time = 200
build_cost = 25000
if(2)
build_type = "/obj/item/robot_parts/r_arm"
build_type = /obj/item/robot_parts/r_arm
build_time = 200
build_cost = 25000
if(3)
build_type = "/obj/item/robot_parts/l_leg"
build_type = /obj/item/robot_parts/l_leg
build_time = 200
build_cost = 25000
if(4)
build_type = "/obj/item/robot_parts/r_leg"
build_type = /obj/item/robot_parts/r_leg
build_time = 200
build_cost = 25000
if(5)
build_type = "/obj/item/robot_parts/chest"
build_type = /obj/item/robot_parts/chest
build_time = 350
build_cost = 50000
if(6)
build_type = "/obj/item/robot_parts/head"
build_type = /obj/item/robot_parts/head
build_time = 350
build_cost = 50000
if(7)
build_type = "/obj/item/robot_parts/robot_suit"
build_type = /obj/item/robot_parts/frame
build_time = 600
build_cost = 75000
var/building = text2path(build_type)
if(!isnull(building))
if(!isnull(build_type))
if(metal_amount >= build_cost)
operating = 1
update_use_power(USE_POWER_ACTIVE)
metal_amount = max(0, metal_amount - build_cost)
being_built = new building(src)
being_built = new build_type(src) // TODO: pass in model info to new
add_overlay("fab-active")
updateUsrDialog()
@@ -1,7 +1,7 @@
/obj/effect/decal/cleanable/blood/gibs/robot
name = "robot debris"
desc = "It's a useless heap of junk... <i>or is it?</i>"
icon = 'icons/mob/robots.dmi'
icon = 'icons/mob/robot_gibs.dmi'
icon_state = "gib1"
basecolor = SYNTH_BLOOD_COLOUR
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6", "gib7")
+1 -1
View File
@@ -14,7 +14,7 @@
/obj/effect/decal/remains/robot
desc = "They look like the remains of something mechanical. They have a strange aura about them."
icon = 'icons/mob/robots.dmi'
icon = 'icons/mob/robot_gibs.dmi'
icon_state = "remainsrobot"
/obj/effect/decal/remains/mouse
@@ -0,0 +1,194 @@
/obj/item/robot_parts/frame
name = "standard robot frame"
desc = "A complex metal backbone with standard limb sockets and pseudomuscle anchors."
icon_state = "robo_suit"
var/list/parts = list()
var/list/required_parts = list(
BP_L_ARM = /obj/item/robot_parts/l_arm,
BP_R_ARM = /obj/item/robot_parts/r_arm,
BP_TORSO = /obj/item/robot_parts/chest,
BP_L_LEG = /obj/item/robot_parts/l_leg,
BP_R_LEG = /obj/item/robot_parts/r_leg,
BP_HEAD = /obj/item/robot_parts/head
)
var/created_name = ""
var/product = /mob/living/silicon/robot
/obj/item/robot_parts/frame/examine(mob/user)
. = ..()
if(check_completion())
. += SPAN_NOTICE("It is ready to receive a controlling intelligence.")
else
for(var/part in required_parts)
if(!parts[part])
var/obj/item/part_type = part
. += SPAN_WARNING("It is missing \a [initial(part_type.name)]")
/obj/item/robot_parts/frame/update_model_info(var/model)
return FALSE
/obj/item/robot_parts/frame/Initialize()
. = ..()
update_icon()
/obj/item/robot_parts/frame/update_icon()
cut_overlays()
for(var/part in required_parts)
if(parts[part])
add_overlay("[part]+o")
/obj/item/robot_parts/frame/proc/check_completion()
for(var/part in required_parts)
if(!parts[part])
return FALSE
return TRUE
/obj/item/robot_parts/frame/attackby(obj/item/W, mob/user)
// Uninstall a robotic part.
if(W.is_crowbar())
if(!parts.len)
to_chat(user, SPAN_WARNING("\The [src] has no parts to remove."))
return
var/removing = pick(parts)
var/obj/item/robot_parts/part = parts[removing]
part.forceMove(get_turf(src))
user.put_in_hands(part)
parts -= removing
to_chat(user, SPAN_WARNING("You lever \the [part] off \the [src]."))
update_icon()
// Install a robotic part.
else if (istype(W, /obj/item/robot_parts))
var/obj/item/robot_parts/part = W
if(!required_parts[part.bp_tag] || !istype(W, required_parts[part.bp_tag]))
to_chat(user, SPAN_WARNING("\The [src] is not compatible with \the [W]."))
return
if(parts[part.bp_tag])
to_chat(user, SPAN_WARNING("\The [src] already has \a [W] installed."))
return
if(part.can_install(user) && user.unEquip(W, src))
parts[part.bp_tag] = part
part.forceMove(src)
update_icon()
// Install an MMI/brain.
else if(istype(W, /obj/item/mmi))
if(!istype(loc,/turf))
to_chat(user, SPAN_WARNING("You can't put \the [W] in without the frame being on the ground."))
return
if(!check_completion())
to_chat(user, SPAN_WARNING("The frame is not ready for the central processor to be installed."))
return
var/obj/item/mmi/M = W
var/mob/living/carbon/brain/B = M.brainmob
if(!B)
to_chat(user, SPAN_WARNING("Sticking an empty [W.name] into the frame would sort of defeat the purpose."))
return
if(jobban_isbanned(B, "Robot"))
to_chat(user, SPAN_WARNING("\The [W] does not seem to fit."))
return
if(B.stat == DEAD)
to_chat(user, SPAN_WARNING("Sticking a dead [W.name] into the frame would sort of defeat the purpose."))
return
var/ghost_can_reenter = 0
if(B.mind)
if(B.key)
ghost_can_reenter = TRUE
else
for(var/mob/observer/dead/G in player_list)
if(G.can_reenter_corpse && G.mind == B.mind)
ghost_can_reenter = TRUE
//Jamming a ghosted brain into a borg is likely detrimental, and may result in some problems.
to_chat(user, SPAN_NOTICE("\The [W] is completely unresponsive, but it may be able to auto-resuscitate if you leave it be for awhile."))
break
if(!ghost_can_reenter)
to_chat(user, SPAN_WARNING("\The [W] is completely unresponsive; there's no point."))
return
if(!user.unEquip(W))
return
var/mob/living/silicon/robot/O = new product(get_turf(loc))
if(!O)
return
O.mmi = W
O.invisibility = 0
O.custom_name = created_name
O.updatename("Default")
B.mind.transfer_to(O)
if(O.mind && O.mind.assigned_role)
O.job = O.mind.assigned_role
else
O.job = "Robot"
var/obj/item/robot_parts/chest/chest = parts[BP_TORSO]
if (chest && chest.cell)
chest.cell.forceMove(O)
W.forceMove(O) //Should fix cybros run time erroring when blown up. It got deleted before, along with the frame.
// Since we "magically" installed a cell, we also have to update the correct component.
if(O.cell)
var/datum/robot_component/cell_component = O.components["power cell"]
cell_component.wrapped = O.cell
cell_component.installed = 1
callHook("borgify", list(O))
O.Namepick()
qdel(src)
else if(istype(W, /obj/item/pen))
var/t = sanitizeSafe(input(user, "Enter new robot name", src.name, src.created_name), MAX_NAME_LEN)
if(t && (in_range(src, user) || loc == user))
created_name = t
else
..()
/obj/item/robot_parts/frame/Destroy()
parts.Cut()
for(var/thing in contents)
qdel(thing)
. = ..()
/obj/item/robot_parts/frame/proc/dismantled_from(mob/living/silicon/robot/donor)
for(var/thing in required_parts - list(BP_TORSO, BP_HEAD))
var/part_type = required_parts[thing]
parts[thing] = new part_type(src)
var/obj/item/robot_parts/chest/chest = (locate() in donor.contents) || new
if(chest)
chest.forceMove(src)
parts[BP_TORSO] = chest
update_icon()
/obj/item/robot_parts/frame/SetDefaultName()
name = initial(name)
/obj/item/robot_parts/frame/flyer
name = "flying robot frame"
icon = 'icons/obj/robot_parts_flying.dmi'
product = /mob/living/silicon/robot/flying
required_parts = list(
BP_L_ARM = /obj/item/robot_parts/l_arm,
BP_R_ARM = /obj/item/robot_parts/r_arm,
BP_TORSO = /obj/item/robot_parts/chest,
BP_HEAD = /obj/item/robot_parts/head
)
/obj/item/robot_parts/frame/platform
name = "large robot frame"
icon = 'icons/obj/robot_parts_platform.dmi'
product = /mob/living/silicon/robot/platform
required_parts = list(
BP_L_ARM = /obj/item/robot_parts/l_arm,
BP_R_ARM = /obj/item/robot_parts/r_arm,
BP_L_LEG = /obj/item/robot_parts/l_leg,
BP_R_LEG = /obj/item/robot_parts/r_leg,
BP_TORSO = /obj/item/robot_parts/chest,
BP_HEAD = /obj/item/robot_parts/head
)
+151 -223
View File
@@ -4,294 +4,222 @@
item_state = "buildpipe"
icon_state = "blank"
slot_flags = SLOT_BELT
dir = SOUTH
var/list/part = null // Order of args is important for installing robolimbs.
var/sabotaged = 0 //Emagging limbs can have repercussions when installed as prosthetics.
var/model_info
dir = SOUTH
var/bp_tag = null // What part is this?
/obj/item/robot_parts/set_dir()
return
/obj/item/robot_parts/proc/update_model_info(var/model)
if(!model)
return FALSE
model_info = model
var/datum/robolimb/R = all_robolimbs[model]
if(R)
name = "[R.company] [initial(name)]"
desc = "[R.desc]"
if(icon_state in icon_states(R.icon))
icon = R.icon
return TRUE
return FALSE
/obj/item/robot_parts/Initialize(ml, model)
. = ..(ml)
if(!update_model_info(model))
SetDefaultName()
/obj/item/robot_parts/proc/SetDefaultName()
name = "robot [initial(name)]"
/obj/item/robot_parts/proc/can_install(mob/user)
return TRUE
/obj/item/robot_parts/l_arm
name = "cyborg left arm"
name = "left arm"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
icon_state = "l_arm"
part = list(BP_L_ARM, BP_L_HAND)
model_info = 1
bp_tag = BP_L_ARM
/obj/item/robot_parts/r_arm
name = "cyborg right arm"
name = "right arm"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
icon_state = "r_arm"
part = list(BP_R_ARM, BP_R_HAND)
model_info = 1
bp_tag = BP_R_ARM
/obj/item/robot_parts/l_leg
name = "cyborg left leg"
name = "left leg"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
icon_state = "l_leg"
part = list(BP_L_LEG, BP_L_FOOT)
model_info = 1
bp_tag = BP_L_LEG
/obj/item/robot_parts/r_leg
name = "cyborg leg"
name = "right leg"
desc = "A skeletal limb wrapped in pseudomuscles, with a low-conductivity case."
icon_state = "r_leg"
part = list(BP_R_LEG, BP_R_FOOT)
model_info = 1
/obj/item/robot_parts/chest
name = "cyborg chest"
desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell."
icon_state = "chest"
part = list(BP_GROIN,BP_TORSO)
var/wires = 0.0
var/obj/item/cell/cell = null
bp_tag = BP_R_LEG
/obj/item/robot_parts/head
name = "cyborg head"
name = "head"
desc = "A standard reinforced braincase, with spine-plugged neural socket and sensor gimbals."
icon_state = "head"
part = list(BP_HEAD)
bp_tag = BP_HEAD
var/obj/item/flash/flash1 = null
var/obj/item/flash/flash2 = null
/obj/item/robot_parts/robot_suit
name = "endoskeleton"
desc = "A complex metal backbone with standard limb sockets and pseudomuscle anchors."
icon_state = "robo_suit"
var/obj/item/robot_parts/l_arm/l_arm = null
var/obj/item/robot_parts/r_arm/r_arm = null
var/obj/item/robot_parts/l_leg/l_leg = null
var/obj/item/robot_parts/r_leg/r_leg = null
var/obj/item/robot_parts/chest/chest = null
var/obj/item/robot_parts/head/head = null
var/created_name = ""
/obj/item/robot_parts/head/can_install(mob/user)
var/success = TRUE
if(!flash1 || !flash2)
to_chat(user, SPAN_WARNING("You need to attach a flash to it first!"))
success = FALSE
return success && ..()
/obj/item/robot_parts/robot_suit/Initialize()
. = ..()
src.updateicon()
/obj/item/robot_parts/chest
name = "torso"
desc = "A heavily reinforced case containing cyborg logic boards, with space for a standard power cell."
icon_state = "torso"
part = list(BP_GROIN,BP_TORSO)
bp_tag = BP_TORSO
var/wires = 0.0
var/obj/item/cell/cell = null
/obj/item/robot_parts/robot_suit/proc/updateicon()
cut_overlays()
if(src.l_arm)
add_overlay("l_arm+o")
if(src.r_arm)
add_overlay("r_arm+o")
if(src.chest)
add_overlay("chest+o")
if(src.l_leg)
add_overlay("l_leg+o")
if(src.r_leg)
add_overlay("r_leg+o")
if(src.head)
add_overlay("head+o")
/obj/item/robot_parts/chest/can_install(mob/user)
var/success = TRUE
if(!wires)
to_chat(user, SPAN_WARNING("You need to attach wires to it first!"))
success = FALSE
if(!cell)
to_chat(user, SPAN_WARNING("You need to attach a cell to it first!"))
success = FALSE
return success && ..()
/obj/item/robot_parts/robot_suit/proc/check_completion()
if(src.l_arm && src.r_arm)
if(src.l_leg && src.r_leg)
if(src.chest && src.head)
feedback_inc("cyborg_frames_built",1)
return 1
return 0
/obj/item/robot_parts/chest/attackby(obj/item/W, mob/user)
/obj/item/robot_parts/robot_suit/attackby(obj/item/W as obj, mob/user as mob)
..()
if(istype(W, /obj/item/stack/material) && W.get_material_name() == MAT_STEEL && !l_arm && !r_arm && !l_leg && !r_leg && !chest && !head)
var/obj/item/stack/material/M = W
if (M.use(1))
var/obj/item/secbot_assembly/ed209_assembly/B = new /obj/item/secbot_assembly/ed209_assembly
B.loc = get_turf(src)
to_chat(user, "<span class='notice'>You armed the robot frame.</span>")
if (user.get_inactive_hand()==src)
user.remove_from_mob(src)
user.put_in_inactive_hand(B)
qdel(src)
else
to_chat(user, "<span class='warning'>You need one sheet of metal to arm the robot frame.</span>")
if(istype(W, /obj/item/robot_parts/l_leg))
if(src.l_leg) return
user.drop_item()
W.loc = src
src.l_leg = W
src.updateicon()
if(istype(W, /obj/item/robot_parts/r_leg))
if(src.r_leg) return
user.drop_item()
W.loc = src
src.r_leg = W
src.updateicon()
if(istype(W, /obj/item/robot_parts/l_arm))
if(src.l_arm) return
user.drop_item()
W.loc = src
src.l_arm = W
src.updateicon()
if(istype(W, /obj/item/robot_parts/r_arm))
if(src.r_arm) return
user.drop_item()
W.loc = src
src.r_arm = W
src.updateicon()
if(istype(W, /obj/item/robot_parts/chest))
if(src.chest) return
if(W:wires && W:cell)
user.drop_item()
W.loc = src
src.chest = W
src.updateicon()
else if(!W:wires)
to_chat(user, "<span class='warning'>You need to attach wires to it first!</span>")
else
to_chat(user, "<span class='warning'>You need to attach a cell to it first!</span>")
if(istype(W, /obj/item/robot_parts/head))
if(src.head) return
if(W:flash2 && W:flash1)
user.drop_item()
W.loc = src
src.head = W
src.updateicon()
else
to_chat(user, "<span class='warning'>You need to attach a flash to it first!</span>")
if(istype(W, /obj/item/mmi))
var/obj/item/mmi/M = W
if(check_completion())
if(!istype(loc,/turf))
to_chat(user, "<span class='warning'>You can't put \the [W] in, the frame has to be standing on the ground to be perfectly precise.</span>")
return
if(!istype(W, /obj/item/mmi/inert))
if(!M.brainmob)
to_chat(user, "<span class='warning'>Sticking an empty [W] into the frame would sort of defeat the purpose.</span>")
return
if(!M.brainmob.key)
var/ghost_can_reenter = 0
if(M.brainmob.mind)
for(var/mob/observer/dead/G in player_list)
if(G.can_reenter_corpse && G.mind == M.brainmob.mind)
ghost_can_reenter = 1 //May come in use again at another point.
to_chat(user, "<span class='notice'>\The [W] is completely unresponsive; though it may be able to auto-resuscitate.</span>") //Jamming a ghosted brain into a borg is likely detrimental, and may result in some problems.
return
if(!ghost_can_reenter)
to_chat(user, "<span class='notice'>\The [W] is completely unresponsive; there's no point.</span>")
return
if(M.brainmob.stat == DEAD)
to_chat(user, "<span class='warning'>Sticking a dead [W] into the frame would sort of defeat the purpose.</span>")
return
if(jobban_isbanned(M.brainmob, "Cyborg"))
to_chat(user, "<span class='warning'>This [W] does not seem to fit.</span>")
return
var/mob/living/silicon/robot/O = new /mob/living/silicon/robot(get_turf(loc), TRUE)
if(!O) return
user.drop_item()
O.mmi = W
O.post_mmi_setup()
O.invisibility = 0
O.custom_name = created_name
O.updatename("Default")
if(M.brainmob)
M.brainmob.mind.transfer_to(O)
if(O.mind && O.mind.special_role)
O.mind.store_memory("In case you look at this after being borged, the objectives are only here until I find a way to make them not show up for you, as I can't simply delete them without screwing up round-end reporting. --NeoFite")
for(var/datum/language/L in M.brainmob.languages)
O.add_language(L.name)
O.job = "Cyborg"
O.cell = chest.cell
O.cell.loc = O
W.loc = O//Should fix cybros run time erroring when blown up. It got deleted before, along with the frame.
// Since we "magically" installed a cell, we also have to update the correct component.
if(O.cell)
var/datum/robot_component/cell_component = O.components["power cell"]
cell_component.wrapped = O.cell
cell_component.installed = 1
feedback_inc("cyborg_birth",1)
callHook("borgify", list(O))
O.Namepick()
qdel(src)
else
to_chat(user, "<span class='warning'>The MMI must go in after everything else!</span>")
if (istype(W, /obj/item/pen))
var/t = sanitizeSafe(input(user, "Enter new robot name", src.name, src.created_name), MAX_NAME_LEN)
if (!t)
return
if (!in_range(src, usr) && src.loc != usr)
return
src.created_name = t
return
/obj/item/robot_parts/chest/attackby(obj/item/W as obj, mob/user as mob)
..()
if(istype(W, /obj/item/cell))
if(src.cell)
to_chat(user, "<span class='warning'>You have already inserted a cell!</span>")
return
else
user.drop_item()
W.loc = src
to_chat(user, SPAN_WARNING("You have already inserted a cell!"))
return TRUE
if(user.unEquip(W, src))
src.cell = W
to_chat(user, "<span class='notice'>You insert the cell!</span>")
W.forceMove(src)
to_chat(user, SPAN_NOTICE("You insert the cell!"))
return TRUE
if(istype(W, /obj/item/stack/cable_coil))
if(src.wires)
to_chat(user, "<span class='warning'>You have already inserted wire!</span>")
return
else
var/obj/item/stack/cable_coil/coil = W
coil.use(1)
to_chat(user, SPAN_WARNING("You have already inserted wire!"))
return TRUE
var/obj/item/stack/cable_coil/coil = W
if(coil.use(1))
src.wires = 1.0
to_chat(user, "<span class='notice'>You insert the wire!</span>")
return
to_chat(user, SPAN_NOTICE("You insert the wire!"))
return TRUE
/obj/item/robot_parts/head/attackby(obj/item/W as obj, mob/user as mob)
if(istype(W, /obj/item/robot_parts/head))
var/obj/item/robot_parts/head/head_part = W
// Attempt to create full-body prosthesis.
var/success = TRUE
success &= can_install(user)
success &= head_part.can_install(user)
if (success)
// Species selection.
var/species = input(user, "Select a species for the prosthetic.") as null|anything in GetCyborgSpecies()
if(!species)
return TRUE
var/name = sanitizeSafe(input(user,"Set a name for the new prosthetic."), MAX_NAME_LEN)
if(!name)
name = "prosthetic ([random_id("prosthetic_id", 1, 999)])"
// Create a new, nonliving human.
var/mob/living/carbon/human/H = new /mob/living/carbon/human(get_turf(loc))
H.death(0, DEATHGASP_NO_MESSAGE)
H.set_species(species)
H.fully_replace_character_name(name)
// Remove all external organs other than chest and head..
for (var/O in list(BP_L_ARM, BP_R_ARM, BP_L_LEG, BP_R_LEG))
var/obj/item/organ/external/organ = H.organs_by_name[O]
H.organs -= organ
H.organs_by_name[organ.organ_tag] = null
qdel(organ)
// Remove brain (we want to put one in).
var/obj/item/organ/internal/brain = H.internal_organs_by_name[O_BRAIN]
H.organs -= brain
H.organs_by_name[brain.organ_tag] = null
qdel(brain)
// Robotize remaining organs: Eyes, head, and chest.
// Respect brand used.
var/obj/item/organ/internal/eyes = H.internal_organs_by_name[O_EYES]
eyes.robotize()
var/obj/item/organ/external/head = H.organs_by_name[BP_HEAD]
var/head_company = head_part.model_info
head.robotize(head_company)
var/obj/item/organ/external/chest = H.organs_by_name[BP_TORSO]
var/chest_company = model_info
chest.robotize(chest_company)
// Cleanup
qdel(W)
qdel(src)
return TRUE
return ..()
/obj/item/robot_parts/chest/proc/GetCyborgSpecies()
. = list()
for(var/N in GLOB.playable_species)
var/datum/species/S = GLOB.all_species[N]
if(S.spawn_flags & SPECIES_NO_FBP_CONSTRUCTION)
continue
. += N
/obj/item/robot_parts/head/attackby(obj/item/W, mob/user)
..()
if(istype(W, /obj/item/flash))
if(istype(user,/mob/living/silicon/robot))
var/current_module = user.get_active_hand()
if(current_module == W)
to_chat(user, "<span class='warning'>How do you propose to do that?</span>")
to_chat(user, SPAN_WARNING("How do you propose to do that?"))
return
else
add_flashes(W,user)
else
add_flashes(W,user)
return
/obj/item/robot_parts/head/proc/add_flashes(obj/item/W as obj, mob/user as mob) //Made into a separate proc to avoid copypasta
/obj/item/robot_parts/head/proc/add_flashes(obj/item/W, mob/user) //Made into a seperate proc to avoid copypasta
if(src.flash1 && src.flash2)
to_chat(user, "<span class='notice'>You have already inserted the eyes!</span>")
to_chat(user, SPAN_NOTICE("You have already inserted the eyes!"))
return
else if(src.flash1)
user.drop_item()
W.loc = src
if(!user.unEquip(W, src))
return
src.flash2 = W
to_chat(user, "<span class='notice'>You insert the flash into the eye socket!</span>")
W.forceMove(src)
to_chat(user, SPAN_NOTICE("You insert the flash into the eye socket!"))
else
user.drop_item()
W.loc = src
if(!user.unEquip(W, src))
return
src.flash1 = W
to_chat(user, "<span class='notice'>You insert the flash into the eye socket!</span>")
W.forceMove(src)
to_chat(user, SPAN_NOTICE("You insert the flash into the eye socket!"))
/obj/item/robot_parts/emag_act(var/remaining_charges, var/mob/user)
/obj/item/robot_parts/emag_act(remaining_charges, mob/user)
if(sabotaged)
to_chat(user, "<span class='warning'>[src] is already sabotaged!</span>")
to_chat(user, SPAN_WARNING("[src] is already sabotaged!"))
else
to_chat(user, "<span class='warning'>You short out the safeties.</span>")
to_chat(user, SPAN_WARNING("You short out the safeties."))
sabotaged = 1
return 1
@@ -133,22 +133,17 @@
require_module = 1
/obj/item/borg/upgrade/jetpack/action(var/mob/living/silicon/robot/R)
if(..()) return 0
if(..())
return FALSE
var/obj/item/tank/jetpack/carbondioxide/T = locate() in R.module
if(!T)
T = locate() in R.module.contents
if(!T)
T = locate() in R.module.modules
if(!T)
R.module.modules += new/obj/item/tank/jetpack/carbondioxide(R.module)
for(var/obj/item/tank/jetpack/carbondioxide in R.module.modules)
R.internals = src
return 1
if(T)
to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!")
if(R.module.jetpack)
to_chat(R, "Upgrade mounting error! No suitable hardpoint detected!")
to_chat(usr, "There's no mounting point for the module!")
return 0
return FALSE
R.module.jetpack = new /obj/item/tank/jetpack/carbondioxide(R.module)
R.internals = R.module.jetpack
return TRUE
/obj/item/borg/upgrade/advhealth
name = "advanced health analyzer module"
@@ -163,7 +163,7 @@
update_state()
/obj/structure/door_assembly/attack_robot(mob/living/silicon/robot/user)
if(Adjacent(user) && (user.module && (istype(user.module,/obj/item/robot_module/robot/engineering/general)) \
if(Adjacent(user) && (user.module && (istype(user.module,/obj/item/robot_module/robot/engineering)) \
|| istype(user.module,/obj/item/robot_module/drone))) //Only dron (and engiborg) needs this.
rename_door(user)
@@ -17,7 +17,7 @@
/obj/structure/ghost_pod/manual/lost_drone/create_occupant(var/mob/M)
density = FALSE
var/mob/living/silicon/robot/lost/randomlaws/R = new(get_turf(src))
var/mob/living/silicon/robot/flying/lost/randomlaws/R = new(get_turf(src))
R.adjustBruteLoss(rand(5, 30))
R.adjustFireLoss(rand(5, 10))
if(M.mind)
@@ -75,7 +75,7 @@
update_state()
/obj/structure/windoor_assembly/attack_robot(mob/living/silicon/robot/user)
if(Adjacent(user) && (user.module && (istype(user.module,/obj/item/robot_module/robot/engineering/general)) \
if(Adjacent(user) && (user.module && (istype(user.module,/obj/item/robot_module/robot/engineering)) \
|| istype(user.module,/obj/item/robot_module/drone))) //Only dron (and engiborg) needs this.
rename_door(user)
-8
View File
@@ -124,14 +124,6 @@ var/global/DBConnection/dbcon_old = new() // /tg/station database (Old database)
// Added for Xenoarchaeology, might be useful for other stuff.
var/global/list/alphabet_uppercase = list("A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z")
// Used by robots and robot preferences.
var/global/list/robot_module_types = list(
"Standard", "Engineering", "Surgeon", "Crisis",
"Miner", "Janitor", "Service", "Clerical", "Security",
"Research"
)
// Some scary sounds.
var/global/static/list/scarySounds = list(
'sound/weapons/thudswoosh.ogg',
@@ -15,7 +15,7 @@
//Flavour text for robots.
S["flavour_texts_robot_Default"] >> pref.flavour_texts_robot["Default"]
for(var/module in robot_module_types)
for(var/module in SSrobots.all_module_names)
S["flavour_texts_robot_[module]"] >> pref.flavour_texts_robot[module]
/datum/category_item/player_setup_item/general/flavor/save_character(var/savefile/S)
@@ -30,7 +30,7 @@
S["flavor_texts_feet"] << pref.flavor_texts["feet"]
S["flavour_texts_robot_Default"] << pref.flavour_texts_robot["Default"]
for(var/module in robot_module_types)
for(var/module in SSrobots.all_module_names)
S["flavour_texts_robot_[module]"] << pref.flavour_texts_robot[module]
/datum/category_item/player_setup_item/general/flavor/sanitize_character()
@@ -129,7 +129,7 @@
HTML += "<a href='?src=\ref[src];flavour_text_robot=Default'>Default:</a> "
HTML += TextPreview(pref.flavour_texts_robot["Default"])
HTML += "<hr />"
for(var/module in robot_module_types)
for(var/module in SSrobots.all_module_names)
HTML += "<a href='?src=\ref[src];flavour_text_robot=[module]'>[module]:</a> "
HTML += TextPreview(pref.flavour_texts_robot[module])
HTML += "<br>"
+1 -1
View File
@@ -912,7 +912,7 @@
return
if((istype(wearer.loc, /turf/space)) || (wearer.lastarea.has_gravity == 0))
if(!wearer.Process_Spacemove(0))
if(!wearer.Process_Spacemove(FALSE))
return 0
if(malfunctioning)
+2 -2
View File
@@ -211,7 +211,7 @@
. += "<span class='deadsay'>It appears to be completely inactive.</span>"
else
. += "<span class='deadsay'>It appears to be completely inactive.</span>"
/obj/item/mmi/digital/emp_act(severity)
if(!src.brainmob)
return
@@ -351,4 +351,4 @@
icon = 'icons/obj/module.dmi'
icon_state = "mainboard"
w_class = ITEMSIZE_NORMAL
origin_tech = list(TECH_ENGINEERING = 2, TECH_MATERIAL = 2, TECH_BLUESPACE = 2, TECH_DATA = 3)
origin_tech = list(TECH_ENGINEERING = 2, TECH_MATERIAL = 2, TECH_BLUESPACE = 2, TECH_DATA = 3)
@@ -173,34 +173,12 @@
for(var/obj/item/rig_module/maneuvering_jets/module in rig.installed_modules)
return module.jets
/mob/living/carbon/human/Process_Spacemove(var/check_drift = 0)
//Can we act?
if(restrained()) return 0
if(..()) //Can move due to other reasons, don't use jetpack fuel
return 1
//Do we have a working jetpack?
var/obj/item/tank/jetpack/thrust = get_jetpack()
if(thrust)
if(((!check_drift) || (check_drift && thrust.stabilization_on)) && (!lying) && (thrust.do_thrust(0.01, src)))
inertia_dir = 0
return 1
return 0
/mob/living/carbon/human/Process_Spaceslipping(var/prob_slip = 5)
//If knocked out we might just hit it and stop. This makes it possible to get dead bodies and such.
if(species.flags & NO_SLIP)
return 0
var/obj/item/tank/jetpack/thrust = get_jetpack()
if(thrust?.can_thrust(0.01))
return 0
if(stat)
prob_slip = 0 // Changing this to zero to make it line up with the comment, and also, make more sense.
@@ -209,13 +187,16 @@
prob_slip = 0
//Check hands and mod slip
if(!l_hand) prob_slip -= 2
else if(l_hand.w_class <= 2) prob_slip -= 1
if (!r_hand) prob_slip -= 2
else if(r_hand.w_class <= 2) prob_slip -= 1
if(!l_hand)
prob_slip -= 2
else if(l_hand.w_class <= 2)
prob_slip -= 1
if (!r_hand)
prob_slip -= 2
else if(r_hand.w_class <= 2)
prob_slip -= 1
prob_slip = round(prob_slip)
return(prob_slip)
return round(prob_slip)
// Handle footstep sounds
/mob/living/carbon/human/handle_footstep(var/turf/T)
+1 -1
View File
@@ -249,7 +249,7 @@ default behaviour is:
/mob/living/proc/inertial_drift()
if(x > 1 && x < (world.maxx) && y > 1 && y < (world.maxy))
if(Process_Spacemove(1))
if(Process_Spacemove(TRUE))
inertia_dir = 0
return
@@ -82,6 +82,11 @@
external_type = /obj/item/robot_parts/robot_component/armour_platform
max_damage = 140
/datum/robot_component/armour/light
name = "lightweight armour plating"
external_type = /obj/item/robot_parts/robot_component/armour_light
max_damage = 75
// ACTUATOR
// Enables movement.
// Uses no power when idle. Uses 200J for each tile the cyborg moves.
@@ -181,13 +186,13 @@
// Initializes cyborg's components. Technically, adds default set of components to new borgs
/mob/living/silicon/robot/proc/initialize_components()
components["actuator"] = new/datum/robot_component/actuator(src)
components["radio"] = new/datum/robot_component/radio(src)
components["power cell"] = new/datum/robot_component/cell(src)
components["diagnosis unit"] = new/datum/robot_component/diagnosis_unit(src)
components["camera"] = new/datum/robot_component/camera(src)
components["comms"] = new/datum/robot_component/binary_communication(src)
components["armour"] = new/datum/robot_component/armour(src)
components["actuator"] = new /datum/robot_component/actuator(src)
components["radio"] = new /datum/robot_component/radio(src)
components["power cell"] = new /datum/robot_component/cell(src)
components["diagnosis unit"] = new /datum/robot_component/diagnosis_unit(src)
components["camera"] = new /datum/robot_component/camera(src)
components["comms"] = new /datum/robot_component/binary_communication(src)
components["armour"] = new /datum/robot_component/armour(src)
// Checks if component is functioning
/mob/living/silicon/robot/proc/is_component_functioning(module_name)
@@ -258,6 +263,12 @@
icon_state_broken = "armor_broken"
color = COLOR_GRAY80
/obj/item/robot_parts/robot_component/armour_light
name = "lightweight armour plating"
desc = "A pair of flexible, light armor plates, used to protect the internals of robots equipped with anti-gravity frames."
icon_state = "armor_l"
icon_state_broken = "armor_l_broken"
/obj/item/robot_parts/robot_component/camera
name = "camera"
desc = "A modified camera module used as a visual receptor for robots and exosuits, also serving as a relay for wireless video feed."
@@ -274,4 +285,4 @@
name = "radio"
desc = "A modular, multi-frequency radio used by robots and exosuits to enable communication systems. Comes with built-in subspace receivers."
icon_state = "radio"
icon_state_broken = "radio_broken"
icon_state_broken = "radio_broken"
@@ -21,7 +21,6 @@ var/global/list/mob_hat_cache = list()
/mob/living/silicon/robot/drone
name = "maintenance drone"
real_name = "drone"
icon = 'icons/mob/robots.dmi'
icon_state = "repairbot"
maxHealth = 35
health = 35
@@ -153,7 +152,7 @@ var/global/list/mob_hat_cache = list()
/mob/living/silicon/robot/drone/choose_icon()
return
/mob/living/silicon/robot/drone/pick_module()
/mob/living/silicon/robot/drone/pick_module(override)
return
/mob/living/silicon/robot/drone/proc/wear_hat(var/obj/item/new_hat)
@@ -272,10 +271,6 @@ var/global/list/mob_hat_cache = list()
return
..()
//DRONE MOVEMENT.
/mob/living/silicon/robot/drone/Process_Spaceslipping(var/prob_slip)
return 0
//CONSOLE PROCS
/mob/living/silicon/robot/drone/proc/law_resync()
if(stat != DEAD)
@@ -129,6 +129,17 @@
)
/obj/item/gripper/cultivator
name = "cultivator gripper"
icon_state = "gripper"
desc = "A simple grasping tool used to perform tasks in the xenobiology division, such as handling plant samples and disks."
can_hold = list(
/obj/item/reagent_containers/glass,
/obj/item/seeds,
/obj/item/slime_extract,
/obj/item/disk/botany
)
/obj/item/gripper/circuit
name = "circuit assembly gripper"
icon_state = "gripper-circ"
+35 -32
View File
@@ -3,7 +3,7 @@
/mob/living/silicon/robot
name = "Cyborg"
real_name = "Cyborg"
icon = 'icons/mob/robots.dmi'
icon = 'icons/mob/robots/robots_grounded.dmi'
icon_state = "robot"
maxHealth = 200
health = 200
@@ -14,6 +14,7 @@
var/lights_on = 0 // Is our integrated light on?
var/used_power_this_tick = 0
var/power_efficiency = 1
var/sight_mode = 0
var/custom_name = ""
var/custom_sprite = 0 //Due to all the sprites involved, a var for our custom borgs may be best
@@ -22,6 +23,8 @@
var/crisis_override = 0
var/integrated_light_power = 6
var/datum/wires/robot/wires
var/module_category = ROBOT_MODULE_TYPE_GROUNDED
var/dismantle_type = /obj/item/robot_parts/frame
can_be_antagged = TRUE
@@ -75,7 +78,6 @@
var/viewalerts = 0
var/modtype = "Default"
var/lower_mod = 0
var/jetpack = 0
var/datum/effect_system/ion_trail_follow/ion_trail = null
var/datum/effect_system/spark_spread/spark_system//So they can initialize sparks whenever/N
var/jeton = 0
@@ -258,28 +260,42 @@
updateicon()
return module_sprites
/mob/living/silicon/robot/proc/pick_module()
if(module)
return
var/list/modules = list()
modules.Add(robot_module_types)
if((crisis && security_level == SEC_LEVEL_RED) || crisis_override) //Leaving this in until it's balanced appropriately.
to_chat(src, "<font color='red'>Crisis mode active. Combat module available.</font>")
modules+="Combat"
modtype = input("Please, select a module!", "Robot module", null, null) as null|anything in modules
/mob/living/silicon/robot/proc/pick_module(override)
if(module)
if(module && !override)
return
if(!(modtype in robot_modules))
var/is_crisis_mode = crisis_override || (security_level == SEC_LEVEL_RED)
var/list/robot_modules = SSrobots.get_available_modules(module_category, is_crisis_mode, override)
if(!length(robot_modules))
to_chat(src, SPAN_WARNING("For some reason, no modules are available to you. Please report this on the issue tracker!"))
return
if(!override)
if(is_crisis_mode)
to_chat(src, SPAN_WARNING("Crisis mode active. Additional modules available."))
modtype = input("Please select a module!", "Robot module", null, null) as null|anything in robot_modules
else
if(module)
QDEL_NULL(module)
modtype = override
if(module || !modtype)
return
var/module_type = robot_modules[modtype]
if(!module_type)
to_chat(src, SPAN_WARNING("You are unable to select a module."))
return
new module_type(src)
hands.icon_state = lowertext(modtype)
if(hands)
hands.icon_state = lowertext(modtype)
feedback_inc("cyborg_[lowertext(modtype)]",1)
updatename()
notify_ai(ROBOT_NOTIFICATION_NEW_MODULE, module.name)
if(module)
notify_ai(ROBOT_NOTIFICATION_NEW_MODULE, module.name)
/mob/living/silicon/robot/proc/update_braintype()
if(istype(mmi, /obj/item/mmi/digital/posibrain))
@@ -416,19 +432,11 @@
// this function displays jetpack pressure in the stat panel
/mob/living/silicon/robot/proc/show_jetpack_pressure()
// if you have a jetpack, show the internal tank pressure
var/obj/item/tank/jetpack/current_jetpack = installed_jetpack()
var/obj/item/tank/jetpack/current_jetpack = get_jetpack()
if (current_jetpack)
stat("Internal Atmosphere Info", current_jetpack.name)
stat("Tank Pressure", current_jetpack.air_contents.return_pressure())
// this function returns the robots jetpack, if one is installed
/mob/living/silicon/robot/proc/installed_jetpack()
if(module)
return (locate(/obj/item/tank/jetpack) in module.modules)
return 0
// this function displays the cyborgs current cell charge in the stat panel
/mob/living/silicon/robot/proc/show_cell_power()
if(cell)
@@ -555,13 +563,8 @@
to_chat(user, "<span class='filter_notice'>You jam the crowbar into the robot and begin levering [mmi].</span>")
sleep(30)
to_chat(user, "<span class='filter_notice'>You damage some parts of the chassis, but eventually manage to rip out [mmi]!</span>")
var/obj/item/robot_parts/robot_suit/C = new/obj/item/robot_parts/robot_suit(loc)
C.l_leg = new/obj/item/robot_parts/l_leg(C)
C.r_leg = new/obj/item/robot_parts/r_leg(C)
C.l_arm = new/obj/item/robot_parts/l_arm(C)
C.r_arm = new/obj/item/robot_parts/r_arm(C)
C.updateicon()
new/obj/item/robot_parts/chest(loc)
var/obj/item/robot_parts/frame/C = new dismantle_type(loc)
C.dismantled_from(src)
qdel(src)
else
// Okay we're not removing the cell or an MMI, but maybe something else?
@@ -1016,7 +1019,7 @@
if(icontype == "Custom")
icon = CUSTOM_ITEM_SYNTH
else // This is to fix an issue where someone with a custom borg sprite chooses a non-custom sprite and turns invisible.
icon = 'icons/mob/robots.dmi'
icon = initial(icon)
icon_state = module_sprites[icontype]
updateicon()
@@ -0,0 +1,256 @@
/obj/item/robot_module
name = "robot module"
icon = 'icons/obj/module.dmi'
icon_state = "std_module"
w_class = ITEMSIZE_NO_CONTAINER
item_state = "std_mod"
var/unavailable_by_default
var/display_name
var/hide_on_manifest = FALSE
var/channels = list()
var/networks = list()
var/languages = list(
LANGUAGE_SOL_COMMON = 1,
LANGUAGE_SIVIAN= 0,
LANGUAGE_TRADEBAND = 1,
LANGUAGE_UNATHI = 0,
LANGUAGE_SIIK = 0,
LANGUAGE_AKHANI = 0,
LANGUAGE_SKRELLIAN = 0,
LANGUAGE_GUTTER = 0,
LANGUAGE_SCHECHI = 0,
LANGUAGE_SIGN = 0,
LANGUAGE_TERMINUS = 1,
LANGUAGE_ZADDAT = 0
)
var/sprites = list()
var/can_be_pushed = 1
var/no_slip = 0
var/list/modules = list()
var/list/datum/matter_synth/synths = list()
var/obj/item/emag = null
var/obj/item/borg/upgrade/advhealth = null
var/list/subsystems = list()
var/list/obj/item/borg/upgrade/supported_upgrades = list()
var/obj/item/tank/jetpack/jetpack
var/list/universal_equipment = list(
/obj/item/flash/robot,
/obj/item/tool/crowbar/cyborg,
/obj/item/extinguisher,
/obj/item/gps/robot
)
// Module categorization values.
var/module_category = ROBOT_MODULE_TYPE_GROUNDED
var/upgrade_locked = FALSE
var/crisis_locked = FALSE
// Bookkeeping
var/list/original_languages = list()
var/list/added_networks = list()
/obj/item/robot_module/proc/hide_on_manifest()
. = hide_on_manifest
/obj/item/robot_module/Initialize(var/ml)
. = ..()
var/mob/living/silicon/robot/R = loc
if(!istype(R))
return INITIALIZE_HINT_QDEL
R.module = src
build_equipment(R)
build_emag(R)
build_synths(R)
finalize_equipment(R)
finalize_emag(R)
finalize_synths(R)
add_camera_networks(R)
add_languages(R)
add_subsystems(R)
apply_status_flags(R)
handle_shell(R)
if(R.radio)
addtimer(CALLBACK(R.radio, /obj/item/radio/proc/recalculateChannels), 0)
R.set_module_sprites(sprites)
addtimer(CALLBACK(R, /mob/living/silicon/robot/proc/choose_icon, R.module_sprites.len + 1, R.module_sprites), 0)
/obj/item/robot_module/proc/build_equipment()
SHOULD_CALL_PARENT(TRUE)
for(var/thing in (modules|universal_equipment))
modules -= thing
if(ispath(thing, /obj/item))
modules += new thing(src)
else if(isitem(thing))
var/obj/item/I = thing
I.forceMove(src)
modules += I
else
log_debug("Invalid var type in [type] equipment creation - [thing]")
if(ispath(jetpack))
jetpack = new jetpack(src)
/obj/item/robot_module/proc/finalize_equipment()
SHOULD_CALL_PARENT(TRUE)
for(var/obj/item/I in modules)
I.canremove = FALSE
if(jetpack)
if(istype(jetpack))
jetpack.canremove = FALSE
var/mob/living/silicon/robot/robit = loc
if(istype(robit))
jetpack.forceMove(robit)
robit.internals = jetpack
else
log_debug("Invalid var type in [type] jetpack creation - [jetpack]")
jetpack = null
/obj/item/robot_module/proc/build_emag()
SHOULD_CALL_PARENT(TRUE)
if(ispath(emag))
emag = new emag(src)
/obj/item/robot_module/proc/finalize_emag()
SHOULD_CALL_PARENT(TRUE)
if(emag)
if(istype(emag))
emag.canremove = FALSE
else
log_debug("Invalid var type in [type] emag creation - [emag]")
emag = null
/obj/item/robot_module/proc/build_synths()
SHOULD_CALL_PARENT(TRUE)
for(var/thing in synths)
if(istype(thing, /datum/matter_synth))
continue
if(!ispath(thing, /datum/matter_synth))
log_debug("Invalid var type in [type] synth creation - [thing]")
continue
if(isnull(synths[thing]))
synths += new thing
else
synths += new thing(synths[thing])
synths -= thing
/obj/item/robot_module/proc/finalize_synths()
SHOULD_CALL_PARENT(TRUE)
return
/obj/item/robot_module/proc/Reset(var/mob/living/silicon/robot/R)
remove_camera_networks(R)
remove_languages(R)
remove_subsystems(R)
remove_status_flags(R)
if(R.radio)
R.radio.recalculateChannels()
R.choose_icon(0, R.set_module_sprites(list("Default" = "robot")))
// This can qdel before init if spawned outside a mob, so
// Destroy() needs to be a bit nuanced to avoid runtimes.
/obj/item/robot_module/Destroy()
for(var/datum/thing in modules)
qdel(thing)
// Robot icons unit test needs the module types list.
#ifndef UNIT_TEST
modules = null
#endif
for(var/datum/thing in synths)
qdel(thing)
synths = null
if(istype(emag))
QDEL_NULL(emag)
if(istype(jetpack))
QDEL_NULL(jetpack)
return ..()
/obj/item/robot_module/emp_act(severity)
if(modules)
for(var/obj/O in modules)
O.emp_act(severity)
if(emag)
emag.emp_act(severity)
if(synths)
for(var/datum/matter_synth/S in synths)
S.emp_act(severity)
..()
return
/obj/item/robot_module/proc/respawn_consumable(var/mob/living/silicon/robot/R, var/rate)
if(!synths || !synths.len)
return
for(var/datum/matter_synth/T in synths)
T.add_charge(T.recharge_rate * rate)
/obj/item/robot_module/proc/rebuild()//Rebuilds the list so it's possible to add/remove items from the module
var/list/temp_list = modules
modules = list()
for(var/obj/O in temp_list)
if(O)
modules += O
/obj/item/robot_module/proc/add_languages(var/mob/living/silicon/robot/R)
// Stores the languages as they were before receiving the module, and whether they could be synthezized.
for(var/datum/language/language_datum in R.languages)
original_languages[language_datum] = (language_datum in R.speech_synthesizer_langs)
for(var/language in languages)
R.add_language(language, languages[language])
/obj/item/robot_module/proc/remove_languages(var/mob/living/silicon/robot/R)
// Clear all added languages, whether or not we originally had them.
for(var/language in languages)
R.remove_language(language)
// Then add back all the original languages, and the relevant synthezising ability
for(var/original_language in original_languages)
R.add_language(original_language, original_languages[original_language])
original_languages.Cut()
/obj/item/robot_module/proc/add_camera_networks(var/mob/living/silicon/robot/R)
if(R.camera && (NETWORK_ROBOTS in R.camera.network))
for(var/network in networks)
if(!(network in R.camera.network))
R.camera.add_network(network)
added_networks |= network
/obj/item/robot_module/proc/remove_camera_networks(var/mob/living/silicon/robot/R)
if(R.camera)
R.camera.remove_networks(added_networks)
added_networks.Cut()
/obj/item/robot_module/proc/add_subsystems(var/mob/living/silicon/robot/R)
R.verbs |= subsystems
/obj/item/robot_module/proc/remove_subsystems(var/mob/living/silicon/robot/R)
R.verbs -= subsystems
/obj/item/robot_module/proc/apply_status_flags(var/mob/living/silicon/robot/R)
if(!can_be_pushed)
R.status_flags &= ~CANPUSH
/obj/item/robot_module/proc/remove_status_flags(var/mob/living/silicon/robot/R)
if(!can_be_pushed)
R.status_flags |= CANPUSH
/obj/item/robot_module/proc/handle_shell(var/mob/living/silicon/robot/R)
if(R.braintype == BORG_BRAINTYPE_AI_SHELL)
channels = list(
"Medical" = 1,
"Engineering" = 1,
"Security" = 1,
"Service" = 1,
"Supply" = 1,
"Science" = 1,
"Command" = 1,
"Explorer" = 1
)
@@ -3,86 +3,68 @@
// The module that borgs on the surface have. Generally has a lot of useful tools in exchange for questionable loyalty to the crew.
/obj/item/robot_module/robot/lost
name = "lost robot module"
display_name = "Unregistered"
module_category = ROBOT_MODULE_TYPE_FLYING
unavailable_by_default = TRUE
hide_on_manifest = TRUE
sprites = list(
"Drone" = "drone-lost"
)
/obj/item/robot_module/robot/lost/Initialize(var/ml)
"Drone" = "drone-lost"
)
modules = list(
/obj/item/melee/baton/shocker/robot,
/obj/item/handcuffs/cyborg,
/obj/item/borg/combat/shield,
/obj/item/healthanalyzer,
/obj/item/reagent_containers/borghypo/lost,
/obj/item/weldingtool/electric/mounted,
/obj/item/tool/screwdriver/cyborg,
/obj/item/tool/wrench/cyborg,
/obj/item/tool/wirecutters/cyborg,
/obj/item/multitool,
/obj/item/robotanalyzer,
/obj/item/stack/cable_coil/cyborg
)
emag = /obj/item/gun/energy/retro/mounted
synths = list(
/datum/matter_synth/wire
)
/obj/item/robot_module/robot/lost/finalize_synths()
. = ..()
if(. != INITIALIZE_HINT_NORMAL)
return
// Sec
src.modules += new /obj/item/melee/baton/shocker/robot(src)
src.modules += new /obj/item/handcuffs/cyborg(src)
src.modules += new /obj/item/borg/combat/shield(src)
// Med
src.modules += new /obj/item/healthanalyzer(src)
src.modules += new /obj/item/reagent_containers/borghypo/lost(src)
// Engi
src.modules += new /obj/item/weldingtool/electric/mounted(src)
src.modules += new /obj/item/tool/screwdriver/cyborg(src)
src.modules += new /obj/item/tool/wrench/cyborg(src)
src.modules += new /obj/item/tool/wirecutters/cyborg(src)
src.modules += new /obj/item/multitool(src)
// Sci
src.modules += new /obj/item/robotanalyzer(src)
// Potato
src.emag = new /obj/item/gun/energy/retro/mounted(src)
var/datum/matter_synth/wire = new /datum/matter_synth/wire()
synths += wire
var/obj/item/stack/cable_coil/cyborg/C = new /obj/item/stack/cable_coil/cyborg(src)
var/datum/matter_synth/wire/wire = locate() in synths
var/obj/item/stack/cable_coil/cyborg/C = locate() in modules
C.synths = list(wire)
src.modules += C
/obj/item/robot_module/robot/gravekeeper
name = "gravekeeper robot module"
display_name = "Gravekeeper"
unavailable_by_default = TRUE
hide_on_manifest = TRUE
sprites = list(
"Drone" = "drone-gravekeeper",
"Sleek" = "sleek-gravekeeper"
)
/obj/item/robot_module/robot/gravekeeper/Initialize(var/ml)
"Gravekeeper" = "sleek-gravekeeper"
)
modules = list(
/obj/item/melee/baton/shocker/robot,
/obj/item/borg/combat/shield,
/obj/item/weldingtool/electric/mounted,
/obj/item/tool/screwdriver/cyborg,
/obj/item/tool/wrench/cyborg,
/obj/item/material/minihoe,
/obj/item/material/knife/machete/hatchet,
/obj/item/analyzer/plant_analyzer,
/obj/item/storage/bag/plants,
/obj/item/robot_harvester,
/obj/item/shovel,
/obj/item/gripper/gravekeeper
)
emag = /obj/item/gun/energy/retro/mounted
synths = list(
/datum/matter_synth/wood = 25000
)
/obj/item/robot_module/robot/gravekeeper/finalize_synths()
. = ..()
if(. != INITIALIZE_HINT_NORMAL)
return
// For fending off animals and looters
src.modules += new /obj/item/melee/baton/shocker/robot(src)
src.modules += new /obj/item/borg/combat/shield(src)
// For repairing gravemarkers
src.modules += new /obj/item/weldingtool/electric/mounted(src)
src.modules += new /obj/item/tool/screwdriver/cyborg(src)
src.modules += new /obj/item/tool/wrench/cyborg(src)
// For growing flowers
src.modules += new /obj/item/material/minihoe(src)
src.modules += new /obj/item/material/knife/machete/hatchet(src)
src.modules += new /obj/item/analyzer/plant_analyzer(src)
src.modules += new /obj/item/storage/bag/plants(src)
src.modules += new /obj/item/robot_harvester(src)
// For digging and beautifying graves
src.modules += new /obj/item/shovel(src)
src.modules += new /obj/item/gripper/gravekeeper(src)
// For really persistent looters
src.emag = new /obj/item/gun/energy/retro/mounted(src)
var/datum/matter_synth/wood = new /datum/matter_synth/wood(25000)
synths += wood
var/obj/item/stack/material/cyborg/wood/W = new (src)
var/datum/matter_synth/wood/wood = locate() in synths
var/obj/item/stack/material/cyborg/wood/W = locate() in modules
W.synths = list(wood)
src.modules += W
src.modules += W
File diff suppressed because it is too large Load Diff
@@ -1,32 +1,31 @@
/obj/item/robot_module/drone/swarm
name = "swarm drone module"
display_name = "Swarm Drone"
unavailable_by_default = TRUE
modules = list(
/obj/item/rcd/electric/mounted/borg/swarm,
/obj/item/flash/robot,
/obj/item/handcuffs/cable/tape/cyborg,
/obj/item/melee/baton/robot,
/obj/item/gun/energy/taser/mounted/cyborg/swarm,
/obj/item/matter_decompiler/swarm
)
var/id
/obj/item/robot_module/drone/swarm/Initialize(var/ml)
/obj/item/robot_module/drone/swarm/build_equipment()
. = ..()
if(. != INITIALIZE_HINT_NORMAL)
return
var/mob/living/silicon/robot/R = loc
id = R.idcard
src.modules += id
src.modules += new /obj/item/rcd/electric/mounted/borg/swarm(src)
src.modules += new /obj/item/flash/robot(src)
src.modules += new /obj/item/handcuffs/cable/tape/cyborg(src)
src.modules += new /obj/item/melee/baton/robot(src)
src.modules += new /obj/item/gun/energy/taser/mounted/cyborg/swarm(src)
src.modules += new /obj/item/matter_decompiler/swarm(src)
if(istype(R) && R.idcard)
id = R.idcard
modules += id
/obj/item/robot_module/drone/swarm/ranged
name = "swarm gunner module"
/obj/item/robot_module/drone/swarm/ranged/Initialize(var/ml)
/obj/item/robot_module/drone/swarm/ranged/build_equipment()
. = ..()
if(. == INITIALIZE_HINT_NORMAL)
modules += new /obj/item/gun/energy/xray/swarm(src)
modules += new /obj/item/gun/energy/xray/swarm(src)
/obj/item/robot_module/drone/swarm/melee/Initialize(var/ml)
/obj/item/robot_module/drone/swarm/melee/build_equipment()
. = ..()
if(. == INITIALIZE_HINT_NORMAL)
modules += new /obj/item/melee/energy/sword/ionic_rapier/lance(src)
modules += new /obj/item/melee/energy/sword/ionic_rapier/lance(src)
@@ -2,7 +2,9 @@
/obj/item/robot_module/robot/syndicate
name = "illegal robot module"
display_name = "Subverted"
hide_on_manifest = TRUE
unavailable_by_default = TRUE
languages = list(
LANGUAGE_SOL_COMMON = 1,
LANGUAGE_SIVIAN = 0,
@@ -21,42 +23,42 @@
LANGUAGE_ZADDAT = 0
)
sprites = list(
"Cerberus" = "syndie_bloodhound",
"Cerberus - Treaded" = "syndie_treadhound",
"Ares" = "squats",
"Telemachus" = "toiletbotantag",
"WTOperator" = "hosborg",
"XI-GUS" = "spidersyndi",
"XI-ALP" = "syndi-heavy"
)
"Cerberus" = "syndie_bloodhound",
"Cerberus - Treaded" = "syndie_treadhound",
"Ares" = "squats",
"Telemachus" = "toiletbotantag",
"XI-GUS" = "spidersyndi",
"XI-ALP" = "syndi-heavy"
)
universal_equipment = list(
/obj/item/flash/robot,
/obj/item/tool/crowbar/cyborg,
/obj/item/extinguisher,
/obj/item/gps/robot,
/obj/item/pinpointer/shuttle/merc,
/obj/item/melee/energy/sword,
)
jetpack = /obj/item/tank/jetpack/carbondioxide
synths = list(
/datum/matter_synth/cloth = 40000
)
var/id
// All syndie modules get these, and the base borg items (flash, crowbar, etc).
/obj/item/robot_module/robot/syndicate/Initialize()
/obj/item/robot_module/robot/syndicate/finalize_synths()
. = ..()
if(. != INITIALIZE_HINT_NORMAL)
return
src.modules += new /obj/item/pinpointer/shuttle/merc(src)
src.modules += new /obj/item/melee/energy/sword(src)
var/datum/matter_synth/cloth = new /datum/matter_synth/cloth(40000)
synths += cloth
var/obj/item/stack/sandbags/cyborg/SB = new /obj/item/stack/sandbags/cyborg(src)
var/datum/matter_synth/cloth/cloth = locate() in synths
var/obj/item/stack/sandbags/cyborg/SB = locate() in modules
SB.synths += list(cloth)
var/jetpack = new/obj/item/tank/jetpack/carbondioxide(src)
src.modules += jetpack
/obj/item/robot_module/robot/syndicate/finalize_equipment()
. = ..()
var/mob/living/silicon/robot/R = loc
R.internals = jetpack
id = R.idcard
src.modules += id
if(istype(R))
id = R.idcard
modules += id
/obj/item/robot_module/robot/syndicate/Destroy()
src.modules -= id
id = null
return ..()
@@ -69,17 +71,12 @@
"Ares" = "squats",
"XI-ALP" = "syndi-heavy"
)
/obj/item/robot_module/robot/syndicate/protector/Initialize()
. = ..()
if(. != INITIALIZE_HINT_NORMAL)
return
src.modules += new /obj/item/shield_projector/rectangle/weak(src)
src.modules += new /obj/item/gun/energy/dakkalaser(src)
src.modules += new /obj/item/handcuffs/cyborg(src)
src.modules += new /obj/item/melee/baton/robot(src)
modules = list(
/obj/item/shield_projector/rectangle/weak,
/obj/item/gun/energy/dakkalaser,
/obj/item/handcuffs/cyborg,
/obj/item/melee/baton/robot
)
// 95% engi-borg and 15% roboticist.
/obj/item/robot_module/robot/syndicate/mechanist
@@ -87,133 +84,114 @@
sprites = list(
"XI-GUS" = "spidersyndi",
"WTOperator" = "sleekhos"
)
/obj/item/robot_module/robot/syndicate/mechanist/Initialize()
)
modules = list(
/obj/item/borg/sight/meson,
/obj/item/weldingtool/electric/mounted/cyborg,
/obj/item/tool/screwdriver/cyborg,
/obj/item/tool/wrench/cyborg,
/obj/item/tool/wirecutters/cyborg,
/obj/item/multitool/ai_detector,
/obj/item/pickaxe/plasmacutter,
/obj/item/rcd/electric/mounted/borg/lesser,
/obj/item/melee/energy/sword/ionic_rapier,
/obj/item/robotanalyzer,
/obj/item/shockpaddles/robot/jumper,
/obj/item/gripper/no_use/organ/robotics,
/obj/item/card/robot/syndi,
/obj/item/card/emag,
/obj/item/stack/nanopaste,
/obj/item/stack/material/cyborg/steel,
/obj/item/stack/material/cyborg/glass,
/obj/item/stack/rods/cyborg,
/obj/item/stack/cable_coil/cyborg,
/obj/item/stack/material/cyborg/glass/reinforced
)
synths = list(
/datum/matter_synth/nanite = 10000,
/datum/matter_synth/metal = 40000,
/datum/matter_synth/glass = 40000,
/datum/matter_synth/wire
)
/obj/item/robot_module/robot/syndicate/mechanist/finalize_synths()
. = ..()
if(. != INITIALIZE_HINT_NORMAL)
return
// General engineering/hacking.
src.modules += new /obj/item/borg/sight/meson(src)
src.modules += new /obj/item/weldingtool/electric/mounted/cyborg(src)
src.modules += new /obj/item/tool/screwdriver/cyborg(src)
src.modules += new /obj/item/tool/wrench/cyborg(src)
src.modules += new /obj/item/tool/wirecutters/cyborg(src)
src.modules += new /obj/item/multitool/ai_detector(src)
src.modules += new /obj/item/pickaxe/plasmacutter(src)
src.modules += new /obj/item/rcd/electric/mounted/borg/lesser(src) // Can't eat rwalls to prevent AI core cheese.
src.modules += new /obj/item/melee/energy/sword/ionic_rapier(src)
// FBP repair.
src.modules += new /obj/item/robotanalyzer(src)
src.modules += new /obj/item/shockpaddles/robot/jumper(src)
src.modules += new /obj/item/gripper/no_use/organ/robotics(src)
// Hacking other things.
src.modules += new /obj/item/card/robot/syndi(src)
src.modules += new /obj/item/card/emag(src)
// Materials.
var/datum/matter_synth/nanite = new /datum/matter_synth/nanite(10000)
synths += nanite
var/datum/matter_synth/wire = new /datum/matter_synth/wire()
synths += wire
var/datum/matter_synth/metal = new /datum/matter_synth/metal(40000)
synths += metal
var/datum/matter_synth/glass = new /datum/matter_synth/glass(40000)
synths += glass
var/obj/item/stack/nanopaste/N = new /obj/item/stack/nanopaste(src)
var/datum/matter_synth/nanite/nanite = locate() in synths
var/obj/item/stack/nanopaste/N = locate() in modules
N.uses_charge = 1
N.charge_costs = list(1000)
N.synths = list(nanite)
src.modules += N
var/obj/item/stack/material/cyborg/steel/M = new (src)
var/datum/matter_synth/metal/metal = locate() in synths
var/obj/item/stack/material/cyborg/steel/M = locate() in modules
var/obj/item/stack/rods/cyborg/rods = locate() in modules
M.synths = list(metal)
src.modules += M
var/obj/item/stack/material/cyborg/glass/G = new (src)
G.synths = list(glass)
src.modules += G
var/obj/item/stack/rods/cyborg/rods = new /obj/item/stack/rods/cyborg(src)
rods.synths = list(metal)
src.modules += rods
var/obj/item/stack/cable_coil/cyborg/C = new /obj/item/stack/cable_coil/cyborg(src)
var/datum/matter_synth/glass/glass = locate() in synths
var/obj/item/stack/material/cyborg/glass/G = locate() in modules
G.synths = list(glass)
var/datum/matter_synth/wire/wire = locate() in synths
var/obj/item/stack/cable_coil/cyborg/C = locate() in modules
C.synths = list(wire)
src.modules += C
var/obj/item/stack/material/cyborg/glass/reinforced/RG = new (src)
var/obj/item/stack/material/cyborg/glass/reinforced/RG = locate() in modules
RG.synths = list(metal, glass)
src.modules += RG
// Mediborg optimized for on-the-field healing, but can also do surgery if needed.
/obj/item/robot_module/robot/syndicate/combat_medic
name = "combat medic robot module"
sprites = list(
"Telemachus" = "toiletbotantag"
)
/obj/item/robot_module/robot/syndicate/combat_medic/Initialize()
)
modules = list(
/obj/item/borg/sight/hud/med,
/obj/item/healthanalyzer/advanced,
/obj/item/reagent_containers/borghypo/merc,
/obj/item/autopsy_scanner,
/obj/item/surgical/scalpel/cyborg,
/obj/item/surgical/hemostat/cyborg,
/obj/item/surgical/retractor/cyborg,
/obj/item/surgical/cautery/cyborg,
/obj/item/surgical/bonegel/cyborg,
/obj/item/surgical/FixOVein/cyborg,
/obj/item/surgical/bonesetter/cyborg,
/obj/item/surgical/circular_saw/cyborg,
/obj/item/surgical/surgicaldrill/cyborg,
/obj/item/gripper/no_use/organ,
/obj/item/gripper/medical,
/obj/item/shockpaddles/robot/combat,
/obj/item/reagent_containers/dropper,
/obj/item/reagent_containers/syringe,
/obj/item/roller_holder,
/obj/item/stack/medical/advanced/ointment,
/obj/item/stack/medical/advanced/bruise_pack,
/obj/item/stack/medical/splint
)
synths = list(
/datum/matter_synth/medicine = 15000
)
/obj/item/robot_module/robot/syndicate/combat_medic/finalize_synths()
. = ..()
if(. != INITIALIZE_HINT_NORMAL)
return
src.modules += new /obj/item/borg/sight/hud/med(src)
src.modules += new /obj/item/healthanalyzer/advanced(src)
src.modules += new /obj/item/reagent_containers/borghypo/merc(src)
// Surgery things.
src.modules += new /obj/item/autopsy_scanner(src)
src.modules += new /obj/item/surgical/scalpel/cyborg(src)
src.modules += new /obj/item/surgical/hemostat/cyborg(src)
src.modules += new /obj/item/surgical/retractor/cyborg(src)
src.modules += new /obj/item/surgical/cautery/cyborg(src)
src.modules += new /obj/item/surgical/bonegel/cyborg(src)
src.modules += new /obj/item/surgical/FixOVein/cyborg(src)
src.modules += new /obj/item/surgical/bonesetter/cyborg(src)
src.modules += new /obj/item/surgical/circular_saw/cyborg(src)
src.modules += new /obj/item/surgical/surgicaldrill/cyborg(src)
src.modules += new /obj/item/gripper/no_use/organ(src)
// General healing.
src.modules += new /obj/item/gripper/medical(src)
src.modules += new /obj/item/shockpaddles/robot/combat(src)
src.modules += new /obj/item/reagent_containers/dropper(src) // Allows borg to fix necrosis apparently
src.modules += new /obj/item/reagent_containers/syringe(src)
src.modules += new /obj/item/roller_holder(src)
// Materials.
var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(15000)
synths += medicine
var/obj/item/stack/medical/advanced/ointment/O = new /obj/item/stack/medical/advanced/ointment(src)
var/obj/item/stack/medical/advanced/bruise_pack/B = new /obj/item/stack/medical/advanced/bruise_pack(src)
var/obj/item/stack/medical/splint/S = new /obj/item/stack/medical/splint(src)
var/datum/matter_synth/medicine/medicine = locate() in synths
var/obj/item/stack/medical/advanced/ointment/O = locate() in modules
O.uses_charge = 1
O.charge_costs = list(1000)
O.synths = list(medicine)
var/obj/item/stack/medical/advanced/bruise_pack/B = locate() in modules
B.uses_charge = 1
B.charge_costs = list(1000)
B.synths = list(medicine)
var/obj/item/stack/medical/splint/S = locate() in modules
S.uses_charge = 1
S.charge_costs = list(1000)
S.synths = list(medicine)
src.modules += O
src.modules += B
src.modules += S
/obj/item/robot_module/robot/syndicate/combat_medic/respawn_consumable(var/mob/living/silicon/robot/R, var/amount)
var/obj/item/reagent_containers/syringe/S = locate() in src.modules
var/obj/item/reagent_containers/syringe/S = locate() in modules
if(S.mode == 2)
S.reagents.clear_reagents()
S.mode = initial(S.mode)
@@ -1,29 +1,11 @@
/mob/living/silicon/robot/get_jetpack()
if(module)
for(var/obj/item/tank/jetpack/J in module.modules)
return J
return module?.jetpack
/mob/living/silicon/robot/Check_Shoegrip()
return module && module.no_slip
/mob/living/silicon/robot/Process_Spaceslipping(var/prob_slip)
var/obj/item/tank/jetpack/thrust = get_jetpack()
if(thrust?.can_thrust(0.01))
return 0
if(module && module.no_slip)
return 0
..(prob_slip)
/mob/living/silicon/robot/Process_Spacemove(var/check_drift = 0)
if(..())//Can move due to other reasons, don't use jetpack fuel
return 1
var/obj/item/tank/jetpack/thrust = get_jetpack()
if(thrust && (!check_drift || (check_drift && thrust.stabilization_on)) && thrust.do_thrust(0.01))
inertia_dir = 0
return 1
return 0
return ..(module?.no_slip ? 0 : prob_slip)
//No longer needed, but I'll leave it here incase we plan to re-use it.
/mob/living/silicon/robot/movement_delay()
@@ -43,7 +25,7 @@
return 0
var/datum/robot_component/actuator/A = get_component("actuator")
if (cell_use_power(A.active_usage))
if (cell_use_power(A.active_usage * power_efficiency))
return ..()
/mob/living/silicon/robot/Moved(atom/old_loc, direction, forced = FALSE)
@@ -0,0 +1,58 @@
/mob/living/silicon/robot/flying
desc = "A utility robot with an anti-gravity hover unit and a lightweight frame."
icon = 'icons/mob/robots/robots_flying.dmi'
icon_state = "drone-standard"
module_category = ROBOT_MODULE_TYPE_FLYING
dismantle_type = /obj/item/robot_parts/frame/flyer
power_efficiency = 0.75
// They are not very heavy or strong.
mob_size = MOB_SMALL
mob_bump_flag = SIMPLE_ANIMAL
mob_swap_flags = MONKEY|SLIME|SIMPLE_ANIMAL
mob_push_flags = MONKEY|SLIME|SIMPLE_ANIMAL
/mob/living/silicon/robot/flying/initialize_components()
components["actuator"] = new/datum/robot_component/actuator(src)
components["radio"] = new/datum/robot_component/radio(src)
components["power cell"] = new/datum/robot_component/cell(src)
components["diagnosis unit"] = new/datum/robot_component/diagnosis_unit(src)
components["camera"] = new /datum/robot_component/camera(src)
components["comms"] = new/datum/robot_component/binary_communication(src)
components["armour"] = new/datum/robot_component/armour/light(src)
/mob/living/silicon/robot/flying/Life()
. = ..()
if(incapacitated() || !is_component_functioning("actuator"))
stop_hovering()
else
start_hovering()
/mob/living/silicon/robot/flying/proc/start_hovering()
hovering = TRUE
pass_flags |= PASSTABLE
default_pixel_y = 0
make_floating(10)
/mob/living/silicon/robot/flying/proc/stop_hovering()
hovering = FALSE
pass_flags &= ~PASSTABLE
default_pixel_y = -8
stop_floating()
/mob/living/silicon/robot/flying/death()
. = ..()
if(!QDELETED(src) && stat == DEAD)
stop_hovering()
/mob/living/silicon/robot/flying/Allow_Spacemove(var/dense_object, check_drift = 0)
return hovering || ..()
/mob/living/silicon/robot/flying/Process_Spaceslipping(var/prob_slip = 5)
return ..(hovering ? 0 : prob_slip)
/mob/living/silicon/robot/flying/can_fall(anchor_bypass = FALSE, turf/location_override = loc)
return !hovering && ..()
/mob/living/silicon/robot/flying/can_overcome_gravity()
return hovering
@@ -11,17 +11,12 @@
/mob/living/silicon/robot/gravekeeper/init()
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
mmi = new /obj/item/mmi/digital/robot(src)
module = new /obj/item/robot_module/robot/gravekeeper(src)
cut_overlays()
init_id()
updatename("Gravekeeper")
if(!cell)
cell = new /obj/item/cell/high(src) // 15k cell, as recharging stations are a lot more rare on the Surface.
laws = new /datum/ai_laws/gravekeeper()
playsound(src, 'sound/mecha/nominalsyndi.ogg', 75, 0)
@@ -1,4 +1,4 @@
/mob/living/silicon/robot/lost
/mob/living/silicon/robot/flying/lost
lawupdate = 0
scrambledcodes = 1
icon_state = "drone-lost"
@@ -8,7 +8,7 @@
idcard_type = /obj/item/card/id
icon_selected = FALSE
/mob/living/silicon/robot/lost/init()
/mob/living/silicon/robot/flying/lost/init()
aiCamera = new/obj/item/camera/siliconcam/robot_camera(src)
mmi = new /obj/item/mmi/digital/robot(src)
@@ -23,12 +23,12 @@
playsound(src, 'sound/mecha/nominalsyndi.ogg', 75, 0)
/mob/living/silicon/robot/lost/speech_bubble_appearance()
/mob/living/silicon/robot/flying/lost/speech_bubble_appearance()
return "synthetic_evil"
/mob/living/silicon/robot/lost/randomlaws
/mob/living/silicon/robot/flying/lost/randomlaws
/mob/living/silicon/robot/lost/randomlaws/init()
/mob/living/silicon/robot/flying/lost/randomlaws/init()
..()
laws = give_random_lawset()
@@ -1,28 +1,12 @@
// Spawner landmarks are used because platforms that are mapped during
// SSatoms init try to Initialize() twice. I have no idea why and I am
// not paid enough to spend more time trying to debug it.
/obj/effect/landmark/robot_platform
name = "recon platform spawner"
icon = 'icons/mob/screen1.dmi'
icon_state = "x3"
delete_me = TRUE
var/platform_type
/obj/effect/landmark/robot_platform/Initialize()
if(platform_type)
new platform_type(get_turf(src))
return ..()
/mob/living/silicon/robot/platform
name = "support platform"
desc = "A large quadrupedal AI platform, colloquially known as a 'think-tank' due to the flexible onboard intelligence."
icon = 'icons/mob/robots_thinktank.dmi'
icon = 'icons/mob/robots/robots_platform.dmi'
icon_state = "tachi"
color = "#68a2f2"
cell = /obj/item/cell/mech
idcard_type = /obj/item/card/id/platform
module = /obj/item/robot_module/robot/platform
lawupdate = FALSE
modtype = "Standard"
@@ -33,6 +17,10 @@
mob_push_flags = HEAVY
mob_size = MOB_LARGE
dismantle_type = /obj/item/robot_parts/frame/platform
module_category = ROBOT_MODULE_TYPE_PLATFORM
var/mapped = FALSE
var/has_had_player = FALSE
var/const/platform_respawn_time = 3 MINUTES
@@ -42,19 +30,6 @@
var/tmp/recharger_tick_cost = 80 KILOWATTS
var/weakref/recharging
var/list/stored_atoms
var/max_stored_atoms = 1
var/static/list/can_store_types = list(
/mob/living,
/obj/item,
/obj/structure,
/obj/machinery
)
// Currently set to prevent tonks hauling a deliaminating SM into the middle of the station.
var/static/list/cannot_store_types = list(
/obj/machinery/power/supermatter
)
/mob/living/silicon/robot/platform/Login()
. = ..()
has_had_player = TRUE
@@ -66,9 +41,10 @@
/mob/living/silicon/robot/platform/Initialize(var/mapload)
. = ..()
if(!mmi)
mmi = new /obj/item/mmi/digital/robot(src)
SetName("inactive [initial(name)]")
if(mapped)
if(!mmi)
mmi = new /obj/item/mmi/digital/robot(src)
SetName("inactive [initial(name)]")
updateicon()
// Copypasting from root proc to avoid calling ..() and accidentally creating duplicate armour etc.
@@ -82,11 +58,13 @@
components["armour"] = new /datum/robot_component/armour/platform(src)
/mob/living/silicon/robot/platform/Destroy()
for(var/weakref/drop_ref in stored_atoms)
var/atom/movable/drop_atom = drop_ref.resolve()
if(istype(drop_atom) && !QDELETED(drop_atom) && drop_atom.loc == src)
drop_atom.dropInto(loc)
stored_atoms = null
var/obj/item/robot_module/robot/platform/thinktank_module = module
if(istype(thinktank_module))
for(var/weakref/drop_ref in thinktank_module.stored_atoms)
var/atom/movable/drop_atom = drop_ref.resolve()
if(istype(drop_atom) && !QDELETED(drop_atom) && drop_atom.loc == src)
drop_atom.dropInto(loc)
thinktank_module.stored_atoms = null
if(recharging)
var/obj/item/recharging_atom = recharging.resolve()
if(istype(recharging_atom) && recharging_atom.loc == src)
@@ -108,9 +86,10 @@
else
. += "Its recharging port is empty."
if(length(stored_atoms))
var/obj/item/robot_module/robot/platform/thinktank_module = module
if(istype(thinktank_module) && length(thinktank_module.stored_atoms))
var/list/atom_names = list()
for(var/weakref/stored_ref in stored_atoms)
for(var/weakref/stored_ref in thinktank_module.stored_atoms)
var/atom/movable/AM = stored_ref.resolve()
if(istype(AM))
atom_names += "\a [AM]"
@@ -127,9 +106,6 @@
if(ispath(module, /obj/item/robot_module))
module = new module(src)
/mob/living/silicon/robot/platform/module_reset()
return FALSE
/mob/living/silicon/robot/platform/use_power()
. = ..()
@@ -5,56 +5,74 @@
cut_overlays()
underlays.Cut()
var/use_armor_color
var/use_pupil_color
var/use_base_color
var/use_eye_color
var/use_state
var/list/use_decals
var/obj/item/robot_module/robot/platform/tank_module = module
if(!istype(tank_module))
icon = initial(icon)
icon_state = initial(icon_state)
color = initial(color)
return
if(istype(tank_module))
use_pupil_color = tank_module.pupil_color
use_base_color = tank_module.base_color
use_eye_color = tank_module.eye_color
use_armor_color = tank_module.armor_color
icon = tank_module.user_icon
use_state = tank_module.user_icon_state
use_decals = tank_module.decals
else
tank_module = /obj/item/robot_module/robot/platform
use_pupil_color = initial(tank_module.pupil_color)
use_base_color = initial(tank_module.base_color)
use_eye_color = initial(tank_module.eye_color)
use_armor_color = initial(tank_module.armor_color)
icon = initial(tank_module.user_icon)
use_state = initial(tank_module.user_icon_state)
// This is necessary due to Polaris' liberal use of KEEP_TOGETHER and propensity for scaling transforms.
// If we just apply state/colour to the base icon, RESET_COLOR on the additional overlays is ignored.
icon = tank_module.user_icon
icon_state = "blank"
color = null
var/image/I = image(tank_module.user_icon, tank_module.user_icon_state)
I.color = tank_module.base_color
var/image/I = image(icon, use_state)
I.color = use_base_color
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
underlays += I
if(tank_module.armor_color)
I = image(icon, "[tank_module.user_icon_state]_armour")
I.color = tank_module.armor_color
if(use_armor_color)
I = image(icon, "[use_state]_armour")
I.color = use_armor_color
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
add_overlay(I)
for(var/decal in tank_module.decals)
I = image(icon, "[tank_module.user_icon_state]_[decal]")
I.color = tank_module.decals[decal]
for(var/decal in use_decals)
I = image(icon, "[use_state]_[decal]")
I.color = use_decals[decal]
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
add_overlay(I)
if(tank_module.eye_color)
I = image(icon, "[tank_module.user_icon_state]_eyes")
I.color = tank_module.eye_color
if(use_eye_color)
I = image(icon, "[use_state]_eyes")
I.color = use_eye_color
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
add_overlay(I)
if(client && key && stat == CONSCIOUS && tank_module.pupil_color)
I = image(icon, "[tank_module.user_icon_state]_pupils")
I.color = tank_module.pupil_color
if(use_pupil_color && client && key && stat == CONSCIOUS)
I = image(icon, "[use_state]_pupils")
I.color = use_pupil_color
I.plane = PLANE_LIGHTING_ABOVE
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
add_overlay(I)
if(opened)
add_overlay("[tank_module.user_icon_state]-open")
add_overlay("[use_state]-open")
if(wiresexposed)
I = image(icon, "[tank_module.user_icon_state]-wires")
I = image(icon, "[use_state]-wires")
else if(cell)
I = image(icon, "[tank_module.user_icon_state]-cell")
I = image(icon, "[use_state]-cell")
else
I = image(icon, "[tank_module.user_icon_state]-nowires")
I = image(icon, "[use_state]-nowires")
I.appearance_flags |= (RESET_COLOR|PIXEL_SCALE)
add_overlay(I)
@@ -34,7 +34,7 @@
/mob/living/silicon/robot/platform/attack_ghost(mob/observer/ghost/user)
if(client || key || stat == DEAD || !ticker || !ticker.mode)
if(!mapped || client || key || stat == DEAD || !ticker || !ticker.mode)
return ..()
var/confirm = alert("Do you wish to take control of \the [src]?", "Platform Control", "No", "Yes")
@@ -43,7 +43,7 @@
if(jobban_isbanned(user, "Robot"))
to_chat(user, SPAN_WARNING("You are banned from synthetic roles and cannot take control of \the [src]."))
return
return
// Boilerplate from drone fabs, unsure if there's a shared proc to use instead.
var/deathtime = world.time - user.timeofdeath
@@ -1,25 +1,36 @@
/obj/item/robot_module/robot/platform
hide_on_manifest = TRUE
module_category = ROBOT_MODULE_TYPE_PLATFORM
unavailable_by_default = TRUE
var/pupil_color = COLOR_CYAN
var/base_color = COLOR_WHITE
var/eye_color = COLOR_BEIGE
var/armor_color = "#68a2f2"
var/user_icon = 'icons/mob/robots_thinktank.dmi'
var/user_icon = 'icons/mob/robots/robots_platform.dmi'
var/user_icon_state = "tachi"
var/list/decals
var/list/available_decals = list(
"Stripe" = "stripe",
"Stripe" = "stripe",
"Vertical Stripe" = "stripe_vertical"
)
// Only show on manifest if they have a player.
/obj/item/robot_module/robot/platform/hide_on_manifest()
if(isrobot(loc))
var/mob/living/silicon/robot/R = loc
return !R.key
var/list/stored_atoms
var/max_stored_atoms = 1
var/static/list/can_store_types = list(
/mob/living,
/obj/item,
/obj/structure,
/obj/machinery
)
// Currently set to prevent tonks hauling a deliaminating SM into the middle of the station.
var/static/list/cannot_store_types = list(
/obj/machinery/power/supermatter
)
/obj/item/robot_module/robot/platform/Destroy()
QDEL_NULL_LIST(stored_atoms)
return ..()
/obj/item/robot_module/robot/platform/verb/set_eye_colour()
@@ -31,11 +42,14 @@
var/new_pupil_color = input(usr, "Select a pupil colour.", "Pupil Colour Selection") as color|null
if(usr.incapacitated() || QDELETED(usr) || QDELETED(src) || loc != usr)
return
pupil_color = new_pupil_color || initial(pupil_color)
usr.update_icon()
/obj/item/robot_module/robot/platform/explorer
name = "recon platform module"
display_name = "Recon"
unavailable_by_default = FALSE
armor_color = "#528052"
eye_color = "#7b7b46"
decals = list(
@@ -46,32 +60,28 @@
"Science" = 1,
"Explorer" = 1
)
modules = list(
/obj/item/tool/wrench/cyborg,
/obj/item/weldingtool/electric/mounted/cyborg,
/obj/item/tool/wirecutters/cyborg,
/obj/item/tool/screwdriver/cyborg,
/obj/item/pickaxe/plasmacutter,
/obj/item/material/knife/machete/cyborg,
/obj/item/gun/energy/phasegun/mounted/cyborg,
/obj/item/stack/medical/bruise_pack
)
emag = /obj/item/chainsaw
synths = list(
/datum/matter_synth/medicine = 7500
)
/obj/item/robot_module/robot/platform/explorer/Initialize()
. = ..()
if(. != INITIALIZE_HINT_NORMAL)
return
modules += new /obj/item/tool/wrench/cyborg(src)
modules += new /obj/item/weldingtool/electric/mounted/cyborg(src)
modules += new /obj/item/tool/wirecutters/cyborg(src)
modules += new /obj/item/tool/screwdriver/cyborg(src)
modules += new /obj/item/pickaxe/plasmacutter(src)
modules += new /obj/item/material/knife/machete/cyborg(src)
var/datum/matter_synth/medicine = new /datum/matter_synth/medicine(7500)
var/obj/item/stack/medical/bruise_pack/bandaid = new(src)
/obj/item/robot_module/robot/platform/explorer/finalize_synths()
..()
var/datum/matter_synth/medicine/medicine = locate() in synths
var/obj/item/stack/medical/bruise_pack/bandaid = locate() in modules
bandaid.uses_charge = 1
bandaid.charge_costs = list(1000)
bandaid.synths = list(medicine)
modules += bandaid
synths += medicine
var/obj/item/gun/energy/phasegun/mounted/cyborg/phasegun = new(src)
modules += phasegun
emag = new /obj/item/chainsaw(src)
/obj/item/robot_module/robot/platform/explorer/respawn_consumable(var/mob/living/silicon/robot/R, rate)
. = ..()
@@ -83,6 +93,9 @@
pew.charge_tick = 0
/obj/item/robot_module/robot/platform/cargo
name = "logistics platform module"
display_name = "Logistics"
unavailable_by_default = FALSE
armor_color = "#d5b222"
eye_color = "#686846"
decals = list(
@@ -91,17 +104,13 @@
)
channels = list("Supply" = 1)
networks = list(NETWORK_MINE)
/obj/item/robot_module/robot/platform/cargo/Initialize()
. = ..()
if(. != INITIALIZE_HINT_NORMAL)
return
modules += new /obj/item/packageWrap(src)
modules += new /obj/item/pen/multi(src)
modules += new /obj/item/destTagger(src)
emag = new /obj/item/stamp/denied
max_stored_atoms = 3
modules = list(
/obj/item/packageWrap,
/obj/item/pen/multi,
/obj/item/destTagger,
)
emag = /obj/item/stamp/denied
/obj/item/robot_module/robot/platform/cargo/respawn_consumable(mob/living/silicon/robot/R, rate)
. = ..()
@@ -9,18 +9,24 @@
recharging_atom.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),30)
recharging = null
if(length(stored_atoms))
for(var/weakref/stored_ref in stored_atoms)
var/obj/item/robot_module/robot/platform/thinktank_module = module
if(istype(thinktank_module) && length(thinktank_module.stored_atoms))
for(var/weakref/stored_ref in thinktank_module.stored_atoms)
var/atom/movable/dropping = stored_ref.resolve()
if(istype(dropping) && !QDELETED(dropping) && dropping.loc == src)
dropping.dropInto(loc)
dropping.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),30)
stored_atoms = null
thinktank_module.stored_atoms = null
. = ..()
/mob/living/silicon/robot/platform/proc/can_store_atom(var/atom/movable/storing, var/mob/user)
var/obj/item/robot_module/robot/platform/thinktank_module = module
if(!istype(thinktank_module))
to_chat(user, SPAN_WARNING("Select a module first!"))
return FALSE
if(!istype(storing))
var/storing_target = (user == src) ? "yourself" : "\the [src]"
to_chat(user, SPAN_WARNING("You cannot store that inside [storing_target]."))
@@ -38,7 +44,7 @@
to_chat(user, SPAN_WARNING("You cannot store [storing_target] inside [storing_target]!"))
return FALSE
if(length(stored_atoms) >= max_stored_atoms)
if(length(thinktank_module.stored_atoms) >= thinktank_module.max_stored_atoms)
var/storing_target = (user == src) ? "Your" : "\The [src]'s"
to_chat(user, SPAN_WARNING("[storing_target] cargo compartment is full."))
return FALSE
@@ -50,13 +56,13 @@
to_chat(user, SPAN_WARNING("\The [storing] is too big for [storing_target]."))
return FALSE
for(var/store_type in can_store_types)
for(var/store_type in thinktank_module.can_store_types)
if(istype(storing, store_type))
. = TRUE
break
if(.)
for(var/store_type in cannot_store_types)
for(var/store_type in thinktank_module.cannot_store_types)
if(istype(storing, store_type))
. = FALSE
break
@@ -65,20 +71,25 @@
to_chat(user, SPAN_WARNING("You cannot store \the [storing] inside [storing_target]."))
/mob/living/silicon/robot/platform/proc/store_atom(var/atom/movable/storing, var/mob/user)
if(istype(storing))
var/obj/item/robot_module/robot/platform/thinktank_module = module
if(istype(thinktank_module) && istype(storing))
storing.forceMove(src)
LAZYDISTINCTADD(stored_atoms, weakref(storing))
LAZYDISTINCTADD(thinktank_module.stored_atoms, weakref(storing))
/mob/living/silicon/robot/platform/proc/drop_stored_atom(var/atom/movable/ejecting, var/mob/user)
if(!ejecting && length(stored_atoms))
var/weakref/stored_ref = stored_atoms[1]
var/obj/item/robot_module/robot/platform/thinktank_module = module
if(!istype(thinktank_module))
return
if(!ejecting && length(thinktank_module.stored_atoms))
var/weakref/stored_ref = thinktank_module.stored_atoms[1]
if(!istype(stored_ref))
LAZYREMOVE(stored_atoms, stored_ref)
LAZYREMOVE(thinktank_module.stored_atoms, stored_ref)
else
ejecting = stored_ref?.resolve()
LAZYREMOVE(stored_atoms, weakref(ejecting))
LAZYREMOVE(thinktank_module.stored_atoms, weakref(ejecting))
if(istype(ejecting) && !QDELETED(ejecting) && ejecting.loc == src)
ejecting.dropInto(loc)
if(user == src)
@@ -90,14 +101,15 @@
if(isrobot(user) && user.Adjacent(src))
return try_remove_cargo(user)
return ..()
/mob/living/silicon/robot/platform/proc/try_remove_cargo(var/mob/user)
if(!length(stored_atoms) || !istype(user))
var/obj/item/robot_module/robot/platform/thinktank_module = module
if(!istype(thinktank_module) || !length(thinktank_module.stored_atoms) || !istype(user))
return FALSE
var/weakref/remove_ref = stored_atoms[length(stored_atoms)]
var/weakref/remove_ref = thinktank_module.stored_atoms[length(thinktank_module.stored_atoms)]
var/atom/movable/removing = remove_ref?.resolve()
if(!istype(removing) || QDELETED(removing) || removing.loc != src)
LAZYREMOVE(stored_atoms, remove_ref)
LAZYREMOVE(thinktank_module.stored_atoms, remove_ref)
else
user.visible_message(SPAN_NOTICE("\The [user] begins unloading \the [removing] from \the [src]'s cargo compartment."))
if(do_after(user, 3 SECONDS, src) && !QDELETED(removing) && removing.loc == src)
@@ -113,7 +125,8 @@
to_chat(src, SPAN_WARNING("You are not in any state to do that."))
return
if(length(stored_atoms))
var/obj/item/robot_module/robot/platform/thinktank_module = module
if(istype(thinktank_module) && length(thinktank_module.stored_atoms))
drop_stored_atom(user = src)
else
to_chat(src, SPAN_WARNING("You have nothing in your cargo compartment."))
@@ -136,4 +149,4 @@
return FALSE
if(user.incapacitated() || !Adjacent(user) || !dropping.Adjacent(user))
return FALSE
return TRUE
return TRUE
@@ -1,32 +0,0 @@
/mob/living/silicon/robot/platform/explorer
name = "recon platform"
desc = "A large quadrupedal AI platform, colloquially known as a 'think-tank' due to the flexible onboard intelligence. This one is lightly armoured and fitted with all-terrain wheels."
modtype = "Recon"
module = /obj/item/robot_module/robot/platform/explorer
/mob/living/silicon/robot/platform/explorer/Initialize()
. = ..()
laws = new /datum/ai_laws/explorer
/mob/living/silicon/robot/platform/explorer/welcome_client()
..()
if(client) // ganbatte tachikoma-san
to_chat(src, SPAN_NOTICE("You are tasked with supporting the Exploration and Science staff as they unearth the secrets of the planet. Do your best!"))
/obj/effect/landmark/robot_platform/explorer
platform_type = /mob/living/silicon/robot/platform/explorer
/mob/living/silicon/robot/platform/cargo
name = "logistics platform"
desc = "A large quadrupedal AI platform, colloquially known as a 'think-tank' due to the flexible onboard intelligence. This one has an expanded storage compartment."
modtype = "Logistics"
module = /obj/item/robot_module/robot/platform/cargo
max_stored_atoms = 3
/mob/living/silicon/robot/platform/cargo/welcome_client()
..()
if(client)
to_chat(src, SPAN_NOTICE("You are tasked with supporting the Cargo and Supply staff as they handle operational logistics. Do your best!"))
/obj/effect/landmark/robot_platform/cargo
platform_type = /mob/living/silicon/robot/platform/cargo
@@ -99,4 +99,4 @@
icon_scale_y = 0.5
/decl/mob_organ_names/bird
hit_zones = list("head", "chest", "left leg", "right leg", "left wing", "right wing")
hit_zones = list("head", "chest", "left leg", "right leg", "left wing", "right wing")
@@ -12,4 +12,4 @@
// They can also, you know, move around, in space
/mob/living/simple_mob/animal/space/Process_Spacemove(var/check_drift = 0)
return TRUE
return TRUE
@@ -430,4 +430,4 @@
/obj/random/projectile/scrapped_grenadelauncher = 100,
/obj/item/grenade/spawnergrenade/manhacks/mercenary = 50,
/obj/item/grenade/spawnergrenade/manhacks/mercenary = 30
)
)
@@ -150,4 +150,4 @@
/decl/mob_organ_names/miningdrone
hit_zones = list("chassis", "comms array", "sensor suite", "left excavator module", "right excavator module", "maneuvering thruster")
hit_zones = list("chassis", "comms array", "sensor suite", "left excavator module", "right excavator module", "maneuvering thruster")
@@ -44,4 +44,4 @@
return TRUE
/decl/mob_organ_names/hoverpod
hit_zones = list("central chassis", "control module", "hydraulics", "left manipulator", "right manipulator", "left landing strut", "right landing strut", "maneuvering thruster", "sensor suite", "radiator", "power supply")
hit_zones = list("central chassis", "control module", "hydraulics", "left manipulator", "right manipulator", "left landing strut", "right landing strut", "maneuvering thruster", "sensor suite", "radiator", "power supply")
@@ -142,8 +142,8 @@
. += "<span class='warning'><B>It looks severely dented!</B></span>"
//Constructs levitate, can fall from a shuttle with no harm, and are piloted by either damned spirits or some otherworldly entity. Let 'em float in space.
/mob/living/simple_mob/construct/Process_Spacemove()
return 1
/mob/living/simple_mob/construct/Process_Spacemove(var/check_drift = 0)
return TRUE
/*
// Glowing Procs
@@ -155,4 +155,4 @@
/mob/living/simple_mob/construct/proc/remove_glow()
overlays.Cut()
*/
*/
@@ -43,7 +43,7 @@
minbodytemp = 0
/mob/living/simple_mob/faithless/Process_Spacemove(var/check_drift = 0)
return 1
return TRUE
/mob/living/simple_mob/faithless/apply_melee_effects(var/atom/A)
if(isliving(A))
@@ -238,4 +238,4 @@ var/global/list/_slime_default_emotes = list(
visible_message("<b>\The [src]</b> squishes!")
/decl/mob_organ_names/slime
hit_zones = list("cytoplasmic membrane")
hit_zones = list("cytoplasmic membrane")
+28 -11
View File
@@ -202,7 +202,7 @@
// Can't control ourselves when drifting
if((isspace(loc) || my_mob.lastarea?.has_gravity == 0) && isturf(loc))
if(!my_mob.Process_Spacemove(0))
if(!my_mob.Process_Spacemove(FALSE))
return 0
// Inside an object, tell it we moved
@@ -395,6 +395,18 @@
/mob/proc/get_jetpack()
return
// Checks whether this mob is allowed to move in space
// Return 1 for movement, 0 for none,
/mob/proc/Allow_Spacemove(var/dense_object)
if(restrained())
return FALSE
var/obj/item/tank/jetpack/J = get_jetpack()
if(J?.can_thrust(0.01))
return TRUE
if(!dense_object) //Nothing to push off of so end here
return FALSE
return TRUE
///Process_Spacemove
///Called by /client/Move()
///For moving in space
@@ -402,26 +414,31 @@
/mob/proc/Process_Spacemove(var/check_drift = 0)
if(is_incorporeal())
return
return FALSE
if(!Check_Dense_Object()) //Nothing to push off of so end here
update_floating(0)
return 0
var/dense_object = Check_Dense_Object()
if(!Allow_Spacemove())
update_floating(dense_object)
return FALSE
update_floating(1)
if(restrained()) //Check to see if we can do things
return 0
var/obj/item/tank/jetpack/thrust = get_jetpack()
if(dense_object || ((!check_drift || thrust?.stabilization_on) && !lying && thrust.do_thrust(0.01, src)))
inertia_dir = 0
return TRUE
else if(!dense_object) //Nothing to push off of so end here
update_floating(FALSE)
return FALSE
//Check to see if we slipped
if(prob(Process_Spaceslipping(5)) && !buckled)
to_chat(src, "<span class='notice'><B>You slipped!</B></span>")
inertia_dir = last_move
step(src, src.inertia_dir) // Not using Move for smooth glide here because this is a 'slip' so should be sudden.
return 0
return FALSE
//If not then we can reset inertia and move
inertia_dir = 0
return 1
return TRUE
/mob/proc/Check_Dense_Object() //checks for anything to push off in the vicinity. also handles magboots on gravity-less floors tiles
+10 -5
View File
@@ -419,6 +419,13 @@
var/datum/job/J = SSjob.get_job(rank)
// Get the appropriate announcement title.
var/announce_rank = rank
if(J?.substitute_announce_title)
announce_rank = J.substitute_announce_title
else if(character.mind.role_alt_title)
announce_rank = character.mind.role_alt_title
// AIs don't need a spawnpoint, they must spawn at an empty core
if(J.mob_type & JOB_SILICON_AI)
@@ -431,7 +438,7 @@
// AIize the character, but don't move them yet
character = character.AIize(move = FALSE) // Dupe of code in /datum/controller/subsystem/ticker/proc/create_characters() for non-latespawn, unify?
AnnounceCyborg(character, rank, "has been transferred to the empty core in \the [character.loc.loc]")
AnnounceCyborg(character, announce_rank, "has been transferred to the empty core in \the [character.loc.loc]")
ticker.mode.latespawn(character)
qdel(C) //Deletes empty core (really?)
@@ -453,10 +460,10 @@
var/do_announce = join_props["announce"] && join_message && announce_channel
if(J.mob_type & JOB_SILICON)
if(do_announce)
AnnounceCyborg(character, rank, join_message, announce_channel, character.z)
AnnounceCyborg(character, announce_rank, join_message, announce_channel, character.z)
else
if(do_announce)
AnnounceArrival(character, J?.substitute_announce_title || rank, join_message, announce_channel, character.z)
AnnounceArrival(character, announce_rank, join_message, announce_channel, character.z)
data_core.manifest_inject(character)
ticker.minds += character.mind//Cyborgs and AIs handle this in the transform proc. //TODO!!!!! ~Carn
@@ -465,8 +472,6 @@
/mob/new_player/proc/AnnounceCyborg(var/mob/living/character, var/rank, var/join_message, var/channel, var/zlevel)
if (ticker.current_state == GAME_STATE_PLAYING)
var/list/zlevels = zlevel ? using_map.get_map_levels(zlevel, TRUE, om_range = DEFAULT_OVERMAP_RANGE) : null
if(character.mind.role_alt_title)
rank = character.mind.role_alt_title
// can't use their name here, since cyborg namepicking is done post-spawn, so we'll just say "A new Cyborg has arrived"/"A new Android has arrived"/etc.
global_announcer.autosay("A new[rank ? " [rank]" : " visitor" ] [join_message ? join_message : "has arrived on the station"].", "Arrivals Announcement Computer", channel, zlevels)
+7 -10
View File
@@ -136,7 +136,7 @@
return O
//human -> robot
/mob/living/carbon/human/proc/Robotize()
/mob/living/carbon/human/proc/Robotize(supplied_robot_type = /mob/living/silicon/robot)
if (transforming)
return
for(var/obj/item/W in src)
@@ -149,7 +149,7 @@
for(var/t in organs)
qdel(t)
var/mob/living/silicon/robot/O = new /mob/living/silicon/robot( loc )
var/mob/living/silicon/robot/O = new supplied_robot_type( loc )
// cyborgs produced by Robotize get an automatic power cell
O.cell = new(O)
@@ -171,15 +171,12 @@
O.loc = loc
O.job = "Cyborg"
if(O.mind.assigned_role == "Cyborg")
if(O.mind.role_alt_title == "Robot")
O.mmi = new /obj/item/mmi/digital/posibrain(O)
else if(O.mind.role_alt_title == "Drone")
O.mmi = new /obj/item/mmi/digital/robot(O)
else
O.mmi = new /obj/item/mmi(O)
O.mmi.transfer_identity(src)
if(O.mind.assigned_role == "Cyborg")
var/mmi_type = SSrobots.get_mmi_type_by_title(O.mind.role_alt_title ? O.mind.role_alt_title : O.mind.assigned_role)
if(mmi_type)
O.mmi = new mmi_type(O)
O.mmi.transfer_identity(src)
if(O.client && O.client.prefs)
var/datum/preferences/B = O.client.prefs
+1 -13
View File
@@ -29,18 +29,6 @@
if(length(A.name) + length(label) > 64)
to_chat(user, SPAN_WARNING("\The [src]'s label too big."))
return
if(istype(A, /mob/living/silicon/robot/platform))
var/mob/living/silicon/robot/platform/P = A
if(!P.allowed(user))
to_chat(usr, SPAN_WARNING("Access denied."))
else if(P.client || P.key)
to_chat(user, SPAN_NOTICE("You rename \the [P] to [label]."))
to_chat(P, SPAN_NOTICE("\The [user] renames you to [label]."))
P.custom_name = label
P.SetName(P.custom_name)
else
to_chat(user, SPAN_WARNING("\The [src] is inactive and cannot be renamed."))
return
if(ishuman(A))
to_chat(user, SPAN_WARNING("The label refuses to stick to [A.name]."))
return
@@ -80,4 +68,4 @@
label = str
to_chat(user, SPAN_NOTICE("You set the text to '[str]'."))
else
to_chat(user, SPAN_NOTICE("You turn off \the [src]."))
to_chat(user, SPAN_NOTICE("You turn off \the [src]."))
+20 -1
View File
@@ -277,10 +277,24 @@
/datum/design/item/prosfab/cyborg/exoskeleton
name = "Robot Exoskeleton"
id = "robot_exoskeleton"
build_path = /obj/item/robot_parts/robot_suit
build_path = /obj/item/robot_parts/frame
time = 50
materials = list(MAT_STEEL = 37500)
/datum/design/item/prosfab/cyborg/exoskeleton_flying
name = "Flying Robot Exoskeleton"
id = "robot_exoskeleton_flyer"
build_path = /obj/item/robot_parts/frame/flyer
time = 40
materials = list(MAT_STEEL = 32500)
/datum/design/item/prosfab/cyborg/exoskeleton_platform
name = "Platform Exoskeleton"
id = "robot_exoskeleton_platform"
build_path = /obj/item/robot_parts/frame/platform
time = 60
materials = list(MAT_STEEL = 42500)
/datum/design/item/prosfab/cyborg/torso
name = "Robot Torso"
id = "robot_torso"
@@ -366,6 +380,11 @@
id = "platform_armour"
build_path = /obj/item/robot_parts/robot_component/armour_platform
/datum/design/item/prosfab/cyborg/component/armour_light
name = "Armour Plating (Light)"
id = "light_armour"
build_path = /obj/item/robot_parts/robot_component/armour_light
/datum/design/item/prosfab/cyborg/component/ai_shell
name = "AI Remote Interface"
id = "mmi_ai_shell"
@@ -424,7 +424,7 @@
//robot remains
apply_prefix = FALSE
item_type = "[pick("mechanical","robotic","cyborg")] [pick("remains","chassis","debris")]"
icon = 'icons/mob/robots.dmi'
icon = 'icons/mob/robot_gibs.dmi'
icon_state = "remainsrobot"
additional_desc = pick("Almost mistakeable for the remains of a modern cyborg.",\
"They are barely recognisable as anything other than a pile of waste metals.",\
+139
View File
@@ -0,0 +1,139 @@
/datum/unit_test/robot_module_icons_shall_be_valid
name = "ICONS: Robot module icons shall be valid"
var/list/check_module_categories = list(
ROBOT_MODULE_TYPE_GROUNDED,
ROBOT_MODULE_TYPE_FLYING
)
var/list/panel_overlays = list(
"ov-openpanel +w",
"ov-openpanel +c",
"ov-openpanel -c"
)
var/list/gear_to_check = list(
/obj/item/borg/combat/shield = "-shield",
/obj/item/borg/combat/mobility = "-roll"
)
/datum/unit_test/robot_module_icons_shall_be_valid/start_test()
var/list/failures = list()
// fetch our icon states to check against
var/list/icon_state_cache = list(
ROBOT_MODULE_TYPE_GROUNDED = icon_states('icons/mob/robots/robots_grounded.dmi'),
ROBOT_MODULE_TYPE_FLYING = icon_states('icons/mob/robots/robots_flying.dmi')
)
var/list/found_states = list() // Keep track of this for checking for unused states later.
// Kick it off by doing a sprite check on all flying and grounded modules.
for(var/module_type in typesof(/obj/item/robot_module))
// Skip abstract modules and think-tanks as they do icon gen differently.
var/obj/item/robot_module/module = module_type
if(!initial(module.display_name) || !(initial(module.module_category) in check_module_categories))
continue
module = new module // this will automatically qdelete, but we just want the sprites.
// Check that the expected states are actually in the icon file.
var/check_states = icon_state_cache[module.module_category]
for(var/sprite in module.sprites)
// Basic sprite.
var/check_state = module.sprites[sprite]
if(check_state in check_states)
LAZYDISTINCTADD(found_states[module.module_category], check_state)
else
failures += "missing base state '[check_state]' for [module.display_name] ([module.module_category])"
// Eyes overlay.
var/eye_check_state = "eyes-[check_state]"
if(eye_check_state in check_states)
LAZYDISTINCTADD(found_states[module.module_category], eye_check_state)
else
failures += "missing eyes state '[eye_check_state]' for [module.display_name] ([module.module_category])"
// Equipment overlays.
for(var/geartype in gear_to_check)
var/suffix = gear_to_check[geartype]
for(var/gear in module.modules)
if(!ispath(gear, geartype))
continue
var/gear_check_state = "[check_state][suffix]"
if(gear_check_state in check_states)
LAZYDISTINCTADD(found_states[module.module_category], gear_check_state)
else
failures += "missing gear state '[gear_check_state]' for [module.display_name] ([module.module_category])"
break
// Check for drone AI eyes.
if(istype(module, /obj/item/robot_module/drone))
var/ai_eye_state = "[eye_check_state]-ai"
if(ai_eye_state in check_states)
LAZYDISTINCTADD(found_states[module.module_category], ai_eye_state)
else
failures += "missing drone AI control state '[ai_eye_state]' for [module.display_name] ([module.module_category])"
// Check for missing panel states.
for(var/module_category in check_module_categories)
var/list/check_states = icon_state_cache[module_category]
for(var/panel_state in panel_overlays)
if(panel_state in check_states)
LAZYDISTINCTADD(found_states[module_category], panel_state)
else
failures += "missing panel state '[panel_state]' for [module_category]"
// Now we can do tachikoma sprites.
var/list/tachikoma_icon_states = list()
for(var/module_type in typesof(/obj/item/robot_module/robot/platform))
// Skip abstract modules.
var/obj/item/robot_module/robot/platform/module = module_type
if(!initial(module.display_name) || !initial(module.module_category) || !initial(module.user_icon))
continue
// We need a module instance to check the decal list.
module = new module_type
if(!tachikoma_icon_states[module.user_icon])
tachikoma_icon_states[module.user_icon] = icon_states(module.user_icon)
LAZYDISTINCTADD(icon_state_cache[ROBOT_MODULE_TYPE_PLATFORM], tachikoma_icon_states[module.user_icon])
/*
unexpected state 'tachi_cross' for platform
unexpected state 'tachi-open-wires' for platform
unexpected state 'tachi-open-cell' for platform
*/
var/list/states_to_check = list(
"blank",
module.user_icon_state,
"[module.user_icon_state]-open",
"[module.user_icon_state]-wires",
"[module.user_icon_state]-cell",
"[module.user_icon_state]-nowires"
)
if(module.armor_color)
states_to_check += "[module.user_icon_state]_armour"
for(var/decal in module.decals)
states_to_check += "[module.user_icon_state]_[decal]"
if(module.eye_color)
states_to_check += "[module.user_icon_state]_eyes"
if(module.pupil_color)
states_to_check += "[module.user_icon_state]_pupils"
for(var/check_state in states_to_check)
if(check_state in tachikoma_icon_states[module.user_icon])
LAZYDISTINCTADD(found_states[ROBOT_MODULE_TYPE_PLATFORM], check_state)
else
failures += "missing platform state '[check_state]' in icon file [module.user_icon]"
// Check that there aren't any unexpected states.
for(var/module_category in icon_state_cache)
var/list/check_found_states = LAZYACCESS(found_states, module_category)
for(var/check_state in icon_state_cache[module_category])
if(!(check_state in check_found_states))
failures += "unexpected state '[check_state]' for [module_category]"
if(length(failures))
fail("Some robot module sprites are invalid:\n" + failures.Join("\n"))
else
pass("All robot module sprites are valid.")
return 1
Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 566 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 579 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 915 B

-3
View File
@@ -20941,7 +20941,6 @@
/area/shuttle/exploration/general)
"jDG" = (
/obj/machinery/mech_recharger,
/obj/effect/landmark/robot_platform/cargo,
/turf/simulated/floor/tiled/dark,
/area/surface/station/quartermaster/lockerroom)
"jDW" = (
@@ -37761,7 +37760,6 @@
/area/surface/station/library)
"qCU" = (
/obj/machinery/mech_recharger,
/obj/effect/landmark/robot_platform/explorer,
/turf/simulated/floor/tiled/dark,
/area/surface/station/garage)
"qCW" = (
@@ -43241,7 +43239,6 @@
/area/surface/station/quartermaster/lockerroom)
"tdK" = (
/obj/machinery/mech_recharger,
/obj/effect/landmark/robot_platform/explorer,
/obj/machinery/firealarm{
pixel_y = 24
},
+1 -1
View File
@@ -7793,7 +7793,7 @@
/turf/simulated/floor/tiled/milspec/dark,
/area/shuttle/escape/centcom)
"iNR" = (
/obj/item/robot_parts/robot_suit,
/obj/item/robot_parts/frame,
/obj/item/robot_parts/r_leg,
/obj/item/robot_parts/r_arm,
/turf/simulated/shuttle/plating,
-1
View File
@@ -5,7 +5,6 @@
#include "cynosure_jobs.dm"
#include "cynosure_elevator.dm"
#include "cynosure_events.dm"
#include "cynosure_overrides.dm"
#include "cynosure_presets.dm"
#include "cynosure_shuttles.dm"
-9
View File
@@ -1,9 +0,0 @@
/mob/living/silicon/robot/platform/explorer
req_access = list(access_explorer)
/mob/living/silicon/robot/platform/cargo
req_access = list(access_cargo_bot)
/obj/item/card/id/platform/Initialize()
. = ..()
access |= access_explorer
+1 -1
View File
@@ -2285,7 +2285,7 @@
"RW" = (/obj/structure/table/rack,/obj/item/grenade/empgrenade,/obj/item/grenade/flashbang,/obj/item/grenade/spawnergrenade/manhacks,/turf/simulated/shuttle/floor/red,/area/skipjack_station/start)
"RX" = (/obj/structure/table/steel,/obj/machinery/recharger,/obj/machinery/light/small{dir = 4},/turf/simulated/shuttle/floor/red,/area/skipjack_station/start)
"RY" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/shuttle/plating,/area/skipjack_station/start)
"RZ" = (/obj/item/robot_parts/robot_suit,/obj/item/robot_parts/r_leg,/obj/item/robot_parts/r_arm,/turf/simulated/shuttle/plating,/area/skipjack_station/start)
"RZ" = (/obj/item/robot_parts/frame,/obj/item/robot_parts/r_leg,/obj/item/robot_parts/r_arm,/turf/simulated/shuttle/plating,/area/skipjack_station/start)
"Sa" = (/obj/machinery/computer/communications,/turf/unsimulated/floor{icon_state = "dark"},/area/wizard_station)
"Sb" = (/obj/structure/sign/double/map/left{pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station)
"Sc" = (/obj/structure/sign/double/map/right{pixel_y = 32},/turf/unsimulated/floor{icon_state = "vault"; dir = 5},/area/wizard_station)
+3 -3
View File
@@ -107,7 +107,7 @@
"cc" = (/obj/machinery/light/small{ icon_state = "bulb1"; dir = 4},/obj/machinery/atmospherics/pipe/simple{ icon_state = "intact"; dir = 2; level = 2},/turf/simulated/floor/plating,/area/ship/scrap/crew)
"cd" = (/turf/simulated/wall/r_wall,/area/ship/scrap/crew/saloon)
"ce" = (/obj/machinery/atmospherics/pipe/simple{ icon_state = "intact"; dir = 2; level = 2},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/door/airlock/maintenance_hatch{name = "Hatch"; normalspeed = 0},/turf/simulated/floor{icon_state = "white"},/area/ship/scrap/crew/saloon)
"cf" = (/obj/machinery/light/small{ icon_state = "bulb1"; dir = 8},/obj/item/crowbar,/obj/machinery/atmospherics/pipe/simple{ icon_state = "intact"; dir = 2; level = 2},/turf/simulated/floor/plating,/area/ship/scrap/crew)
"cf" = (/obj/machinery/light/small{ icon_state = "bulb1"; dir = 8},/obj/item/tool/crowbar,/obj/machinery/atmospherics/pipe/simple{ icon_state = "intact"; dir = 2; level = 2},/turf/simulated/floor/plating,/area/ship/scrap/crew)
"cg" = (/turf/simulated/wall/r_wall,/area/ship/scrap/crew/dorms)
"ch" = (/obj/structure/sign/poster,/turf/simulated/wall,/area/ship/scrap/crew/dorms)
"ci" = (/obj/structure/window/reinforced{dir = 5; health = 1e+007},/obj/structure/grille,/obj/machinery/door/poddoor{density = 0; icon_state = "pdoor0"; id = "scraplock"; name = "External Blast Doors"; opacity = 0},/obj/structure/window/reinforced{dir = 5; health = 1e+007},/turf/simulated/floor{icon_state = "white"},/area/ship/scrap/crew/dorms)
@@ -229,7 +229,7 @@
"eu" = (/turf/simulated/floor/plating{dir = 2; icon_state = "warnplate"},/area/ship/scrap/maintenance/engine)
"ev" = (/obj/structure/window/reinforced{dir = 1},/turf/simulated/floor/plating/airless,/area/ship/scrap/maintenance/engine)
"ew" = (/obj/structure/window/reinforced{dir = 1},/obj/machinery/light/small{ icon_state = "bulb1"; dir = 1},/turf/simulated/floor/plating/airless,/area/ship/scrap/maintenance/engine)
"ex" = (/obj/item/screwdriver,/turf/simulated/floor/plating,/area)
"ex" = (/obj/item/tool/screwdriver,/turf/simulated/floor/plating,/area)
"ey" = (/turf/simulated/wall,/area/ship/scrap/crew/wash)
"ez" = (/obj/structure/closet/crate,/obj/item/stack/sheet/metal{amount = 50},/obj/item/stack/sheet/metal{amount = 50},/turf/simulated/floor{ icon_state = "bot"; dir = 2},/area/ship/scrap/cargo)
"eA" = (/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/atmospherics/pipe/simple{ icon_state = "intact"; dir = 2; level = 2},/turf/simulated/floor,/area/ship/scrap/cargo)
@@ -326,7 +326,7 @@
"gn" = (/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/obj/effect/decal/cleanable/dirt,/turf/simulated/floor{ icon_state = "floorgrime"; dir = 6},/area/ship/scrap/maintenance)
"go" = (/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/turf/simulated/floor/plating,/area/ship/scrap/maintenance)
"gp" = (/obj/machinery/atmospherics/pipe/manifold4w{level = 2},/obj/structure/cable{d1 = 1; d2 = 2; icon_state = "1-2"},/obj/machinery/light/small{dir = 8; icon_state = "bulb1"; pixel_y = 16},/turf/simulated/floor,/area/ship/scrap/maintenance)
"gq" = (/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/obj/machinery/light/small{ icon_state = "bulb1"; dir = 1},/obj/item/crowbar,/turf/simulated/floor/plating,/area/ship/scrap/maintenance)
"gq" = (/obj/machinery/atmospherics/pipe/simple{dir = 4; icon_state = "intact"; level = 2},/obj/machinery/light/small{ icon_state = "bulb1"; dir = 1},/obj/item/tool/crowbar,/turf/simulated/floor/plating,/area/ship/scrap/maintenance)
"gr" = (/obj/machinery/atmospherics/pipe/simple{dir = 9; icon_state = "intact"; level = 2},/turf/simulated/floor{ icon_state = "wall_thermite"; dir = 2},/area/ship/scrap/maintenance)
"gs" = (/turf/simulated/wall/r_wall,/area/ship/scrap/maintenance/atmos)
"gt" = (/turf/simulated/wall,/area/ship/scrap/maintenance/atmos)
-1
View File
@@ -72947,7 +72947,6 @@
},
/obj/machinery/mech_recharger,
/obj/effect/floor_decal/industrial/hatch/yellow,
/obj/effect/landmark/robot_platform/cargo,
/turf/simulated/floor/tiled/steel,
/area/quartermaster/warehouse)
"cHa" = (
-2
View File
@@ -13977,7 +13977,6 @@
dir = 4
},
/obj/machinery/mech_recharger,
/obj/effect/landmark/robot_platform/explorer,
/turf/simulated/floor/plating,
/area/surface/outpost/main/garage)
"GT" = (
@@ -14102,7 +14101,6 @@
"Lz" = (
/obj/effect/floor_decal/industrial/hatch/yellow,
/obj/machinery/mech_recharger,
/obj/effect/landmark/robot_platform/explorer,
/turf/simulated/floor/plating,
/area/surface/outpost/main/garage)
"LH" = (
+1 -1
View File
@@ -2135,7 +2135,7 @@
"Pc" = (/obj/structure/table/steel,/obj/machinery/recharger,/obj/machinery/light/small{dir = 4},/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start)
"Pd" = (/obj/machinery/portable_atmospherics/canister/oxygen,/turf/simulated/shuttle/floor/darkred,/area/skipjack_station/start)
"Pe" = (/obj/structure/reagent_dispensers/fueltank,/turf/simulated/shuttle/plating,/area/skipjack_station/start)
"Pf" = (/obj/item/robot_parts/robot_suit,/obj/item/robot_parts/r_leg,/obj/item/robot_parts/r_arm,/turf/simulated/shuttle/plating,/area/skipjack_station/start)
"Pf" = (/obj/item/robot_parts/frame,/obj/item/robot_parts/r_leg,/obj/item/robot_parts/r_arm,/turf/simulated/shuttle/plating,/area/skipjack_station/start)
"Pg" = (/obj/structure/flight_left{icon_state = "left"; dir = 8},/turf/simulated/shuttle/floor/voidcraft,/area/syndicate_station/start)
"Ph" = (/obj/item/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Syndicate Intercom"; pixel_x = 32; subspace_transmission = 1; syndie = 1},/turf/simulated/shuttle/floor/voidcraft/light,/area/syndicate_station/start)
"Pi" = (/obj/item/radio/intercom{desc = "Talk through this. Evilly"; frequency = 1213; name = "Syndicate Intercom"; pixel_x = -32; subspace_transmission = 1; syndie = 1},/turf/simulated/shuttle/floor/voidcraft/dark,/area/syndicate_station/start)
+1 -2
View File
@@ -7,7 +7,6 @@
#include "southern_cross_jobs.dm"
#include "southern_cross_elevator.dm"
#include "southern_cross_events.dm"
#include "southern_cross_overrides.dm"
#include "southern_cross_presets.dm"
#include "southern_cross_shuttles.dm"
@@ -56,4 +55,4 @@
#warn A map has already been included, ignoring Southern Cross
#endif
#endif
@@ -1,10 +0,0 @@
/mob/living/silicon/robot/platform/explorer
req_access = list(access_explorer)
/mob/living/silicon/robot/platform/cargo
req_access = list(access_cargo_bot)
/obj/item/card/id/platform/Initialize()
. = ..()
access |= access_explorer
access |= access_pilot
+5 -1
View File
@@ -244,6 +244,7 @@
#include "code\controllers\subsystems\persistence.dm"
#include "code\controllers\subsystems\planets.dm"
#include "code\controllers\subsystems\radiation.dm"
#include "code\controllers\subsystems\robots.dm"
#include "code\controllers\subsystems\shuttles.dm"
#include "code\controllers\subsystems\skybox.dm"
#include "code\controllers\subsystems\sqlite.dm"
@@ -1017,6 +1018,7 @@
#include "code\game\objects\items\devices\radio\jammer.dm"
#include "code\game\objects\items\devices\radio\radio.dm"
#include "code\game\objects\items\devices\radio\radiopack.dm"
#include "code\game\objects\items\robot\robot_frame.dm"
#include "code\game\objects\items\mines\_mine.dm"
#include "code\game\objects\items\mines\_mine_payload.dm"
#include "code\game\objects\items\mines\mine_assembly.dm"
@@ -2447,10 +2449,12 @@
#include "code\modules\mob\living\silicon\robot\drone\swarm.dm"
#include "code\modules\mob\living\silicon\robot\drone\swarm_abilities.dm"
#include "code\modules\mob\living\silicon\robot\drone\swarm_items.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules\_module.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules\event.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules\station.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules\swarm.dm"
#include "code\modules\mob\living\silicon\robot\robot_modules\syndicate.dm"
#include "code\modules\mob\living\silicon\robot\subtypes\flying.dm"
#include "code\modules\mob\living\silicon\robot\subtypes\gravekeeper.dm"
#include "code\modules\mob\living\silicon\robot\subtypes\lost_drone.dm"
#include "code\modules\mob\living\silicon\robot\subtypes\syndicate.dm"
@@ -2459,7 +2463,6 @@
#include "code\modules\mob\living\silicon\robot\subtypes\thinktank\thinktank_interactions.dm"
#include "code\modules\mob\living\silicon\robot\subtypes\thinktank\thinktank_module.dm"
#include "code\modules\mob\living\silicon\robot\subtypes\thinktank\thinktank_storage.dm"
#include "code\modules\mob\living\silicon\robot\subtypes\thinktank\thinktank_subtypes.dm"
#include "code\modules\mob\living\simple_mob\appearance.dm"
#include "code\modules\mob\living\simple_mob\butchering.dm"
#include "code\modules\mob\living\simple_mob\combat.dm"
@@ -3314,6 +3317,7 @@
#include "code\modules\xgm\xgm_gas_data.dm"
#include "code\modules\xgm\xgm_gas_mixture.dm"
#include "code\unit_tests\decl_tests.dm"
#include "code\unit_tests\icon_tests.dm"
#include "code\unit_tests\language_tests.dm"
#include "code\unit_tests\loadout_tests.dm"
#include "code\unit_tests\map_tests.dm"