diff --git a/code/__DEFINES/dcs/mob_signals.dm b/code/__DEFINES/dcs/mob_signals.dm index bcbdc4fbf73c..597c9c1738ef 100644 --- a/code/__DEFINES/dcs/mob_signals.dm +++ b/code/__DEFINES/dcs/mob_signals.dm @@ -150,6 +150,11 @@ #define COMSIG_LIVING_FIRE_TICK "living_fire_tick" //sent from living mobs when they are ahealed #define COMSIG_LIVING_AHEAL "living_aheal" +//sent from base of /obj/item/healthanalyzer/get_carapace_damage_level: () +#define COMSIG_SHELL_GET_CARAPACE_LEVEL "surgery_get_carapace_level" +//sent from base of /datum/surgery_step/set_bone/end_step: () +#define COMSIG_SHELL_GET_CARAPACE_STATE "surgery_get_carapace_state" + #define CARAPACE_SHELL_BROKEN (1<<0) //sent from mobs when they exit their body as a ghost #define COMSIG_LIVING_GHOSTIZED "ghostized" //sent from mobs when they re-enter their body as a ghost diff --git a/code/datums/datacore.dm b/code/datums/datacore.dm index 07b21892ed8e..755bf9fb9d28 100644 --- a/code/datums/datacore.dm +++ b/code/datums/datacore.dm @@ -259,6 +259,12 @@ GLOBAL_VAR_INIT(record_id_num, 1001) temp = new /icon(icobase, "[head]_[g]") preview_icon.Blend(temp, ICON_OVERLAY) + // SS220 EDIT START - SERPENTIDS + if(is_species(H, /datum/species/serpentid)) + temp = new/icon("icon" = 'modular_ss220/species/serpentids/icons/mob/r_serpentid.dmi', "icon_state" = "preview") + preview_icon.Blend(temp, ICON_OVERLAY) + // SS220 EDIT END - SERPENTIDS + //Tail if(H.body_accessory && (istype(H.body_accessory, /datum/body_accessory/tail) || istype(H.body_accessory, /datum/body_accessory/wing))) temp = new/icon("icon" = H.body_accessory.icon, "icon_state" = H.body_accessory.icon_state) @@ -395,6 +401,10 @@ GLOBAL_VAR_INIT(record_id_num, 1001) job_clothes = custom_job else if(H.mind) job_clothes = H.mind.assigned_role + //SS220 EDIT START - SERPENTIDS + if(is_species(H, /datum/species/serpentid)) + job_clothes = "Naked" + //SS220 EDIT END - SERPENTIDS switch(job_clothes) if("Head of Personnel") clothes_s = new /icon('icons/mob/clothing/under/civilian.dmi', "hop_s") diff --git a/code/game/gamemodes/cult/cult_mode.dm b/code/game/gamemodes/cult/cult_mode.dm index 371eb3200f8a..e6de3eb9f079 100644 --- a/code/game/gamemodes/cult/cult_mode.dm +++ b/code/game/gamemodes/cult/cult_mode.dm @@ -25,7 +25,7 @@ if(GLOB.configuration.gamemode.prevent_mindshield_antags) restricted_jobs += protected_jobs - var/list/cultists_possible = get_players_for_role(ROLE_CULTIST) + var/list/cultists_possible = get_players_for_role(ROLE_CULTIST, species_exclude = list("Serpentids")) // SS220 EDIT - SERPENTIDS for(var/cultists_number = 1 to max_cultists_to_start) if(!length(cultists_possible)) break diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm index 76b07df2e7f0..83f07df2c41a 100644 --- a/code/game/gamemodes/cult/runes.dm +++ b/code/game/gamemodes/cult/runes.dm @@ -273,6 +273,14 @@ structure_check() searches for nearby cultist structures required for the invoca if(!IS_CULTIST(M) || (M.mind && IS_SACRIFICE_TARGET(M.mind))) if(isconstruct(M)) // No offering constructs please continue + // SS220 EDIT START - SERPENTIDS + if(is_species(M, /datum/species/serpentid)) + M.Paralyse(15 SECONDS) + M.AdjustSleeping(60 SECONDS, bound_lower = 60 SECONDS, bound_upper = 100 SECONDS) + for(var/I in invokers) + to_chat(I, "Предложенная кровь недостаточно хороша для подношения, найдите другую жертву!") + continue + // SS220 EDIT END - SERPENTIDS offer_targets += M // Offering a head/brain diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 143a8c90ff66..f2ed89d4a9bb 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -276,7 +276,7 @@ if(rev_team) rev_team.check_all_victory() -/datum/game_mode/proc/get_players_for_role(role, override_jobbans = FALSE, species_exclusive = null) +/datum/game_mode/proc/get_players_for_role(role, override_jobbans = FALSE, species_exclusive = null, list/species_exclude = null) var/list/players = list() var/list/candidates = list() @@ -302,6 +302,10 @@ if(!eligible_player.client.skip_antag) if(species_exclusive && (eligible_player.client.prefs.active_character.species != species_exclusive)) continue + // SS220 ADDITION START - SERPENTIDS + if(species_exclude && (eligible_player.client.prefs.active_character.species in species_exclude)) + continue + // SS220 ADDITION END - SERPENTIDS if(role in eligible_player.client.prefs.be_special) player_draft_log += "[eligible_player.key] had [roletext] enabled, so we are drafting them." candidates += eligible_player.mind diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index d324ad250fe2..ee2a51ca0689 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -502,6 +502,10 @@ GLOBAL_LIST_INIT(potential_theft_objectives, (subtypesof(/datum/theft_objective) /datum/objective/escape/escape_with_identity/is_invalid_target(datum/mind/possible_target) if(..() || !possible_target.current.client) return TRUE + // SS220 EDIT START - GAS FIXES AND REBALANCE + if(is_species(possible_target, /datum/species/serpentid)) + return TRUE + // SS220 EDIT END - GAS FIXES AND REBALANCE // If the target is geneless, then it's an invalid target. return HAS_TRAIT(possible_target.current, TRAIT_GENELESS) diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 37372543ccb5..de9dd64ec94b 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -397,6 +397,11 @@ SLIME SCANNER if(H.radiation > RAD_MOB_SAFE) msgs += "Subject is irradiated." + //SS220 ADDITION START - SERPENTIDS + if(SEND_SIGNAL(H, COMSIG_SHELL_GET_CARAPACE_STATE) & CARAPACE_SHELL_BROKEN) + msgs = get_carapace_damage_level(H, msgs) + //SS220 ADDITION END - SERPENTIDS + to_chat(user, chat_box_healthscan(msgs.Join("
"))) /obj/item/healthanalyzer/attackby__legacy__attackchain(obj/item/I, mob/user, params) diff --git a/code/modules/antagonists/changeling/powers/tiny_prick.dm b/code/modules/antagonists/changeling/powers/tiny_prick.dm index 985fb92b83b8..58f9d6f05605 100644 --- a/code/modules/antagonists/changeling/powers/tiny_prick.dm +++ b/code/modules/antagonists/changeling/powers/tiny_prick.dm @@ -61,6 +61,11 @@ if(ismachineperson(target)) to_chat(user, "This won't work on synthetics.") return FALSE + // SS220 EDIT START - GAS FIXES AND REBALANCE + if(is_species(target, /datum/species/serpentid)) + to_chat(user, "This won't work on serpentids armor.") + return FALSE + // SS220 EDIT START - GAS FIXES AND REBALANCE if(IS_CHANGELING(target)) sting_feedback(user, target) take_chemical_cost() diff --git a/code/modules/ruins/lavalandruin_code/sin_ruins.dm b/code/modules/ruins/lavalandruin_code/sin_ruins.dm index cfa4c18f3c8b..b28b3ecef62e 100644 --- a/code/modules/ruins/lavalandruin_code/sin_ruins.dm +++ b/code/modules/ruins/lavalandruin_code/sin_ruins.dm @@ -200,7 +200,7 @@ return if(!istype(user)) return - if(ishuman(AM)) + if(ishuman(AM) && !is_species(AM, /datum/species/serpentid)) // SS220 EDIT - SERPENTIDS var/mob/living/carbon/human/H = AM if(user.real_name != H.dna.real_name) user.real_name = H.dna.real_name diff --git a/config/names/serpentids_names.txt b/config/names/serpentids_names.txt new file mode 100644 index 000000000000..ba5b115c9613 --- /dev/null +++ b/config/names/serpentids_names.txt @@ -0,0 +1,16 @@ +Бламг +Брэцк +Вшиси +Вхус +Клатси +Клух +Звин +Зцохи +Рари +Ристи +Скрик +Скрум +Щерс +Шухса +Цвальк +Цвун diff --git a/modular_ss220/_defines220/code/signals_mob/signals_mob_carbon.dm b/modular_ss220/_defines220/code/signals_mob/signals_mob_carbon.dm index 1cce544ff6d0..2a37301618b1 100644 --- a/modular_ss220/_defines220/code/signals_mob/signals_mob_carbon.dm +++ b/modular_ss220/_defines220/code/signals_mob/signals_mob_carbon.dm @@ -1,7 +1,8 @@ // Signals for /mob/living/carbon /// called by /mob/equip_to_slot() : (/datum/component/mob_overlay_shift) #define COMSIG_MOB_ON_EQUIP "mob_on_equip" - +/// called by /datum/action/changeling/transform/sting_action() : (/datum/component/mob_overlay_shift) +#define COMSIG_CHANGELING_FINISHED_TRANSFORM "changeling_finished_transform" /// called by /mob/ClickOn() : (/datum/component/mob_overlay_shift) #define COMSIG_MOB_ON_CLICK "mob_on_click" diff --git a/modular_ss220/_defines220/code/signals_obj.dm b/modular_ss220/_defines220/code/signals_obj.dm index 4d539f801f83..707f68c53d31 100644 --- a/modular_ss220/_defines220/code/signals_obj.dm +++ b/modular_ss220/_defines220/code/signals_obj.dm @@ -8,6 +8,8 @@ #define COMSIG_LIMB_RECEIVE_DAMAGE "limb_receive_damage" /// called by /obj/item/organ/external/heal_damage() : (/datum/component/carapace) #define COMSIG_LIMB_HEAL_DAMAGE "limb_heal_damage" +/// called by /datum/surgery_step/set_bone/end_step(), /datum/surgery_step/retract_carapace/end_step : (/datum/component/carapace) +#define COMSIG_LIMB_SHELL_OPERATION "limb_shell_operation" /// called by /obj/item/organ/internal/cyberimp/arm/Extend() /obj/item/organ/internal/cyberimp/arm/Retract() : (/datum/element/paired_implants) #define COMSIG_DOUBLEIMP_SYNCHONIZE "doubleimp_synchonize" /// called by /obj/item/organ/internal/remove() /obj/item/organ/internal/insert() : (/datum/element/paired_implants) diff --git a/modular_ss220/_defines220/code/species.dm b/modular_ss220/_defines220/code/species.dm index aa25bfb03f7f..8ea70bf5aa43 100644 --- a/modular_ss220/_defines220/code/species.dm +++ b/modular_ss220/_defines220/code/species.dm @@ -19,3 +19,7 @@ /mob/living/carbon/human var/atom/movable/loaded = null var/mob/living/passenger = null + +/mob/living/proc/isCarrying() + var/mob/living/carbon/human/check_one = src + return check_one?.loaded || check_one?.passenger diff --git a/modular_ss220/pixel_shift/code/pixel_shift_component.dm b/modular_ss220/pixel_shift/code/pixel_shift_component.dm index b6da4c78a331..fb1af983c400 100644 --- a/modular_ss220/pixel_shift/code/pixel_shift_component.dm +++ b/modular_ss220/pixel_shift/code/pixel_shift_component.dm @@ -63,7 +63,7 @@ /datum/component/pixel_shift/proc/pixel_shift(mob/target, direction) var/mob/living/owner = parent - if(HAS_TRAIT(owner, TRAIT_RESTRAINED) || HAS_TRAIT(owner, TRAIT_IMMOBILIZED) || length(owner.grabbed_by) || owner.stat != CONSCIOUS) + if(HAS_TRAIT(owner, TRAIT_RESTRAINED) || HAS_TRAIT(owner, TRAIT_IMMOBILIZED) || length(owner.grabbed_by) || owner.stat != CONSCIOUS || owner.isCarrying()) return passthroughable = NONE switch(direction) diff --git a/modular_ss220/species/_components/appearance/mob_overlay_shift.dm b/modular_ss220/species/_components/appearance/mob_overlay_shift.dm index 849e8536b821..140ccc0ff3fe 100644 --- a/modular_ss220/species/_components/appearance/mob_overlay_shift.dm +++ b/modular_ss220/species/_components/appearance/mob_overlay_shift.dm @@ -35,17 +35,26 @@ shift_call(parent) /datum/component/mob_overlay_shift/RegisterWithParent() - RegisterSignal(parent, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_MOB_ON_EQUIP, COMSIG_MOB_ON_CLICK), PROC_REF(shift_call)) + RegisterSignal(parent, list(COMSIG_COMPONENT_CLEAN_ACT, COMSIG_MOVABLE_MOVED, COMSIG_MOB_ON_EQUIP, COMSIG_MOB_ON_CLICK, COMSIG_CHANGELING_FINISHED_TRANSFORM), PROC_REF(shift_call)) + RegisterSignal(parent, list(COMSIG_ATOM_DIR_CHANGE), PROC_REF(update_dir)) RegisterSignal(parent, list(COMSIG_MOB_GET_OVERLAY_SHIFTS_LIST), PROC_REF(get_list)) /datum/component/mob_overlay_shift/UnregisterFromParent() - UnregisterSignal(parent, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_MOB_ON_EQUIP, COMSIG_MOB_ON_CLICK, COMSIG_MOB_GET_OVERLAY_SHIFTS_LIST)) + UnregisterSignal(parent, list(COMSIG_ATOM_DIR_CHANGE, COMSIG_MOVABLE_MOVED, COMSIG_COMPONENT_CLEAN_ACT, COMSIG_MOB_ON_EQUIP, COMSIG_MOB_ON_CLICK, COMSIG_MOB_GET_OVERLAY_SHIFTS_LIST, COMSIG_CHANGELING_FINISHED_TRANSFORM)) + +/datum/component/mob_overlay_shift/proc/update_dir(mob/living/carbon/human/mob, olddir, newdir) + SIGNAL_HANDLER + if(newdir) + dir = newdir + update_apperance(mob) /datum/component/mob_overlay_shift/proc/shift_call(mob/living/carbon/human/mob) SIGNAL_HANDLER if(mob.dir) dir = mob.dir + update_apperance(mob) +/datum/component/mob_overlay_shift/proc/update_apperance(mob/living/carbon/human/mob) var/list/body_parts = list(MOB_OVERLAY_SHIFT_HAND, MOB_OVERLAY_SHIFT_BELT, MOB_OVERLAY_SHIFT_BACK, MOB_OVERLAY_SHIFT_HEAD) var/position switch(dir) @@ -59,7 +68,8 @@ position = MOB_OVERLAY_SHIFT_FRONT var/flip = (dir == WEST || dir == SOUTH) ? -1 : 1 - + if(!position) + position = MOB_OVERLAY_SHIFT_SIDE //ГБС лежит // Update shift values based on direction for(var/body_part in body_parts) var/x_shift_key = "shift_x" @@ -70,8 +80,11 @@ var/x_central_value = shift_data[body_part][MOB_OVERLAY_SHIFT_CENTER]["x"] var/y_central_value = shift_data[body_part][MOB_OVERLAY_SHIFT_CENTER]["y"] - shift_data[body_part][x_shift_key] = flip * x_shift_value + x_central_value - shift_data[body_part][y_shift_key] = flip * y_shift_value + y_central_value + shift_data[body_part][y_shift_key] = 0 + shift_data[body_part][x_shift_key] = 0 + if(isserpentid(mob)) + shift_data[body_part][x_shift_key] = flip * x_shift_value + x_central_value + shift_data[body_part][y_shift_key] = flip * y_shift_value + y_central_value update_call(mob) @@ -97,3 +110,7 @@ #undef MOB_OVERLAY_SHIFT_SIDE #undef MOB_OVERLAY_SHIFT_FRONT #undef MOB_OVERLAY_SHIFT_CENTER + +/atom/movable/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change) + . = ..() + l_move_time = world.time diff --git a/modular_ss220/species/_components/attacking/double_attack.dm b/modular_ss220/species/_components/attacking/double_attack.dm index fe145efcc688..8d2eb9ed0b64 100644 --- a/modular_ss220/species/_components/attacking/double_attack.dm +++ b/modular_ss220/species/_components/attacking/double_attack.dm @@ -1,8 +1,6 @@ /* ===Компонент на атаку парного оружия -Срабатывает при атаке оружием. Второе оружие через паузу в 0.2 секунды запускает атаку. - -Срабатывает только, если оружие одинаковое. +Срабатывает при атаке оружием. Второе оружие через паузу в N секунд запускает атаку. */ /datum/component/double_attack diff --git a/modular_ss220/species/_components/carapace/carapace.dm b/modular_ss220/species/_components/carapace/carapace.dm index 6a6b5c1d30dc..4320b4d17bab 100644 --- a/modular_ss220/species/_components/carapace/carapace.dm +++ b/modular_ss220/species/_components/carapace/carapace.dm @@ -27,6 +27,7 @@ /datum/component/carapace var/self_mending = FALSE var/broken_treshold = CARAPACE_BROKEN_STATE + var/operation_in_process = FALSE /datum/component/carapace/Initialize(allow_self_mending, break_threshold) src.self_mending = allow_self_mending @@ -37,10 +38,16 @@ /datum/component/carapace/RegisterWithParent() RegisterSignal(parent, COMSIG_LIMB_RECEIVE_DAMAGE, PROC_REF(receive_damage)) RegisterSignal(parent, COMSIG_LIMB_HEAL_DAMAGE, PROC_REF(heal_damage)) + RegisterSignal(parent, COMSIG_LIMB_SHELL_OPERATION, PROC_REF(handle_operation_status)) /datum/component/carapace/UnregisterFromParent() UnregisterSignal(parent, COMSIG_LIMB_RECEIVE_DAMAGE) UnregisterSignal(parent, COMSIG_LIMB_HEAL_DAMAGE) + UnregisterSignal(parent, COMSIG_LIMB_SHELL_OPERATION) + +/datum/component/carapace/proc/handle_operation_status(obj/item/organ/external/affected_limb, state_to_apply) + SIGNAL_HANDLER + operation_in_process = state_to_apply //Проки, срабатываемые при получении или исцелении урона /datum/component/carapace/proc/receive_damage(obj/item/organ/external/affected_limb, brute, burn, sharp, used_weapon = null, list/forbidden_limbs = list(), ignore_resists = FALSE, updating_health = TRUE) @@ -49,12 +56,12 @@ affected_limb.fracture() if(length(affected_limb.internal_organs)) var/obj/item/organ/internal/O = pick(affected_limb.internal_organs) - O.receive_damage(burn * affected_limb.burn_dam) + O.receive_damage(burn) /datum/component/carapace/proc/heal_damage(obj/item/organ/external/affected_limb, brute, burn, internal = 0, robo_repair = 0, updating_health = TRUE) SIGNAL_HANDLER if((affected_limb.status & ORGAN_BROKEN) && affected_limb.get_damage() == 0) - if(self_mending || prob(CARAPACE_HEAL_BROKEN_PROB)) + if((self_mending || prob(CARAPACE_HEAL_BROKEN_PROB)) && !operation_in_process) affected_limb.mend_fracture() ////////////////////////////////////////////////////////////////// @@ -62,7 +69,7 @@ ////////////////////////////////////////////////////////////////// ///Датумы для операций /datum/surgery/carapace_break - name = "Break carapace" + name = "Break chitin" steps = list( /datum/surgery_step/saw_carapace, /datum/surgery_step/cut_carapace, @@ -83,7 +90,7 @@ requires_organic_bodypart = TRUE /datum/surgery/bone_repair/carapace - name = "Carapace Repair" + name = "Chitin Repair" steps = list( /datum/surgery_step/glue_bone, /datum/surgery_step/set_bone, @@ -133,7 +140,7 @@ //Блокировка простого скальпеля (базовый начальный шаг любой операции), если карапас не был сломан, но появилась какая-то операция, которая не должна быть /datum/surgery_step/generic/cut_open/begin_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery) var/obj/item/organ/external/affected = target.get_organ(target_zone) - if((affected?.encased == CARAPACE_ENCASE_WORD) && !(affected.status & ORGAN_BROKEN)) + if((affected?.encased == CARAPACE_ENCASE_WORD) && !(affected.status & ORGAN_BROKEN) && !istype(surgery, /datum/surgery/carapace_shell_repair)) to_chat(user, span_notice("[capitalize(target.declent_ru(NOMINATIVE))] покрыта крепким хитином. Сломайте его, прежде чем начать операцию.")) return SURGERY_BEGINSTEP_ABORT . = .. () @@ -142,12 +149,18 @@ var/obj/item/organ/external/affected = target.get_organ(user.zone_selected) if((affected?.encased == CARAPACE_ENCASE_WORD) && !(affected.status & ORGAN_BROKEN)) affected.fracture() + REMOVE_TRAIT(target, TRAIT_PIERCEIMMUNE, "carapace_state") + SEND_SIGNAL(affected, COMSIG_LIMB_SHELL_OPERATION, TRUE) . = .. () /datum/surgery_step/set_bone/end_step(mob/living/user, mob/living/carbon/human/target, target_zone, obj/item/tool) var/obj/item/organ/external/affected = target.get_organ(user.zone_selected) - if((affected?.encased == CARAPACE_ENCASE_WORD) && !(affected.status & ORGAN_BROKEN)) + if((affected?.encased == CARAPACE_ENCASE_WORD) && (affected.status & ORGAN_BROKEN)) affected.mend_fracture() + if(isserpentid(target)) + if(!(SEND_SIGNAL(target, COMSIG_SHELL_GET_CARAPACE_STATE) & CARAPACE_SHELL_BROKEN)) + ADD_TRAIT(target, TRAIT_PIERCEIMMUNE, "carapace_state") + SEND_SIGNAL(affected, COMSIG_LIMB_SHELL_OPERATION, FALSE) . = .. () #undef CARAPACE_BROKEN_STATE diff --git a/modular_ss220/species/_components/carapace/carapace_shell.dm b/modular_ss220/species/_components/carapace/carapace_shell.dm index fdf588bd6dc0..8899e9735234 100644 --- a/modular_ss220/species/_components/carapace/carapace_shell.dm +++ b/modular_ss220/species/_components/carapace/carapace_shell.dm @@ -44,12 +44,35 @@ RegisterSignal(H, COMSIG_SURGERY_STOP, PROC_REF(check_surgery_perform)) RegisterSignal(H, COMSIG_SURGERY_REPAIR, PROC_REF(surgery_carapace_shell_repair)) RegisterSignal(H, COMSIG_MOB_APPLY_DAMAGE, PROC_REF(update_attacked_time)) + RegisterSignal(H, COMSIG_LIVING_AHEAL, PROC_REF(clear_state)) + RegisterSignal(H, COMSIG_SHELL_GET_CARAPACE_STATE, PROC_REF(is_armor_piercied)) + RegisterSignal(H, COMSIG_SHELL_GET_CARAPACE_LEVEL, PROC_REF(get_broken_stage)) /datum/component/carapace_shell/UnregisterFromParent() UnregisterSignal(H, COMSIG_LIVING_LIFE) UnregisterSignal(H, COMSIG_SURGERY_STOP) UnregisterSignal(H, COMSIG_SURGERY_REPAIR) UnregisterSignal(H, COMSIG_MOB_APPLY_DAMAGE) + UnregisterSignal(H, COMSIG_LIVING_AHEAL) + UnregisterSignal(H, COMSIG_SHELL_GET_CARAPACE_STATE) + UnregisterSignal(H, COMSIG_SHELL_GET_CARAPACE_LEVEL) + +/datum/component/carapace_shell/proc/is_armor_piercied() + SIGNAL_HANDLER + return broken_stage > 0 ? CARAPACE_SHELL_BROKEN : FALSE + +/datum/component/carapace_shell/proc/get_broken_stage(mob/human, list/msg) + SIGNAL_HANDLER + var/level + switch(broken_stage) + if(1) + level = "умеренные" + if(2) + level = "опасные" + if(3) + level = "критические" + if(level) + msg += "Обнаружены [level] повреждения целостности панциря." /datum/component/carapace_shell/proc/stage_1_break() H.dna.species.brute_mod = CARAPACE_SHELL_BROKEN_BRUTE @@ -62,7 +85,6 @@ H.dna.species.brute_mod = CARAPACE_SHELL_ARMORED_BRUTE H.dna.species.burn_mod = CARAPACE_SHELL_ARMORED_BURN ADD_TRAIT(H, TRAIT_PIERCEIMMUNE, "carapace_state") - H.clear_alert("carapace_break") broken_stage-- /datum/component/carapace_shell/proc/stage_2_break() @@ -155,10 +177,17 @@ if(istype(organ)) organ.switch_mode(force_off = TRUE) + if((broken_stage < 1 && character_damage < state_1_threshold) || !isserpentid(H)) + H.clear_alert("carapace_break") + +/datum/component/carapace_shell/proc/clear_state() + SIGNAL_HANDLER + broken_stage = 0 + ////////////////////////////////////////////////////////////////// // Хирургия для панциря // ////////////////////////////////////////////////////////////////// -/datum/surgery/bone_repair/carapace_shell +/datum/surgery/carapace_shell_repair name = "Carapace Integrity Repair" steps = list( /datum/surgery_step/generic/cut_open, @@ -219,7 +248,7 @@ ) return SURGERY_STEP_RETRY -/datum/surgery/bone_repair/carapace_shell/can_start(mob/user, mob/living/carbon/target) +/datum/surgery/carapace_shell_repair/can_start(mob/user, mob/living/carbon/target) var/can_start = (SEND_SIGNAL(target, COMSIG_SURGERY_STOP) & SURGERY_STOP) return can_start @@ -227,3 +256,8 @@ #undef CARAPACE_SHELL_ARMORED_BURN #undef CARAPACE_SHELL_BROKEN_BRUTE #undef CARAPACE_SHELL_BROKEN_BURN + +/proc/get_carapace_damage_level(mob/target, list/msgs) + . = msgs + SEND_SIGNAL(target, COMSIG_SHELL_GET_CARAPACE_LEVEL, .) + return . diff --git a/modular_ss220/species/_components/carrying/grab_and_drag_on_mob_crates.dm b/modular_ss220/species/_components/carrying/grab_and_drag_on_mob_crates.dm index d7503c89e504..50a7ac66076e 100644 --- a/modular_ss220/species/_components/carrying/grab_and_drag_on_mob_crates.dm +++ b/modular_ss220/species/_components/carrying/grab_and_drag_on_mob_crates.dm @@ -25,11 +25,13 @@ RegisterSignal(parent, COMSIG_GADOM_LOAD, PROC_REF(try_load_cargo)) RegisterSignal(parent, COMSIG_GADOM_UNLOAD, PROC_REF(try_unload_cargo)) RegisterSignal(parent, COMSIG_GADOM_CAN_GRAB, PROC_REF(block_operation)) + RegisterSignal(parent, COMSIG_CHANGELING_FINISHED_TRANSFORM, PROC_REF(try_unload_cargo)) /datum/component/gadom_cargo/UnregisterFromParent() UnregisterSignal(parent, COMSIG_GADOM_LOAD) UnregisterSignal(parent, COMSIG_GADOM_UNLOAD) UnregisterSignal(parent, COMSIG_GADOM_CAN_GRAB) + UnregisterSignal(parent, COMSIG_CHANGELING_FINISHED_TRANSFORM) /datum/component/gadom_cargo/proc/block_operation() SIGNAL_HANDLER @@ -74,6 +76,7 @@ if(!isliving(AM)) AM.crate_carrying_person = carrier + AM.density = FALSE AM.forceMove(carrier.loc) carrier.loaded = AM @@ -101,7 +104,8 @@ var/turf/newT = get_step(T,dirn) if(carrier.loaded.CanPass(carrier.loaded, newT)) step(carrier.loaded, dirn) + carrier.loaded.density = TRUE carrier.loaded.crate_carrying_person = null carrier.loaded = null - carrier.clear_alert("serpentid_holding") carrier.update_icon(UPDATE_OVERLAYS) + carrier.clear_alert("serpentid_holding") diff --git a/modular_ss220/species/_components/carrying/grab_and_drag_on_mob_mobs.dm b/modular_ss220/species/_components/carrying/grab_and_drag_on_mob_mobs.dm index fa7a34893d61..b2a8d4cb7dfb 100644 --- a/modular_ss220/species/_components/carrying/grab_and_drag_on_mob_mobs.dm +++ b/modular_ss220/species/_components/carrying/grab_and_drag_on_mob_mobs.dm @@ -8,17 +8,20 @@ /datum/component/gadom_living/Initialize() carrier = parent + carrier.can_buckle = FALSE START_PROCESSING(SSprojectiles, src) /datum/component/gadom_living/RegisterWithParent() RegisterSignal(parent, COMSIG_GADOM_LOAD, PROC_REF(try_load_mob)) RegisterSignal(parent, COMSIG_GADOM_UNLOAD, PROC_REF(try_unload_mob)) RegisterSignal(parent, COMSIG_GADOM_CAN_GRAB, PROC_REF(block_operation)) + RegisterSignal(parent, COMSIG_CHANGELING_FINISHED_TRANSFORM, PROC_REF(try_unload_mob)) /datum/component/gadom_living/UnregisterFromParent() UnregisterSignal(parent, COMSIG_GADOM_LOAD) UnregisterSignal(parent, COMSIG_GADOM_UNLOAD) UnregisterSignal(parent, COMSIG_GADOM_CAN_GRAB) + UnregisterSignal(parent, COMSIG_CHANGELING_FINISHED_TRANSFORM) /datum/component/gadom_living/proc/block_operation(datum/component_holder) SIGNAL_HANDLER @@ -78,7 +81,7 @@ carrier.loaded = null carrier.passenger = null carrier.unbuckle_all_mobs() - carrier.can_buckle = TRUE + carrier.can_buckle = FALSE carrier.update_icon(UPDATE_OVERLAYS) carrier.clear_alert("serpentid_holding") @@ -89,3 +92,4 @@ passenger = null M.layer = initial(M.layer) M.pixel_y = initial(M.pixel_y) + clear_alert("serpentid_holding") diff --git a/modular_ss220/species/_components/organs/organ_actions_component.dm b/modular_ss220/species/_components/organs/organ_actions_component.dm index aff4eceb221e..ad67960ccd74 100644 --- a/modular_ss220/species/_components/organs/organ_actions_component.dm +++ b/modular_ss220/species/_components/organs/organ_actions_component.dm @@ -38,7 +38,10 @@ for(var/obj/item/organ/internal/I in organs_list) if(I.radial_action_state && I.radial_action_icon) - choices["[I.name]"] = image(icon = I.radial_action_icon, icon_state = I.radial_action_state) + var/image/organ_image = image(icon = I.radial_action_icon, icon_state = I.radial_action_state) + if(I.get_active_state()) + organ_image.underlays += image(icon = 'icons/hud/radial.dmi', icon_state = "module_active") + choices["[I.name]"] = organ_image var/choice = show_radial_menu(user, user, choices, custom_check = CALLBACK(src, PROC_REF(check_actions), user)) if(!check_actions(user)) @@ -78,3 +81,6 @@ /obj/item/organ/internal var/radial_action_state var/radial_action_icon + +/obj/item/organ/internal/proc/get_active_state() + return diff --git a/modular_ss220/species/_components/organs/organ_decay.dm b/modular_ss220/species/_components/organs/organ_decay.dm index d061cde5c602..1273b21e7701 100644 --- a/modular_ss220/species/_components/organs/organ_decay.dm +++ b/modular_ss220/species/_components/organs/organ_decay.dm @@ -15,12 +15,13 @@ var/recover_rate var/decay_rate var/death_state_timer - var/dead_last_state = FALSE + var/lt_live = FALSE /datum/component/organ_decay/Initialize(income_decay_rate = BASIC_RECOVER_VALUE, income_recover_rate = BASIC_DECAY_VALUE) organ = parent recover_rate = income_recover_rate decay_rate = income_decay_rate + death_state_timer = world.time START_PROCESSING(SSdcs, src) /datum/component/organ_decay/Destroy(force, silent) @@ -32,11 +33,11 @@ return var/is_no_owner = isnull(organ.owner) - if(!dead_last_state) + if(lt_live) death_state_timer = world.time - dead_last_state = organ?.owner.stat == DEAD + lt_live = (organ?.owner?.stat != DEAD) var/formaldehyde_found = organ.owner?.get_chemical_value("formaldehyde") > 0 - var/is_destroying = (dead_last_state || (is_no_owner && !organ.is_in_freezer)) + var/is_destroying = (!lt_live || (is_no_owner && !organ.is_in_freezer)) if(is_destroying && !formaldehyde_found && ((world.time - death_state_timer) >= ORGAN_DEATH_TIMER)) organ.receive_damage(decay_rate, 1) if((organ.damage <= (organ.max_damage / ORGAN_RECOVERY_THRESHOLD)) && (organ.damage > 0) && !is_destroying) diff --git a/modular_ss220/species/_components/organs/organ_hunger.dm b/modular_ss220/species/_components/organs/organ_hunger.dm index a3fe81100e7f..7cc8d51300a8 100644 --- a/modular_ss220/species/_components/organs/organ_hunger.dm +++ b/modular_ss220/species/_components/organs/organ_hunger.dm @@ -21,9 +21,22 @@ SIGNAL_HANDLER if(isnull(organ.owner)) return TRUE + var/active = FALSE + if(istype(organ, /obj/item/organ/internal/kidneys/serpentid)) + var/obj/item/organ/internal/kidneys/serpentid/checkorgan = organ + active = checkorgan.cloak_engaged + if(istype(organ, /obj/item/organ/internal/eyes/serpentid)) + var/obj/item/organ/internal/eyes/serpentid/checkorgan = organ + active = checkorgan.active + if(istype(organ, /obj/item/organ/internal/lungs/serpentid)) + var/obj/item/organ/internal/lungs/serpentid/checkorgan = organ + active = checkorgan.active_secretion + if(istype(organ, /obj/item/organ/internal/ears/serpentid)) + var/obj/item/organ/internal/ears/serpentid/checkorgan = organ + active = checkorgan.active if(consuption_count && organ.owner.nutrition > NUTRITION_LEVEL_HYPOGLYCEMIA) organ.owner.adjust_nutrition(-consuption_count) - else //Если количества недостаточно - выключить режим + else if(active) //Если количества недостаточно - выключить режим organ.switch_mode(force_off = TRUE) diff --git a/modular_ss220/species/serpentids/code/mob/emotes.dm b/modular_ss220/species/serpentids/code/mob/emotes.dm index a7aaef7e64e1..ebab24d93475 100644 --- a/modular_ss220/species/serpentids/code/mob/emotes.dm +++ b/modular_ss220/species/serpentids/code/mob/emotes.dm @@ -1,6 +1,11 @@ #define EMOTE_HUMAN_SERPENTIDROAR "Рычать" #define EMOTE_HUMAN_SERPENTIDHISS "Шипеть" #define EMOTE_HUMAN_SERPENTIDWIGGLE "Шевелить усиками" +#define EMOTE_HUMAN_SERPENTIDBLINK "Моргать щитками" +#define EMOTE_HUMAN_SERPENTIDBLINKBLADES "Чистить глаза" +#define EMOTE_HUMAN_SERPENTIDBUZZ "Стрекот крыльев" +#define EMOTE_HUMAN_SERPENTIDMANDIBLES "Стучать мандибулами" +#define EMOTE_HUMAN_SERPENTIDBLADES "Стучать клинками" /mob/living/carbon/human/proc/emote_serpentidroar() set name = "< " + EMOTE_HUMAN_SERPENTIDROAR + " >" @@ -17,6 +22,31 @@ set category = "Эмоции" emote("serpentidwiggles", intentional = TRUE) +/mob/living/carbon/human/proc/emote_serpentidblinks() + set name = "◦ " + EMOTE_HUMAN_SERPENTIDBLINK + " >" + set category = "Эмоции" + emote("serpentidblinks", intentional = TRUE) + +/mob/living/carbon/human/proc/emote_serpentidblinksblades() + set name = "◦ " + EMOTE_HUMAN_SERPENTIDBLINKBLADES + " >" + set category = "Эмоции" + emote("serpentidblinksblades", intentional = TRUE) + +/mob/living/carbon/human/proc/emote_serpentidbuzzes() + set name = "< " + EMOTE_HUMAN_SERPENTIDBUZZ + " >" + set category = "Эмоции" + emote("serpentidbuzzes", intentional = TRUE) + +/mob/living/carbon/human/proc/emote_serpentidmandibles() + set name = "< " + EMOTE_HUMAN_SERPENTIDMANDIBLES + " >" + set category = "Эмоции" + emote("serpentidmandibles", intentional = TRUE) + +/mob/living/carbon/human/proc/emote_serpentidblades() + set name = "< " + EMOTE_HUMAN_SERPENTIDBLADES + " >" + set category = "Эмоции" + emote("serpentidblades", intentional = TRUE) + /datum/emote/living/carbon/human/serpentidroar name = EMOTE_HUMAN_SERPENTIDROAR @@ -26,6 +56,21 @@ /datum/emote/living/carbon/human/serpentidwiggles name = EMOTE_HUMAN_SERPENTIDWIGGLE +/datum/emote/living/carbon/human/serpentidblinks + name = EMOTE_HUMAN_SERPENTIDBLINK + +/datum/emote/living/carbon/human/serpentidblinksblades + name = EMOTE_HUMAN_SERPENTIDBLINKBLADES + +/datum/emote/living/carbon/human/serpentidbuzzes + name = EMOTE_HUMAN_SERPENTIDBUZZ + +/datum/emote/living/carbon/human/serpentidblinksblades + name = EMOTE_HUMAN_SERPENTIDMANDIBLES + +/datum/emote/living/carbon/human/serpentidblades + name = EMOTE_HUMAN_SERPENTIDBLADES + /datum/emote/living/carbon/human/serpentidroar key = "serpentidroar" key_third_person = "serpentidroar" @@ -65,6 +110,74 @@ target_behavior = EMOTE_TARGET_BHVR_USE_PARAMS_ANYWAY emote_target_type = EMOTE_TARGET_ANY +/datum/emote/living/carbon/human/serpentidblinks + key = "serpentidblinks" + key_third_person = "serpentidblinks" + message = "опускает и поднимает глазные щитки." + message_param = "опускает и поднимает глазные щитки, смотря на %t." + species_type_whitelist_typecache = list(/datum/species/serpentid) + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + age_based = TRUE + sound = null + hands_use_check = FALSE + target_behavior = EMOTE_TARGET_BHVR_USE_PARAMS_ANYWAY + emote_target_type = EMOTE_TARGET_ANY + +/datum/emote/living/carbon/human/serpentidblinksblades + key = "serpentidblinksblades" + key_third_person = "serpentidblinksblades" + message = "прочищает глаза краями лезвий." + message_param = "прочищает глаза краями лезвий, смотря на %t." + species_type_whitelist_typecache = list(/datum/species/serpentid) + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + age_based = TRUE + sound = null + hands_use_check = FALSE + target_behavior = EMOTE_TARGET_BHVR_USE_PARAMS_ANYWAY + emote_target_type = EMOTE_TARGET_ANY + +/datum/emote/living/carbon/human/serpentidbuzzes + key = "serpentidbuzzes" + key_third_person = "serpentidbuzzes" + message = "слегка вибрирует спинным панцирем." + message_param = "слегка вибрирует спинным панцирем в сторону %t." + cooldown = 5 SECONDS + species_type_whitelist_typecache = list(/datum/species/serpentid) + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + age_based = TRUE + sound = 'sound/voice/scream_moth.ogg' + hands_use_check = FALSE + target_behavior = EMOTE_TARGET_BHVR_USE_PARAMS_ANYWAY + emote_target_type = EMOTE_TARGET_ANY + +/datum/emote/living/carbon/human/serpentidmandibles + key = "serpentidmandibles" + key_third_person = "serpentidmandibles" + message = "стучит мандибулами" + message_param = "стучит мандибулами в сторону %t." + cooldown = 5 SECONDS + species_type_whitelist_typecache = list(/datum/species/serpentid) + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + age_based = TRUE + sound = 'sound/effects/Kidanclack.ogg' + hands_use_check = FALSE + target_behavior = EMOTE_TARGET_BHVR_USE_PARAMS_ANYWAY + emote_target_type = EMOTE_TARGET_ANY + +/datum/emote/living/carbon/human/serpentidblades + key = "serpentidblades" + key_third_person = "serpentidblades" + message = "стучит лезвиями." + message_param = "стучит лезвиями в сторону %t." + cooldown = 5 SECONDS + species_type_whitelist_typecache = list(/datum/species/serpentid) + emote_type = EMOTE_VISIBLE | EMOTE_AUDIBLE + age_based = TRUE + sound = 'sound/weapons/blade_unsheath.ogg' + hands_use_check = FALSE + target_behavior = EMOTE_TARGET_BHVR_USE_PARAMS_ANYWAY + emote_target_type = EMOTE_TARGET_ANY + /datum/keybinding/emote/carbon/human/serpentidroar linked_emote = /datum/emote/living/carbon/human/serpentidroar name = EMOTE_HUMAN_SERPENTIDROAR @@ -76,3 +189,23 @@ /datum/keybinding/emote/carbon/human/serpentidwiggles linked_emote = /datum/emote/living/carbon/human/serpentidwiggles name = EMOTE_HUMAN_SERPENTIDWIGGLE + +/datum/keybinding/emote/carbon/human/serpentidblinks + linked_emote = /datum/emote/living/carbon/human/serpentidblinks + name = EMOTE_HUMAN_SERPENTIDBLINK + +/datum/keybinding/emote/carbon/human/serpentidblinksblades + linked_emote = /datum/emote/living/carbon/human/serpentidblinksblades + name = EMOTE_HUMAN_SERPENTIDBLINKBLADES + +/datum/keybinding/emote/carbon/human/serpentidbuzzes + linked_emote = /datum/emote/living/carbon/human/serpentidbuzzes + name = EMOTE_HUMAN_SERPENTIDBUZZ + +/datum/keybinding/emote/carbon/human/serpentidmandibles + linked_emote = /datum/emote/living/carbon/human/serpentidmandibles + name = EMOTE_HUMAN_SERPENTIDMANDIBLES + +/datum/keybinding/emote/carbon/human/serpentidblades + linked_emote = /datum/emote/living/carbon/human/serpentidblades + name = EMOTE_HUMAN_SERPENTIDBLADES diff --git a/modular_ss220/species/serpentids/code/mob/language.dm b/modular_ss220/species/serpentids/code/mob/language.dm index f66ec43831f2..bcaafa6a684d 100644 --- a/modular_ss220/species/serpentids/code/mob/language.dm +++ b/modular_ss220/species/serpentids/code/mob/language.dm @@ -3,20 +3,16 @@ /datum/language/serpentid name = "Nabberian" - desc = "Звук, издаваемый этим языком похоже на кононаду из скрежета мандибул, лезвий, стука конечностей, трения антенн и утробного рева" + desc = "Звук, издаваемый этим языком похоже на канонаду из скрежета мандибул, лезвий, стука конечностей, трения антенн и утробного рева" speech_verb = "стучит клинками и жестикулирует конечностями" ask_verb = "стучит жвалами и жестикулирует конечностями" exclaim_verbs = list("издает гремящие щелчки") - colour = "serpentid" - key = "g" + colour = "orangei" + key = "y" flags = RESTRICTED | WHITELISTED syllables = list("click","clack","cling","clang","cland","clog") no_tts = TRUE /datum/language/serpentid/get_random_name(gender) - var/new_name = "" - if(gender == FEMALE) - new_name = capitalize(pick(GLOB.first_names_female)) - else - new_name = capitalize(pick(GLOB.first_names_male)) + var/new_name = capitalize(pick(file2list("config/names/serpentids_names.txt"))) return new_name diff --git a/modular_ss220/species/serpentids/code/mob/serpentids.dm b/modular_ss220/species/serpentids/code/mob/serpentids.dm index e51cd3f59181..dc70b80ecb1a 100644 --- a/modular_ss220/species/serpentids/code/mob/serpentids.dm +++ b/modular_ss220/species/serpentids/code/mob/serpentids.dm @@ -19,8 +19,9 @@ dangerous_existence = TRUE species_traits = list(LIPS, NO_HAIR, TTS_TRAIT_ROBOTIZE) - inherent_traits = list(TRAIT_NOPAIN) + inherent_traits = list(TRAIT_NOPAIN, TRAIT_CHUNKYFINGERS) inherent_biotypes = MOB_ORGANIC | MOB_HUMANOID | MOB_REPTILE + no_equip = ITEM_SLOT_OUTER_SUIT | ITEM_SLOT_GLOVES | ITEM_SLOT_SHOES | ITEM_SLOT_JUMPSUIT | ITEM_SLOT_SUIT_STORE dietflags = DIET_OMNI taste_sensitivity = TASTE_SENSITIVITY_SHARP @@ -134,7 +135,6 @@ ) ) - //Перенести на карапас/грудь /datum/species/serpentid/handle_life(mob/living/carbon/human/H) if(gene_lastcall >= SERPENTID_GENE_DEGRADATION_CD) @@ -168,6 +168,11 @@ H.verbs |= /mob/living/carbon/human/proc/emote_serpentidroar H.verbs |= /mob/living/carbon/human/proc/emote_serpentidhiss H.verbs |= /mob/living/carbon/human/proc/emote_serpentidwiggles + H.verbs |= /mob/living/carbon/human/proc/emote_serpentidblinks + H.verbs |= /mob/living/carbon/human/proc/emote_serpentidblinksblades + H.verbs |= /mob/living/carbon/human/proc/emote_serpentidbuzzes + H.verbs |= /mob/living/carbon/human/proc/emote_serpentidmandibles + H.verbs |= /mob/living/carbon/human/proc/emote_serpentidblades H.verbs -= /mob/living/carbon/human/verb/emote_cry H.verbs -= /mob/living/carbon/human/verb/emote_cough H.verbs -= /mob/living/carbon/human/verb/emote_sneeze @@ -177,12 +182,19 @@ H.verbs -= /mob/living/carbon/human/verb/emote_blink H.verbs -= /mob/living/carbon/human/verb/emote_blink_r H.chat_message_y_offset = 11 + H.status_flags &= ~CANPUSH + H.move_resist = MOVE_FORCE_STRONG /datum/species/serpentid/on_species_loss(mob/living/carbon/human/H) ..() H.verbs -= /mob/living/carbon/human/proc/emote_serpentidroar H.verbs -= /mob/living/carbon/human/proc/emote_serpentidhiss H.verbs -= /mob/living/carbon/human/proc/emote_serpentidwiggles + H.verbs -= /mob/living/carbon/human/proc/emote_serpentidblinks + H.verbs -= /mob/living/carbon/human/proc/emote_serpentidblinksblades + H.verbs -= /mob/living/carbon/human/proc/emote_serpentidbuzzes + H.verbs -= /mob/living/carbon/human/proc/emote_serpentidmandibles + H.verbs -= /mob/living/carbon/human/proc/emote_serpentidblades H.verbs |= /mob/living/carbon/human/verb/emote_cough H.verbs |= /mob/living/carbon/human/verb/emote_cry H.verbs |= /mob/living/carbon/human/verb/emote_sneeze @@ -191,6 +203,8 @@ H.verbs |= /mob/living/carbon/human/verb/emote_sigh H.verbs |= /mob/living/carbon/human/verb/emote_blink H.verbs |= /mob/living/carbon/human/verb/emote_blink_r + H.status_flags |= CANPUSH + H.move_resist = MOVE_FORCE_DEFAULT //Работа с инвентарем /datum/species/serpentid/can_equip(obj/item/I, slot, disable_warning = FALSE, mob/living/carbon/human/H) @@ -203,21 +217,48 @@ return FALSE if(ITEM_SLOT_OUTER_SUIT) return FALSE + if(ITEM_SLOT_HEAD) + if(istype(I,/obj/item/clothing/head/helmet/changeling)) //Снятие шлема линга + return FALSE . = .. () //Ограничение на роли антагов (генокрад онли) -/datum/antag_scenario/vampire/New() - restricted_species += list("Serpentid") - . = .. () +/datum/antag_scenario/vampire + restricted_species = list("Machine","Serpentid") -/datum/antag_scenario/traitor/New() - restricted_species += list("Serpentid") - . = .. () +/datum/antag_scenario/traitor + restricted_species = list("Serpentid") -/datum/antag_scenario/team/blood_brothers/New() - restricted_species += list("Serpentid") - . = .. () +/datum/antag_scenario/mindflayer + restricted_species = list("Serpentid") + +/datum/antag_scenario/team/blood_brothers + restricted_species = list("Serpentid") //Расширение для действий органов серпентидов /datum/action/item_action/organ_action/toggle/serpentid name = "serpentid organ selection" + +/datum/action/changeling/transform/sting_action(mob/living/carbon/human/user) + . = ..() + if(!.) + return + SEND_SIGNAL(user, COMSIG_CHANGELING_FINISHED_TRANSFORM) + +/mob/living/death(gibbed) + . = ..() + if(!.) + return + SEND_SIGNAL(src, COMSIG_GADOM_UNLOAD) + +/mob/living/on_immobilized_trait_gain(datum/source) + . = ..() + SEND_SIGNAL(src, COMSIG_GADOM_UNLOAD) + +/mob/living/on_knockedout_trait_gain(datum/source) + . = ..() + SEND_SIGNAL(src, COMSIG_GADOM_UNLOAD) + +/mob/living/on_floored_trait_gain(datum/source) + . = ..() + SEND_SIGNAL(src, COMSIG_GADOM_UNLOAD) diff --git a/modular_ss220/species/serpentids/code/organs/external/serpentids_organs_torso.dm b/modular_ss220/species/serpentids/code/organs/external/serpentids_organs_torso.dm index e8025e4ae5d9..48b97802c827 100644 --- a/modular_ss220/species/serpentids/code/organs/external/serpentids_organs_torso.dm +++ b/modular_ss220/species/serpentids/code/organs/external/serpentids_organs_torso.dm @@ -1,6 +1,6 @@ -#define SERPENTID_ARMOR_THRESHOLD_1 30 -#define SERPENTID_ARMOR_THRESHOLD_2 60 -#define SERPENTID_ARMOR_THRESHOLD_3 90 +#define SERPENTID_ARMOR_THRESHOLD_1 35 +#define SERPENTID_ARMOR_THRESHOLD_2 80 +#define SERPENTID_ARMOR_THRESHOLD_3 130 #define SERPENTID_ARMORED_LOW_TEMP 0 #define SERPENTID_ARMORED_HIGH_TEMP 400 @@ -18,6 +18,16 @@ . = ..() AddComponent(/datum/component/carapace_shell, owner, treshold_1 = SERPENTID_ARMOR_THRESHOLD_1, treshold_2 = SERPENTID_ARMOR_THRESHOLD_2, treshold_3 = SERPENTID_ARMOR_THRESHOLD_3, threshold_cold = SERPENTID_ARMORED_LOW_TEMP, threshold_heat = SERPENTID_ARMORED_HIGH_TEMP, temp_progression = SERPENTID_ARMORED_STEP_TEMP) +/obj/item/organ/external/chest/carapace/Destroy() + if(owner) + owner.clear_alert("carapace_break") + . = ..() + +/obj/item/organ/external/chest/carapace/rejuvenate() + . = ..() + if(owner) + owner.clear_alert("carapace_break") + #undef SERPENTID_ARMOR_THRESHOLD_1 #undef SERPENTID_ARMOR_THRESHOLD_2 #undef SERPENTID_ARMOR_THRESHOLD_3 diff --git a/modular_ss220/species/serpentids/code/organs/internal/implants/serpentid_mantis_blades.dm b/modular_ss220/species/serpentids/code/organs/internal/implants/serpentid_mantis_blades.dm index 0eb45db8c0dd..4cced2c930a5 100644 --- a/modular_ss220/species/serpentids/code/organs/internal/implants/serpentid_mantis_blades.dm +++ b/modular_ss220/species/serpentids/code/organs/internal/implants/serpentid_mantis_blades.dm @@ -8,13 +8,42 @@ desc = "Biological melee weapon. Sharp and durable. It can cut off some heads, or maybe not..." origin_tech = null force = 11 - armour_penetration_flat = 30 + armour_penetration_flat = 20 tool_behaviour = TOOL_SAW new_attack_chain = TRUE + var/obj/item/organ/internal/cyberimp/chest/serpentid_blades/parent_blade_implant /obj/item/kitchen/knife/combat/serpentblade/Initialize(mapload) . = ..() ADD_TRAIT(src, TRAIT_ADVANCED_SURGICAL, ROUNDSTART_TRAIT) - AddComponent(/datum/component/forces_doors_open) + AddComponent(/datum/component/surgery_initiator) + AddComponent(/datum/component/forces_doors_open/serpentid_blades) AddComponent(/datum/component/parry, _stamina_constant = 2, _stamina_coefficient = 0.5, _parryable_attack_types = NON_PROJECTILE_ATTACKS) AddComponent(/datum/component/double_attack) + +/obj/item/kitchen/knife/combat/serpentblade/equipped(mob/user, slot, initial) + . = ..() + var/mob/living/carbon/human/owner = loc + if(ishuman(owner)) + if(IS_CHANGELING(owner) && force == 11) + force = 8 + armour_penetration_flat = 10 + +/obj/item/kitchen/knife/combat/serpentblade/attack(mob/living/M, mob/living/user, def_zone) + . = ..() + var/mob/living/carbon/human/H = user + if(H.invisibility == INVISIBILITY_LEVEL_TWO || H.alpha != 255) + var/obj/item/organ/internal/kidneys/serpentid/kidneys= H.get_int_organ(/obj/item/organ/internal/kidneys/serpentid) + H.reset_visibility() + kidneys.switch_mode(force_off = TRUE) + +/// subtype for mantis blades +/datum/component/forces_doors_open/serpentid_blades/on_interact(datum/source, mob/user, atom/target) + if(check_intent(user)) + return + + if(try_to_open_firedoor(target)) + return ITEM_INTERACT_COMPLETE + + if(try_to_force_open_airlock(user, target)) + return ITEM_INTERACT_COMPLETE diff --git a/modular_ss220/species/serpentids/code/organs/internal/implants/serpentid_mantis_chest.dm b/modular_ss220/species/serpentids/code/organs/internal/implants/serpentid_mantis_chest.dm index 7ec2b5818b1f..357ce7640b77 100644 --- a/modular_ss220/species/serpentids/code/organs/internal/implants/serpentid_mantis_chest.dm +++ b/modular_ss220/species/serpentids/code/organs/internal/implants/serpentid_mantis_chest.dm @@ -5,7 +5,7 @@ icon_state = "chest_implant" parent_organ = "chest" actions_types = list(/datum/action/item_action/organ_action/toggle/switch_blades) - contents = newlist(/obj/item/kitchen/knife/combat/serpentblade,/obj/item/kitchen/knife/combat/serpentblade) + contents = newlist(/obj/item/kitchen/knife/combat/serpentblade) action_icon = list(/datum/action/item_action/organ_action/toggle/switch_blades = 'modular_ss220/species/serpentids/icons/organs.dmi') action_icon_state = list(/datum/action/item_action/organ_action/toggle/switch_blades = "serpentid_hand_act") var/obj/item/holder_l = null @@ -19,6 +19,13 @@ unremovable = TRUE emp_proof = TRUE var/first_recollor = TRUE + destroy_on_removal = TRUE + stealth_level = 5 + +/obj/item/organ/internal/cyberimp/chest/serpentid_blades/Initialize(mapload) + . = ..() + var/obj/item/kitchen/knife/combat/serpentblade/blade = contents[1] + blade.parent_blade_implant = src /datum/action/item_action/organ_action/toggle/switch_blades name = "Switch Threat Mode" @@ -47,8 +54,8 @@ if(crit_fail || (!holder_l && !length(contents))) to_chat(owner, span_warning("Вы не можете поднять клинки")) return - var/extended = holder_l && !(holder_l in src) - if(extended) + + if(blades_active) if(!activation_in_progress) activation_in_progress = TRUE Retract() @@ -86,6 +93,21 @@ holder_l.w_class = WEIGHT_CLASS_HUGE holder_l.materials = null + if(IS_CHANGELING(owner)) //Если линг + for(var/arm_slot in list(ITEM_SLOT_LEFT_HAND,ITEM_SLOT_RIGHT_HAND)) //Если активны в одной руке щит или меч - убрать + var/obj/item/arm_item = owner.get_item_by_slot(arm_slot) + + if(arm_item) + if(istype(arm_item, /obj/item/melee/arm_blade) || istype(arm_item, /obj/item/shield/changeling)) + if(istype(arm_item, /obj/item/melee/arm_blade)) + var/obj/item/melee/arm_blade/armblade = arm_item + var/datum/action/changeling/weapon/item_datum = armblade.parent_action + item_datum.retract(owner, TRUE) + else + var/obj/item/shield/changeling/armshield = arm_item + qdel(armshield) + + for(var/arm_slot in list(ITEM_SLOT_LEFT_HAND,ITEM_SLOT_RIGHT_HAND)) var/obj/item/arm_item = owner.get_item_by_slot(arm_slot) @@ -100,11 +122,15 @@ else to_chat(owner, span_notice("You drop [arm_item] to activate [src]!")) - if(!owner.put_in_l_hand(holder_l)) - return + holder_l.forceMove(owner) + owner.l_hand = holder_l + holder_l.layer = ABOVE_HUD_LAYER //TODO: move to equipped? + holder_l.plane = ABOVE_HUD_PLANE //TODO: move to equipped? + holder_l.equipped(owner, ITEM_SLOT_LEFT_HAND) + owner.update_inv_l_hand() blades_active = TRUE - playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1) + playsound(get_turf(owner), 'sound/weapons/blade_unsheath.ogg', 50, 1) new_icon_state = "blades_1" update_icon(UPDATE_OVERLAYS) return TRUE @@ -116,7 +142,7 @@ owner.transfer_item_to(holder_l, src, force = TRUE) holder_l = null blades_active = FALSE - playsound(get_turf(owner), 'sound/mecha/mechmove03.ogg', 50, 1) + playsound(get_turf(owner), 'sound/weapons/blade_unsheath.ogg', 50, 1) new_icon_state = "blades_0" update_icon(UPDATE_OVERLAYS) @@ -126,8 +152,6 @@ return var/obj/item/organ/internal/cyberimp/chest/serpentid_blades/blades_implant = M.get_int_organ(/obj/item/organ/internal/cyberimp/chest/serpentid_blades) if(blades_implant) - if(blades_implant.owner.invisibility != INVISIBILITY_OBSERVER) - blades_implant.owner.reset_visibility() if(blades_implant.blades_active) if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(M, 0, M.name, attack_type = UNARMED_ATTACK)) add_attack_logs(M, H, "Melee attacked with blades (miss/block)") @@ -138,7 +162,6 @@ if(INTENT_HELP) help(M, H, attacker_style) - if(INTENT_GRAB) blades_grab(M, H, attacker_style) @@ -150,10 +173,21 @@ else . = ..() else + if(isserpentid(M)) + var/obj/item/organ/internal/kidneys/serpentid/kidneys = M.get_int_organ(/obj/item/organ/internal/kidneys/serpentid) + M.reset_visibility() + kidneys.switch_mode(force_off = TRUE) . = ..() //Модификация усиленного граба /datum/species/proc/blades_grab(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) + var/grab_level = GRAB_AGGRESSIVE + if(isserpentid(user) && (user.invisibility == INVISIBILITY_LEVEL_TWO)) + var/obj/item/organ/internal/kidneys/serpentid/kidneys = user.get_int_organ(/obj/item/organ/internal/kidneys/serpentid) + user.reset_visibility() + kidneys.switch_mode(force_off = TRUE) + else + grab_level = GRAB_PASSIVE if(target.check_block()) target.visible_message(span_warning("[target] blocks [user]'s grab attempt!")) return FALSE @@ -164,11 +198,15 @@ user.swap_hand() target.grabbedby(user) var/obj/item/grab/grab_item = user.get_active_hand() - grab_item.state = GRAB_AGGRESSIVE + grab_item.state = grab_level grab_item.icon_state = "grabbed1" //Модификация усиленного дизарма /datum/species/proc/blades_disarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style) + if(isserpentid(user)) + var/obj/item/organ/internal/kidneys/serpentid/kidneys = user.get_int_organ(/obj/item/organ/internal/kidneys/serpentid) + user.reset_visibility() + kidneys.switch_mode(force_off = TRUE) if(user == target) return FALSE if(target.check_block()) @@ -265,5 +303,9 @@ return FALSE if(!user.hand) user.swap_hand() + if(isserpentid(user)) + var/obj/item/organ/internal/kidneys/serpentid/kidneys = user.get_int_organ(/obj/item/organ/internal/kidneys/serpentid) + user.reset_visibility() + kidneys.switch_mode(force_off = TRUE) var/obj/item/kitchen/knife/combat/serpentblade/blade = user.get_active_hand() blade.attack(target, user) diff --git a/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_ears.dm b/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_ears.dm index 7bbc3db1bc9a..5096e08588b5 100644 --- a/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_ears.dm +++ b/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_ears.dm @@ -16,7 +16,7 @@ /obj/item/organ/internal/ears/serpentid/Initialize(mapload) . = ..() - AddComponent(/datum/component/organ_decay, 0.05, BASIC_RECOVER_VALUE) + AddComponent(/datum/component/organ_decay, 0.2, BASIC_RECOVER_VALUE) AddComponent(/datum/component/organ_toxin_damage, 0.05) AddComponent(/datum/component/hunger_organ) AddComponent(/datum/component/organ_action, radial_action_state, radial_action_icon) @@ -39,6 +39,9 @@ owner.visible_message(span_notice("Тело [owner] перестает колыхаться.")) SEND_SIGNAL(src, COMSIG_ORGAN_CHANGE_CHEM_CONSUPTION, chemical_consuption) +/obj/item/organ/internal/ears/serpentid/get_active_state() + return active + /obj/item/organ/internal/ears/serpentid/proc/sense_creatures() for(var/mob/living/creature in range(9, owner)) var/last_movement_timer = world.time - creature.l_move_time diff --git a/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_eyes.dm b/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_eyes.dm index 6d4e0330acd5..b09655456773 100644 --- a/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_eyes.dm +++ b/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_eyes.dm @@ -18,7 +18,7 @@ /obj/item/organ/internal/eyes/serpentid/Initialize(mapload) . = ..() - AddComponent(/datum/component/organ_decay, 0.04, BASIC_RECOVER_VALUE) + AddComponent(/datum/component/organ_decay, 0.16, BASIC_RECOVER_VALUE) AddComponent(/datum/component/organ_toxin_damage, 0.02) AddComponent(/datum/component/hunger_organ) AddComponent(/datum/component/organ_action, radial_action_state, radial_action_icon) @@ -54,13 +54,18 @@ . = ..() if(!force_off && owner?.nutrition >= NUTRITION_LEVEL_HYPOGLYCEMIA && !(status & ORGAN_DEAD) && !active) see_in_dark = 8 + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE chemical_consuption = initial(chemical_consuption) active = TRUE owner.visible_message(span_warning("Зрачки [owner] расширяются!")) else see_in_dark = initial(see_in_dark) + lighting_alpha = initial(lighting_alpha) chemical_consuption = 0 active = FALSE owner.visible_message(span_notice("Зрачки [owner] сужаются.")) owner?.update_sight() SEND_SIGNAL(src, COMSIG_ORGAN_CHANGE_CHEM_CONSUPTION, chemical_consuption) + +/obj/item/organ/internal/eyes/serpentid/get_active_state() + return active diff --git a/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_heart.dm b/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_heart.dm index f5054489ae04..b722a66c5828 100644 --- a/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_heart.dm +++ b/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_heart.dm @@ -1,13 +1,14 @@ /obj/item/organ/internal/heart/serpentid name = "double heart" icon = 'modular_ss220/species/serpentids/icons/organs.dmi' - icon_state = "heart_on" + icon_state = "heart-on" + dead_icon = "heart-off" dead_icon = "heart" base_icon_state = "heart" desc = "A pair of hearts." /obj/item/organ/internal/heart/serpentid/Initialize(mapload) . = ..() - AddComponent(/datum/component/organ_decay, 0.5, BASIC_RECOVER_VALUE) + AddComponent(/datum/component/organ_decay, 0.8, BASIC_RECOVER_VALUE) AddComponent(/datum/component/organ_toxin_damage, 0.03) AddComponent(/datum/component/defib_heart_hunger) diff --git a/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_kidneys.dm b/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_kidneys.dm index cee80221cc3d..8253419b7e7f 100644 --- a/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_kidneys.dm +++ b/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_kidneys.dm @@ -14,7 +14,7 @@ /obj/item/organ/internal/kidneys/serpentid/Initialize(mapload) . = ..() - AddComponent(/datum/component/organ_decay, 0.03, BASIC_RECOVER_VALUE) + AddComponent(/datum/component/organ_decay, 0.12, BASIC_RECOVER_VALUE) AddComponent(/datum/component/organ_toxin_damage, 0.15) AddComponent(/datum/component/hunger_organ) AddComponent(/datum/component/organ_action, radial_action_state, radial_action_icon) @@ -42,3 +42,6 @@ chemical_consuption = 0 owner.visible_message(span_notice("Тело [owner] перестает преломлять свет.")) SEND_SIGNAL(src, COMSIG_ORGAN_CHANGE_CHEM_CONSUPTION, chemical_consuption) + +/obj/item/organ/internal/kidneys/serpentid/get_active_state() + return cloak_engaged diff --git a/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_liver.dm b/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_liver.dm index f24d54aec74a..d641dfb37c3c 100644 --- a/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_liver.dm +++ b/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_liver.dm @@ -10,7 +10,7 @@ /obj/item/organ/internal/liver/serpentid/Initialize(mapload) . = ..() - AddComponent(/datum/component/organ_decay, 0.04, BASIC_RECOVER_VALUE) + AddComponent(/datum/component/organ_decay, 0.3, BASIC_RECOVER_VALUE) AddComponent(/datum/component/organ_toxin_damage, 0.1) /obj/item/organ/internal/liver/serpentid/on_life() diff --git a/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_lungs.dm b/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_lungs.dm index b9a1f8e4a64f..4c07d29fa4da 100644 --- a/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_lungs.dm +++ b/modular_ss220/species/serpentids/code/organs/internal/organs/serpentids_organs_lungs.dm @@ -27,7 +27,7 @@ /obj/item/organ/internal/lungs/serpentid/Initialize(mapload) . = ..() - AddComponent(/datum/component/organ_decay, 0.05, BASIC_RECOVER_VALUE) + AddComponent(/datum/component/organ_decay, 0.25, BASIC_RECOVER_VALUE) AddComponent(/datum/component/organ_toxin_damage, 0.05) AddComponent(/datum/component/organ_action, radial_action_state, radial_action_icon) AddComponent(/datum/component/hunger_organ) @@ -58,6 +58,7 @@ chemical_consuption = initial(chemical_consuption) last_safe_zone_check = world.time owner.visible_message(span_warning("Рот [owner] замирает, переставая выдыхать воздух!")) + SEND_SIGNAL(src, COMSIG_ORGAN_CHANGE_CHEM_CONSUPTION, chemical_consuption) else switch_mode_off() @@ -65,6 +66,7 @@ active_secretion = FALSE chemical_consuption = 0 owner.visible_message(span_notice("Из рта [owner] снова начинает исходить воздух.")) + SEND_SIGNAL(src, COMSIG_ORGAN_CHANGE_CHEM_CONSUPTION, chemical_consuption) /obj/item/organ/internal/lungs/serpentid/switch_mode(force_off = FALSE) . = ..() @@ -72,7 +74,9 @@ switch_mode_on() else switch_mode_off() - SEND_SIGNAL(src, COMSIG_ORGAN_CHANGE_CHEM_CONSUPTION, chemical_consuption) + +/obj/item/organ/internal/lungs/serpentid/get_active_state() + return active_secretion /obj/item/organ/internal/lungs/serpentid/on_life() . = ..() @@ -95,7 +99,8 @@ owner.reagents.add_reagent("salbutamol", salbutamol_production) // Если Серпентид выделяет вещества, но среда опасна и не активен "болон" - дышать через мешок - if(danger_air && !owner.internal) + if(danger_air && !ispath(owner.internal, /obj/item/tank/internals/oxygen/)) + owner.internal = null //Необходимо для сброса баллона и переключения дыхания на мешок owner.internal = serpentid_vault // Если Серпентид выделяет вещества, но среда не опасна и с момента последней проверки на безопасность дыхание прошло более 10 секунд - прекращение выделения @@ -103,9 +108,12 @@ if(safe_zone_timer > SERPENTID_LUNGS_SAFE_TIMER && !danger_air) switch_mode_off() + else + if(owner.internal == serpentid_vault) + owner.internal = null // Если Серпентид не выделяет вещества, и среда опасна и он без сознания - начать выделять вещества if(danger_air && (owner.stat == UNCONSCIOUS) && !active_secretion) - if(!owner.internal) + if(!active_secretion) switch_mode_on() // Если среда не опасна и Серпентид дышит через мешок - дышать нормально diff --git a/modular_ss220/species/serpentids/icons/mob/r_serpentid_blood.dmi b/modular_ss220/species/serpentids/icons/mob/r_serpentid_blood.dmi index 3de76cd5019a..f2d676aae5f4 100644 Binary files a/modular_ss220/species/serpentids/icons/mob/r_serpentid_blood.dmi and b/modular_ss220/species/serpentids/icons/mob/r_serpentid_blood.dmi differ diff --git a/modular_ss220/species/serpentids/icons/organs.dmi b/modular_ss220/species/serpentids/icons/organs.dmi index 86520e31b911..f46c08cc9f95 100644 Binary files a/modular_ss220/species/serpentids/icons/organs.dmi and b/modular_ss220/species/serpentids/icons/organs.dmi differ