[PLUS] Randomly numbered Limited Edition.

Damien

Don't need glasses if you can C#
Feb 26, 2012
426
640
Someone asked me to code this into plus for them, thought I'd share it for everyone. @Meap

Firstly add this method:
Code:
public static void Shuffle<T>(this List<T> list)
{
    int n = list.Count;
    while (n > 1)
    {
        n--;
        int k = r.Next(n + 1);
        T value = list[k];
        list[k] = list[n];
        list[n] = value;
    }
}


Don't forget the reference:
Code:
using System.Collections.Generic;

Replace the constructor with this:
Code:
public CatalogItem(int id, int itemId, ItemData data, string catalogName, int pageId, int costCredits, int costPixels,
    int costDiamonds, int amount, int limitedEditionSells, int limitedEditionStack, bool hasOffer, string extraData, string badge, int offerId)
    int costDiamonds, int amount, List<int> limitedNumbers, int limitedEditionStack, bool hasOffer, string extraData, string badge, int offerId)
{
    Id = id;
    Name = catalogName;
    ItemId = itemId;
    Data = data;
    PageID = pageId;
    CostCredits = costCredits;
    CostPixels = costPixels;
    CostDiamonds = costDiamonds;
    Amount = amount;
    LimitedEditionSells = limitedEditionSells;
    LimitedNumbers = limitedNumbers;
    LimitedEditionSells = limitedEditionStack - limitedNumbers.Count;
    LimitedEditionStack = limitedEditionStack;
    IsLimited = (limitedEditionStack > 0);
    IsLimited = limitedEditionStack > 0;
    HaveOffer = hasOffer;
    ExtraData = extraData;
    Badge = badge;
    OfferId = offerId;
}


Making sure to add the variable
Code:
public List<int> LimitedNumbers { get; private set; }

Add this method:
Code:
private List<int> GetLimitedNumbers(int itemId, int size)
{
    List<int> availableNumbers = new List<int>();
    List<int> takenNumbers = new List<int>();

    using (IQueryAdapter dbClient = PlusEnvironment.GetDatabaseManager().GetQueryReactor())
    {
        dbClient.SetQuery("SELECT `number` FROM `catalog_items_limited` WHERE `item_id` = @itemId");
        dbClient.AddParameter("itemId", itemId);
        DataTable limitedNumbers = dbClient.GetTable();

        if (limitedNumbers != null)
        {
            foreach (DataRow row in limitedNumbers.Rows)
            {
                int numberId = Convert.ToInt32(row["number"]);
                if (!takenNumbers.Contains(numberId))
                    takenNumbers.Add(numberId);
            }
        }
    }

    for (int i = 1; i <= size; i++)
    {
        if (!takenNumbers.Contains(i))
            availableNumbers.Add(i);
    }

    return availableNumbers;
}


Then change this script:
Code:
_items[PageId].Add(Convert.ToInt32(Row["id"]), new CatalogItem(...));


To this:
Code:
List<int> limitedNumbers = GetLimitedNumbers(
    Convert.ToInt32(Row["id"]),
    Convert.ToInt32(Row["limited_stack"]));
limitedNumbers.Shuffle();

_items[PageId].Add(Convert.ToInt32(Row["id"]), new CatalogItem(Convert.ToInt32(Row["id"]), Convert.ToInt32(Row["item_id"]),
    Data, Convert.ToString(Row["catalog_name"]), Convert.ToInt32(Row["page_id"]), Convert.ToInt32(Row["cost_credits"]), Convert.ToInt32(Row["cost_pixels"]), Convert.ToInt32(Row["cost_diamonds"]),
    Convert.ToInt32(Row["amount"]), Convert.ToInt32(Row["limited_sells"]), Convert.ToInt32(Row["limited_stack"]), PlusEnvironment.EnumToBool(Row["offer_active"].ToString()),
    Convert.ToInt32(Row["amount"]), limitedNumbers, Convert.ToInt32(Row["limited_stack"]), PlusEnvironment.EnumToBool(Row["offer_active"].ToString()),
    Convert.ToString(Row["extradata"]), Convert.ToString(Row["badge"]), Convert.ToInt32(Row["offer_id"])));


Making sure to add the appropriate references:
Code:
using Plus.Utilities;

Change this script:
Code:
ItemDataList.Add(new CatalogItem(...));


To this:
Code:
ItemDataList.Add(new CatalogItem(0, itemId, data, string.Empty, 0, 0, 0, 0, Amount, new List<int>(), 0, false, "", "", 0));

Find this if statement:
Code:
if (item.IsLimited)
{
    ....
}


