private void EquipmentSlot_FireRecycle(ILContext il) { ILCursor c = new ILCursor(il); int boost = 0; c.Emit(OpCodes.Ldarg_0); c.EmitDelegate<Action<EquipmentSlot>>((slot) => { boost = Embryo.CheckLastEmbryoProc(slot); }); bool ILFound = c.TryGotoNext( x => x.MatchLdloc(out _), x => x.MatchLdcI4(1), x => x.MatchCallOrCallvirt<GenericPickupController>("set_NetworkRecycled")); if(ILFound) { c.Index++; c.Emit(OpCodes.Dup); c.Index++; c.EmitDelegate<Func<GenericPickupController, bool, bool>>((pctrl, origRecyc) => { Debug.Log($"setting recyc flag {boost} {pctrl} {pctrl?.GetComponent<EmbryoRecycleFlag>()?.ToString() ?? "NULL"}"); if(boost > 0 && pctrl && pctrl.GetComponent<EmbryoRecycleFlag>() == null) { pctrl.gameObject.AddComponent<EmbryoRecycleFlag>(); return false; } return true; }); } else { ClassicItemsPlugin._logger.LogError("Failed to apply Beating Embryo IL patch: Recycle; target instructions not found"); } }
private void EquipmentSlot_FixedUpdate(ILContext il) { ILCursor c = new ILCursor(il); int boost = 0; c.Emit(OpCodes.Ldarg_0); c.EmitDelegate <Action <EquipmentSlot> >((slot) => { boost = Embryo.CheckLastEmbryoProc(slot); }); bool ilFound = c.TryGotoNext( x => x.MatchLdstr("Prefabs/Projectiles/BeamSphere")) && c.TryGotoNext( x => x.MatchCallvirt <CharacterBody>("get_damage"), x => x.OpCode == OpCodes.Ldc_R4, x => x.MatchMul()); if (ilFound) { c.Index += 2; c.EmitDelegate <Func <float, float> >((origDamage) => { return(origDamage * (boost + 1)); }); } else { ClassicItemsPlugin._logger.LogError("Failed to apply Beating Embryo IL patch: BFG (FixedUpdate)"); } }
private void GoldGatFire_FireBullet(ILContext il) { ILCursor c = new ILCursor(il); int boost = 0; c.Emit(OpCodes.Ldarg_0); c.EmitDelegate <Action <EntityStates.GoldGat.GoldGatFire> >((ggf) => { boost = Embryo.CheckEmbryoProc(ggf.networkedBodyAttachment?.attachedBodyObject?.GetComponent <CharacterBody>()); }); bool ILFound; ILFound = c.TryGotoNext( x => x.MatchStfld <EntityStates.GoldGat.GoldGatFire>("fireFrequency")); if (ILFound) { c.EmitDelegate <Func <float, float> >((origFreq) => { return(origFreq * (boost + 1)); }); } else { ClassicItemsPlugin._logger.LogError("Failed to apply Beating Embryo IL patch: GoldGat (FireBullet); target instructions not found"); } }
private void IL_UtilCleanseBody(ILContext il) { ILCursor c = new ILCursor(il); int boost = 0; c.Emit(OpCodes.Ldarg_0); c.EmitDelegate <Action <EquipmentSlot> >((slot) => { boost = Embryo.CheckLastEmbryoProc(slot); }); bool ILFound = c.TryGotoNext( x => x.MatchCall <Vector3>("get_sqrMagnitude"), x => x.MatchLdloc(out _), x => x.MatchBgeUn(out _)); if (ILFound) { c.Index += 2; c.Emit(OpCodes.Ldarg_0); c.EmitDelegate <Func <float, CharacterBody, float> >((origValue, body) => { return(origValue * (boost + 1)); }); } else { ClassicItemsPlugin._logger.LogError("Failed to apply Beating Embryo IL patch: Blast Shower (Util.CleanseBody); target instructions not found"); } }
private void EquipmentSlot_FireFireBallDash(ILContext il) { var c = new ILCursor(il); int boost = 0; c.Emit(OpCodes.Ldarg_0); c.EmitDelegate <Action <EquipmentSlot> >((slot) => { boost = Embryo.CheckLastEmbryoProc(slot); }); bool ILFound = c.TryGotoNext( x => x.MatchLdstr("Prefabs/NetworkedObjects/FireballVehicle")) && c.TryGotoNext( x => x.MatchCallOrCallvirt <UnityEngine.Object>("Instantiate")); if (ILFound) { c.Index++; c.Emit(OpCodes.Dup); c.EmitDelegate <Action <GameObject> >((go) => { go.GetComponent <FireballVehicle>().targetSpeed *= (boost + 1); go.GetComponent <FireballVehicle>().acceleration *= (boost + 1); go.GetComponent <FireballVehicle>().blastDamageCoefficient *= (boost + 1); go.GetComponent <FireballVehicle>().overlapDamageCoefficient *= (boost + 1); }); } else { ClassicItemsPlugin._logger.LogError("Failed to apply Beating Embryo IL patch: FireBallDash; target instructions not found"); } }
private void EquipmentSlot_FireGateway(ILContext il) { ILCursor c = new ILCursor(il); int boost = 0; c.Emit(OpCodes.Ldarg_0); c.EmitDelegate <Action <EquipmentSlot> >((slot) => { boost = Embryo.CheckLastEmbryoProc(slot); }); bool ilFound = c.TryGotoNext(MoveType.After, x => x.MatchLdstr("Prefabs/NetworkedObjects/Zipline"), x => x.MatchCallOrCallvirt("RoR2.LegacyResourcesAPI", "Load")); if (ilFound) { c.EmitDelegate <Func <GameObject, GameObject> >((obj) => { return((boost > 0) ? boostedGatewayPrefab : obj); }); } else { ClassicItemsPlugin._logger.LogError("Failed to apply Beating Embryo IL patch: Gateway; target instructions not found"); } }
private void EquipmentSlot_FireBlackhole(ILContext il) { ILCursor c = new ILCursor(il); int boost = 0; c.Emit(OpCodes.Ldarg_0); c.EmitDelegate <Action <EquipmentSlot> >((slot) => { boost = Embryo.CheckLastEmbryoProc(slot); }); bool ilFound = c.TryGotoNext(MoveType.After, x => x.MatchLdstr("Prefabs/Projectiles/GravSphere"), x => x.MatchCallOrCallvirt("RoR2.LegacyResourcesAPI", "Load")); if (ilFound) { c.EmitDelegate <Func <GameObject, GameObject> >((obj) => { var newobj = UnityEngine.Object.Instantiate(obj); newobj.GetComponent <RadialForce>().radius *= boost + 1; return(newobj); }); } else { ClassicItemsPlugin._logger.LogError("Failed to apply Beating Embryo IL patch: Blackhole; target instructions not found"); } }
protected override void OnUpdate() { List <ChildInfo> children = new List <ChildInfo>(); for (int i = 0; i < Data.Length; ++i) { Embryo embryo = Data.Embryo[i]; Transform transform = Data.Transform[i]; Stats stats = Data.Stats[i]; // Create a child foreach (NetData netdata in embryo.netdata) { ChildInfo child = new ChildInfo(); child.tag = stats.Tag; child.container = transform.parent; child.position = transform.position + new Vector3(1, 0, 1); child.generation = stats.Generation + 1; child.netData = netdata; children.Add(child); } PostUpdateCommands.SetComponent <Stats>(Data.Entities[i], stats); PostUpdateCommands.RemoveComponent <Embryo>(Data.Entities[i]); } // Spawn the children foreach (ChildInfo child in children) { // TODO MAKE GENERIC NET INITIALIZATION RATHER THAN HERBIVORE // Debug.Log("CREATING CHILD"); GameObject obj = GameObject.Instantiate(Prefabs[child.tag], child.position, Quaternion.identity, child.container); obj.GetComponent <HerbivoreController>().InitalNet = child.netData; obj.name = Prefabs[child.tag].name + " Gen-" + child.generation + " (" + child.container.childCount + ")"; } }
private void GlobalEventManager_OnHitEnemy(ILContext il) { ILCursor c = new ILCursor(il); int bodyIndex = 0; bool ilFound = c.TryGotoNext(MoveType.After, x => x.MatchLdloc(out bodyIndex), x => x.MatchLdsfld("RoR2.RoR2Content/Buffs", "LifeSteal"), x => x.MatchCallOrCallvirt <CharacterBody>(nameof(CharacterBody.HasBuff)), x => x.MatchBrfalse(out _), x => x.MatchLdarg(1), x => x.MatchLdfld <DamageInfo>(nameof(DamageInfo.damage)), x => x.MatchLdcR4(out _)); if (ilFound) { c.Emit(OpCodes.Ldloc, bodyIndex); c.EmitDelegate <Func <float, CharacterBody, float> >((origAmt, body) => { var boost = Embryo.CheckLastEmbryoProc(body); return(origAmt * (boost + 1)); }); } else { ClassicItemsPlugin._logger.LogError("Failed to apply Beating Embryo IL patch: LifestealOnHit; target instructions not found"); } }
private void IL_ESRpcOnEquipmentActivationReceived(ILContext il) { ILCursor c = new ILCursor(il); int boost = 0; c.Emit(OpCodes.Ldarg_0); c.EmitDelegate <Action <EquipmentSlot> >((slot) => { boost = Embryo.CheckLastEmbryoProc(slot); }); bool ILFound = c.TryGotoNext(MoveType.After, x => x.MatchLdstr("activeDuration"), x => x.MatchLdcR4(out _)); if (ILFound) { c.Emit(OpCodes.Ldarg_0); c.EmitDelegate <Func <float, EquipmentSlot, float> >((origValue, slot) => { return(origValue * (boost + 1)); }); } else { ClassicItemsPlugin._logger.LogError("Failed to apply Beating Embryo IL patch: CritOnUse VFX (RpcOnEquipmentActivationReceived); target instructions not found"); } }
private void EquipmentSlot_FireCritOnUse(ILContext il) { ILCursor c = new ILCursor(il); int boost = 0; c.Emit(OpCodes.Ldarg_0); c.EmitDelegate <Action <EquipmentSlot> >((slot) => { boost = Embryo.CheckLastEmbryoProc(slot); }); bool ilFound = c.TryGotoNext( x => x.OpCode == OpCodes.Ldc_R4, x => x.MatchCallOrCallvirt <CharacterBody>("AddTimedBuff")); if (ilFound) { c.Index += 1; c.EmitDelegate <Func <float, float> >((origBuffTime) => { return(origBuffTime * (boost + 1)); }); } else { ClassicItemsPlugin._logger.LogError("Failed to apply Beating Embryo IL patch: CritOnUse; target instructions not found"); } }
private void RecalculateStatsAPI_GetStatCoefficients(CharacterBody sender, RecalculateStatsAPI.StatHookEventArgs args) { if (!sender.HasBuff(RoR2Content.Buffs.ElephantArmorBoost)) { return; } var boost = Embryo.CheckLastEmbryoProc(sender); args.armorAdd += boost * 500f; }
private bool EquipmentSlot_FireJetpack(On.RoR2.EquipmentSlot.orig_FireJetpack orig, EquipmentSlot self) { var(boost, cpt) = Embryo.InjectLastProcCheckDirect <EmbryoJetpackComponent>(self); if (cpt) { cpt.boostedFlightTime += boost * 15f; } return(orig(self)); }
private bool On_ESFireCommandMissile(On.RoR2.EquipmentSlot.orig_FireCommandMissile orig, EquipmentSlot self) { var prevM = self.remainingMissiles; var retv = orig(self); var addedM = self.remainingMissiles - prevM; var(boost, cpt) = Embryo.InjectLastProcCheckDirect <EmbryoCommandMissileComponent>(self); if (boost > 0 && cpt) { var procM = addedM * boost; cpt.boostedMissiles += procM + addedM; self.remainingMissiles += procM; } return(retv); }
private void EquipmentSlot_FireTeamWarCry(ILContext il) { ILCursor c = new ILCursor(il); int boost = 0; c.Emit(OpCodes.Ldarg_0); c.EmitDelegate <Action <EquipmentSlot> >((slot) => { boost = Embryo.CheckLastEmbryoProc(slot); }); bool ILFound = c.TryGotoNext(MoveType.After, x => x.MatchLdcR4(out _), x => x.MatchCallOrCallvirt <CharacterBody>("AddTimedBuff")); if (ILFound) { c.Index--; c.EmitDelegate <Func <float, float> >((origBuffTime) => { return(origBuffTime * (boost + 1)); }); } else { ClassicItemsPlugin._logger.LogError("Failed to apply Beating Embryo IL patch: TeamWarCry; target instructions not found (first buff time replacement)"); } ILFound = c.TryGotoNext(MoveType.After, x => x.MatchLdcR4(out _), x => x.MatchCallOrCallvirt <CharacterBody>("AddTimedBuff")); if (ILFound) { c.Index--; c.EmitDelegate <Func <float, float> >((origBuffTime) => { return(origBuffTime * (boost + 1)); }); } else { ClassicItemsPlugin._logger.LogError("Failed to apply Beating Embryo IL patch: TeamWarCry; target instructions not found (second buff time replacement)"); } }
private void JetpackController_FixedUpdate(ILContext il) { ILCursor c = new ILCursor(il); int boost = 0; EmbryoJetpackComponent cpt = null; c.Emit(OpCodes.Ldarg_0); c.EmitDelegate <Action <EquipmentSlot> >((slot) => { boost = Embryo.CheckLastEmbryoProc(slot); cpt = slot?.characterBody?.GetComponent <EmbryoJetpackComponent>(); }); bool ILFound = c.TryGotoNext( x => x.MatchCallOrCallvirt <UnityEngine.Time>("get_fixedDeltaTime"), x => x.MatchAdd(), x => x.MatchStfld <JetpackController>("stopwatch")); if (ILFound) { c.Index++; c.Emit(OpCodes.Ldarg_0); c.EmitDelegate <Func <float, JetpackController, float> >((origDecr, jpc) => { if (!cpt || cpt.boostedFlightTime <= 0) { return(origDecr); } cpt.boostedFlightTime -= origDecr; return(0f); }); } else { ClassicItemsPlugin._logger.LogError("Failed to apply Beating Embryo IL patch: Jetpack (FixedUpdate); target instructions not found"); } }