Перейти к основному содержимому
The project's repository is archived as part of the GitHub Archive Program. RogueLibs' code and the documentation will no longer be updated.

Объединяемые предметы

Делаем предметы объединяемыми

Просто реализуйте интерфейс IItemCombinable в классе вашего предмета:

MyCombinableItem.cs
public class MyCombinableItem : CustomItem, IItemCombinable
{
public bool CombineFilter(InvItem other) { /* ... */ }
public bool CombineItems(InvItem other) { /* ... */ }
public CustomTooltip CombineTooltip(InvItem other) { /* ... */ }
public CustomTooltip CombineCursorText(InvItem other) { /* ... */ }
}

Плюс, тип предмета должен быть "Combine":

    public override void SetupDetails()
{
Item.itemType = ItemTypes.Combine;
/* ... */
}

CombineFilter определяет какие предметы будут подсвечиваться, при объединении текущего предмета.

CombineItems объединяет текущий предмет с другим. Возвращаемое значение определяет успешно ли были предметы объединены или нет. Обычно, если предметы не могут быть объединены, проигрывается звук "CantDo". Возврат true также проигрывает анимацию.

CombineTooltip определяет текст подсказки в левом верхнем углу слота инвентаря. Text выставленный на null определится как пустая строка, и Color выставленный на null определится как

#FFED00
. Смотрите инструмент ниже.

CombineCursorText определяет текст возле курсора над выбранным предметом. Text выставленный на null определится как "Объединить", и Color выставленный на null определится как

#FFFFFF
.

Превью слота инвентаря

Хотите увидеть как ваш CombineTooltip будет выглядеть в игре? Зацените этот маленький инструмент:

$123

Примеры

Довольно сложный пример с кучей математики.

using UnityEngine;

namespace RogueLibsCore.Test
{
[ItemCategories(RogueCategories.Technology, RogueCategories.GunAccessory, RogueCategories.Guns)]
public class AmmoBox : CustomItem, IItemCombinable
{
[RLSetup]
public static void Setup()
{
RogueLibs.CreateCustomItem<AmmoBox>()
.WithName(new CustomNameInfo("Ammo Box"))
.WithDescription(new CustomNameInfo("Combine with any refillable weapon to refill it. Limited ammo."))
.WithSprite(Properties.Resources.AmmoBox)
.WithUnlock(new ItemUnlock
{
UnlockCost = 10,
LoadoutCost = 5,
CharacterCreationCost = 3,
Prerequisites = { VanillaItems.KillAmmunizer },
});
}

public override void SetupDetails()
{
Item.itemType = ItemTypes.Combine;
Item.itemValue = 4;
Item.initCount = 100;
Item.rewardCount = 200;
Item.hasCharges = true;
Item.stackable = true;
}
public bool CombineFilter(InvItem other) => other.itemType == ItemTypes.WeaponProjectile && !other.noRefills;
public bool CombineItems(InvItem other)
{
if (!CombineFilter(other))
{
gc.audioHandler.Play(Owner, VanillaAudio.CantDo);
return false;
}
if (other.invItemCount >= other.maxAmmo)
{
Owner!.SayDialogue("AmmoDispenserFull");
gc.audioHandler.Play(Owner, VanillaAudio.CantDo);
return false;
}

int amountToRefill = other.maxAmmo - other.invItemCount;
float singleCost = (float)other.itemValue / other.maxAmmo;
if (Owner!.oma.superSpecialAbility && Owner.agentName is VanillaAgents.Soldier or VanillaAgents.Doctor)
singleCost = 0f;

int affordableAmount = (int)Mathf.Ceil(Count / singleCost);
int willBeBought = Mathf.Min(affordableAmount, amountToRefill);
int willBeReduced = (int)Mathf.Min(Count, willBeBought * singleCost);

Count -= willBeReduced;
other.invItemCount += willBeBought;
Owner.SayDialogue("AmmoDispenserFilled");
gc.audioHandler.Play(Owner, VanillaAudio.BuyItem);
return true;
}

public CustomTooltip CombineTooltip(InvItem other)
{
if (!CombineFilter(other)) return default;

int amountToRefill = other.maxAmmo - other.invItemCount;
if (amountToRefill == 0) return default;

float singleCost = (float)other.itemValue / other.maxAmmo;
if (Owner!.oma.superSpecialAbility && Owner.agentName is VanillaAgents.Soldier or VanillaAgents.Doctor)
singleCost = 0f;
int cost = (int)Mathf.Floor(amountToRefill * singleCost);
int canAfford = (int)Mathf.Ceil(Count / singleCost);

return "+" + Mathf.Min(amountToRefill, canAfford) + " (" + Mathf.Min(cost, Count) + ")";
}

public CustomTooltip CombineCursorText(InvItem other) => gc.nameDB.GetName("RefillGun", NameTypes.Interface);
// it's one of the vanilla dialogues, so there's no need to define it in the mod
}
}

The project's repository is archived as part of the GitHub Archive Program. RogueLibs' code and the documentation will no longer be updated.