And change it to this:
Code:
if (item.IsLimited)
{
    if (item.LimitedNumbers.Count <= 0)
    {
        session.SendNotification("This item has sold out!\n\n" + "Please note, you have not recieved another item (You have also not been charged for it!)");
        session.SendPacket(new CatalogUpdatedComposer());
        session.SendPacket(new PurchaseOKComposer());
        return;
    }

    limitedEditionNumber = item.LimitedNumbers[0];
    limitedEditionStack = item.LimitedEditionStack;
    item.LimitedEditionSells++;

    using (IQueryAdapter dbClient = PlusEnvironment.GetDatabaseManager().GetQueryReactor())
    {
        dbClient.SetQuery("INSERT INTO `catalog_items_limited` (`number`, `item_id`) VALUES (@number, @itemId)");
        dbClient.AddParameter("number", limitedEditionNumber);
        dbClient.AddParameter("itemId", item.Id);
        dbClient.RunQuery();
  
        item.LimitedNumbers.Remove(limitedEditionNumber);
    }
}


Then change every reference for:
Code:
limitedEditionSells


To this:
Code:
limitedEditionNumber

Code:
CREATE TABLE `catalog_items_limited`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `number` int(11) NOT NULL DEFAULT 0,
  `item_id` int(11) NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `number, item_id`(`number`, `item_id`) USING BTREE,
  INDEX `item_id`(`item_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;

And you're done.
 
Last edited:

Meap

Don't need glasses if you C#
Nov 7, 2010
1,045
296
Code:
CREATE TABLE `catalog_items_limited` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `number` varchar(55) NOT NULL DEFAULT '',
  `item_id` varchar(85) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
@Damien
 

Meap

Don't need glasses if you C#
Nov 7, 2010
1,045
296
What does it do? Randomly give you the #number from the Limited Edition on offer?
Its how habbo do their LTD's
instead of it giving you an LTD in increment order so like if theres 20/20 and you buy the first itll give you #1
itll give you a random number out of those 20 available so that way its random at what number you get and it makes getting #1 or whatever number you want a bit more challenging and fun
and everyone gets a chance at getting the #1 LTD
 

Joe

Well-Known Member
Jun 10, 2012
4,090
1,918
Its how habbo do their LTD's
instead of it giving you an LTD in increment order so like if theres 20/20 and you buy the first itll give you #1
itll give you a random number out of those 20 available so that way its random at what number you get and it makes getting #1 or whatever number you want a bit more challenging and fun
and everyone gets a chance at getting the #1 LTD
Thank you. I thought so, when did Habbo change to this style? I always thought first come first server.

It's a good idea, not sure why they didn't do this from the beginning.
 

Meap

Don't need glasses if you C#
Nov 7, 2010
1,045
296
Thank you. I thought so, when did Habbo change to this style? I always thought first come first server.

It's a good idea, not sure why they didn't do this from the beginning.
think its been like that for a while tbh
pretty sure arcturus also has their LTD's setup like that and it got requested by a user of mine so I tried and failed LOL
then asked the big boss himself if he could do it
 

Sledmore

Chaturbate Livestreamer
Staff member
FindRetros Moderator
Jul 24, 2010
5,194
3,901
Spooky timing, was literally planning to do this today, what a time saver - thanks for the release.

I'd probably just consider adding a foreign key to the table in relation to the items table, and probably adding two indexes, for example:

Code:
CREATE TABLE `catalog_items_limited`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `number` int(11) NOT NULL DEFAULT 0,
  `item_id` int(11) NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `number, item_id`(`number`, `item_id`) USING BTREE,
  INDEX `item_id`(`item_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;
 

Damien

Don't need glasses if you can C#
Feb 26, 2012
426
640
Spooky timing, was literally planning to do this today, what a time saver - thanks for the release.

I'd probably just consider adding a foreign key to the table in relation to the items table, and probably adding two indexes, for example:

Code:
CREATE TABLE `catalog_items_limited`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `number` int(11) NOT NULL DEFAULT 0,
  `item_id` int(11) NOT NULL DEFAULT 0,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `number, item_id`(`number`, `item_id`) USING BTREE,
  INDEX `item_id`(`item_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Dynamic;


No worries, thanks for the updated sql.

The commit can be located here for convenience to anyone who finds this easier. Just ignore the assembly changes, since I was too lazy to install the correct framework.
Code:
https://github.com/DamienJolly/PlusEMU/commit/75d246f5c7a0d7b4c7c24995b867adc6b2d9ba3a
 

Users who are viewing this thread

Top