Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Example Implementation: MwSkinEvents.cs
Updated a week agousing MwSkinAdditions;
using RoR2;
using UnityEngine;
namespace MioHuntress {
public static class MwSkinEvents {
public static VoiceGroup[] voiceGroups;
public static VoiceArray blockDamage = new VoiceArray(
new VoiceInfo[] {
new VoiceInfo("Play_MioHuntress_Block_1", 1.1f),
new VoiceInfo("Play_MioHuntress_Block_2", 1.7f),
}
);
public static VoiceArray damage = new VoiceArray(
new VoiceInfo[] {
new VoiceInfo("Play_MioHuntress_Damage_1", 0.6f),
new VoiceInfo("Play_MioHuntress_Damage_2", 0.8f),
new VoiceInfo("Play_MioHuntress_Damage_3", 0.9f),
new VoiceInfo("Play_MioHuntress_Damage_4", 0.6f),
new VoiceInfo("Play_MioHuntress_Damage_5", 0.5f),
new VoiceInfo("Play_MioHuntress_Damage_6", 0.5f),
new VoiceInfo("Play_MioHuntress_Damage_7", 0.5f),
}
);
public static VoiceArray death = new VoiceArray(
new VoiceInfo[] {
new VoiceInfo("Play_MioHuntress_Death_1", 2.7f),
new VoiceInfo("Play_MioHuntress_Death_2", 2.1f),
new VoiceInfo("Play_MioHuntress_Death_3", 1.0f),
}
);
public static VoiceArray defeatBossGroup = new VoiceArray(
new VoiceInfo[] {
new VoiceInfo("Play_MioHuntress_Defeat_Boss_Group_1", 1.5f),
new VoiceInfo("Play_MioHuntress_Defeat_Boss_Group_2", 1.3f),
new VoiceInfo("Play_MioHuntress_Defeat_Boss_Group_3", 1.8f),
new VoiceInfo("Play_MioHuntress_Defeat_Boss_Group_3", 1.3f),
}
);
public static VoiceArray getItem = new VoiceArray(
new VoiceInfo[] {
new VoiceInfo("Play_MioHuntress_Get_Item_1", 1.0f),
new VoiceInfo("Play_MioHuntress_Get_Item_2", 2.5f),
new VoiceInfo("Play_MioHuntress_Get_Item_3", 1.4f),
new VoiceInfo("Play_MioHuntress_Get_Item_4", 1.6f),
new VoiceInfo("Play_MioHuntress_Get_Item_5", 1.6f),
}
);
public static VoiceArray heal = new VoiceArray(
new VoiceInfo[] {
new VoiceInfo("Play_MioHuntress_Heal_1", 1.7f),
new VoiceInfo("Play_MioHuntress_Heal_2", 1.5f),
}
);
public static VoiceArray leavePod = new VoiceArray(
new VoiceInfo[] {
new VoiceInfo("Play_MioHuntress_Leave_Pod_1", 1.0f),
new VoiceInfo("Play_MioHuntress_Leave_Pod_2", 1.1f),
}
);
public static VoiceArray levelUp = new VoiceArray(
new VoiceInfo[] {
new VoiceInfo("Play_MioHuntress_Level_Up_1", 1.5f),
new VoiceInfo("Play_MioHuntress_Level_Up_2", 1.3f),
new VoiceInfo("Play_MioHuntress_Level_Up_2", 1.6f),
}
);
public static VoiceArray lowHealth = new VoiceArray(
new VoiceInfo[] {
new VoiceInfo("Play_MioHuntress_Low_Health_1", 3.4f),
new VoiceInfo("Play_MioHuntress_Low_Health_2", 1.6f),
}
);
public static VoiceArray secondary = new VoiceArray(
new VoiceInfo[] {
new VoiceInfo("Play_MioHuntress_Secondary_1", 1.0f),
new VoiceInfo("Play_MioHuntress_Secondary_2", 0.8f),
new VoiceInfo("Play_MioHuntress_Secondary_3", 1.1f),
new VoiceInfo("Play_MioHuntress_Secondary_4", 1.3f),
new VoiceInfo("Play_MioHuntress_Secondary_5", 1.6f),
}
);
public static VoiceArray shrineFailure = new VoiceArray(
new VoiceInfo[] {
new VoiceInfo("Play_MioHuntress_Shrine_Failure_1", 0.7f),
new VoiceInfo("Play_MioHuntress_Shrine_Failure_2", 0.7f),
}
);
public static VoiceArray shrineSuccess = new VoiceArray(
new VoiceInfo[] {
new VoiceInfo("Play_MioHuntress_Shrine_Success_1", 1.5f),
new VoiceInfo("Play_MioHuntress_Shrine_Success_2", 0.8f),
new VoiceInfo("Play_MioHuntress_Shrine_Success_3", 0.6f),
}
);
public static VoiceArray special = new VoiceArray(
new VoiceInfo[] {
new VoiceInfo("Play_MioHuntress_Special_1", 1.8f),
new VoiceInfo("Play_MioHuntress_Special_2", 1.2f),
new VoiceInfo("Play_MioHuntress_Special_3", 1.2f),
new VoiceInfo("Play_MioHuntress_Special_4", 1.3f),
new VoiceInfo("Play_MioHuntress_Special_5", 1.0f),
}
);
public static VoiceArray endTP = new VoiceArray(
new VoiceInfo[] {
new VoiceInfo("Play_MioHuntress_TP_End_1", 2.6f),
new VoiceInfo("Play_MioHuntress_TP_End_2", 2.3f),
new VoiceInfo("Play_MioHuntress_TP_End_3", 2.2f),
new VoiceInfo("Play_MioHuntress_TP_End_4", 3.2f),
new VoiceInfo("Play_MioHuntress_TP_End_5", 3.0f),
new VoiceInfo("Play_MioHuntress_TP_End_6", 3.0f),
new VoiceInfo("Play_MioHuntress_TP_End_7", 2.1f),
new VoiceInfo("Play_MioHuntress_TP_End_8", 1.6f),
}
);
public static VoiceArray startTP = new VoiceArray(
new VoiceInfo[] {
new VoiceInfo("Play_MioHuntress_TP_Start_1", 2.0f),
new VoiceInfo("Play_MioHuntress_TP_Start_2", 2.2f),
new VoiceInfo("Play_MioHuntress_TP_Start_3", 1.6f),
new VoiceInfo("Play_MioHuntress_TP_Start_4", 3.4f),
new VoiceInfo("Play_MioHuntress_TP_Start_5", 2.8f),
new VoiceInfo("Play_MioHuntress_TP_Start_6", 3.0f),
new VoiceInfo("Play_MioHuntress_TP_Start_7", 1.6f),
new VoiceInfo("Play_MioHuntress_TP_Start_8", 1.9f),
new VoiceInfo("Play_MioHuntress_TP_Start_9", 1.4f),
new VoiceInfo("Play_MioHuntress_TP_Start_10", 2.7f),
}
);
public static void Init(SkinDef skinDef) {
EventSub eventSub = new EventSub(
skinDef,
new EventSubOptions() {
boneTransformations = new BoneTransformation[] {
new BoneTransformation("HuntressArmature/ROOT/base/stomach/chest/upper_arm.l", Vector3.one * 0.822f, Vector3.zero),
new BoneTransformation("HuntressArmature/ROOT/base/stomach/chest/upper_arm.r", Vector3.one * 0.822f, Vector3.zero),
new BoneTransformation("HuntressArmature/ROOT/base/BowRoot", Vector3.one * 0.822f, Vector3.zero),
},
useAnimations = true,
blinkAnimations = new BlendShapeAnimation[] {
new BlinkBlendShapeAnimation("HuntressMesh", "LowBlink")
},
voiceGroups = voiceGroups,
conditionalIdleAnimations = new IdleAnimation[] {
new IdleAnimation(
new BlendShapeAnimation[] {
new BlendShapeAnimation("HuntressMesh", "EyesTense", 0, -2, 0.3f, Mathf.Infinity, 0.3f),
},
InCombat,
true
),
new IdleAnimation(
new BlendShapeAnimation[] {
new BlendShapeAnimation("HuntressMesh", "BrowHurt", 1, -1, 0.3f, Mathf.Infinity, 0.3f),
},
IsLowHealth,
true
)
}
}
);
eventSub.TakeDamage += ExpressionOnHit;
eventSub.Death += ExpressionOnDeath;
eventSub.ShrineFailure += ExpressionOnShrineFailure;
eventSub.LevelUp += ExpressionOnHoldoutOnLevelOnMithrix;
eventSub.MithrixDefeat += ExpressionOnHoldoutOnLevelOnMithrix;
eventSub.HoldoutZoneCharged += ExpressionOnHoldoutOnLevelOnMithrix;
eventSub.GetItem += ExpressionOnItem;
eventSub.TakeDamage += LowHealthLine;
eventSub.Heal += HeavyHealLine;
eventSub.TakeDamage += (GameObject body, DamageReport damageReport) => { body?.GetComponent<VoiceController>()?.TryPlayRandomUniqueSoundServer(damage, body, 0.4f); };
eventSub.Death += (GameObject body) => { body?.GetComponent<VoiceController>()?.TryPlayRandomSoundServer(death, body); };
eventSub.DefeatBossGroup += (GameObject body) => { body?.GetComponent<VoiceController>()?.TryPlayRandomUniqueSoundServer(defeatBossGroup, body); };
eventSub.TeleporterStart += (GameObject body) => { body?.GetComponent<VoiceController>()?.TryPlayRandomUniqueSoundServer(startTP, body); };
eventSub.TeleporterEnd += (GameObject body) => { body?.GetComponent<VoiceController>()?.TryPlayRandomUniqueSoundServer(endTP, body); };
eventSub.LeavePod += (GameObject body) => { body?.GetComponent<VoiceController>()?.TryPlayRandomUniqueSoundServer(leavePod, body); };
eventSub.GetItem += (GameObject body, ItemIndex itemIndex) => { body?.GetComponent<VoiceController>()?.TryPlayRandomUniqueSoundServer(getItem, body, 0.75f); };
eventSub.ShrineSuccess += (GameObject body) => { body?.GetComponent<VoiceController>()?.TryPlayRandomUniqueSoundServer(shrineSuccess, body); };
eventSub.ShrineFailure += (GameObject body) => { body?.GetComponent<VoiceController>()?.TryPlayRandomUniqueSoundServer(shrineFailure, body); };
eventSub.LevelUp += (GameObject body) => { body?.GetComponent<VoiceController>()?.TryPlayRandomUniqueSoundServer(levelUp, body, 0.25f); };
eventSub.BearDamageBlock += (GameObject body) => { body?.GetComponent<VoiceController>()?.TryPlayRandomUniqueSoundServer(blockDamage, body, 0.6f); };
eventSub.UseSpecial += (GameObject body) => { body?.GetComponent<VoiceController>()?.TryPlayRandomUniqueSoundServer(special, body, 0.45f); };
eventSub.UseSecondary += (GameObject body) => { body?.GetComponent<VoiceController>()?.TryPlayRandomUniqueSoundServer(secondary, body, 0.4f); };
eventSub.Init();
}
private static bool InCombat(ExpressionController expressionController) {
CharacterBody characterBody = expressionController.characterBody;
if (characterBody != null) {
return !characterBody.outOfCombat;
}
return false;
}
private static bool IsLowHealth(ExpressionController expressionController) {
CharacterBody characterBody = expressionController.characterBody;
if (characterBody != null) {
return characterBody?.healthComponent?.combinedHealthFraction <= 0.25f;
}
return false;
}
private static void LowHealthLine(GameObject body, DamageReport damageReport) {
if (damageReport?.victim?.GetComponent<HealthComponent>().combinedHealthFraction <= 0.25f) {
body?.GetComponent<VoiceController>()?.TryPlayRandomUniqueSoundServer(lowHealth, body, 0.8f);
}
}
private static void HeavyHealLine(GameObject body, float amount) {
if (body?.GetComponent<VoiceController>() is VoiceController voiceController) {
if (body?.GetComponent<CharacterBody>()?.healthComponent is HealthComponent healthComponent
&& amount >= 0.5f * healthComponent.fullCombinedHealth
&& healthComponent.combinedHealth < 0.5f * healthComponent.fullCombinedHealth) {
voiceController.TryPlayRandomSoundServer(heal, body);
}
}
}
private static void ExpressionOnHit(GameObject body, DamageReport damageReport) {
if (damageReport?.victim?.GetComponent<HealthComponent>().combinedHealthFraction > 0.25f && body.GetComponent<ExpressionController>() is ExpressionController expressionController) {
expressionController.TryPlayAnimation(new BlendShapeAnimation("HuntressMesh", "HighBlink", 0, 0, 0.1f, 0.1f, 0.1f, true));
expressionController.TryPlayAnimation(new BlendShapeAnimation("HuntressMesh", "BrowHurt", 1, 0, 0.1f, 0.1f, 0.1f));
expressionController.TryPlayAnimation(new BlendShapeAnimation("HuntressMesh", "MouthHurt", 2, 0, 0.1f, 0.1f, 0.1f));
}
}
private static void ExpressionOnShrineFailure(GameObject body) {
if (body.GetComponent<ExpressionController>() is ExpressionController expressionController) {
expressionController.TryPlayAnimation(new BlendShapeAnimation("HuntressMesh", "EyesDisappointed", 0, 0, 0.2f, 0.4f, 0.2f, true));
expressionController.TryPlayAnimation(new BlendShapeAnimation("HuntressMesh", "MouthFrown", 2, 0, 0.2f, 0.4f, 0.2f));
}
}
private static void ExpressionOnHoldoutOnLevelOnMithrix(GameObject body) {
if (body.GetComponent<ExpressionController>() is ExpressionController expressionController) {
expressionController.TryPlayAnimation(new BlendShapeAnimation("HuntressMesh", "BrowHappy", 1, 0, 0.2f, 0.6f, 0.2f));
expressionController.TryPlayAnimation(new BlendShapeAnimation("HuntressMesh", "mouth_smile_A", 2, 0, 0.2f, 0.6f, 0.2f));
}
}
private static void ExpressionOnItem(GameObject body, ItemIndex itemIndex) {
if (body.GetComponent<ExpressionController>() is ExpressionController expressionController) {
expressionController.TryPlayAnimation(new BlendShapeAnimation("HuntressMesh", "HighBlink", 0, 0, 0.2f, 0.6f, 0.2f, true));
expressionController.TryPlayAnimation(new BlendShapeAnimation("HuntressMesh", "BrowHappy", 1, 0, 0.2f, 0.6f, 0.2f));
expressionController.TryPlayAnimation(new BlendShapeAnimation("HuntressMesh", "mouth_smile_A", 2, 0, 0.2f, 0.6f, 0.2f));
}
}
private static void ExpressionOnDeath(GameObject body) {
if (body.GetComponent<ExpressionController>() is ExpressionController expressionController) {
expressionController.TryPlayAnimation(new BlendShapeAnimation("HuntressMesh", "HighBlink", 0, 2, 0.2f, Mathf.Infinity, 0.2f, true));
expressionController.TryPlayAnimation(new BlendShapeAnimation("HuntressMesh", "BrowHurt", 1, 2, 0.2f, Mathf.Infinity, 0.2f));
expressionController.TryPlayAnimation(new BlendShapeAnimation("HuntressMesh", "mouth_i_B", 2, 2, 0.2f, Mathf.Infinity, 0.2f));
}
}
public static void CreateVoiceGroups() {
RoR2Application.onLoadFinished += Options.OnLoadFinished;
voiceGroups = new VoiceGroup[] {
new VoiceGroup(
new VoiceArray[] { leavePod },
0.5f,
0.5f
),
new VoiceGroup(
new VoiceArray[] { death },
5f,
5f
),
new VoiceGroup(
new VoiceArray[] { getItem },
15f,
60f
),
new VoiceGroup(
new VoiceArray[] { shrineSuccess, shrineFailure },
10f,
20f
),
new VoiceGroup(
new VoiceArray[] { levelUp },
10f,
30f
),
new VoiceGroup(
new VoiceArray[] { damage, secondary, special, blockDamage, heal, lowHealth },
0.5f,
8f
),
new VoiceGroup(
new VoiceArray[] { startTP, defeatBossGroup, endTP },
5f,
10f
),
};
}
}
}