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-08-01 16:22:12 +10:00
committed by GitHub
parent 0941bbacae
commit 658e19e734
75 changed files with 2004 additions and 1621 deletions
+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