public void SetupBoss(Character c, BossTemplate template) { BasicResurrectSetup(c); MoveAndSetActive(c); // change light color to red Light light = c.GetComponent <Light>() ?? c.gameObject.AddComponent <Light>(); light.color = Color.red; light.range = 4; light.intensity = 2.0f; // override name At.SetValue(template.Name, typeof(Character), c, "m_name"); At.SetValue("", typeof(Character), c, "m_nameLocKey"); // set HP float healthTarget = template.Health + (300 * (global.BossesSpawned - 1)); Stat maxHP = new Stat(healthTarget); At.SetValue(maxHP, typeof(CharacterStats), c.Stats, "m_maxHealthStat"); c.Stats.FullHealth(); // start boss coroutine StartCoroutine(BossCoroutine(c, template)); }
private void SetupWeapon(Weapon weapon, BossTemplate template, float templateMod, float weaponTemplateScale) { weapon.InstantLoadWeapon(); // set boss weapon template if (template != null) { At.SetValue(template.weaponDamages, typeof(WeaponStats), weapon.Stats, "BaseDamage"); weapon.Stats.Impact += templateMod; for (int i = 0; i < weapon.Stats.Attacks.Count(); i++) { List <float> stepDamage = new List <float>(); float stepImpact = template.weaponImpact; foreach (DamageType dtype in template.weaponDamages.List) { stepDamage.Add(dtype.Damage + (0.5f * templateMod)); } global.statUtil.SetScaledDamages(weapon.Type, i, ref stepDamage, ref stepImpact); weapon.Stats.Attacks[i].Damage = stepDamage; weapon.Stats.Attacks[i].Knockback = stepImpact + templateMod; weapon.LoadedVisual.transform.localScale = new Vector3(1, 1, 1) * weaponTemplateScale; } } }
// ============== CUSTOM NPC GEAR =============== private void SetupEquipment(Character c, List <int> itemIDs, BossTemplate template = null, float templateMod = 0f, float weaponTemplateScale = 1.0f) { foreach (int id in itemIDs) { Item item = ItemManager.Instance.GenerateItemNetwork(id); if (template != null) { // set weapon 2H type if (item is Weapon w) { w.TwoHand = template.TwoHandType; w.Type = template.WeaponType; } } c.Inventory.TakeItem(item, false); At.Call(c.Inventory.Equipment, "EquipWithoutAssociating", new object[] { item, false }); item.ProcessInit(); if (item is Weapon weapon && weapon.Type != Weapon.WeaponType.Shield) { SetupWeapon(weapon, template, templateMod, weaponTemplateScale); } } }
// ==================== BOSS SETUP ===================== public void SpawnBoss(BossTemplate template) { if (CharacterManager.Instance.Characters.Values .Find(x => x.name.ToLower().Contains("newbanditequip") && !x.name.ToLower().Contains("archer")) is Character c) { SetupBoss(c, template); StartCoroutine(global.gui.SetMessage(template.Name + " Challenges You!", 5)); } }
private void GenerateDroptable(Character c, BossTemplate template) { int b = global.BossesSpawned - 1; int r = UnityEngine.Random.Range(template.DropTable.MinDrops + b, template.DropTable.MaxDrops + b); for (int i = 0; i < r; i++) { // get the max dice value int maxdice = 0; int j; for (j = 0; j < template.DropTable.DroppedItems.Count; j++) { maxdice += template.DropTable.ItemChances[j]; } // generate a random roll, and check which item range it falls in int r2 = UnityEngine.Random.Range(0, maxdice - 1); int dropID = -1; int currentMax = 0; for (j = 0; j < template.DropTable.DroppedItems.Count; j++) { currentMax += template.DropTable.ItemChances[j]; // add the current item chance to the max value if (r2 < currentMax) // if the roll was less than this max { dropID = template.DropTable.DroppedItems[j]; // set the drop ID (otherwise, increase the max value and check next item) break; } } if (dropID != -1) { // generate a random quantity int r3 = UnityEngine.Random.Range(template.DropTable.ItemMinQtys[j], template.DropTable.ItemMaxQtys[j]); int k; for (k = 0; k < r3; k++) { // for each quantity, spawn an take the item Item item = ItemManager.Instance.GenerateItemNetwork(dropID); item.transform.parent = c.Inventory.Pouch.transform; } } } }
private void LateUpdateBossFix(Character c, BossTemplate template) { float transformScale = Mathf.Clamp(1.1f + (0.1f * global.BossesSpawned), 1.1f, 1.6f); float statMod = 5 * global.BossesSpawned; // transform scale c.transform.localScale = new Vector3(1, 1, 1) * transformScale; // fix UI bar pos c.UIBarOffSet = new Vector3(0, 1, 0) * transformScale; DestroyEquipment(c); SetupEquipment(c, global.CurrentTemplate.BossTemplate.Equipment, global.CurrentTemplate.BossTemplate, statMod, transformScale); // add imbue fx (just fire rag for visuals, no major damage) var preset = ResourcesPrefabManager.Instance.GetEffectPreset(202); if (preset is ImbueEffectPreset fireRag) { c.CurrentWeapon.AddImbueEffect(fireRag, 240); } // set resistances List <Stat> newDmgRes = new List <Stat>(); for (int i = 0; i < 9; i++) { float resTarget = template.Resistances[i]; resTarget = Mathf.Clamp(resTarget + statMod, resTarget, 90); Stat stat = new Stat(resTarget); newDmgRes.Add(stat); } At.SetValue(newDmgRes.ToArray(), typeof(CharacterStats), c.Stats, "m_damageResistance"); Stat impRes = new Stat(Mathf.Clamp(template.impactRes + statMod, template.impactRes, 90)); At.SetValue(impRes, typeof(CharacterStats), c.Stats, "m_impactResistance"); // final fix c.gameObject.SetActive(false); c.gameObject.SetActive(true); }
private IEnumerator BossCoroutine(Character c, BossTemplate template) { while (!c.IsLateInitDone) { yield return(null); } yield return(new WaitForSeconds(0.2f)); LateUpdateBossFix(c, template); // wait til boss is dead while (c.Health > 0) { global.TimeSpentOnBosses += Time.deltaTime; yield return(null); } // drop table GenerateDroptable(c, template); global.BossActive = false; global.ShouldRest = true; }