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` ALTER TABLE `permissions`
ADD COLUMN `acc_mimic_unredeemed` enum('0','1') NOT NULL DEFAULT '0'; 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 #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<>(); THashSet<HabboItem> itemsList = new THashSet<>();
@ -1073,94 +1070,71 @@ public class CatalogManager
limitedStack = limitedConfiguration.getTotalSet(); 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<>(); List<String> badges = new ArrayList<>();
boolean badgeFound = false; boolean badgeFound = false;
for (int i = 0; i < amount; i++) 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();
}
habbo.getHabboStats().addLtdLog(item.getId(), Emulator.getIntUnixTimestamp()); 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++) {
for (Item baseItem : item.getBaseItems()) if (baseItem.getName().startsWith("rentable_bot_") || baseItem.getName().startsWith("bot_")) {
{
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_", ""); String type = item.getName().replace("rentable_bot_", "");
type = type.replace("bot_", ""); type = type.replace("bot_", "");
type = type.replace("visitor_logger", "visitor_log"); type = type.replace("visitor_logger", "visitor_log");
THashMap<String, String> data = new THashMap<>(); THashMap<String, String> data = new THashMap<>();
for (String s : item.getExtradata().split(";")) for (String s : item.getExtradata().split(";")) {
{ if (s.contains(":")) {
if (s.contains(":"))
{
data.put(s.split(":")[0], s.split(":")[1]); data.put(s.split(":")[0], s.split(":")[1]);
} }
} }
Bot bot = Emulator.getGameEnvironment().getBotManager().createBot(data, type); Bot bot = Emulator.getGameEnvironment().getBotManager().createBot(data, type);
if (bot != null) if (bot != null) {
{
bot.setOwnerId(habbo.getClient().getHabbo().getHabboInfo().getId()); bot.setOwnerId(habbo.getClient().getHabbo().getHabboInfo().getId());
bot.setOwnerName(habbo.getClient().getHabbo().getHabboInfo().getUsername()); bot.setOwnerName(habbo.getClient().getHabbo().getHabboInfo().getUsername());
bot.needsUpdate(true); bot.needsUpdate(true);
Emulator.getThreading().run(bot); Emulator.getThreading().run(bot);
habbo.getClient().getHabbo().getInventory().getBotsComponent().addBot(bot); habbo.getClient().getHabbo().getInventory().getBotsComponent().addBot(bot);
habbo.getClient().sendResponse(new AddBotComposer(bot)); habbo.getClient().sendResponse(new AddBotComposer(bot));
} else } else {
{
throw new Exception("Failed to create bot of type: " + type); 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(); int effectId = baseItem.getEffectM();
if (habbo.getHabboInfo().getGender().equals(HabboGender.F)) if (habbo.getHabboInfo().getGender().equals(HabboGender.F)) {
{
effectId = baseItem.getEffectF(); effectId = baseItem.getEffectF();
} }
if (effectId > 0) if (effectId > 0) {
{
habbo.getInventory().getEffectsComponent().createEffect(effectId); habbo.getInventory().getEffectsComponent().createEffect(effectId);
} }
} else if (Item.isPet(baseItem)) } else if (Item.isPet(baseItem)) {
{
String[] data = extradata.split("\n"); String[] data = extradata.split("\n");
if (data.length < 3) if (data.length < 3) {
{
habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR));
return; return;
} }
Pet pet = null; Pet pet = null;
try try {
{
pet = Emulator.getGameEnvironment().getPetManager().createPet(baseItem, data[0], data[1], data[2], habbo.getClient()); pet = Emulator.getGameEnvironment().getPetManager().createPet(baseItem, data[0], data[1], data[2], habbo.getClient());
} catch (Exception e) } catch (Exception e) {
{
Emulator.getLogging().logErrorLine(e); Emulator.getLogging().logErrorLine(e);
habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR));
} }
if (pet == null) if (pet == null) {
{
habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR));
return; return;
} }
@ -1170,24 +1144,17 @@ public class CatalogManager
habbo.getClient().sendResponse(new PetBoughtNotificationComposer(pet, false)); habbo.getClient().sendResponse(new PetBoughtNotificationComposer(pet, false));
AchievementManager.progressAchievement(habbo.getClient().getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("PetLover")); AchievementManager.progressAchievement(habbo.getClient().getHabbo(), Emulator.getGameEnvironment().getAchievementManager().getAchievement("PetLover"));
} else if (baseItem.getType() == FurnitureType.BADGE) } else if (baseItem.getType() == FurnitureType.BADGE) {
{ if (!habbo.getInventory().getBadgesComponent().hasBadge(baseItem.getName())) {
if (!habbo.getInventory().getBadgesComponent().hasBadge(baseItem.getName())) if (!badges.contains(baseItem.getName())) {
{
if (!badges.contains(baseItem.getName()))
{
badges.add(baseItem.getName()); badges.add(baseItem.getName());
} }
} else } else {
{
badgeFound = true; badgeFound = true;
} }
} else } else {
{ if (baseItem.getInteractionType().getType() == InteractionTrophy.class || baseItem.getInteractionType().getType() == InteractionBadgeDisplay.class) {
if (baseItem.getInteractionType().getType() == InteractionTrophy.class || baseItem.getInteractionType().getType() == InteractionBadgeDisplay.class) if (baseItem.getInteractionType().getType() == InteractionBadgeDisplay.class && !habbo.getClient().getHabbo().getInventory().getBadgesComponent().hasBadge(extradata)) {
{
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)); ScripterManager.scripterDetected(habbo.getClient(), Emulator.getTexts().getValue("scripter.warning.catalog.badge_display").replace("%username%", habbo.getClient().getHabbo().getHabboInfo().getUsername()).replace("%badge%", extradata));
extradata = "UMAD"; 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); 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 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); HabboItem teleportTwo = Emulator.getGameEnvironment().getItemManager().createItem(habbo.getClient().getHabbo().getHabboInfo().getId(), baseItem, limitedStack, limitedNumber, extradata);
Emulator.getGameEnvironment().getItemManager().insertTeleportPair(teleportOne.getId(), teleportTwo.getId()); Emulator.getGameEnvironment().getItemManager().insertTeleportPair(teleportOne.getId(), teleportTwo.getId());
itemsList.add(teleportOne); itemsList.add(teleportOne);
itemsList.add(teleportTwo); 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); HabboItem hopper = Emulator.getGameEnvironment().getItemManager().createItem(habbo.getClient().getHabbo().getHabboInfo().getId(), baseItem, limitedStack, limitedNumber, extradata);
Emulator.getGameEnvironment().getItemManager().insertHopper(hopper); Emulator.getGameEnvironment().getItemManager().insertHopper(hopper);
itemsList.add(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; int guildId;
try try {
{
guildId = Integer.parseInt(extradata); guildId = Integer.parseInt(extradata);
} catch (Exception e) } catch (Exception e) {
{
Emulator.getLogging().logErrorLine(e); Emulator.getLogging().logErrorLine(e);
habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR));
return; 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()); SoundTrack track = Emulator.getGameEnvironment().getItemManager().getSoundTrack(item.getExtradata());
if (track == null) if (track == null) {
{
habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR)); habbo.getClient().sendResponse(new AlertPurchaseFailedComposer(AlertPurchaseFailedComposer.SERVER_ERROR));
return; return;
} }
@ -1257,17 +1216,13 @@ public class CatalogManager
itemsList.add(habboItem); itemsList.add(habboItem);
AchievementManager.progressAchievement(habbo, Emulator.getGameEnvironment().getAchievementManager().getAchievement("MusicCollector")); 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); HabboItem habboItem = Emulator.getGameEnvironment().getItemManager().createItem(habbo.getClient().getHabbo().getHabboInfo().getId(), baseItem, limitedStack, limitedNumber, extradata);
itemsList.add(habboItem); itemsList.add(habboItem);
} }
} }
} }
} }
//}
}
}
} }
UserCatalogItemPurchasedEvent purchasedEvent = new UserCatalogItemPurchasedEvent(habbo, item, itemsList, totalCredits, totalPoints, badges); UserCatalogItemPurchasedEvent purchasedEvent = new UserCatalogItemPurchasedEvent(habbo, item, itemsList, totalCredits, totalPoints, badges);
@ -1394,4 +1349,28 @@ public class CatalogManager
{ {
return this.targetOffers.get(offerId); 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 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 @Override
public ServerMessage compose() public ServerMessage compose()
{ {
this.response.init(Outgoing.DiscountComposer); 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(ADDITIONAL_DISCOUNT_THRESHOLDS.length);
for (int threshold : ADDITIONAL_DISCOUNT_THRESHOLDS) {
this.response.appendInt(1); this.response.appendInt(threshold);
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
return this.response; 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.PacketManager;
import com.eu.habbo.messages.incoming.floorplaneditor.FloorPlanEditorSaveEvent; import com.eu.habbo.messages.incoming.floorplaneditor.FloorPlanEditorSaveEvent;
import com.eu.habbo.messages.incoming.hotelview.HotelViewRequestLTDAvailabilityEvent; 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.emulator.EmulatorConfigUpdatedEvent;
import com.eu.habbo.plugin.events.roomunit.RoomUnitLookAtPointEvent; import com.eu.habbo.plugin.events.roomunit.RoomUnitLookAtPointEvent;
import com.eu.habbo.plugin.events.users.*; import com.eu.habbo.plugin.events.users.*;
@ -42,6 +43,7 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.util.Arrays;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
@ -332,6 +334,11 @@ public class PluginManager
RoomTrade.TRADING_ENABLED = Emulator.getConfig().getBoolean("hotel.trading.enabled") && !ShutdownEmulator.instantiated; RoomTrade.TRADING_ENABLED = Emulator.getConfig().getBoolean("hotel.trading.enabled") && !ShutdownEmulator.instantiated;
RoomTrade.TRADING_REQUIRES_PERK = Emulator.getConfig().getBoolean("hotel.trading.requires.perk"); RoomTrade.TRADING_REQUIRES_PERK = Emulator.getConfig().getBoolean("hotel.trading.requires.perk");
WordFilter.ENABLED_FRIENDCHAT = Emulator.getConfig().getBoolean("hotel.wordfilter.messenger"); 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.MINIMUM_CHAT_SPEED = Emulator.getConfig().getInt("hotel.bot.chat.minimum.interval");
BotManager.MAXIMUM_CHAT_LENGTH = Emulator.getConfig().getInt("hotel.bot.max.chatlength"); BotManager.MAXIMUM_CHAT_LENGTH = Emulator.getConfig().getInt("hotel.bot.max.chatlength");