Девять новых испытаний некромантии

Вселиться в зомби и в своего питомца, подорвать одержимого копа, 25 убийств
змеёй, войти в чертоги (ChallengeStatAwarded: счёт шлёт NecroChallenges.cs),
найти череп (Gather), сок чёрной розы, мод «Мёртвая буря», гримуар медведя
(Craft). Тексты намёком, 13 языков.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
AlexCube
2026-10-12 11:39:01 +03:00
co-authored by Claude Opus 5.5
parent 47a4b345af
commit cb2a4f19b4
8 changed files with 109 additions and 1 deletions
File diff suppressed because one or more lines are too long
+52
View File
@@ -182,6 +182,58 @@
reward_text_key="challenge_reward_2000xp" reward_event="challenge_reward_2000">
<objective type="BlockPlace" block="necroHeresyPyramid" count="1"/>
</challenge>
<!-- ИСПЫТАНИЯ 12.10.2026 (указание: «из того что уже реализовано сделай ещё несколько испытаний»).
Тексты - намёком, без инструкций (описание мода «должно привлекать, а не спойлерить»).
Действия (вселение, подрыв, змея, чертоги) - ChallengeStatAwarded: счёт шлёт код мода
(NecroChallenges.cs), как ванильное «попить из озера». Череп - Gather: игра проверяет, что он
лежит в рюкзаке или на поясе (выпадает с шансом 2% при обыске красного трупа). Награды по
прежнему счёту: 1000 - сделать впервые, 2000 - редкое или дорогое, 2500 - долгий счёт и
самый дорогой гримуар. -->
<challenge name="necroPossessZombie" title_key="challengeNecroPossessZombieTitle" icon="ui_game_symbol_zombie" group="NecroPath"
short_description_key="challengeNecroPossessZombieShort" description_key="challengeNecroPossessZombieDesc"
reward_text_key="challenge_reward_1000xp" reward_event="challenge_reward_1000">
<objective type="ChallengeStatAwarded" challenge_stat="necroStatPossessZombie" count="1" stat_text_key="challengeNecroPossessZombieShort"/>
</challenge>
<challenge name="necroPossessPet" title_key="challengeNecroPossessPetTitle" icon="ui_game_symbol_tracking_wolf" group="NecroPath"
short_description_key="challengeNecroPossessPetShort" description_key="challengeNecroPossessPetDesc"
reward_text_key="challenge_reward_1000xp" reward_event="challenge_reward_1000">
<objective type="ChallengeStatAwarded" challenge_stat="necroStatPossessPet" count="1" stat_text_key="challengeNecroPossessPetShort"/>
</challenge>
<challenge name="necroLivingBomb" title_key="challengeNecroLivingBombTitle" icon="ui_game_symbol_explosion" group="NecroPath"
short_description_key="challengeNecroLivingBombShort" description_key="challengeNecroLivingBombDesc"
reward_text_key="challenge_reward_2000xp" reward_event="challenge_reward_2000">
<objective type="ChallengeStatAwarded" challenge_stat="necroStatLivingBomb" count="1" stat_text_key="challengeNecroLivingBombShort"/>
</challenge>
<challenge name="necroSnakeHunt" title_key="challengeNecroSnakeHuntTitle" icon="ui_game_symbol_tracking_snake" group="NecroPath"
short_description_key="challengeNecroSnakeHuntShort" description_key="challengeNecroSnakeHuntDesc"
reward_text_key="challenge_reward_2500xp" reward_event="challenge_reward_2500">
<objective type="ChallengeStatAwarded" challenge_stat="necroStatSnakeKill" count="25" stat_text_key="challengeNecroSnakeHuntShort"/>
</challenge>
<challenge name="necroMindPalace" title_key="challengeNecroMindPalaceTitle" icon="ui_game_symbol_map_bed" group="NecroPath"
short_description_key="challengeNecroMindPalaceShort" description_key="challengeNecroMindPalaceDesc"
reward_text_key="challenge_reward_1000xp" reward_event="challenge_reward_1000">
<objective type="ChallengeStatAwarded" challenge_stat="necroStatMindPalace" count="1" stat_text_key="challengeNecroMindPalaceShort"/>
</challenge>
<challenge name="necroYorick" title_key="challengeNecroYorickTitle" icon="ui_game_symbol_candy_skull_crushers" group="NecroPath"
short_description_key="challengeNecroYorickShort" description_key="challengeNecroYorickDesc"
reward_text_key="challenge_reward_2000xp" reward_event="challenge_reward_2000">
<objective type="Gather" item="necroSkull" count="1"/>
</challenge>
<challenge name="necroBlackRose" title_key="challengeNecroBlackRoseTitle" icon="ui_game_symbol_flower" group="NecroPath"
short_description_key="challengeNecroBlackRoseShort" description_key="challengeNecroBlackRoseDesc"
reward_text_key="challenge_reward_1000xp" reward_event="challenge_reward_1000">
<objective type="Craft" item="resourceNecroBlackRoseJuice"/>
</challenge>
<challenge name="necroDeadStorm" title_key="challengeNecroDeadStormTitle" icon="ui_game_symbol_twitch_spawn_storm" group="NecroPath"
short_description_key="challengeNecroDeadStormShort" description_key="challengeNecroDeadStormDesc"
reward_text_key="challenge_reward_2000xp" reward_event="challenge_reward_2000">
<objective type="Craft" item="necroModKnifeDeadStorm"/>
</challenge>
<challenge name="necroBearHug" title_key="challengeNecroBearTitle" icon="ui_game_symbol_tracking_bear" group="NecroPath"
short_description_key="challengeNecroBearShort" description_key="challengeNecroBearDesc"
reward_text_key="challenge_reward_2500xp" reward_event="challenge_reward_2500">
<objective type="Craft" item="bookSummonZombieBear"/>
</challenge>
</append>
</config>
+1
View File
@@ -978,6 +978,7 @@ namespace NecromancerTome
LogCell(world, _origin + KnifeAt, "нож");
LogCell(world, _origin + BookAt, "книга");
MindControl.Begin(player, spawn, SpawnYaw);
NecroChallenges.Award(NecroChallenges.MindPalace);
player.ScreenEffectManager?.SetScreenEffect("FadeToBlack", 0f, 1.5f);
}
else if (Time.time > _deadline)
+22
View File
@@ -0,0 +1,22 @@
namespace NecromancerTome
{
/// <summary>
/// Испытания вкладки «Некромантия» на действия, а не на крафт (12.10.2026): код мода засчитывает
/// событие, игра ведёт счёт сама - цель challenges.xml type="ChallengeStatAwarded" с тем же
/// challenge_stat (как ванильное «попить из озера» - AwardChallenge drinkwater). Счёт - у локального
/// игрока (QuestEventManager.Current), поэтому звать там, где действие делает он сам.
/// </summary>
public static class NecroChallenges
{
public const string PossessZombie = "necroStatPossessZombie";
public const string PossessPet = "necroStatPossessPet";
public const string LivingBomb = "necroStatLivingBomb";
public const string SnakeKill = "necroStatSnakeKill";
public const string MindPalace = "necroStatMindPalace";
public static void Award(string _stat, int _count = 1)
{
QuestEventManager.Current?.ChallengeAwardCredited(_stat, _count);
}
}
}
+2
View File
@@ -321,6 +321,7 @@ namespace NecromancerTome
_zombie.motion = Vector3.zero;
}
Debug.Log("[NecromancerTome] Possession: вселение в " + (_pet ? "питомца " : "") + _zombie.EntityName + " (" + _zombie.entityId + ")" + (Flying ? ", полёт" : ""));
NecroChallenges.Award(_pet ? NecroChallenges.PossessPet : NecroChallenges.PossessZombie);
return true;
}
@@ -555,6 +556,7 @@ namespace NecromancerTome
{
Debug.Log("[NecromancerTome] Possession: подрыв " + z.EntityName);
cop.HandlePrimingDetonator();
NecroChallenges.Award(NecroChallenges.LivingBomb);
}
Ranged(z, ranged, rangedHeld);
+5 -1
View File
@@ -471,7 +471,11 @@ namespace NecromancerTome
NecroBurst.Pending.Add(target.entityId);
target.DamageEntity(new DamageSourceEntity(EnumDamageSource.External, EnumDamageTypes.Piercing, _player.entityId),
99999, false);
if (!target.IsDead())
if (target.IsDead())
{
NecroChallenges.Award(NecroChallenges.SnakeKill);
}
else
{
NecroBurst.Pending.Remove(target.entityId);
NoLoot.Remove(target.entityId);
Binary file not shown.
Binary file not shown.