Search code examples
javascriptangularjsinventory

Replicate an ingame inventory on the web


I'm trying to replicate an inventory from a mmorpg online game called CABAL on the web, the game's inventory looks like this:

enter image description here

Basically, inventory has 4 tabs each with 8x8, so on every tab there are a 64 totals of cells and in total 256, though, the index starts from 0 to 63 on each tab and the total from 0 to 255.

As you can see some items occupies 1:1 (rowspan:colspan) some 2:2, some can even be 2:6 for example an armoursuit, anyway the point is that I tried here replicate as best as I could, though i managed to make 1 tab only.

    function createCells(rows, cols) {
        var cells = {},
            x = 0,
            startRow = 0,
            endRow = 0;

        for (var i = 0; i < rows; i++) {
            cells[i] = {};
            for (var j = 0; j < cols; j++) {
                cells[i][j] = { id: "e" + x };

                if (angular.isDefined(items[x])) {
                    cells[i][j] = items[x];
                    if (items[x].colspan > 1 && items[x].rowspan > 1) {
                        startRow = x % rows;
                        endRow = parseInt(x / cols, 10) + items[x].rowspan;
                        console.log(j);
                        console.log("Start column " + startRow + " end rowspan " + endRow + " x = " + x);
                    }
                    // console.log();
                    // if (j >= 5 && j <= 8) {
                    //     x += j;
                    // }
                }

                if (!angular.equals(cells[i][j], {})) {
                    console.log(cells[i][j]);
                }


                x++;
            }
        }

        return cells;
    }

So what that issue is that if an item occupies rowspan and colspan bigger than 1 it pushes the other cells after and I need them removed (e7, e14, e15, e39, e46, e47, e54, e55, e62, e63). I need that loops do to calcs automatically based on the items rowspan and colspan that are inventory. The items that are in var items are a sample of the api response so 3, 6, 12, 240, 105 are items for tab 1.

So anyone can help me further? I'm stuck for days on this.


Solution

  • If you don't mind a small approach change, you could try this out:

    • Before making cells, loop through all your items
    • For each item, identify the row and col combinations that will be blocked

    Now, you have a map of all blocked (i.e.: not empty) cells. In the createCells loop, you can use this map to determine if you need a place holder. There are now three cases for each cell:

    • It's the exact slot an item goes in: add an item
    • It's a slot that is blocked by an item: do nothing
    • It's not related to an item: insert placeholder

    Here's how I did it:

    function createCells(rows, cols) {
      var cells = {};
    
      // Create an object that holds all cell codes blocked by an item
      var itemMap = Object.keys(items).reduce(function(map, key) {
        var item = items[key],
          cStart = item.slot % cols,
          rStart = Math.floor(item.slot / cols)
        for (var c = 0; c < item.colspan; c += 1) {
          for (var r = 0; r < item.rowspan; r += 1) {
            map[(r + rStart) + ";" + (c + cStart)] = item;
          }
        }
        return map;
      }, {});
    
      var currentNr;
      for (var i = 0; i < rows; i++) {
        cells[i] = {};
    
        for (var j = 0; j < cols; j++) {
          currentNr = i * cols + j;
    
          // If there's an item with this slot, place it
          if (items[currentNr]) {
            // Add item
            cells[i][j] = items[currentNr];
    
          } else if (itemMap[i + ";" + j]) { // The item isn't in the exact spot, but blocks it
            // Block square, do nothing
          } else {
            // Add empty square
            cells[i][j] = {
              id: "e" + currentNr
            }
          }
        }
      }
      return cells;
    }
    

    In a working fiddle: http://jsfiddle.net/q1ba3x4h/