test: cover testTrade
This commit is contained in:
1 parent
5fba3c338a
commit
f2782c8ffb
1 file changed
+156
@@ -157,3 +157,159 @@ VF_TEST(restockRefillsUsesAndLetsDemandAndPriceFallBack) {
|
||||
Container wallet = makeWallet(400);
|
||||
TradeSession session(villager, offers, wallet);
|
||||
|
||||
for (int i = 0; i < 10; ++i) CHECK(session.trade(comparatorOffer).success);
|
||||
int busyPrice = session.priceOf(comparatorOffer);
|
||||
int busyDemand = offers.at(comparatorOffer).demand;
|
||||
CHECK_EQ(offers.at(comparatorOffer).uses, 10);
|
||||
|
||||
CHECK(restockOffers(offers));
|
||||
CHECK_EQ(offers.at(comparatorOffer).uses, 0);
|
||||
CHECK_EQ(offers.at(comparatorOffer).demand, busyDemand - tradeDemandDecayPerRestock);
|
||||
CHECK(session.priceOf(comparatorOffer) <= busyPrice);
|
||||
CHECK(session.available(comparatorOffer));
|
||||
|
||||
for (int i = 0; i < 20; ++i) restockOffers(offers);
|
||||
CHECK_EQ(offers.at(comparatorOffer).demand, 0);
|
||||
CHECK_EQ(session.priceOf(comparatorOffer), offers.at(comparatorOffer).basePrice());
|
||||
CHECK(!restockOffers(offers));
|
||||
}
|
||||
|
||||
VF_TEST(theVillagerRestocksAtMostTwiceADayAndOnlyAtItsOwnWorkstation) {
|
||||
World world = makeShopWorld();
|
||||
PoiRegistry pois;
|
||||
pois.scan(world, villageCenter, 10, 4);
|
||||
|
||||
Villager villager = makeLibrarian(3);
|
||||
TradeOfferList offers = buildTradeOffers(VillagerProfession::Librarian, 1u);
|
||||
Container wallet = makeWallet(400);
|
||||
TradeSession session(villager, offers, wallet);
|
||||
VillagerSchedule schedule;
|
||||
TimeOfDay clock(static_cast<WorldTick>(0.35 * 24000.0));
|
||||
|
||||
CHECK(session.trade(comparatorOffer).success);
|
||||
CHECK(!tickVillagerRestock(villager, offers, clock));
|
||||
|
||||
for (int tick = 0; tick < 400; ++tick)
|
||||
tickVillager(world, villager, pois, clock, schedule, villageCenter, false, 0.05f);
|
||||
CHECK(villager.activity == VillagerActivity::Work);
|
||||
CHECK(villager.state == VillagerState::AtTarget);
|
||||
CHECK_EQ(pois.at(villager.workstationIndex).block, Block::Lectern);
|
||||
|
||||
CHECK(tickVillagerRestock(villager, offers, clock));
|
||||
CHECK_EQ(villager.restocksToday, 1);
|
||||
CHECK(!tickVillagerRestock(villager, offers, clock));
|
||||
|
||||
CHECK(session.trade(comparatorOffer).success);
|
||||
CHECK(tickVillagerRestock(villager, offers, clock));
|
||||
CHECK_EQ(villager.restocksToday, tradeRestocksPerDay);
|
||||
|
||||
CHECK(session.trade(comparatorOffer).success);
|
||||
CHECK(!tickVillagerRestock(villager, offers, clock));
|
||||
|
||||
clock.setTick(static_cast<WorldTick>(24000 + 0.35 * 24000.0));
|
||||
CHECK(tickVillagerRestock(villager, offers, clock));
|
||||
CHECK_EQ(villager.restocksToday, 1);
|
||||
CHECK_EQ(villager.lastRestockDay, 1);
|
||||
}
|
||||
|
||||
VF_TEST(tradingWithoutEnoughEmeraldsFailsAndLeavesTheInventoryAlone) {
|
||||
Villager villager = makeLibrarian(3);
|
||||
TradeOfferList offers = buildTradeOffers(VillagerProfession::Librarian, 1u);
|
||||
Container wallet = makeWallet(2);
|
||||
TradeSession session(villager, offers, wallet);
|
||||
|
||||
CHECK(session.available(comparatorOffer));
|
||||
CHECK(!session.canAfford(comparatorOffer));
|
||||
TradeResult outcome = session.trade(comparatorOffer);
|
||||
CHECK(!outcome.success);
|
||||
CHECK(outcome.reason == TradeResult::Reason::MissingInputA);
|
||||
CHECK_EQ(stockOf(wallet, ItemId::EmeraldGem), 2);
|
||||
CHECK_EQ(stockOf(wallet, ItemId::Comparator), 0);
|
||||
CHECK_EQ(offers.at(comparatorOffer).uses, 0);
|
||||
CHECK_EQ(villager.experience, villagerExperienceForLevel(3));
|
||||
|
||||
CHECK(session.trade(-1).reason == TradeResult::Reason::NoSuchOffer);
|
||||
CHECK(session.trade(offers.size()).reason == TradeResult::Reason::NoSuchOffer);
|
||||
CHECK(!session.available(99));
|
||||
CHECK_EQ(session.priceOf(99), 0);
|
||||
}
|
||||
|
||||
VF_TEST(aDeadOrUnemployedVillagerRefusesToTradeAtAll) {
|
||||
Villager villager = makeLibrarian(3);
|
||||
TradeOfferList offers = buildTradeOffers(VillagerProfession::Librarian, 1u);
|
||||
Container wallet = makeWallet(400);
|
||||
TradeSession session(villager, offers, wallet);
|
||||
CHECK(session.trade(comparatorOffer).success);
|
||||
|
||||
villager.alive = false;
|
||||
TradeResult dead = session.trade(comparatorOffer);
|
||||
CHECK(!dead.success);
|
||||
CHECK(dead.reason == TradeResult::Reason::VillagerUnavailable);
|
||||
|
||||
villager.alive = true;
|
||||
villager.profession = VillagerProfession::Unemployed;
|
||||
CHECK(session.trade(comparatorOffer).reason == TradeResult::Reason::VillagerUnavailable);
|
||||
CHECK_EQ(session.tradesCompleted(), 1);
|
||||
}
|
||||
|
||||
VF_TEST(heroOfTheVillageCutsPricesWhileHittingAVillagerRaisesThem) {
|
||||
Villager villager = makeLibrarian(3);
|
||||
TradeOfferList offers = buildTradeOffers(VillagerProfession::Librarian, 1u);
|
||||
Container wallet = makeWallet(400);
|
||||
TradeSession session(villager, offers, wallet);
|
||||
|
||||
int listPrice = session.priceOf(comparatorOffer);
|
||||
CHECK_EQ(listPrice, offers.at(comparatorOffer).basePrice());
|
||||
|
||||
ReputationView neutral = buildReputation(villager.gossip, {});
|
||||
session.setPriceModifier(priceModifierFor(neutral, 1, 0));
|
||||
int heroPrice = session.priceOf(comparatorOffer);
|
||||
CHECK(heroPrice < listPrice);
|
||||
CHECK_EQ(session.priceModifier().totalPercent(), heroDiscountPercentPerLevel);
|
||||
|
||||
villager.gossip.add(GossipKind::MinorNegative, gossipMinorNegativeGain);
|
||||
CHECK_EQ(villagerHitCount(villager.gossip), 1);
|
||||
session.refreshPrices(buildReputation(villager.gossip, {}), 0);
|
||||
int angryPrice = session.priceOf(comparatorOffer);
|
||||
CHECK(angryPrice > listPrice);
|
||||
CHECK(session.priceModifier().totalPercent() < 0);
|
||||
|
||||
session.refreshPrices(buildReputation(villager.gossip, {}), 1);
|
||||
CHECK(session.priceOf(comparatorOffer) < angryPrice);
|
||||
}
|
||||
|
||||
VF_TEST(priceNeverDropsBelowOneNoMatterHowLargeTheDiscount) {
|
||||
TradeOffer offer;
|
||||
offer.inputA = ItemId::EmeraldGem;
|
||||
offer.inputACount = 2;
|
||||
offer.output = ItemId::Bread;
|
||||
offer.outputCount = 4;
|
||||
|
||||
PriceModifier generous;
|
||||
generous.heroLevel = 5;
|
||||
CHECK_EQ(generous.totalPercent(), 90);
|
||||
CHECK_EQ(offerPrice(offer, generous), 1);
|
||||
|
||||
PriceModifier absurd;
|
||||
absurd.reputationPercent = 60;
|
||||
absurd.heroLevel = 5;
|
||||
CHECK_EQ(absurd.totalPercent(), 90);
|
||||
CHECK_EQ(offerPrice(offer, absurd), 1);
|
||||
|
||||
PriceModifier hostile;
|
||||
hostile.hitCount = 8;
|
||||
CHECK_EQ(hostile.totalPercent(), -160);
|
||||
CHECK_EQ(offerPrice(offer, hostile), 5);
|
||||
|
||||
offer.demand = 40;
|
||||
CHECK(offerPrice(offer, PriceModifier{}) > 2);
|
||||
CHECK_EQ(offerPrice(offer, generous), 1);
|
||||
}
|
||||
|
||||
VF_TEST(aCompletedTradeMovesBothSidesAndFeedsTheVillagerExperience) {
|
||||
Villager villager = makeLibrarian(1);
|
||||
villager.experience = 0;
|
||||
TradeOfferList offers = buildTradeOffers(VillagerProfession::Librarian, 1u);
|
||||
Container wallet = makeWallet(40);
|
||||
TradeSession session(villager, offers, wallet);
|
||||
|
||||
Reference in new issue
Block a user