diff --git a/code/__DEFINES/~doppler_defines/robot_defines.dm b/code/__DEFINES/~doppler_defines/robot_defines.dm new file mode 100644 index 0000000000000..be1d9e2ef758e --- /dev/null +++ b/code/__DEFINES/~doppler_defines/robot_defines.dm @@ -0,0 +1,35 @@ +/// Resting for borgs, especially if we ever get more than one type +#define ROBOT_REST_NORMAL 1 + +/// Features that a specific borg skin has +#define SKIN_FEATURES "skin_features" + +// Icon file locations for modular borg icons +/// Medical +#define CYBORG_ICON_MED_TALL 'modular_doppler/big_borg_lmao/icons/tallrobot_med.dmi' +/// Engineer +#define CYBORG_ICON_ENG_TALL 'modular_doppler/big_borg_lmao/icons/tallrobot_eng.dmi' +/// Peacekeeper +#define CYBORG_ICON_PEACEKEEPER_TALL 'modular_doppler/big_borg_lmao/icons/tallrobot_pk.dmi' +/// Service +#define CYBORG_ICON_SERVICE_TALL 'modular_doppler/big_borg_lmao/icons/tallrobot_serv.dmi' +/// Service +#define CYBORG_ICON_MINING_TALL 'modular_doppler/big_borg_lmao/icons/tallrobot_mine.dmi' +/// Janitor +#define CYBORG_ICON_JANI_TALL 'modular_doppler/big_borg_lmao/icons/tallrobot_jani.dmi' +/// Evil +#define CYBORG_ICON_SYNDIE_TALL 'modular_doppler/big_borg_lmao/icons/tallrobot_syndi.dmi' +/// Ninja (Evil) +#define CYBORG_ICON_NINJA_TALL 'modular_doppler/big_borg_lmao/icons/tallrobot_ninja.dmi' + +//Defines for model features, set in the model_features list of a robot model datum. Are they a dogborg? Is the model small? etc. +/// Cyborgs with unique sprites for when they get totally broken down. +#define TRAIT_R_UNIQUEWRECK "unique_wreck" +/// Or when tipped over. +#define TRAIT_R_UNIQUETIP "unique_tip" +/// 32x64 skins +#define TRAIT_R_TALL "tall_borg" +/// Any model small enough to reject the shrinker upgrade. +#define TRAIT_R_SMALL "small_chassis" +/// Any model that has a custom front panel +#define TRAIT_R_UNIQUEPANEL "unique_openpanel" diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm index 99faa8ff2e1fd..952d44a8e1767 100644 --- a/code/_globalvars/traits/_traits.dm +++ b/code/_globalvars/traits/_traits.dm @@ -586,7 +586,6 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_IGNORE_FIRE_PROTECTION" = TRAIT_IGNORE_FIRE_PROTECTION, "TRAIT_LEFT_EYE_SCAR" = TRAIT_LEFT_EYE_SCAR, "TRAIT_RIGHT_EYE_SCAR" = TRAIT_RIGHT_EYE_SCAR, - "TRAIT_SYSTEM_SHOCK" = TRAIT_SYSTEM_SHOCK, // DOPPLER EDIT ADDITION "TRAIT_BAD_VIBES" = TRAIT_BAD_VIBES, // DOPPLER EDIT ADDITION ), /obj/item = list( @@ -736,12 +735,11 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_TURF_IGNORE_SLIPPERY" = TRAIT_TURF_IGNORE_SLIPPERY, "TRAIT_TURF_IGNORE_SLOWDOWN" = TRAIT_TURF_IGNORE_SLOWDOWN, ), - // DOPPLER EDIT ADDITION START - MODULAR TRAITS - /obj/item/toy/plush/modular = list( + /obj/item/toy/plush/modular = list( // DOPPLER EDIT ADDITION START - MODULAR TRAITS "TRAIT_CURRENTLY_GLASSBLOWING" = TRAIT_CURRENTLY_GLASSBLOWING, "TRAIT_ANIMALISTIC" = TRAIT_ANIMALISTIC, "TRAIT_GLASSBLOWING" = TRAIT_GLASSBLOWING, - "TRAIT_OXYIMMUNE" = TRAIT_OXYIMMUNE, //Doppler Edit Addition - Needed for hemophages. + "TRAIT_OXYIMMUNE" = TRAIT_OXYIMMUNE, "TRAIT_XENOARCH_QUALIFIED" = TRAIT_XENOARCH_QUALIFIED, "TRAIT_DETECTIVE" = TRAIT_DETECTIVE, "TRAIT_EXCITABLE" = TRAIT_EXCITABLE, @@ -752,8 +750,13 @@ GLOBAL_LIST_INIT(traits_by_type, list( "TRAIT_CHARGING" = TRAIT_CHARGING, "TRAIT_LEFT_HANDED" = TRAIT_LEFT_HANDED, "TRAIT_SPEECH_ONLY_MUTE" = TRAIT_SPEECH_ONLY_MUTE, - ), - // DOPPLER EDIT ADDITION END + "TRAIT_R_UNIQUEWRECK" = TRAIT_R_UNIQUEWRECK, + "TRAIT_R_UNIQUETIP" = TRAIT_R_UNIQUETIP, + "TRAIT_R_TALL" = TRAIT_R_TALL, + "TRAIT_R_SMALL" = TRAIT_R_SMALL, + "TRAIT_R_UNIQUEPANEL" = TRAIT_R_UNIQUEPANEL, + "TRAIT_SYSTEM_SHOCK" = TRAIT_SYSTEM_SHOCK, + ), // DOPPLER EDIT ADDITION END )) /// value -> trait name, list of ALL traits that exist in the game, used for any type of accessing. diff --git a/code/_globalvars/traits/admin_tooling.dm b/code/_globalvars/traits/admin_tooling.dm index f61e96de0c82d..1b62e3c5a1892 100644 --- a/code/_globalvars/traits/admin_tooling.dm +++ b/code/_globalvars/traits/admin_tooling.dm @@ -333,7 +333,6 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_IGNORE_FIRE_PROTECTION" = TRAIT_IGNORE_FIRE_PROTECTION, "TRAIT_LEFT_EYE_SCAR" = TRAIT_LEFT_EYE_SCAR, "TRAIT_RIGHT_EYE_SCAR" = TRAIT_RIGHT_EYE_SCAR, - "TRAIT_SYSTEM_SHOCK" = TRAIT_SYSTEM_SHOCK, // DOPPLER EDIT ADDITION "TRAIT_BAD_VIBES" = TRAIT_BAD_VIBES, // DOPPLER EDIT ADDITION ), /obj/item = list( @@ -397,8 +396,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( /obj/item/organ/lungs = list( "TRAIT_SPACEBREATHING" = TRAIT_SPACEBREATHING, ), - // DOPPLER EDIT ADDITION START - MODULAR TRAITS - /obj/item/toy/plush/modular = list( + /obj/item/toy/plush/modular = list( // DOPPLER EDIT ADDITION START - MODULAR TRAITS "TRAIT_CURRENTLY_GLASSBLOWING" = TRAIT_CURRENTLY_GLASSBLOWING, "TRAIT_ANIMALISTIC" = TRAIT_ANIMALISTIC, "TRAIT_GLASSBLOWING" = TRAIT_GLASSBLOWING, @@ -411,8 +409,13 @@ GLOBAL_LIST_INIT(admin_visible_traits, list( "TRAIT_CHARGING" = TRAIT_CHARGING, "TRAIT_LEFT_HANDED" = TRAIT_LEFT_HANDED, "TRAIT_SPEECH_ONLY_MUTE" = TRAIT_SPEECH_ONLY_MUTE, - ), - // DOPPLER EDIT ADDITION END + "TRAIT_R_UNIQUEWRECK" = TRAIT_R_UNIQUEWRECK, + "TRAIT_R_UNIQUETIP" = TRAIT_R_UNIQUETIP, + "TRAIT_R_TALL" = TRAIT_R_TALL, + "TRAIT_R_SMALL" = TRAIT_R_SMALL, + "TRAIT_R_UNIQUEPANEL" = TRAIT_R_UNIQUEPANEL, + "TRAIT_SYSTEM_SHOCK" = TRAIT_SYSTEM_SHOCK, + ), // DOPPLER EDIT ADDITION END )) /// value -> trait name, generated as needed for adminning. diff --git a/code/modules/mob/living/silicon/robot/robot_model.dm b/code/modules/mob/living/silicon/robot/robot_model.dm index 60cf2f6d04654..aac73bcd6b4b4 100644 --- a/code/modules/mob/living/silicon/robot/robot_model.dm +++ b/code/modules/mob/living/silicon/robot/robot_model.dm @@ -245,6 +245,8 @@ cyborg.diag_hud_set_aishell() log_silicon("CYBORG: [key_name(cyborg)] has transformed into the [new_model] model.") + new_model.update_tallborg() // DOPPLER EDIT ADDITION - TALLBORGS + if(transform) INVOKE_ASYNC(new_model, PROC_REF(do_transform_animation)) qdel(src) @@ -268,6 +270,7 @@ cyborg_base_icon = details[SKIN_ICON_STATE] if(!isnull(details[SKIN_ICON])) cyborg.icon = details[SKIN_ICON] + cyborg_icon_override = details[SKIN_ICON] // DOPPLER EDIT ADDITION if(!isnull(details[SKIN_PIXEL_X])) cyborg.base_pixel_x = details[SKIN_PIXEL_X] if(!isnull(details[SKIN_PIXEL_Y])) @@ -278,6 +281,8 @@ hat_offset = details[SKIN_HAT_OFFSET] if(!isnull(details[SKIN_TRAITS])) model_traits += details[SKIN_TRAITS] + if(!isnull(details[SKIN_FEATURES])) // DOPPLER EDIT ADDITION + model_features += details[SKIN_FEATURES] // DOPPLER EDIT ADDITION for(var/i in old_model.added_modules) added_modules += i old_model.added_modules -= i diff --git a/modular_doppler/big_borg_lmao/code/robot.dm b/modular_doppler/big_borg_lmao/code/robot.dm new file mode 100644 index 0000000000000..d264237aa3bf4 --- /dev/null +++ b/modular_doppler/big_borg_lmao/code/robot.dm @@ -0,0 +1,94 @@ +/mob/living/silicon/robot/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change = TRUE) + . = ..() + if(robot_resting) + robot_resting = FALSE + on_standing_up() + update_icons() + +/mob/living/silicon/robot/toggle_resting() + robot_lay_down() + +/mob/living/silicon/robot/on_lying_down(new_lying_angle) + if(layer == initial(layer)) //to avoid things like hiding larvas. + layer = LYING_MOB_LAYER //so mob lying always appear behind standing mobs + density = FALSE // We lose density and stop bumping passable dense things. + if(model && model.model_features && (TRAIT_R_TALL in model.model_features)) + maptext_height = 32 //Offset base chat-height value + // Resting effects + var/turf/sit_pos = get_turf(src) + var/obj/structure/table/tabled = locate(/obj/structure/table) in sit_pos.contents + if(!tabled) + new /obj/effect/temp_visual/mook_dust/robot(get_turf(src)) + playsound(src, 'modular_doppler/big_borg_lmao/sounds/robot_sit.ogg', 25, TRUE) + return + else + new /obj/effect/temp_visual/mook_dust/robot/table(get_turf(src)) + playsound(src, 'modular_doppler/big_borg_lmao/sounds/robot_bump.ogg', 50, TRUE) + var/list/items_to_move = list() + for(var/obj/item/gen_item in sit_pos.contents) + if(!gen_item.anchored) + items_to_move += gen_item + if(items_to_move.len >= 8) + break + for(var/obj/item/table_contents in items_to_move) + table_contents.throw_at(get_ranged_target_turf(table_contents, pick(GLOB.cardinals), range = 1), range = 1, speed = 1) + +/mob/living/silicon/robot/on_standing_up() + if(layer == LYING_MOB_LAYER) + layer = initial(layer) + density = initial(density) // We were prone before, so we become dense and things can bump into us again. + if(model && model.model_features && (TRAIT_R_TALL in model.model_features)) + maptext_height = 48 //Offset value of tallborgs + +/mob/living/silicon/robot/proc/rest_style() + set name = "Switch Rest Style" + set category = "AI Commands" + set desc = "Select your resting pose." + if(!can_rest()) + to_chat(src, span_warning("You can't do that!")) + return + robot_resting = ROBOT_REST_NORMAL + on_lying_down() + update_icons() + +/mob/living/silicon/robot/proc/robot_lay_down() + set name = "Lay down" + set category = "AI Commands" + if(!can_rest()) + to_chat(src, span_warning("You can't do that!")) + return + if(stat != CONSCIOUS) //Make sure we don't enable movement when not concious + return + if(robot_resting) + to_chat(src, span_notice("You are now getting up.")) + robot_resting = FALSE + mobility_flags = MOBILITY_FLAGS_DEFAULT + on_standing_up() + else + to_chat(src, span_notice("You are now laying down.")) + robot_resting = robot_rest_style + on_lying_down() + update_icons() + +/mob/living/silicon/robot/update_resting() + . = ..() + if(can_rest()) + robot_resting = FALSE + update_icons() + +/mob/living/silicon/robot/update_module_innate() + ..() + if(hands) + hands.icon = (model.model_select_alternate_icon ? model.model_select_alternate_icon : initial(hands.icon)) + +/** + * Safe check of the cyborg's model_features list. + * + * model_features is defined in modular_nova\modules\altborgs\code\modules\mob\living\silicon\robot\robot_model.dm. + */ +/mob/living/silicon/robot/proc/can_rest() + if(model && model.model_features && (TRAIT_R_TALL in model.model_features)) + if(TRAIT_IMMOBILIZED in _status_traits) + return FALSE + return TRUE + return FALSE diff --git a/modular_doppler/big_borg_lmao/code/robot_defines.dm b/modular_doppler/big_borg_lmao/code/robot_defines.dm new file mode 100644 index 0000000000000..a157e6c2cae01 --- /dev/null +++ b/modular_doppler/big_borg_lmao/code/robot_defines.dm @@ -0,0 +1,3 @@ +/mob/living/silicon/robot + var/robot_resting = FALSE + var/robot_rest_style = ROBOT_REST_NORMAL diff --git a/modular_doppler/big_borg_lmao/code/robot_model.dm b/modular_doppler/big_borg_lmao/code/robot_model.dm new file mode 100644 index 0000000000000..e2328eaf48edc --- /dev/null +++ b/modular_doppler/big_borg_lmao/code/robot_model.dm @@ -0,0 +1,125 @@ +/obj/item/robot_model + var/icon/cyborg_icon_override + var/sleeper_overlay + var/cyborg_pixel_offset + /// Alternate icon file used for this module's collapsed UI icon + var/model_select_alternate_icon + /// Traits unique to this model, i.e. having a unique dead sprite, being wide or being small enough to reject shrinker modules. Leverages defines in code\__DEFINES\~nova_defines\robot_defines.dm + /// If a sprite overlaps above the standard height, ensure it is not overlapping icons in the selector wheel. + var/list/model_features = list() + +/obj/item/robot_model/proc/update_tallborg() + var/mob/living/silicon/robot/cyborg = robot || loc + if (!istype(robot)) + return + if (model_features && (TRAIT_R_TALL in model_features)) + cyborg.maptext_height = 48 //Runechat blabla + cyborg.AddElement(/datum/element/footstep, FOOTSTEP_MOB_SHOE, 2, -6, sound_vary = TRUE) + add_verb(cyborg, /mob/living/silicon/robot/proc/robot_lay_down) + switch(cyborg_base_icon) + if("mekamine") + cyborg.AddComponent(/datum/component/robot_smoke) + else + cyborg.maptext_height = initial(cyborg.maptext_height) + cyborg.RemoveElement(/datum/element/footstep, FOOTSTEP_MOB_SHOE, 2, -6, sound_vary = TRUE) + remove_verb(cyborg, /mob/living/silicon/robot/proc/robot_lay_down) + if(cyborg.GetComponent(/datum/component/robot_smoke)) + qdel(cyborg.GetComponent(/datum/component/robot_smoke)) + QDEL_NULL(cyborg.particles) // Removing left over particles + +// STANDARD +/obj/item/robot_model/standard + name = "Standard" + borg_skins = list( + "Default" = list(SKIN_ICON_STATE = "robot", SKIN_FEATURES = list(TRAIT_R_SMALL)), + ) + +// SERVICE +/obj/item/robot_model/service + special_light_key = null + borg_skins = list( + /// 32x32 Skins + "Waitress" = list(SKIN_ICON_STATE = "service_f", SKIN_LIGHT_KEY = "service"), + "Butler" = list(SKIN_ICON_STATE = "service_m", SKIN_LIGHT_KEY = "service"), + "Bro" = list(SKIN_ICON_STATE = "brobot", SKIN_LIGHT_KEY = "service"), + "Tophat" = list(SKIN_ICON_STATE = "tophat", SKIN_HAT_OFFSET = INFINITY), + "Kent" = list(SKIN_ICON_STATE = "kent", SKIN_LIGHT_KEY = "medical", SKIN_HAT_OFFSET = 3), + "Can" = list(SKIN_ICON_STATE = "kent", SKIN_LIGHT_KEY = "medical", SKIN_HAT_OFFSET = 3), + /// 32x64 skins + "Meka" = list(SKIN_ICON_STATE = "mekaserve", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "Meka (Alt)" = list(SKIN_ICON_STATE = "mekaserve_alt", SKIN_LIGHT_KEY = "mekaserve", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKA" = list(SKIN_ICON_STATE = "fmekaserv", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKO" = list(SKIN_ICON_STATE = "mmekaserv", SKIN_ICON = CYBORG_ICON_SERVICE_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + ) + +// MINING +/obj/item/robot_model/miner + special_light_key = null + borg_skins = list( + /// 32x32 Skins + "Lavaland" = list(SKIN_ICON_STATE = "miner", SKIN_LIGHT_KEY = "miner"), + "Asteroid" = list(SKIN_ICON_STATE = "minerOLD", SKIN_LIGHT_KEY = "miner"), + "Spider Miner" = list(SKIN_ICON_STATE = "spidermin", SKIN_LIGHT_KEY = "miner"), + /// 32x64 skins + "Meka" = list(SKIN_ICON_STATE = "mekamine", SKIN_ICON = CYBORG_ICON_MINING_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKA" = list(SKIN_ICON_STATE = "fmekamine", SKIN_ICON = CYBORG_ICON_MINING_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKO" = list(SKIN_ICON_STATE = "mmekamine", SKIN_ICON = CYBORG_ICON_MINING_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15) + ) + +// CLOWN +/obj/item/robot_model/clown + borg_skins = list( + "Default" = list(SKIN_ICON_STATE = "clown"), + ) + +// ENGINEERING +/obj/item/robot_model/engineering + borg_skins = list( + /// 32x32 Skins + "Default" = list(SKIN_ICON_STATE = "engineer", SKIN_FEATURES = list(TRAIT_R_SMALL)), + /// 32x64 Skins + "Meka" = list(SKIN_ICON_STATE = "mekaengi", SKIN_ICON = CYBORG_ICON_ENG_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKA" = list(SKIN_ICON_STATE = "fmekaeng", SKIN_ICON = CYBORG_ICON_ENG_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKO" = list(SKIN_ICON_STATE = "mmekaeng", SKIN_ICON = CYBORG_ICON_ENG_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15) + ) + +// JANITOR +/obj/item/robot_model/janitor + borg_skins = list( + /// 32x32 Skins + "Default" = list(SKIN_ICON_STATE = "janitor"), + /// 32x64 Skins + "Meka" = list(SKIN_ICON_STATE = "mekajani", SKIN_ICON = CYBORG_ICON_JANI_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKA" = list(SKIN_ICON_STATE = "fmekajani", SKIN_ICON = CYBORG_ICON_JANI_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKO" = list(SKIN_ICON_STATE = "mmekajani", SKIN_ICON = CYBORG_ICON_JANI_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15) + ) + +// MEDICAL +/obj/item/robot_model/medical + borg_skins = list( + /// 32x32 Skins + "Machinified Doctor" = list(SKIN_ICON_STATE = "medical", SKIN_TRAITS = list(TRAIT_R_SMALL)), + "Qualified Doctor" = list(SKIN_ICON_STATE = "qualified_doctor"), + /// 32x64 Skins + "Meka" = list(SKIN_ICON_STATE = "mekamed", SKIN_ICON = CYBORG_ICON_MED_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKA" = list(SKIN_ICON_STATE = "fmekamed", SKIN_ICON = CYBORG_ICON_MED_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKO" = list(SKIN_ICON_STATE = "mmekamed", SKIN_ICON = CYBORG_ICON_MED_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15) + ) + +// PEACEKEEPER +/obj/item/robot_model/peacekeeper + borg_skins = list( + /// 32x32 Skins + "Default" = list(SKIN_ICON_STATE = "peace"), + /// 32x64 Skins + "Meka" = list(SKIN_ICON_STATE = "mekapeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKA" = list(SKIN_ICON_STATE = "fmekapeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15), + "NiKO" = list(SKIN_ICON_STATE = "mmekapeace", SKIN_ICON = CYBORG_ICON_PEACEKEEPER_TALL, SKIN_FEATURES = list(TRAIT_R_UNIQUEWRECK, TRAIT_R_UNIQUETIP, TRAIT_R_TALL), SKIN_HAT_OFFSET = 15) + ) + +// SECURITY +/obj/item/robot_model/security + borg_skins = list( + /// 32x32 Skins + "Default" = list(SKIN_ICON_STATE = "sec"), + ) diff --git a/modular_doppler/big_borg_lmao/code/robot_other.dm b/modular_doppler/big_borg_lmao/code/robot_other.dm new file mode 100644 index 0000000000000..030e157e5d431 --- /dev/null +++ b/modular_doppler/big_borg_lmao/code/robot_other.dm @@ -0,0 +1,95 @@ +// Smoke particle effect for heavy-duty cyborgs +/datum/component/robot_smoke + +/datum/component/robot_smoke/RegisterWithParent() + add_verb(parent, /mob/living/silicon/robot/proc/toggle_smoke) + RegisterSignal(parent, COMSIG_ATOM_DIR_CHANGE, PROC_REF(dir_change)) + +/datum/component/robot_smoke/UnregisterFromParent() + remove_verb(parent, /mob/living/silicon/robot/proc/toggle_smoke) + UnregisterSignal(parent, COMSIG_ATOM_DIR_CHANGE) + +/datum/component/robot_smoke/Destroy() + return ..() + +/datum/component/robot_smoke/proc/dir_change(datum/source, olddir, newdir) + SIGNAL_HANDLER + + var/atom/movable/movable_parent = parent + + if(!movable_parent.particles) + return + + var/truedir = movable_parent.dir + if(newdir && (truedir != newdir)) + truedir = newdir + + switch(truedir) + if(NORTH) + movable_parent.particles.position = list(-6, 12, 0) + movable_parent.particles.drift = generator("vector", list(0, 0.4), list(0.2, -0.2)) + if(EAST) + movable_parent.particles.position = list(-6, 12, 0) + movable_parent.particles.drift = generator("vector", list(0, 0.4), list(-0.8, 0.2)) + if(SOUTH) + movable_parent.particles.position = list(5, 12, 0) + movable_parent.particles.drift = generator("vector", list(0, 0.4), list(0.2, -0.2)) + if(WEST) + movable_parent.particles.position = list(6, 12, 0) + movable_parent.particles.drift = generator("vector", list(0, 0.4), list(0.8, -0.2)) + + +/mob/living/silicon/robot/proc/toggle_smoke() + set name = "Toggle smoke" + set category = "AI Commands" + + if(particles) + dissipate() + else if (!stat && !robot_resting) + do_jitter_animation(10) + playsound(src, 'modular_doppler/big_borg_lmao/sounds/robot_smoke.ogg', 50) + particles = new /particles/smoke/robot() + +/mob/living/silicon/robot/proc/dissipate() + particles.spawning = 0 + addtimer(CALLBACK(src, PROC_REF(particles_qdel)), 1.5 SECONDS) + +/mob/living/silicon/robot/proc/particles_qdel() + QDEL_NULL(particles) + +/mob/living/silicon/robot/death() + . = ..() + if(GetComponent(/datum/component/robot_smoke)) + dissipate() + +/mob/living/silicon/robot/robot_lay_down() + . = ..() + + if(GetComponent(/datum/component/robot_smoke)) + if(robot_resting) + dissipate() + else + return + +// The smoke +/particles/smoke/robot + spawning = 0.4 + lifespan = 1 SECONDS + fade = 0.75 SECONDS + position = list(5, 12, 0) + velocity = list(0, 0.2, 0) + friction = 0.35 + scale = 0.5 + grow = 0.1 + spin = generator("num", -20, 20) + +// Another smoke effect +/obj/effect/temp_visual/mook_dust/robot + icon = 'modular_doppler/big_borg_lmao/icons/misc/tallrobot_effects.dmi' + icon_state = "impact_cloud" + color = "#a9a9a93c" + +/obj/effect/temp_visual/mook_dust/robot/table + color = "#ffffffc2" + pixel_y = -8 + layer = ABOVE_MOB_LAYER diff --git a/modular_doppler/big_borg_lmao/code/update_icons.dm b/modular_doppler/big_borg_lmao/code/update_icons.dm new file mode 100644 index 0000000000000..4f2ef47a947b6 --- /dev/null +++ b/modular_doppler/big_borg_lmao/code/update_icons.dm @@ -0,0 +1,36 @@ +/mob/living/silicon/robot/update_icons() + icon = (model.cyborg_icon_override ? model.cyborg_icon_override : initial(icon)) + . = ..() + /// Let's give custom borgs the ability to have flavor panels for their model + if(opened && (TRAIT_R_UNIQUEPANEL in model.model_features)) + if(wiresexposed) + add_overlay("[model.cyborg_base_icon]_w") + else if(cell) + add_overlay("[model.cyborg_base_icon]_c") + else + add_overlay("[model.cyborg_base_icon]_cl") + update_altborg_icons() + +/mob/living/silicon/robot/proc/update_altborg_icons() + if(robot_resting) + if(stat != DEAD && can_rest()) + switch(robot_resting) + if(ROBOT_REST_NORMAL) + icon_state = "[model.cyborg_base_icon]-rest" + else + icon_state = "[model.cyborg_base_icon]" + cut_overlays() + if(hat) // Don't forget your hat + var/mutable_appearance/head_overlay = hat.build_worn_icon(default_layer = 20) + head_overlay.pixel_y += (hat_offset - 14) + add_overlay(head_overlay) + else + icon_state = "[model.cyborg_base_icon]" + if((TRAIT_R_UNIQUETIP in model.model_features) && (TRAIT_IMMOBILIZED in _status_traits)) + icon_state = "[model.cyborg_base_icon]-tipped" + if(particles) + dissipate() + cut_overlays() + if(stat == DEAD && (TRAIT_R_UNIQUEWRECK in model.model_features)) + icon_state = "[model.cyborg_base_icon]-wreck" + update_appearance(UPDATE_OVERLAYS) diff --git a/modular_doppler/big_borg_lmao/icons/misc/tallrobot_effects.dmi b/modular_doppler/big_borg_lmao/icons/misc/tallrobot_effects.dmi new file mode 100644 index 0000000000000..6ec12511aa23e Binary files /dev/null and b/modular_doppler/big_borg_lmao/icons/misc/tallrobot_effects.dmi differ diff --git a/modular_doppler/big_borg_lmao/icons/tallrobot_eng.dmi b/modular_doppler/big_borg_lmao/icons/tallrobot_eng.dmi new file mode 100644 index 0000000000000..53e1febae013c Binary files /dev/null and b/modular_doppler/big_borg_lmao/icons/tallrobot_eng.dmi differ diff --git a/modular_doppler/big_borg_lmao/icons/tallrobot_jani.dmi b/modular_doppler/big_borg_lmao/icons/tallrobot_jani.dmi new file mode 100644 index 0000000000000..12918301fe02c Binary files /dev/null and b/modular_doppler/big_borg_lmao/icons/tallrobot_jani.dmi differ diff --git a/modular_doppler/big_borg_lmao/icons/tallrobot_med.dmi b/modular_doppler/big_borg_lmao/icons/tallrobot_med.dmi new file mode 100644 index 0000000000000..836778b84255e Binary files /dev/null and b/modular_doppler/big_borg_lmao/icons/tallrobot_med.dmi differ diff --git a/modular_doppler/big_borg_lmao/icons/tallrobot_mine.dmi b/modular_doppler/big_borg_lmao/icons/tallrobot_mine.dmi new file mode 100644 index 0000000000000..b6a6093c4a5dd Binary files /dev/null and b/modular_doppler/big_borg_lmao/icons/tallrobot_mine.dmi differ diff --git a/modular_doppler/big_borg_lmao/icons/tallrobot_ninja.dmi b/modular_doppler/big_borg_lmao/icons/tallrobot_ninja.dmi new file mode 100644 index 0000000000000..a7bd1f72fcb56 Binary files /dev/null and b/modular_doppler/big_borg_lmao/icons/tallrobot_ninja.dmi differ diff --git a/modular_doppler/big_borg_lmao/icons/tallrobot_pk.dmi b/modular_doppler/big_borg_lmao/icons/tallrobot_pk.dmi new file mode 100644 index 0000000000000..8a92d7c2eb75d Binary files /dev/null and b/modular_doppler/big_borg_lmao/icons/tallrobot_pk.dmi differ diff --git a/modular_doppler/big_borg_lmao/icons/tallrobot_serv.dmi b/modular_doppler/big_borg_lmao/icons/tallrobot_serv.dmi new file mode 100644 index 0000000000000..7036ffe68c5e9 Binary files /dev/null and b/modular_doppler/big_borg_lmao/icons/tallrobot_serv.dmi differ diff --git a/modular_doppler/big_borg_lmao/icons/tallrobot_syndi.dmi b/modular_doppler/big_borg_lmao/icons/tallrobot_syndi.dmi new file mode 100644 index 0000000000000..9fa9fb2250edc Binary files /dev/null and b/modular_doppler/big_borg_lmao/icons/tallrobot_syndi.dmi differ diff --git a/modular_doppler/big_borg_lmao/sounds/robot_bump.ogg b/modular_doppler/big_borg_lmao/sounds/robot_bump.ogg new file mode 100644 index 0000000000000..5a627246de0f6 Binary files /dev/null and b/modular_doppler/big_borg_lmao/sounds/robot_bump.ogg differ diff --git a/modular_doppler/big_borg_lmao/sounds/robot_sit.ogg b/modular_doppler/big_borg_lmao/sounds/robot_sit.ogg new file mode 100644 index 0000000000000..769d2d43b0b7f Binary files /dev/null and b/modular_doppler/big_borg_lmao/sounds/robot_sit.ogg differ diff --git a/modular_doppler/big_borg_lmao/sounds/robot_smoke.ogg b/modular_doppler/big_borg_lmao/sounds/robot_smoke.ogg new file mode 100644 index 0000000000000..bc51d5aa04676 Binary files /dev/null and b/modular_doppler/big_borg_lmao/sounds/robot_smoke.ogg differ diff --git a/tgstation.dme b/tgstation.dme index 9fb5ba4b91a1d..a6670aafba7e4 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -433,6 +433,7 @@ #include "code\__DEFINES\~doppler_defines\reagent_forging_tools.dm" #include "code\__DEFINES\~doppler_defines\reagents.dm" #include "code\__DEFINES\~doppler_defines\reskin_defines.dm" +#include "code\__DEFINES\~doppler_defines\robot_defines.dm" #include "code\__DEFINES\~doppler_defines\say.dm" #include "code\__DEFINES\~doppler_defines\signals.dm" #include "code\__DEFINES\~doppler_defines\sound.dm" @@ -6581,6 +6582,11 @@ #include "modular_doppler\autotransfer\autotransfer_config.dm" #include "modular_doppler\autotransfer\shuttle.dm" #include "modular_doppler\autotransfer\transfer_vote.dm" +#include "modular_doppler\big_borg_lmao\code\robot.dm" +#include "modular_doppler\big_borg_lmao\code\robot_defines.dm" +#include "modular_doppler\big_borg_lmao\code\robot_model.dm" +#include "modular_doppler\big_borg_lmao\code\robot_other.dm" +#include "modular_doppler\big_borg_lmao\code\update_icons.dm" #include "modular_doppler\bitrunning_prefs_disks\code\disks\prefs_disk.dm" #include "modular_doppler\bitrunning_prefs_disks\code\outfit_overrides\bitrunner_outfit_override.dm" #include "modular_doppler\cell_component\code\cell_component.dm"