| Name | Author | Game Mode | Rating | |||||
|---|---|---|---|---|---|---|---|---|
| NpcBunnies | Cranky | Mutator | N/A | |||||
namespace npcBunniesShop
{
class NpcShopItem
{
string name = "";
npcBunniesQuests::NpcReward@ item;
int priceCoins = 0;
int priceGems = 0;
GEM::Color priceGemType = GEM::RED;
int stock = -1;
NpcShopItem()
{
@item = @npcBunniesQuests::NpcReward();
}
}
int shopMoveTicks = 0;
int shopBuyTicks = 0;
bool shopInputReleased = true;
bool IsShopRewardAllowed(npcBunniesQuests::NpcReward@ reward)
{
if(reward is null) return false;
return reward.rewardType != npcBunniesQuests::RewardType::RewardCoins && reward.rewardType != npcBunniesQuests::RewardType::RewardGems && reward.rewardType != npcBunniesQuests::RewardType::RewardGuidePath;
}
string GetWeaponDisplayName(int weaponType)
{
if(weaponType == WEAPON::BOUNCER) return "Bouncer";
if(weaponType == WEAPON::ICE) return "Freezer";
if(weaponType == WEAPON::SEEKER) return "Seeker";
if(weaponType == WEAPON::RF) return "RF";
if(weaponType == WEAPON::TOASTER) return "Toaster";
if(weaponType == WEAPON::TNT) return "TNT";
if(weaponType == WEAPON::GUN8) return "Pepper";
if(weaponType == WEAPON::GUN9) return "Electro";
return "Ammo";
}
string GetGemDisplayName(GEM::Color gemType)
{
if(gemType == GEM::GREEN) return "green gems";
if(gemType == GEM::BLUE) return "blue gems";
if(gemType == GEM::PURPLE) return "purple gems";
return "red gems";
}
string GetShopItemName(NpcShopItem@ item)
{
if(item is null || item.item is null) return "Item";
if(item.name != "") return item.name;
npcBunniesQuests::NpcReward@ reward = item.item;
if(reward.rewardType == npcBunniesQuests::RewardType::RewardAmmo) return reward.amount + " " + GetWeaponDisplayName(reward.weaponType) + " ammo";
if(reward.rewardType == npcBunniesQuests::RewardType::RewardPowerup) return GetWeaponDisplayName(reward.weaponType) + " powerup";
if(reward.rewardType == npcBunniesQuests::RewardType::RewardFastFire) return "Fastfire";
if(reward.rewardType == npcBunniesQuests::RewardType::RewardTeleport) return "Teleport";
if(reward.rewardType == npcBunniesQuests::RewardType::RewardTrigger) return "Trigger";
if(reward.rewardType == npcBunniesQuests::RewardType::RewardMoveable) return "Moveable";
return "Item";
}
bool IsShopItemInStock(NpcShopItem@ item)
{
return !(item is null) && item.stock != 0;
}
string GetShopItemStockText(NpcShopItem@ item)
{
if(item is null || item.stock < 0) return "";
if(item.stock == 0) return "sold out";
return "stock: " + item.stock;
}
string GetShopItemPriceText(NpcShopItem@ item)
{
if(item is null) return "free";
if(item.stock == 0) return "sold out";
string text = "";
if(item.priceCoins > 0) text = item.priceCoins + " coins";
if(item.priceGems > 0)
{
if(text != "") text += " + ";
text += item.priceGems + " " + GetGemDisplayName(item.priceGemType);
}
if(text == "") text = "free";
string stockText = GetShopItemStockText(item);
if(stockText != "") text += " (" + stockText + ")";
return text;
}
string GetShopItemPriceQuestionText(NpcShopItem@ item)
{
if(item is null) return "free";
string text = "";
if(item.priceCoins > 0) text = item.priceCoins + " coins";
if(item.priceGems > 0)
{
if(text != "") text += " and ";
text += item.priceGems + " " + GetGemDisplayName(item.priceGemType);
}
return text == "" ? "free" : text;
}
string GetPlayerShopCurrencyText(jjPLAYER@ player)
{
if(player is null) return "";
return "Red: " + player.gems[GEM::RED] + " Green: " + player.gems[GEM::GREEN] + " Blue: " + player.gems[GEM::BLUE] + " Purple: " + player.gems[GEM::PURPLE] + " Coins: " + player.coins;
}
int GetShopItemPriceIconWidth(NpcShopItem@ item)
{
if(item is null || item.stock == 0) return jjGetStringWidth(item is null ? "free" : "sold out", STRING::SMALL, STRING::NORMAL);
int width = 0;
if(item.priceCoins > 0) width += npcBunniesAnimations::GetNpcItemAmountWidth(item.priceCoins);
if(item.priceGems > 0)
{
if(width > 0) width += 12;
width += npcBunniesAnimations::GetNpcItemAmountWidth(item.priceGems);
}
if(width == 0) width = jjGetStringWidth("free", STRING::SMALL, STRING::NORMAL);
return width;
}
void DrawShopItemPriceIcons(jjCANVAS@ canvas, NpcShopItem@ item, int x, int y)
{
if(item is null) { canvas.drawString(x, y, "free", STRING::SMALL, STRING::NORMAL); return; }
if(item.stock == 0) { canvas.drawString(x, y, "sold out", STRING::SMALL, STRING::NORMAL); return; }
if(item.priceCoins <= 0 && item.priceGems <= 0) { canvas.drawString(x, y, "free", STRING::SMALL, STRING::NORMAL); return; }
if(item.priceCoins > 0)
{
npcBunniesAnimations::NpcUiAnimation coinIcon;
npcBunniesAnimations::GetNpcUiIcon(npcBunniesAnimations::NpcUiIcon::Coin, coinIcon);
npcBunniesAnimations::DrawNpcItemAmount(canvas, x, y, item.priceCoins, coinIcon);
x += npcBunniesAnimations::GetNpcItemAmountWidth(item.priceCoins) + 12;
}
if(item.priceGems > 0)
{
npcBunniesAnimations::NpcUiAnimation gemIcon;
npcBunniesAnimations::GetGemUiIcon(item.priceGemType, gemIcon);
npcBunniesAnimations::DrawNpcItemAmount(canvas, x, y, item.priceGems, gemIcon);
}
}
int GetNpcShopColumns(npcBunniesCore::npcBunny npc)
{
return npc.shopColumns <= 1 ? 1 : 2;
}
int GetShopGemRedValue(GEM::Color gemType)
{
if(gemType == GEM::GREEN) return 5;
if(gemType == GEM::BLUE) return 10;
return 1;
}
int GetShopItemGemPriceRedValue(NpcShopItem@ item)
{
if(item is null || item.priceGems <= 0) return 0;
return item.priceGems * GetShopGemRedValue(item.priceGemType);
}
int GetPlayerShopGemRedValue(jjPLAYER@ player)
{
if(player is null) return 0;
return player.gems[GEM::RED] + player.gems[GEM::PURPLE] + player.gems[GEM::GREEN] * 5 + player.gems[GEM::BLUE] * 10;
}
int SpendPlayerShopGemColor(jjPLAYER@ player, GEM::Color gemType, int gemValue, int remaining)
{
while(remaining > 0 && player.gems[gemType] > 0)
{
player.gems[gemType] = player.gems[gemType] - 1;
remaining -= gemValue;
}
if(remaining < 0)
{
player.gems[GEM::RED] = player.gems[GEM::RED] + -remaining;
remaining = 0;
}
return remaining;
}
void SpendPlayerShopGems(jjPLAYER@ player, int redGemPrice)
{
if(player is null || redGemPrice <= 0) return;
int remaining = redGemPrice;
remaining = SpendPlayerShopGemColor(player, GEM::RED, 1, remaining);
remaining = SpendPlayerShopGemColor(player, GEM::PURPLE, 1, remaining);
remaining = SpendPlayerShopGemColor(player, GEM::GREEN, 5, remaining);
remaining = SpendPlayerShopGemColor(player, GEM::BLUE, 10, remaining);
}
bool CanAffordShopItem(NpcShopItem@ item, jjPLAYER@ player)
{
if(item is null || player is null) return false;
return player.coins >= item.priceCoins && GetPlayerShopGemRedValue(player) >= GetShopItemGemPriceRedValue(item);
}
void SpendShopItemPrice(NpcShopItem@ item, jjPLAYER@ player)
{
if(item is null || player is null) return;
if(item.priceCoins > 0) player.coins = player.coins >= item.priceCoins ? player.coins - item.priceCoins : 0;
SpendPlayerShopGems(player, GetShopItemGemPriceRedValue(item));
}
bool IsValidShopWeaponType(int weaponType)
{
return weaponType > 0 && weaponType < 10;
}
bool IsShopPowerupAtMax(npcBunniesQuests::NpcReward@ reward, jjPLAYER@ player)
{
if(reward is null || player is null || reward.rewardType != npcBunniesQuests::RewardType::RewardPowerup) return false;
if(!IsValidShopWeaponType(reward.weaponType)) return false;
return player.ammo[reward.weaponType] >= 99;
}
void SetShopWeaponAmmo(jjPLAYER@ player, int weaponType, int amount)
{
if(player is null || !IsValidShopWeaponType(weaponType)) return;
int originalMaximum = jjWeapons[weaponType].maximum;
if(amount > jjWeapons[weaponType].maximum) jjWeapons[weaponType].maximum = amount;
player.ammo[weaponType] = amount;
jjWeapons[weaponType].maximum = originalMaximum;
}
void GrantShopPowerupReward(npcBunniesQuests::NpcReward@ reward, jjPLAYER@ player)
{
if(reward is null || player is null || reward.rewardType != npcBunniesQuests::RewardType::RewardPowerup) return;
int weaponType = reward.weaponType;
if(!IsValidShopWeaponType(weaponType)) return;
int ammo = player.ammo[weaponType];
if(ammo <= 0)
{
SetShopWeaponAmmo(player, weaponType, 20);
player.powerup[weaponType] = true;
return;
}
if(!player.powerup[weaponType])
{
player.powerup[weaponType] = true;
return;
}
if(ammo < 50)
{
SetShopWeaponAmmo(player, weaponType, 50);
return;
}
SetShopWeaponAmmo(player, weaponType, 99);
}
void GrantShopItemReward(NpcShopItem@ item, jjPLAYER@ player, int npcId)
{
if(item is null || item.item is null) return;
if(item.item.rewardType == npcBunniesQuests::RewardType::RewardPowerup) GrantShopPowerupReward(item.item, player);
else npcBunniesQuests::GrantNpcReward(item.item, player, npcId);
}
void BuySelectedShopItem(int npcId, jjPLAYER@ player)
{
if(player is null || npcId < 0 || npcId >= int(npcBunniesCore::npcBunnies.length)) return;
jjPLAYER@ buyer = jjPlayers[player.playerID];
npcBunniesCore::npcBunny npc = npcBunniesCore::npcBunnies[npcId];
if(npc.shopItems.length == 0)
{
npc.shopMessage = "This NPC sells no items.";
npcBunniesCore::npcBunnies[npcId] = npc;
return;
}
if(npc.shopSelectedIndex < 0) npc.shopSelectedIndex = 0;
if(npc.shopSelectedIndex >= int(npc.shopItems.length)) npc.shopSelectedIndex = int(npc.shopItems.length) - 1;
NpcShopItem@ item = npc.shopItems[npc.shopSelectedIndex];
NormalizeShopItemReward(item);
if(!IsShopRewardAllowed(item.item))
{
npc.shopMessage = "This item cannot be sold.";
npcBunniesCore::npcBunnies[npcId] = npc;
return;
}
if(!IsShopItemInStock(item))
{
npc.shopMessage = "This item is sold out.";
npcBunniesCore::npcBunnies[npcId] = npc;
return;
}
if(IsShopPowerupAtMax(item.item, buyer))
{
npc.shopMessage = "Already at max.";
npcBunniesCore::npcBunnies[npcId] = npc;
return;
}
if(!CanAffordShopItem(item, buyer))
{
npc.shopMessage = "You cannot afford this.";
npcBunniesCore::npcBunnies[npcId] = npc;
return;
}
SpendShopItemPrice(item, buyer);
GrantShopItemReward(item, buyer, npcId);
if(item.stock > 0) item.stock--;
npc.shopMessage = "Bought " + GetShopItemName(item) + ".";
npcBunniesCore::npcBunnies[npcId] = npc;
}
void OpenShopPurchaseConfirm(int npcId)
{
if(npcId < 0 || npcId >= int(npcBunniesCore::npcBunnies.length)) return;
npcBunniesCore::npcBunny npc = npcBunniesCore::npcBunnies[npcId];
if(npc.shopSelectedIndex < 0 || npc.shopSelectedIndex >= int(npc.shopItems.length)) return;
if(!IsShopItemInStock(npc.shopItems[npc.shopSelectedIndex]))
{
npc.shopMessage = "This item is sold out.";
npcBunniesCore::npcBunnies[npcId] = npc;
return;
}
npc.shopConfirmOpen = true;
npc.shopConfirmYes = true;
npc.shopMessage = "";
npcBunniesCore::npcBunnies[npcId] = npc;
}
void getShopControl(jjPLAYER@ play, int npcId)
{
if(npcId < 0 || npcId >= int(npcBunniesCore::npcBunnies.length)) return;
npcBunniesCore::npcBunny npc = npcBunniesCore::npcBunnies[npcId];
int itemCount = int(npc.shopItems.length);
int exitIndex = itemCount;
int columns = GetNpcShopColumns(npc);
if(npc.shopSelectedIndex < 0) npc.shopSelectedIndex = 0;
if(npc.shopSelectedIndex > exitIndex) npc.shopSelectedIndex = exitIndex;
if(!shopInputReleased)
{
if(!play.keySelect && !play.keyFire && !jjKey[0x0D]) shopInputReleased = true;
npcBunniesCore::npcBunnies[npcId] = npc;
return;
}
if(npc.shopConfirmOpen)
{
if(jjGameTicks > shopMoveTicks + 12)
{
if(play.keyLeft || play.keyRight)
{
npc.shopConfirmYes = !npc.shopConfirmYes;
shopMoveTicks = jjGameTicks;
}
}
if((play.keySelect || play.keyFire || jjKey[0x0D]) && jjGameTicks > shopBuyTicks + 20)
{
bool buy = npc.shopConfirmYes;
npc.shopConfirmOpen = false;
npcBunniesCore::npcBunnies[npcId] = npc;
if(buy) BuySelectedShopItem(npcId, play);
shopBuyTicks = jjGameTicks;
shopInputReleased = false;
npcBunniesMovement::lastKeyFire = jjGameTicks;
npcBunniesMovement::keyTicks[13] = jjGameTicks;
return;
}
if(jjKey[27]) npc.shopConfirmOpen = false;
npcBunniesCore::npcBunnies[npcId] = npc;
return;
}
if(jjGameTicks > shopMoveTicks + 12)
{
if(itemCount > 0 && npc.shopSelectedIndex < itemCount)
{
if(play.keyLeft && columns == 2 && npc.shopSelectedIndex % columns == 1) { npc.shopSelectedIndex--; shopMoveTicks = jjGameTicks; }
else if(play.keyRight && columns == 2 && npc.shopSelectedIndex % columns == 0 && npc.shopSelectedIndex + 1 < itemCount) { npc.shopSelectedIndex++; shopMoveTicks = jjGameTicks; }
else if(play.keyUp && npc.shopSelectedIndex - columns >= 0) { npc.shopSelectedIndex -= columns; shopMoveTicks = jjGameTicks; }
else if(play.keyDown)
{
if(npc.shopSelectedIndex + columns < itemCount) npc.shopSelectedIndex += columns;
else npc.shopSelectedIndex = exitIndex;
shopMoveTicks = jjGameTicks;
}
}
else if(play.keyUp && itemCount > 0)
{
int lastRowStart = ((itemCount - 1) / columns) * columns;
npc.shopSelectedIndex = lastRowStart;
shopMoveTicks = jjGameTicks;
}
}
if((play.keySelect || play.keyFire || jjKey[0x0D]) && jjGameTicks > shopBuyTicks + 20)
{
if(npc.shopSelectedIndex == exitIndex)
{
npcBunniesHooks::exitConv();
shopBuyTicks = jjGameTicks;
return;
}
npcBunniesCore::npcBunnies[npcId] = npc;
OpenShopPurchaseConfirm(npcId);
shopBuyTicks = jjGameTicks;
shopInputReleased = false;
npcBunniesMovement::lastKeyFire = jjGameTicks;
npcBunniesMovement::keyTicks[13] = jjGameTicks;
return;
}
if(jjKey[27]) npcBunniesHooks::exitConv();
npcBunniesCore::npcBunnies[npcId] = npc;
}
void DrawShopItem(jjCANVAS@ canvas, NpcShopItem@ item, int x, int y, int priceRight, bool selected)
{
if(item is null) return;
npcBunniesAnimations::NpcUiAnimation icon;
GetShopItemAnimation(item, icon);
npcBunniesAnimations::DrawNpcUiIcon(canvas, x, y + 10, icon, 0.75);
jjTEXTAPPEARANCE appearance(selected ? STRING::SPIN : STRING::NORMAL);
int nameX = x + 28;
string itemName = GetShopItemName(item);
canvas.drawString(nameX, y + 2, itemName, STRING::SMALL, appearance);
DrawShopItemPriceIcons(canvas, item, priceRight - GetShopItemPriceIconWidth(item), y + 2);
}
void DrawShopConfirm(jjCANVAS@ canvas, npcBunniesCore::npcBunny npc)
{
if(npc.shopSelectedIndex < 0 || npc.shopSelectedIndex >= int(npc.shopItems.length)) return;
NpcShopItem@ item = npc.shopItems[npc.shopSelectedIndex];
canvas.drawRectangle(120, 245, jjResolutionWidth - 240, 100, 0, SPRITE::SHADOW);
canvas.drawString(0x8000, 258, "Buy " + GetShopItemName(item) + " for:", STRING::SMALL, STRING::NORMAL);
int priceWidth = GetShopItemPriceIconWidth(item);
DrawShopItemPriceIcons(canvas, item, (jjResolutionWidth - priceWidth) / 2, 280);
canvas.drawString(0x8000 - 45, 318, "Yes", STRING::SMALL, npc.shopConfirmYes ? STRING::SPIN : STRING::NORMAL);
canvas.drawString(0x8000 + 45, 318, "No", STRING::SMALL, npc.shopConfirmYes ? STRING::NORMAL : STRING::SPIN);
}
void DrawNpcShop(jjPLAYER@ play, jjCANVAS@ canvas, int npcId)
{
if(npcId < 0 || npcId >= int(npcBunniesCore::npcBunnies.length)) return;
getShopControl(play, npcId);
if(npcBunniesMovement::convOn == -1) return;
npcBunniesCore::npcBunny npc = npcBunniesCore::npcBunnies[npcId];
int columns = GetNpcShopColumns(npc);
int itemCount = int(npc.shopItems.length);
int exitIndex = itemCount;
int leftX = columns == 1 ? 210 : 135;
int rightX = jjResolutionWidth / 2 + 20;
int startY = 220;
if(itemCount == 0) canvas.drawString(0x8000, 260, "This NPC sells no items.", STRING::SMALL, STRING::NORMAL);
else
{
for(uint i = 0; i < npc.shopItems.length; i++)
{
int column = columns == 1 ? 0 : int(i) % columns;
int row = columns == 1 ? int(i) : int(i) / columns;
int itemX = column == 0 ? leftX : rightX;
int priceRight = columns == 1 ? jjResolutionWidth - 120 : (column == 0 ? jjResolutionWidth / 2 - 36 : jjResolutionWidth - 36);
DrawShopItem(canvas, npc.shopItems[i], itemX, startY + row * 32, priceRight, int(i) == npc.shopSelectedIndex && !npc.shopConfirmOpen);
}
}
canvas.drawString(0x8000, 345, GetPlayerShopCurrencyText(play), STRING::SMALL, STRING::NORMAL);
canvas.drawString(0x8000, 368, "Exit", STRING::SMALL, npc.shopSelectedIndex == exitIndex && !npc.shopConfirmOpen ? STRING::SPIN : STRING::NORMAL);
if(npc.shopMessage != "") canvas.drawString(0x8000, 390, npc.shopMessage, STRING::SMALL, STRING::NORMAL);
if(npc.shopConfirmOpen) DrawShopConfirm(canvas, npc);
}
int ParseNpcShopStock(array<string>@ tokens, array<int>@ pos)
{
string value = npcBunniesParser::ReadNpcJsonString(tokens, pos);
if(value == "" || jjRegexMatch(value, "inf", true) || jjRegexMatch(value, "infinite", true)) return -1;
int stock = parseInt(value);
return stock < 0 ? -1 : stock;
}
void ParseNpcShop(array<string>@ tokens, array<int>@ pos, npcBunniesCore::npcBunny &inout npc)
{
if(pos[0] >= int(tokens.length) || tokens[pos[0]] != "{") { npcBunniesParser::SkipNpcJsonValue(tokens, pos); return; }
pos[0]++;
while(pos[0] < int(tokens.length) && tokens[pos[0]] != "}")
{
string key = tokens[pos[0]++]; if(pos[0] < int(tokens.length) && tokens[pos[0]] == ":") pos[0]++;
if(jjRegexMatch(key, "Items", true) || jjRegexMatch(key, "ShopItems", true)) ParseNpcShopItems(tokens, pos, npc);
else if(jjRegexMatch(key, "Columns", true) || jjRegexMatch(key, "DisplayColumns", true) || jjRegexMatch(key, "ItemColumns", true)) npc.shopColumns = npcBunniesParser::ReadNpcJsonInt(tokens, pos);
else npcBunniesParser::SkipNpcJsonValue(tokens, pos);
if(pos[0] < int(tokens.length) && tokens[pos[0]] == ",") pos[0]++;
}
if(pos[0] < int(tokens.length) && tokens[pos[0]] == "}") pos[0]++;
}
void ParseNpcShopItems(array<string>@ tokens, array<int>@ pos, npcBunniesCore::npcBunny &inout npc)
{
if(pos[0] >= int(tokens.length) || tokens[pos[0]] != "[") { npcBunniesParser::SkipNpcJsonValue(tokens, pos); return; }
pos[0]++;
while(pos[0] < int(tokens.length) && tokens[pos[0]] != "]")
{
npc.shopItems.insertLast(ParseNpcShopItem(tokens, pos));
if(pos[0] < int(tokens.length) && tokens[pos[0]] == ",") pos[0]++;
}
if(pos[0] < int(tokens.length) && tokens[pos[0]] == "]") pos[0]++;
}
NpcShopItem@ ParseNpcShopItem(array<string>@ tokens, array<int>@ pos)
{
NpcShopItem@ item = @NpcShopItem();
if(pos[0] >= int(tokens.length) || tokens[pos[0]] != "{") { npcBunniesParser::SkipNpcJsonValue(tokens, pos); return item; }
pos[0]++;
while(pos[0] < int(tokens.length) && tokens[pos[0]] != "}")
{
string key = tokens[pos[0]++]; if(pos[0] < int(tokens.length) && tokens[pos[0]] == ":") pos[0]++;
if(jjRegexMatch(key, "Name", true)) item.name = npcBunniesParser::ReadNpcJsonString(tokens, pos);
else if(jjRegexMatch(key, "Item", true) || jjRegexMatch(key, "Reward", true)) @item.item = npcBunniesParser::ParseReward(tokens, pos);
else if(jjRegexMatch(key, "PriceCoins", true) || key == "Coins") item.priceCoins = npcBunniesParser::ReadNpcJsonInt(tokens, pos);
else if(jjRegexMatch(key, "PriceGems", true) || key == "Gems") item.priceGems = npcBunniesParser::ReadNpcJsonInt(tokens, pos);
else if(jjRegexMatch(key, "GemType", true)) item.priceGemType = npcBunniesQuests::ParseGemType(npcBunniesParser::ReadNpcJsonString(tokens, pos));
else if(jjRegexMatch(key, "Stock", true)) item.stock = ParseNpcShopStock(tokens, pos);
else if(jjRegexMatch(key, "Price", true)) ParseNpcShopPrice(tokens, pos, item);
else npcBunniesParser::SkipNpcJsonValue(tokens, pos);
if(pos[0] < int(tokens.length) && tokens[pos[0]] == ",") pos[0]++;
}
if(pos[0] < int(tokens.length) && tokens[pos[0]] == "}") pos[0]++;
NormalizeShopItemReward(item);
return item;
}
void ParseNpcShopPrice(array<string>@ tokens, array<int>@ pos, NpcShopItem@ item)
{
if(pos[0] >= int(tokens.length) || tokens[pos[0]] != "{") { npcBunniesParser::SkipNpcJsonValue(tokens, pos); return; }
pos[0]++;
while(pos[0] < int(tokens.length) && tokens[pos[0]] != "}")
{
string key = tokens[pos[0]++]; if(pos[0] < int(tokens.length) && tokens[pos[0]] == ":") pos[0]++;
if(jjRegexMatch(key, "Coins", true)) item.priceCoins = npcBunniesParser::ReadNpcJsonInt(tokens, pos);
else if(jjRegexMatch(key, "Gems", true)) item.priceGems = npcBunniesParser::ReadNpcJsonInt(tokens, pos);
else if(jjRegexMatch(key, "GemType", true)) item.priceGemType = npcBunniesQuests::ParseGemType(npcBunniesParser::ReadNpcJsonString(tokens, pos));
else npcBunniesParser::SkipNpcJsonValue(tokens, pos);
if(pos[0] < int(tokens.length) && tokens[pos[0]] == ",") pos[0]++;
}
if(pos[0] < int(tokens.length) && tokens[pos[0]] == "}") pos[0]++;
}
bool ShopItemNameContains(const string &in name, const string &in a, const string &in b = "", const string &in c = "")
{
if(int(name.findFirst(a)) >= 0) return true;
if(b != "" && int(name.findFirst(b)) >= 0) return true;
if(c != "" && int(name.findFirst(c)) >= 0) return true;
return false;
}
int GetShopItemWeaponTypeFromName(const string &in name)
{
if(ShopItemNameContains(name, "Blaster", "blaster")) return WEAPON::BLASTER;
if(ShopItemNameContains(name, "Bouncer", "bouncer")) return WEAPON::BOUNCER;
if(ShopItemNameContains(name, "Freezer", "freezer") || ShopItemNameContains(name, "Ice", "ice")) return WEAPON::ICE;
if(ShopItemNameContains(name, "Seeker", "seeker")) return WEAPON::SEEKER;
if(ShopItemNameContains(name, "RF", "rf")) return WEAPON::RF;
if(ShopItemNameContains(name, "Toaster", "toaster")) return WEAPON::TOASTER;
if(ShopItemNameContains(name, "TNT", "tnt")) return WEAPON::TNT;
if(ShopItemNameContains(name, "Pepper", "pepper")) return WEAPON::GUN8;
if(ShopItemNameContains(name, "Electro", "electro")) return WEAPON::GUN9;
return 0;
}
int GetShopItemIconIdFromName(const string &in name)
{
int weaponType = GetShopItemWeaponTypeFromName(name);
if(weaponType <= 0) return npcBunniesAnimations::NpcUiIcon::Unknown;
if(ShopItemNameContains(name, "Powerup", "powerup", "Power-up") || ShopItemNameContains(name, "power-up", " PU", " pu")) return npcBunniesAnimations::GetPowerupRewardIconId(weaponType);
if(ShopItemNameContains(name, "Ammo", "ammo") || ShopItemNameContains(name, "Bullet", "bullet") || ShopItemNameContains(name, "Bullets", "bullets")) return npcBunniesAnimations::GetAmmoRewardIconId(weaponType);
return npcBunniesAnimations::GetAmmoRewardIconId(weaponType);
}
void NormalizeShopItemReward(NpcShopItem@ item)
{
if(item is null || item.item is null || item.name == "") return;
if(item.item.rewardType != npcBunniesQuests::RewardType::RewardCoins && item.item.rewardType != npcBunniesQuests::RewardType::RewardGems) return;
int weaponType = GetShopItemWeaponTypeFromName(item.name);
if(ShopItemNameContains(item.name, "Fastfire", "fastfire", "FastFire"))
{
item.item.rewardType = npcBunniesQuests::RewardType::RewardFastFire;
if(item.item.amount <= 0) item.item.amount = 5;
return;
}
if(weaponType <= 0) return;
if(ShopItemNameContains(item.name, "Powerup", "powerup", "Power-up") || ShopItemNameContains(item.name, "power-up", " PU", " pu"))
{
item.item.rewardType = npcBunniesQuests::RewardType::RewardPowerup;
item.item.weaponType = weaponType;
item.item.amount = 1;
return;
}
if(ShopItemNameContains(item.name, "Ammo", "ammo") || ShopItemNameContains(item.name, "Bullet", "bullet") || ShopItemNameContains(item.name, "Bullets", "bullets"))
{
item.item.rewardType = npcBunniesQuests::RewardType::RewardAmmo;
item.item.weaponType = weaponType;
if(item.item.amount <= 0) item.item.amount = 5;
}
}
void GetShopItemAnimation(NpcShopItem@ item, npcBunniesAnimations::NpcUiAnimation &inout result)
{
if(item is null || item.item is null) { npcBunniesAnimations::GetNpcUiIcon(npcBunniesAnimations::NpcUiIcon::Unknown, result); return; }
NormalizeShopItemReward(item);
if(item.item.iconSpecified) { npcBunniesAnimations::CopyNpcUiAnimation(item.item.icon, result); return; }
if(item.name != "" && (item.item.rewardType == npcBunniesQuests::RewardType::RewardCoins || item.item.rewardType == npcBunniesQuests::RewardType::RewardGems))
{
int nameIcon = GetShopItemIconIdFromName(item.name);
if(nameIcon != npcBunniesAnimations::NpcUiIcon::Unknown) { npcBunniesAnimations::GetNpcUiIcon(nameIcon, result); return; }
}
npcBunniesAnimations::GetRewardUiAnimation(item.item, result);
}
// END NPC SHOP REGION
}
Jazz2Online © 1999-INFINITY (Site Credits). We have a Privacy Policy. Jazz Jackrabbit, Jazz Jackrabbit 2, Jazz Jackrabbit Advance and all related trademarks and media are ™ and © Epic Games. Lori Jackrabbit is © Dean Dodrill. J2O development powered by Loops of Fury and Chemical Beats.
Eat your lima beans, Johnny.