HashLips / hashlips_art_engine

HashLips Art Engine is a tool used to create multiple different instances of artworks based on provided layers.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Finish build when certain trait is used

DUECKX opened this issue · comments

commented

Hi all,

Going to try my best here to explain this but I can't seem to figure this one out.

Let's say I have 4 layers, with 4 different traits each:

  1. Background (background 1, background 2, ...)
  2. Back (back 1, back 2, ...)
  3. Middle (middle 1, middle 2, ...)
  4. Front (front 1, front 2, ...)

Now, is it possible to finish the NFT when a certain trait from the 'Middle' layer is used?

For example:
When 'middle 1' is used, it should continue to the 'Front' folder and choose a random trait from that folder
When 'middle 2' is used, it should not continue to the 'Front' folder but instead it should finish the NFT (ignoring the 'Front' layer)
When 'middle 3' is used, it should continue to the 'Front' folder and choose a random trait from that folder
When 'middle 4' is used, it should not continue to the 'Front' folder but instead it should finish the NFT (ignoring the 'Front' layer)

I've tried several things but I can't seem to get this to work.

Thanks in advance!

@DUECKX if you want to make any changes to generation, you could try editing createDna in src/main.js, lines 282-304:

const createDna = (_layers) => {
let randNum = [];
_layers.forEach((layer) => {
var totalWeight = 0;
layer.elements.forEach((element) => {
totalWeight += element.weight;
});
// number between 0 - totalWeight
let random = Math.floor(Math.random() * totalWeight);
for (var i = 0; i < layer.elements.length; i++) {
// subtract the current weight from the random weight until we reach a sub zero value.
random -= layer.elements[i].weight;
if (random < 0) {
return randNum.push(
`${layer.elements[i].id}:${layer.elements[i].filename}${
layer.bypassDNA ? "?bypassDNA=true" : ""
}`
);
}
}
});
return randNum.join(DNA_DELIMITER);
};

You could change line 284:

let randNum = [];
_layers.forEach((layer) => {
var totalWeight = 0;

To:

  _layers.every((layer) => {

So it will stop generating when we return false.

Then you can change lines 295-299:

return randNum.push(
`${layer.elements[i].id}:${layer.elements[i].filename}${
layer.bypassDNA ? "?bypassDNA=true" : ""
}`
);

To something like:

        randNum.push(
          `${layer.elements[i].id}:${layer.elements[i].filename}${
            layer.bypassDNA ? "?bypassDNA=true" : ""
          }`
        );

        // Return true to continue if it's not 2 or 4, quit if if it is
        return !["middle 2", "middle 4"](layer.elements[i].name)
commented

@bolshoytoster Thanks for taking the time to help me with this!

My code looks slightly different but based on your instructions I've edited lines 340-367:

const selectTraits = (layers) => {
  let traits = [];
  layers.forEach((layer) => {
    var totalWeight = 0;
    layer.elements.forEach((element) => {
      totalWeight += element.weight;
    });
    // number between 0 - totalWeight
    let random = Math.floor(Math.random() * totalWeight);
    for (var i = 0; i < layer.elements.length; i++) {
      // subtract the current weight from the random weight until we reach a sub zero value.
      random -= layer.elements[i].weight;
      if (random < 0) {
        return traits.push({
          layer: layer.name,
          id: layer.elements[i].id,
          name: layer.elements[i].name,
          filename: layer.elements[i].filename,
          bypassDNA: layer.bypassDNA,
          maxRepeatedTrait: layer.maxRepeatedTrait,
          layerItemsMaxRepeatedTrait: layer.layerItemsMaxRepeatedTrait
          },
        );
      }
    }
  });
  return traits;
};

Changed line 342 from:

layers.forEach((layer) => {

to

layers.every((layer) => {

After that I changed line 353-362 from:

        return traits.push({
          layer: layer.name,
          id: layer.elements[i].id,
          name: layer.elements[i].name,
          filename: layer.elements[i].filename,
          bypassDNA: layer.bypassDNA,
          maxRepeatedTrait: layer.maxRepeatedTrait,
          layerItemsMaxRepeatedTrait: layer.layerItemsMaxRepeatedTrait
          },
        );

to

        traits.push({
          layer: layer.name,
          id: layer.elements[i].id,
          name: layer.elements[i].name,
          filename: layer.elements[i].filename,
          bypassDNA: layer.bypassDNA,
          maxRepeatedTrait: layer.maxRepeatedTrait,
          layerItemsMaxRepeatedTrait: layer.layerItemsMaxRepeatedTrait
          },
        );
        
        // Return true to continue if it's not 2 or 4, quit if if it is
        return !["middle 2", "middle 4"](layer.elements[i].name)

But now I get this error as a result:

(node:11352) UnhandledPromiseRejectionWarning: TypeError: ["middle 1","middle 2""] is not a function

Did I do something wrong here?

@DUECKX sorry, looks like I made a typo. Try changing

        return !["middle 2", "middle 4"](layer.elements[i].name)

To

        return !["middle 2", "middle 4"].contains(layer.elements[i].name)