Merge branch 'batch-discount-fix' into 'dev'

Fix catalog item pricing. Closes #9

See merge request morningstar/Arcturus-Community!35
This commit is contained in:
Alejandro 2019-05-17 14:24:27 -04:00
commit aa64bc1aef
4 changed files with 194 additions and 197 deletions

View File

@ -21,4 +21,10 @@ INSERT INTO `emulator_texts`(`key`, `value`) VALUES ('commands.error.cmd_mimic.f
ALTER TABLE `permissions`
ADD COLUMN `acc_mimic_unredeemed` enum('0','1') NOT NULL DEFAULT '0';
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('discount.max.allowed.items', '100');
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('discount.batch.size', '6');
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('discount.batch.free.items', '1');
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('discount.bonus.min.discounts', '1');
INSERT INTO `emulator_settings`(`key`, `value`) VALUES ('discount.additional.thresholds', '40;99');
#END DATABASE UPDATE: 2.0.0 RC-2 -> 2.0.0 RC-3

View File

@ -1045,9 +1045,6 @@ public class CatalogManager
}
}
int totalCredits = 0;
int totalPoints = 0;
THashSet<HabboItem> itemsList = new THashSet<>();
@ -1073,94 +1070,71 @@ public class CatalogManager
limitedStack = limitedConfiguration.getTotalSet();
}
int totalCredits = free ? 0 : this.calculateDiscountedPrice(item.getCredits(), amount, item);
int totalPoints = free ? 0 : this.calculateDiscountedPrice(item.getPoints(), amount, item);
if (totalCredits > 0 && habbo.getHabboInfo().getCredits() - totalCredits < 0) return;
if (totalPoints > 0 && habbo.getHabboInfo().getCurrencyAmount(item.getPointsType()) - totalPoints < 0) return;
List<String> badges = new ArrayList<>();
boolean badgeFound = false;
for (int i = 0; i < amount; i++)
{
if (free || (item.getCredits() <= habbo.getClient().getHabbo().getHabboInfo().getCredits() - totalCredits))
{
if (free ||
item.getPoints() <= habbo.getClient().getHabbo().getHabboInfo().getCurrencyAmount(item.getPointsType()) - totalPoints)
{
if (((i + 1) % 6 != 0 && CatalogItem.haveOffer(item)) || !CatalogItem.haveOffer(item))
{
totalCredits += item.getCredits();
totalPoints += item.getPoints();
}
for (int i = 0; i < amount; i++) {
habbo.getHabboStats().addLtdLog(item.getId(), Emulator.getIntUnixTimestamp());
//for (int j = 0; j < item.getAmount(); j++)
//{
for (Item baseItem : item.getBaseItems())
{
for (int k = 0; k < item.getItemAmount(baseItem.getId()); k++)
{
if (baseItem.getName().startsWith("rentable_bot_") || baseItem.getName().startsWith("bot_"))
{
for (Item baseItem : item.getBaseItems()) {
for (int k = 0; k < item.getItemAmount(baseItem.getId()); k++) {
if (baseItem.getName().startsWith("rentable_bot_") || baseItem.getName().startsWith("bot_")) {
String type = item.getName().replace("rentable_bot_", "");
type = type.replace("bot_", "");
type = type.replace("visitor_logger", "visitor_log");
THashMap<String, String> data = new THashMap<>();
for (String s : item.getExtradata().split(";"))
{
if (s.contains(":"))
{
for (String s : item.getExtradata().split(";")) {
if (s.contains(":")) {
data.put(s.split(":")[0], s.split(":")[1]);
}
}
Bot bot = Emulator.getGameEnvironment().getBotManager().createBot(data, type);
if (bot != null)
{
if (bot != null) {
bot.setOwnerId(habbo.getClient().getHabbo().getHabboInfo().getId());
bot.setOwnerName(habbo.getClient().getHabbo().getHabboInfo().getUsername());
bot.needsUpdate(true);
Emulator.getThreading().run(bot);
habbo.getClient().getHabbo().getInventory().getBotsComponent().addBot(bot);
habbo.getClient().sendResponse(new AddBotComposer(bot));
} else
{
} else {
throw new Exception("Failed to create bot of type: " + type);
}
} else if (baseItem.getType() == FurnitureType.EFFECT)
{
} else if (baseItem.getType() == FurnitureType.EFFECT) {
int effectId = baseItem.getEffectM();
if (habbo.getHabboInfo().getGender().equals(HabboGender.F))
{
if (habbo.getHabboInfo().getGender().equals(HabboGender.F)) {
effectId = baseItem.getEffectF();
}
if (effectId > 0)
{
if (effectId > 0) {
habbo.getInventory().getEffectsComponent().createEffect(effectId);
}
} else if (Item.isPet(baseItem))
{
} else if (Item.isPet(baseItem)) {
String[] data = extradata.split("\n");
if (data.length < 3)
{
if (data.length < 3) {
habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR));
return;
}
Pet pet = null;
try
{
try {
pet = Emulator.getGameEnvironment().getPetManager().createPet(baseItem, data[0], data[1], data[2], habbo.getClient());
} catch (Exception e)
{
} catch (Exception e) {
Emulator.getLogging().logErrorLine(e);
habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR));
}
if (pet == null)
{
if (pet == null) {
habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR));
return;
}
@ -1170,24 +1144,17 @@ public class CatalogManager
habbo.getClient().sendResponse(new PetBoughtNotificationComposer(pet, false));
AchievementManager.progressAchievement(habbo.getClient().getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("PetLover"));
} else if (baseItem.getType() == FurnitureType.BADGE)
{
if (!habbo.getInventory().getBadgesComponent().hasBadge(baseItem.getName()))
{
if (!badges.contains(baseItem.getName()))
{
} else if (baseItem.getType() == FurnitureType.BADGE) {
if (!habbo.getInventory().getBadgesComponent().hasBadge(baseItem.getName())) {
if (!badges.contains(baseItem.getName())) {
badges.add(baseItem.getName());
}
} else
{
} else {
badgeFound = true;
}
} else
{
if (baseItem.getInteractionType().getType() == InteractionTrophy.class || baseItem.getInteractionType().getType() == InteractionBadgeDisplay.class)
{
if (baseItem.getInteractionType().getType() == InteractionBadgeDisplay.class && !habbo.getClient().getHabbo().getInventory().getBadgesComponent().hasBadge(extradata))
{
} else {
if (baseItem.getInteractionType().getType() == InteractionTrophy.class || baseItem.getInteractionType().getType() == InteractionBadgeDisplay.class) {
if (baseItem.getInteractionType().getType() == InteractionBadgeDisplay.class && !habbo.getClient().getHabbo().getInventory().getBadgesComponent().hasBadge(extradata)) {
ScripterManager.scripterDetected(habbo.getClient(), Emulator.getTexts().getValue("scripter.warning.catalog.badge_display").replace("%username%", habbo.getClient().getHabbo().getHabboInfo().getUsername()).replace("%badge%", extradata));
extradata = "UMAD";
}
@ -1195,28 +1162,23 @@ public class CatalogManager
extradata = habbo.getClient().getHabbo().getHabboInfo().getUsername() + (char) 9 + Calendar.getInstance().get(Calendar.DAY_OF_MONTH) + "-" + (Calendar.getInstance().get(Calendar.MONTH) + 1) + "-" + Calendar.getInstance().get(Calendar.YEAR) + (char) 9 + Emulator.getGameEnvironment().getWordFilter().filter(extradata.replace(((char) 9) + "", ""), habbo);
}
if (InteractionTeleport.class.isAssignableFrom(baseItem.getInteractionType().getType()))
{
if (InteractionTeleport.class.isAssignableFrom(baseItem.getInteractionType().getType())) {
HabboItem teleportOne = Emulator.getGameEnvironment().getItemManager().createItem(habbo.getClient().getHabbo().getHabboInfo().getId(), baseItem, limitedStack, limitedNumber, extradata);
HabboItem teleportTwo = Emulator.getGameEnvironment().getItemManager().createItem(habbo.getClient().getHabbo().getHabboInfo().getId(), baseItem, limitedStack, limitedNumber, extradata);
Emulator.getGameEnvironment().getItemManager().insertTeleportPair(teleportOne.getId(), teleportTwo.getId());
itemsList.add(teleportOne);
itemsList.add(teleportTwo);
} else if (baseItem.getInteractionType().getType() == InteractionHopper.class)
{
} else if (baseItem.getInteractionType().getType() == InteractionHopper.class) {
HabboItem hopper = Emulator.getGameEnvironment().getItemManager().createItem(habbo.getClient().getHabbo().getHabboInfo().getId(), baseItem, limitedStack, limitedNumber, extradata);
Emulator.getGameEnvironment().getItemManager().insertHopper(hopper);
itemsList.add(hopper);
} else if (baseItem.getInteractionType().getType() == InteractionGuildFurni.class || baseItem.getInteractionType().getType() == InteractionGuildGate.class)
{
} else if (baseItem.getInteractionType().getType() == InteractionGuildFurni.class || baseItem.getInteractionType().getType() == InteractionGuildGate.class) {
int guildId;
try
{
try {
guildId = Integer.parseInt(extradata);
} catch (Exception e)
{
} catch (Exception e) {
Emulator.getLogging().logErrorLine(e);
habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR));
return;
@ -1239,13 +1201,10 @@ public class CatalogManager
}
}
}
else if (baseItem.getInteractionType().getType() == InteractionMusicDisc.class)
{
} else if (baseItem.getInteractionType().getType() == InteractionMusicDisc.class) {
SoundTrack track = Emulator.getGameEnvironment().getItemManager().getSoundTrack(item.getExtradata());
if (track == null)
{
if (track == null) {
habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR));
return;
}
@ -1257,17 +1216,13 @@ public class CatalogManager
itemsList.add(habboItem);
AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("MusicCollector"));
} else
{
} else {
HabboItem habboItem = Emulator.getGameEnvironment().getItemManager().createItem(habbo.getClient().getHabbo().getHabboInfo().getId(), baseItem, limitedStack, limitedNumber, extradata);
itemsList.add(habboItem);
}
}
}
}
//}
}
}
}
UserCatalogItemPurchasedEvent purchasedEvent = new UserCatalogItemPurchasedEvent(habbo, item, itemsList, totalCredits, totalPoints, badges);
@ -1394,4 +1349,28 @@ public class CatalogManager
{
return this.targetOffers.get(offerId);
}
private int calculateDiscountedPrice(int originalPrice, int amount, CatalogItem item) {
if (!CatalogItem.haveOffer(item)) return originalPrice * amount;
int basicDiscount = amount / DiscountComposer.DISCOUNT_BATCH_SIZE;
int bonusDiscount = 0;
if (basicDiscount >= DiscountComposer.MINIMUM_DISCOUNTS_FOR_BONUS) {
if (amount % DiscountComposer.DISCOUNT_BATCH_SIZE == DiscountComposer.DISCOUNT_BATCH_SIZE - 1) {
bonusDiscount = 1;
}
bonusDiscount += basicDiscount - DiscountComposer.MINIMUM_DISCOUNTS_FOR_BONUS;
}
int additionalDiscounts = 0;
for (int threshold : DiscountComposer.ADDITIONAL_DISCOUNT_THRESHOLDS) {
if (amount >= threshold) additionalDiscounts++;
}
int totalDiscountedItems = (basicDiscount * DiscountComposer.DISCOUNT_AMOUNT_PER_BATCH) + bonusDiscount + additionalDiscounts;
return Math.max(0, originalPrice * (amount - totalDiscountedItems));
}
}

View File

@ -6,21 +6,26 @@ import com.eu.habbo.messages.outgoing.Outgoing;
public class DiscountComposer extends MessageComposer
{
public static int MAXIMUM_ALLOWED_ITEMS = 100;
public static int DISCOUNT_BATCH_SIZE = 6;
public static int DISCOUNT_AMOUNT_PER_BATCH = 1;
public static int MINIMUM_DISCOUNTS_FOR_BONUS = 1;
public static int[] ADDITIONAL_DISCOUNT_THRESHOLDS = new int[]{40, 99};
@Override
public ServerMessage compose()
{
this.response.init(Outgoing.DiscountComposer);
this.response.appendInt(100); // maximum allowed to buy
this.response.appendInt(MAXIMUM_ALLOWED_ITEMS);
this.response.appendInt(DISCOUNT_BATCH_SIZE);
this.response.appendInt(DISCOUNT_AMOUNT_PER_BATCH);
this.response.appendInt(MINIMUM_DISCOUNTS_FOR_BONUS);
this.response.appendInt(6); // free every x
this.response.appendInt(1);
this.response.appendInt(1);
this.response.appendInt(2); // array count for additional extras
this.response.appendInt(40); //extra free at 40
this.response.appendInt(99); //extra free at 99
this.response.appendInt(ADDITIONAL_DISCOUNT_THRESHOLDS.length);
for (int threshold : ADDITIONAL_DISCOUNT_THRESHOLDS) {
this.response.appendInt(threshold);
}
return this.response;
}

View File

@ -24,6 +24,7 @@ import com.eu.habbo.habbohotel.wired.WiredHandler;
import com.eu.habbo.messages.PacketManager;
import com.eu.habbo.messages.incoming.floorplaneditor.FloorPlanEditorSaveEvent;
import com.eu.habbo.messages.incoming.hotelview.HotelViewRequestLTDAvailabilityEvent;
import com.eu.habbo.messages.outgoing.catalog.DiscountComposer;
import com.eu.habbo.plugin.events.emulator.EmulatorConfigUpdatedEvent;
import com.eu.habbo.plugin.events.roomunit.RoomUnitLookAtPointEvent;
import com.eu.habbo.plugin.events.users.*;
@ -42,6 +43,7 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.NoSuchElementException;
import java.util.Objects;
@ -332,6 +334,11 @@ public class PluginManager
RoomTrade.TRADING_ENABLED = Emulator.getConfig().getBoolean("hotel.trading.enabled") && !ShutdownEmulator.instantiated;
RoomTrade.TRADING_REQUIRES_PERK = Emulator.getConfig().getBoolean("hotel.trading.requires.perk");
WordFilter.ENABLED_FRIENDCHAT = Emulator.getConfig().getBoolean("hotel.wordfilter.messenger");
DiscountComposer.MAXIMUM_ALLOWED_ITEMS = Emulator.getConfig().getInt("discount.max.allowed.items", 100);
DiscountComposer.DISCOUNT_BATCH_SIZE = Emulator.getConfig().getInt("discount.batch.size", 6);
DiscountComposer.DISCOUNT_AMOUNT_PER_BATCH = Emulator.getConfig().getInt("discount.batch.free.items", 1);
DiscountComposer.MINIMUM_DISCOUNTS_FOR_BONUS = Emulator.getConfig().getInt("discount.bonus.min.discounts", 1);
DiscountComposer.ADDITIONAL_DISCOUNT_THRESHOLDS = Arrays.stream(Emulator.getConfig().getValue("discount.additional.thresholds", "40;99").split(";")).mapToInt(Integer::parseInt).toArray();
BotManager.MINIMUM_CHAT_SPEED = Emulator.getConfig().getInt("hotel.bot.chat.minimum.interval");
BotManager.MAXIMUM_CHAT_LENGTH = Emulator.getConfig().getInt("hotel.bot.max.chatlength");