/*public void OnTakeDamageServer(DamageReport damageReport) * { * //Here we apply damage to the link found on SearchForLink * if (!NetworkServer.active || !hasLinkTarget) * { #if DEBUG * TurboEdition._logger.LogWarning("LinkComponent has no output link or NetworkServer is not active!"); #endif * return; * } * DamageInfo damageInfo = new DamageInfo * { * attacker = damageReport.attacker, * inflictor = base.gameObject, * position = damageReport.attacker.transform.position, * crit = damageReport.attackerBody.RollCrit(), //Isn't this too much? Who are we refering to? Previous link or the player? * damage = damageReport.damageInfo.damage, * damageColorIndex = DamageColorIndex.Item, * force = Vector3.zero, //Wouldn't it be funny if we set it to non-zero? * procCoefficient = 0f, //See: RandomKill line 131 * damageType = DamageType.Generic, //Thinkan about nonlethal * procChainMask = default(ProcChainMask) * }; #if DEBUG * TurboEdition._logger.LogWarning("LinkComponent owner got damaged and has output, relaying a new damageInfo."); #endif * this.hasLinkTarget.TakeDamage(damageInfo); * }*/ private void SearchForLink() { List <HurtBox> hurtBoxList = CollectionPool <HurtBox, List <HurtBox> > .RentCollection(); //Use these to store the sphere search targets that got found List <Transform> transformList = CollectionPool <Transform, List <Transform> > .RentCollection(); //Use this to store the transforms of the targets //You might say, why not instead of storing two lists you store one and you replace the transforms list with hurtbox and you just go hurtbox by hurtbox getting the transforms? Check around line 468, transforms can be either from the hurtbox or the body if null. if (ownerBody.HasBuff(linkedBuff)) //This previously used networkedBodyAttachment.attachedBody { #if DEBUG TurboEdition._logger.LogWarning("LinkComponent body has the correct debuff, trying to find a match."); #endif this.SearchForTargets(hurtBoxList); } int i = 0; while (i < hurtBoxList.Count) { #if DEBUG TurboEdition._logger.LogWarning("LinkComponent searching for a link (" + (i + 1) + ") in a list out of " + hurtBoxList.Count); #endif HurtBox currentHurtbox = hurtBoxList[i]; var externalLink = currentHurtbox.healthComponent.body.GetComponentInChildren <LinkComponent>(); //we get the link component of whatever we are on rn if (!externalLink) { //They dont have a linkComponent, meaning they aren't debuffed and we don't want to do anything with them #if DEBUG TurboEdition._logger.LogWarning("LinkComponent, match doesn't have LinkComponent, ignoring."); #endif i++; continue; } if ((!currentHurtbox || !currentHurtbox.healthComponent || !currentHurtbox.healthComponent.alive) /*|| currentHurtbox.GetComponentInChildren<LinkComponent>().hasLinkTarget*/) //Commenting this last part because thats the output link, shouldnt be affect input. { //This means it either has no hurtboxes, no health component, not alive, or is already linked. #if DEBUG TurboEdition._logger.LogWarning("LinkComponent, match doesn't have a hurtbox, a HealthComponent, or is already dead, ignoring."); #endif i++; continue; } HealthComponent hcHurtBoxToLink = currentHurtbox.healthComponent; //We make sure we aren't linking ourselves if (!(hcHurtBoxToLink.body == ownerBody)) { if (!tetheredHurtBoxList.Contains(currentHurtbox)) { tetheredHurtBoxList.Add(currentHurtbox); Transform transform = hcHurtBoxToLink.body.coreTransform ?? currentHurtbox.transform; transformList.Add(transform); } if (!externalLink.tetheredHurtBoxList.Contains(ownerBody.mainHurtBox)) { externalLink.tetheredHurtBoxList.Add(ownerBody.mainHurtBox); } #if DEBUG TurboEdition._logger.LogWarning("LinkComponent, found link, adding " + currentHurtbox + " to " + tetheredHurtBoxList); #endif //We also make sure we aren't linking something that is already tethered to avoid drawing two lines if (!externalLink.tetheredHurtBoxList.Contains(ownerBody.mainHurtBox)) //should be transformlist? { //Get the hurtbox transform we are affecting, else the body transform #if DEBUG TurboEdition._logger.LogWarning("LinkComponent, found link that wasn't linked to ours with transform: " + transform); #endif } } if (transformList.Count < 1) { #if DEBUG TurboEdition._logger.LogWarning("LinkComponent, transformList doesn't have the needed amount of elements, searching for more."); #endif i++; continue; } this.isLinkedToAtLeastOneObject = (transformList.Count > 0); if (this.tetherVfxOrigin) { #if DEBUG TurboEdition._logger.LogWarning("LinkComponent, tetherVfxOrigin exists, setting transforms from " + transformList + " with count " + transformList.Count); #endif this.tetherVfxOrigin.SetTetheredTransforms(transformList); } if (this.activeVfx) { #if DEBUG TurboEdition._logger.LogWarning("LinkComponent, activeVfx exists, changing enabled/disabled!"); #endif this.activeVfx.SetActive(isLinkedToAtLeastOneObject); } CollectionPool <Transform, List <Transform> > .ReturnCollection(transformList); CollectionPool <HurtBox, List <HurtBox> > .ReturnCollection(hurtBoxList); } #if DEBUG TurboEdition._logger.LogWarning("LinkComponent, couldn't find match, what a shame!"); #endif }
public static void Init() { CostTypeDef costType_ItemFraction = new CostTypeDef(); costType_ItemFraction.costStringFormatToken = "COST_MYSTICSITEMS_PERCENTAGEITEMS_FORMAT"; costType_ItemFraction.isAffordable = delegate(CostTypeDef costTypeDef2, CostTypeDef.IsAffordableContext context) { CharacterBody body = context.activator.gameObject.GetComponent <CharacterBody>(); if (body) { Inventory inventory = body.inventory; if (inventory) { int totalItemCount = 0; ItemIndex itemIndex = 0; ItemIndex itemCount = (ItemIndex)ItemCatalog.itemCount; while (itemIndex < itemCount) { int thisItemCount = inventory.GetItemCount(itemIndex); if (thisItemCount > 0) { ItemDef itemDef = ItemCatalog.GetItemDef(itemIndex); if (itemDef.canRemove) { totalItemCount += inventory.GetItemCount(itemIndex); } } itemIndex++; int itemsToTake = Mathf.FloorToInt(totalItemCount * Mathf.Clamp01(context.cost / 100f)); if (itemsToTake > 0) { return(true); } } } } return(false); }; costType_ItemFraction.payCost = delegate(CostTypeDef costTypeDef2, CostTypeDef.PayCostContext context) { if (context.activatorBody) { Inventory inventory = context.activatorBody.inventory; if (inventory) { List <ItemIndex> itemsToTake = CollectionPool <ItemIndex, List <ItemIndex> > .RentCollection(); WeightedSelection <ItemIndex> weightedSelection = new WeightedSelection <ItemIndex>(8); WeightedSelection <ItemIndex> weightedSelectionScrap = new WeightedSelection <ItemIndex>(8); int totalItemCount = 0; // Populate weighted selections with items from the inventory (weight is equal to the item count) foreach (ItemIndex itemIndex in ItemCatalog.allItems) { if (itemIndex != context.avoidedItemIndex) { int itemCount = inventory.GetItemCount(itemIndex); if (itemCount > 0) { ItemDef itemDef = ItemCatalog.GetItemDef(itemIndex); if (itemDef.canRemove) { (itemDef.ContainsTag(ItemTag.Scrap) ? weightedSelectionScrap : weightedSelection).AddChoice(itemIndex, (float)itemCount); totalItemCount += itemCount; } } } } int halfTotalItemCount = Mathf.FloorToInt(totalItemCount * Mathf.Clamp01(context.cost / 100f)); // Take choices from the weighted selections and put them into the final list, until we take enough items TakeItemsFromWeightedSelection(weightedSelectionScrap, ref context, ref itemsToTake, halfTotalItemCount); TakeItemsFromWeightedSelection(weightedSelection, ref context, ref itemsToTake, halfTotalItemCount); // Unused shop terminal behaviour? If we didn't take enough items, and the purchasable is a shop terminal choice, add the choice's item index as remaining items to take for (int i = itemsToTake.Count; i < halfTotalItemCount; i++) { itemsToTake.Add(context.avoidedItemIndex); } // Remove the items from the interactor's inventory and add them to the pay context results for (int j = 0; j < itemsToTake.Count; j++) { ItemIndex itemIndex2 = itemsToTake[j]; context.results.itemsTaken.Add(itemIndex2); inventory.RemoveItem(itemIndex2, 1); } CollectionPool <ItemIndex, List <ItemIndex> > .ReturnCollection(itemsToTake); } } }; costType_ItemFraction.colorIndex = ColorCatalog.ColorIndex.Tier1Item; CostTypeCreation.CreateCostType(new CostTypeCreation.CustomCostTypeInfo { costTypeDef = costType_ItemFraction, onRegister = (costTypeIndex) => { if (OnItemFractionCostTypeRegister != null) { OnItemFractionCostTypeRegister(costTypeIndex); } } }); On.RoR2.Language.GetLocalizedFormattedStringByToken += (orig, self, token, args) => { if (token == costType_ItemFraction.costStringFormatToken) { return(orig(self, "COST_ITEM_FORMAT", new object[] { args[0].ToString() + "%" })); } return(orig(self, token, args)); }; }