diff --git a/code/modules/mob/language/language.dm b/code/modules/mob/language/language.dm index 6b2f4b688bd1..4f1c9d1b205a 100644 --- a/code/modules/mob/language/language.dm +++ b/code/modules/mob/language/language.dm @@ -5,7 +5,6 @@ */ /* Current unused keys, please update when you use one. - * e * n * r * t diff --git a/maps/modpack_testing/modpack_testing.dm b/maps/modpack_testing/modpack_testing.dm index 068804e94192..9e9f452aa1ce 100644 --- a/maps/modpack_testing/modpack_testing.dm +++ b/maps/modpack_testing/modpack_testing.dm @@ -51,6 +51,7 @@ #include "../../mods/species/ascent/_ascent.dme" #include "../../mods/species/drakes/_drakes.dme" #include "../../mods/species/neoavians/_neoavians.dme" + #include "../../mods/species/octopus/_octopus.dme" #include "../../mods/species/random_species/_random_species.dme" #include "../../mods/species/serpentid/_serpentid.dme" #include "../../mods/species/skrell/_skrell.dme" diff --git a/maps/tradeship/tradeship.dm b/maps/tradeship/tradeship.dm index acaaf113f919..87eccd3a488b 100644 --- a/maps/tradeship/tradeship.dm +++ b/maps/tradeship/tradeship.dm @@ -56,6 +56,7 @@ #include "../../mods/species/serpentid/_serpentid.dme" #include "../../mods/species/utility_frames/_utility_frames.dme" #include "../../mods/species/vox/_vox.dme" + #include "../../mods/species/octopus/_octopus.dme" #include "../away/bearcat/bearcat.dm" #include "../away/casino/casino.dm" diff --git a/mods/species/octopus/_octopus.dm b/mods/species/octopus/_octopus.dm new file mode 100644 index 000000000000..82127f46df84 --- /dev/null +++ b/mods/species/octopus/_octopus.dm @@ -0,0 +1,13 @@ +#define BODYTYPE_OCTOPODE "octopode" + +#define BP_TENTACLE_1 "tentacle_1" +#define BP_TENTACLE_2 "tentacle_2" +#define BP_TENTACLE_3 "tentacle_3" +#define BP_TENTACLE_4 "tentacle_4" +#define BP_TENTACLE_5 "tentacle_5" +#define BP_TENTACLE_6 "tentacle_6" +#define BP_TENTACLE_7 "tentacle_7" +#define BP_TENTACLE_8 "tentacle_8" + +/decl/modpack/octopus + name = "Octopus Species" diff --git a/mods/species/octopus/_octopus.dme b/mods/species/octopus/_octopus.dme new file mode 100644 index 000000000000..2550e8226e45 --- /dev/null +++ b/mods/species/octopus/_octopus.dme @@ -0,0 +1,11 @@ +#ifndef MODPACK_OCTOPUS +#define MODPACK_OCTOPUS +// BEGIN_INCLUDE +#include "_octopus.dm" +#include "bodytype.dm" +#include "gripper.dm" +#include "language.dm" +#include "organs.dm" +#include "species.dm" +// END_INCLUDE +#endif \ No newline at end of file diff --git a/mods/species/octopus/bodytype.dm b/mods/species/octopus/bodytype.dm new file mode 100644 index 000000000000..270ae2829707 --- /dev/null +++ b/mods/species/octopus/bodytype.dm @@ -0,0 +1,94 @@ +/datum/appearance_descriptor/age/octopus + chargen_min_index = 3 + chargen_max_index = 5 + standalone_value_descriptors = list( + "freshly hatched" = 1, + "a larva" = 2, + "a juvenile" = 5, + "a young adult" = 10, + "an adult" = 15, + "approaching old age" = 30, + "senescent" = 40 + ) + +/decl/bodytype/octopus + name = "octopode" + uid = "bodytype_octopus" + eye_icon = 'mods/species/octopus/icons/eyes.dmi' + age_descriptor = /datum/appearance_descriptor/age/octopus + movement_slowdown = 2 + pixel_offset_x = -8 + + bodytype_category = BODYTYPE_OCTOPODE + icon_base = 'mods/species/octopus/icons/body.dmi' + icon_deformed = 'mods/species/octopus/icons/body.dmi' + icon_template = 'mods/species/octopus/icons/template.dmi' + damage_overlays = 'mods/species/octopus/icons/dam_octopus.dmi' + blood_overlays = 'mods/species/octopus/icons/blood_octopus.dmi' + + body_flags = BODY_FLAG_NO_DNA + appearance_flags = HAS_SKIN_COLOR | HAS_EYE_COLOR + has_organ = list( + (BP_HEART) = /obj/item/organ/internal/heart/octopus, + (BP_LUNGS) = /obj/item/organ/internal/lungs/gills/octopus, + (BP_LIVER) = /obj/item/organ/internal/liver, + (BP_KIDNEYS) = /obj/item/organ/internal/kidneys, + (BP_BRAIN) = /obj/item/organ/internal/brain, + (BP_EYES) = /obj/item/organ/internal/eyes, + ) + + has_limbs = list( + (BP_CHEST) = list("path" = /obj/item/organ/external/chest/unbreakable/octopus), + (BP_GROIN) = list("path" = /obj/item/organ/external/groin/unbreakable/octopus), + (BP_HEAD) = list("path" = /obj/item/organ/external/head/unbreakable/octopus), + (BP_TENTACLE_1) = list("path" = /obj/item/organ/external/octopus_limb/first), + (BP_TENTACLE_2) = list("path" = /obj/item/organ/external/octopus_limb/second), + (BP_TENTACLE_3) = list("path" = /obj/item/organ/external/octopus_limb/third), + (BP_TENTACLE_4) = list("path" = /obj/item/organ/external/octopus_limb/fourth), + (BP_TENTACLE_5) = list("path" = /obj/item/organ/external/octopus_limb/fifth), + (BP_TENTACLE_6) = list("path" = /obj/item/organ/external/octopus_limb/sixth), + (BP_TENTACLE_7) = list("path" = /obj/item/organ/external/octopus_limb/seventh), + (BP_TENTACLE_8) = list("path" = /obj/item/organ/external/octopus_limb/eighth) + ) + limb_mapping = list( + (BP_L_LEG) = list((BP_TENTACLE_1), (BP_TENTACLE_2), (BP_TENTACLE_3), (BP_TENTACLE_4), (BP_TENTACLE_5), (BP_TENTACLE_6), (BP_TENTACLE_7), (BP_TENTACLE_8)), + (BP_R_LEG) = list((BP_TENTACLE_1), (BP_TENTACLE_2), (BP_TENTACLE_3), (BP_TENTACLE_4), (BP_TENTACLE_5), (BP_TENTACLE_6), (BP_TENTACLE_7), (BP_TENTACLE_8)), + (BP_L_FOOT) = list((BP_TENTACLE_1), (BP_TENTACLE_2), (BP_TENTACLE_3), (BP_TENTACLE_4), (BP_TENTACLE_5), (BP_TENTACLE_6), (BP_TENTACLE_7), (BP_TENTACLE_8)), + (BP_R_FOOT) = list((BP_TENTACLE_1), (BP_TENTACLE_2), (BP_TENTACLE_3), (BP_TENTACLE_4), (BP_TENTACLE_5), (BP_TENTACLE_6), (BP_TENTACLE_7), (BP_TENTACLE_8)), + (BP_L_ARM) = list((BP_TENTACLE_1), (BP_TENTACLE_2), (BP_TENTACLE_3), (BP_TENTACLE_4), (BP_TENTACLE_5), (BP_TENTACLE_6), (BP_TENTACLE_7), (BP_TENTACLE_8)), + (BP_R_ARM) = list((BP_TENTACLE_1), (BP_TENTACLE_2), (BP_TENTACLE_3), (BP_TENTACLE_4), (BP_TENTACLE_5), (BP_TENTACLE_6), (BP_TENTACLE_7), (BP_TENTACLE_8)), + (BP_L_HAND) = list((BP_TENTACLE_1), (BP_TENTACLE_2), (BP_TENTACLE_3), (BP_TENTACLE_4), (BP_TENTACLE_5), (BP_TENTACLE_6), (BP_TENTACLE_7), (BP_TENTACLE_8)), + (BP_R_HAND) = list((BP_TENTACLE_1), (BP_TENTACLE_2), (BP_TENTACLE_3), (BP_TENTACLE_4), (BP_TENTACLE_5), (BP_TENTACLE_6), (BP_TENTACLE_7), (BP_TENTACLE_8)) + ) + +/decl/bodytype/octopus/get_movement_slowdown(var/mob/living/human/H) + return H?.loc?.get_fluid_depth() >= FLUID_SHALLOW ? -1 : ..() + +/decl/bodytype/octopus/Initialize() + _equip_adjust = list( + (slot_head_str) = list( + "[NORTH]" = list( 8, -4), + "[EAST]" = list(-2, -4), + "[SOUTH]" = list( 8, -4), + "[WEST]" = list(18, -4) + ), + (slot_back_str) = list( + "[NORTH]" = list( 8, -8), + "[EAST]" = list( 6, -8), + "[SOUTH]" = list( 8, -8), + "[WEST]" = list(12, -8) + ), + (BP_L_HAND) = list( + "[NORTH]" = list( 8, -4), + "[EAST]" = list( 8, -4), + "[SOUTH]" = list( 8, -4), + "[WEST]" = list( 8, -4) + ), + (BP_R_HAND) = list( + "[NORTH]" = list( 8, -4), + "[EAST]" = list( 8, -4), + "[SOUTH]" = list( 8, -4), + "[WEST]" = list( 8, -4) + ) + ) + . = ..() diff --git a/mods/species/octopus/gripper.dm b/mods/species/octopus/gripper.dm new file mode 100644 index 000000000000..f19eeabfe267 --- /dev/null +++ b/mods/species/octopus/gripper.dm @@ -0,0 +1,52 @@ +/datum/inventory_slot/gripper/tentacle + abstract_type = /datum/inventory_slot/gripper/tentacle + ui_label = null + covering_slot_flags = SLOT_HAND_LEFT|SLOT_HAND_RIGHT + +/datum/inventory_slot/gripper/tentacle/first + slot_name = "First Tentacle" + slot_id = BP_TENTACLE_1 + requires_organ_tag = BP_TENTACLE_1 + overlay_slot = BP_L_HAND + +/datum/inventory_slot/gripper/tentacle/second + slot_name = "Second Tentacle" + slot_id = BP_TENTACLE_2 + requires_organ_tag = BP_TENTACLE_2 + overlay_slot = BP_R_HAND + +/datum/inventory_slot/gripper/tentacle/third + slot_name = "Third Tentacle" + slot_id = BP_TENTACLE_3 + requires_organ_tag = BP_TENTACLE_3 + overlay_slot = BP_L_HAND + +/datum/inventory_slot/gripper/tentacle/fourth + slot_name = "Fourth Tentacle" + slot_id = BP_TENTACLE_4 + requires_organ_tag = BP_TENTACLE_4 + overlay_slot = BP_R_HAND + +/datum/inventory_slot/gripper/tentacle/fifth + slot_name = "Fifth Tentacle" + slot_id = BP_TENTACLE_5 + requires_organ_tag = BP_TENTACLE_5 + overlay_slot = BP_L_HAND + +/datum/inventory_slot/gripper/tentacle/sixth + slot_name = "Sixth Tentacle" + slot_id = BP_TENTACLE_6 + requires_organ_tag = BP_TENTACLE_6 + overlay_slot = BP_R_HAND + +/datum/inventory_slot/gripper/tentacle/seventh + slot_name = "Seventh Tentacle" + slot_id = BP_TENTACLE_7 + requires_organ_tag = BP_TENTACLE_7 + overlay_slot = BP_L_HAND + +/datum/inventory_slot/gripper/tentacle/eighth + slot_name = "Eighth Tentacle" + slot_id = BP_TENTACLE_8 + requires_organ_tag = BP_TENTACLE_8 + overlay_slot = BP_R_HAND diff --git a/mods/species/octopus/icons/blood_octopus.dmi b/mods/species/octopus/icons/blood_octopus.dmi new file mode 100644 index 000000000000..47879b76ec05 Binary files /dev/null and b/mods/species/octopus/icons/blood_octopus.dmi differ diff --git a/mods/species/octopus/icons/body.dmi b/mods/species/octopus/icons/body.dmi new file mode 100644 index 000000000000..f2f0ca980a79 Binary files /dev/null and b/mods/species/octopus/icons/body.dmi differ diff --git a/mods/species/octopus/icons/dam_octopus.dmi b/mods/species/octopus/icons/dam_octopus.dmi new file mode 100644 index 000000000000..1403a4da5d8f Binary files /dev/null and b/mods/species/octopus/icons/dam_octopus.dmi differ diff --git a/mods/species/octopus/icons/eyes.dmi b/mods/species/octopus/icons/eyes.dmi new file mode 100644 index 000000000000..4e0e7696ef8c Binary files /dev/null and b/mods/species/octopus/icons/eyes.dmi differ diff --git a/mods/species/octopus/icons/preview.dmi b/mods/species/octopus/icons/preview.dmi new file mode 100644 index 000000000000..10ce1a084c0d Binary files /dev/null and b/mods/species/octopus/icons/preview.dmi differ diff --git a/mods/species/octopus/icons/template.dmi b/mods/species/octopus/icons/template.dmi new file mode 100644 index 000000000000..98218916f7c0 Binary files /dev/null and b/mods/species/octopus/icons/template.dmi differ diff --git a/mods/species/octopus/language.dm b/mods/species/octopus/language.dm new file mode 100644 index 000000000000..0501d8105b49 --- /dev/null +++ b/mods/species/octopus/language.dm @@ -0,0 +1,24 @@ +/decl/language/cephlapoda + name = "Cephlapoda" + shorthand = "CE" + desc = "A melodic and complex language spoken by octopode uplifts. Some of the notes are inaudible to humans." + speech_verb = "warbles" + ask_verb = "warbles" + exclaim_verb = "warbles" + colour = "alien" + key = "e" + flags = LANG_FLAG_WHITELISTED + syllables = list("qr","qrr","xuq","qil","quum","xuqm","vol","xrim","zaoo","qu-uu","qix","qoo","zix","*","!") + speech_sounds = list( + 'mods/species/octopus/sound/warble1.ogg', + 'mods/species/octopus/sound/warble2.ogg', + 'mods/species/octopus/sound/warble3.ogg', + 'mods/species/octopus/sound/warble4.ogg', + 'mods/species/octopus/sound/warble5.ogg', + 'mods/species/octopus/sound/warble6.ogg', + 'mods/species/octopus/sound/warble7.ogg', + 'mods/species/octopus/sound/warble8.ogg', + 'mods/species/octopus/sound/warble9.ogg', + 'mods/species/octopus/sound/warble10.ogg', + 'mods/species/octopus/sound/warble11.ogg' + ) diff --git a/mods/species/octopus/organs.dm b/mods/species/octopus/organs.dm new file mode 100644 index 000000000000..5d89d1a51ff9 --- /dev/null +++ b/mods/species/octopus/organs.dm @@ -0,0 +1,98 @@ +/decl/natural_attack/punch/tentacle + attack_verb = list("smacked", "slapped", "swiped") + attack_noun = list("tentacle") + eye_attack_text = "tentacle" + eye_attack_text_victim = "tentacle" + +/obj/item/organ/internal/heart/octopus + name = "hearts" + gender = PLURAL + +/obj/item/organ/internal/lungs/gills/octopus + name = "funnel" + gender = NEUTER + +/obj/item/organ/external/groin/unbreakable/octopus + organ_categories = @"['" + ORGAN_CATEGORY_STANCE_ROOT + "']" + encased = null + +/obj/item/organ/external/head/unbreakable/octopus + joint = "spine" + amputation_point = "neck" + encased = null + +/obj/item/organ/external/chest/unbreakable/octopus + encased = null + +/obj/item/organ/external/octopus_limb + abstract_type = /obj/item/organ/external/octopus_limb + joint = "base" + amputation_point = "base" + limb_flags = ORGAN_FLAG_CAN_AMPUTATE | ORGAN_FLAG_FINGERPRINT | ORGAN_FLAG_HAS_TENDON | ORGAN_FLAG_CAN_STAND + parent_organ = BP_GROIN + organ_categories = @"['" + ORGAN_CATEGORY_STANCE + "', '" + ORGAN_CATEGORY_MANIPLE + "']" + var/gripper_type + +/obj/item/organ/external/octopus_limb/do_install(mob/living/human/target, affected, in_place, update_icon, detached) + . = ..() + if(. && owner && gripper_type) + owner.add_held_item_slot(new gripper_type) + +/obj/item/organ/external/octopus_limb/do_uninstall(in_place, detach, ignore_children, update_icon) + if(gripper_type) + owner?.remove_held_item_slot(organ_tag) + . = ..() + +/obj/item/organ/external/octopus_limb/get_natural_attacks() + var/static/list/natural_attacks = list( + /decl/natural_attack/punch/tentacle + ) + return natural_attacks + +/obj/item/organ/external/octopus_limb/first + name = "first tentacle" + gripper_type = /datum/inventory_slot/gripper/tentacle/first + organ_tag = BP_TENTACLE_1 + icon_position = LEFT + +/obj/item/organ/external/octopus_limb/second + name = "second tentacle" + gripper_type = /datum/inventory_slot/gripper/tentacle/second + organ_tag = BP_TENTACLE_2 + icon_position = RIGHT + +/obj/item/organ/external/octopus_limb/third + name = "third tentacle" + gripper_type = /datum/inventory_slot/gripper/tentacle/third + organ_tag = BP_TENTACLE_3 + icon_position = LEFT + +/obj/item/organ/external/octopus_limb/fourth + name = "fourth tentacle" + gripper_type = /datum/inventory_slot/gripper/tentacle/fourth + organ_tag = BP_TENTACLE_4 + icon_position = RIGHT + +/obj/item/organ/external/octopus_limb/fifth + name = "fifth tentacle" + gripper_type = /datum/inventory_slot/gripper/tentacle/fifth + organ_tag = BP_TENTACLE_5 + icon_position = LEFT + +/obj/item/organ/external/octopus_limb/sixth + name = "sixth tentacle" + gripper_type = /datum/inventory_slot/gripper/tentacle/sixth + organ_tag = BP_TENTACLE_6 + icon_position = RIGHT + +/obj/item/organ/external/octopus_limb/seventh + name = "seventh tentacle" + gripper_type = /datum/inventory_slot/gripper/tentacle/seventh + organ_tag = BP_TENTACLE_7 + icon_position = LEFT + +/obj/item/organ/external/octopus_limb/eighth + name = "eighth tentacle" + gripper_type = /datum/inventory_slot/gripper/tentacle/eighth + organ_tag = BP_TENTACLE_8 + icon_position = RIGHT diff --git a/mods/species/octopus/sound/warble1.ogg b/mods/species/octopus/sound/warble1.ogg new file mode 100644 index 000000000000..c9b4e1d7b5ea Binary files /dev/null and b/mods/species/octopus/sound/warble1.ogg differ diff --git a/mods/species/octopus/sound/warble10.ogg b/mods/species/octopus/sound/warble10.ogg new file mode 100644 index 000000000000..4d75cd9c4355 Binary files /dev/null and b/mods/species/octopus/sound/warble10.ogg differ diff --git a/mods/species/octopus/sound/warble11.ogg b/mods/species/octopus/sound/warble11.ogg new file mode 100644 index 000000000000..6424ff833027 Binary files /dev/null and b/mods/species/octopus/sound/warble11.ogg differ diff --git a/mods/species/octopus/sound/warble2.ogg b/mods/species/octopus/sound/warble2.ogg new file mode 100644 index 000000000000..3b79ba4e28c0 Binary files /dev/null and b/mods/species/octopus/sound/warble2.ogg differ diff --git a/mods/species/octopus/sound/warble3.ogg b/mods/species/octopus/sound/warble3.ogg new file mode 100644 index 000000000000..4e0ab429f091 Binary files /dev/null and b/mods/species/octopus/sound/warble3.ogg differ diff --git a/mods/species/octopus/sound/warble4.ogg b/mods/species/octopus/sound/warble4.ogg new file mode 100644 index 000000000000..0540caa624ab Binary files /dev/null and b/mods/species/octopus/sound/warble4.ogg differ diff --git a/mods/species/octopus/sound/warble5.ogg b/mods/species/octopus/sound/warble5.ogg new file mode 100644 index 000000000000..fa8a1df8aadd Binary files /dev/null and b/mods/species/octopus/sound/warble5.ogg differ diff --git a/mods/species/octopus/sound/warble6.ogg b/mods/species/octopus/sound/warble6.ogg new file mode 100644 index 000000000000..7d76e2407740 Binary files /dev/null and b/mods/species/octopus/sound/warble6.ogg differ diff --git a/mods/species/octopus/sound/warble7.ogg b/mods/species/octopus/sound/warble7.ogg new file mode 100644 index 000000000000..3423a33a3d54 Binary files /dev/null and b/mods/species/octopus/sound/warble7.ogg differ diff --git a/mods/species/octopus/sound/warble8.ogg b/mods/species/octopus/sound/warble8.ogg new file mode 100644 index 000000000000..d6f941020280 Binary files /dev/null and b/mods/species/octopus/sound/warble8.ogg differ diff --git a/mods/species/octopus/sound/warble9.ogg b/mods/species/octopus/sound/warble9.ogg new file mode 100644 index 000000000000..a823684ddc53 Binary files /dev/null and b/mods/species/octopus/sound/warble9.ogg differ diff --git a/mods/species/octopus/species.dm b/mods/species/octopus/species.dm new file mode 100644 index 000000000000..8cb59a7eeca0 --- /dev/null +++ b/mods/species/octopus/species.dm @@ -0,0 +1,81 @@ +/decl/blood_type/octopus + name = "hemocyanin" + splatter_colour = "#68a6dd" + splatter_name = "hemocyanin" + splatter_desc = "It's some hemocyanin. That's not supposed to be there." + antigens = list("Hc") + antigen_category = "cephalopod" + +/decl/butchery_data/octopus + meat_type = /obj/item/food/butchery/meat/fish/octopus + +/decl/species/octopus + name = "Octopus" + uid = "octopus" + name_plural = "Octopodes" + description = "Octopus uplifts have been a relatively common sight in aquatic environments since the early days of \ + Sol expansion. The are renowned as excellent engineers, bartenders, and massage therapists." + available_bodytypes = list(/decl/bodytype/octopus) + butchery_data = /decl/butchery_data/octopus + + blood_types = list(/decl/blood_type/octopus) + flesh_color = "#dd7b68" + + species_flags = SPECIES_FLAG_NO_SLIP + spawn_flags = SPECIES_CAN_JOIN + + species_hud = /datum/hud_data/octopus + + var/list/camo_last_move_by_mob = list() + var/list/camo_last_alpha_by_mob = list() + var/const/camo_delay = 10 SECONDS + var/const/camo_alpha_step = 10 + var/const/camo_min_alpha = 40 + +/decl/species/octopus/handle_death(var/mob/living/human/H) + update_mob_alpha(H, 255) + +// TODO: either do this without icon ops, or precache the states to +// avoid mob flickering the first time they change camo state. +/decl/species/octopus/proc/update_mob_alpha(var/mob/living/human/H, var/newval = 255) + if(camo_last_alpha_by_mob[H] == newval) + return + camo_last_alpha_by_mob[H] = newval + var/need_update + for(var/thing in H.get_external_organs()) + var/obj/item/organ/external/limb = thing + if(!BP_IS_PROSTHETIC(limb) && limb.species == src && limb.render_alpha != newval) + limb.render_alpha = newval + limb.update_icon() + need_update = TRUE + if(need_update) + H.update_body() + +/decl/species/octopus/handle_post_spawn(var/mob/living/H) + . = ..() + camo_last_alpha_by_mob[H] = 255 + camo_last_move_by_mob[H] = world.time + +/decl/species/octopus/handle_post_move(var/mob/living/human/H, exertion = TRUE) + ..() + camo_last_move_by_mob[H] = world.time + update_mob_alpha(H, min(camo_last_alpha_by_mob[H] + camo_min_alpha, 255)) + +/decl/species/octopus/handle_environment_special(var/mob/living/human/H) + var/last_alpha = camo_last_alpha_by_mob[H] + if(world.time >= camo_last_move_by_mob[H]+camo_delay && last_alpha > camo_min_alpha) + update_mob_alpha(H, max(camo_min_alpha, last_alpha-camo_alpha_step)) + +/datum/hud_data/octopus + inventory_slots = list( + /datum/inventory_slot/uniform, + /datum/inventory_slot/mask, + /datum/inventory_slot/glasses, + /datum/inventory_slot/head, + /datum/inventory_slot/suit_storage, + /datum/inventory_slot/back, + /datum/inventory_slot/id, + /datum/inventory_slot/pocket, + /datum/inventory_slot/pocket/right, + /datum/inventory_slot/belt + )