0

I am currently trying to find a way to allow a function within an object to run once the object is called.

For example, take the following Object...

const textNodes = [
{
    id: 1,
    faction: "Greaser",
    text: "Do you want to help this person?",
    options: [
        {
            text: "Yes",
            nextText: 2
        },
        {
            text: "No",
            nextText: 2
        },
    ]
},
{
    id: 2,
    faction: "greaser",
    text: "It was a trap, do you run or kill them?",
    options: [
        {
            text: "Run",
            nextText: 3,
            damage: 0,
        },
        {
            text: "Kill",
            nextText: 5,
            damage: 8,
            moneyDrop: 20,
            radiationDamage: 2,
            logic: function update() {
                console.log("update function worked")

                if(character.greaser == true && this.faction == "greaser"){
                    console.log("greaser check worked");
                }

                character.health -= this.damage;
                character.cash += this.moneyDrop;
                character.radiationLevel += this.radiationDamage;
                character.maxHP -= this.radiationDamage;

                if(this.radiationDamage >= 1 ){
                    addRadiatedStatus();
                }

                console.log("character HP" + " " +  character.health);
                console.log("character maxHP" + " " +  character.maxHP);
                console.log("moneyDrop " + " " +  this.moneyDrop);
                console.log("character cash" + " " +  character.cash);
                console.log("radiation level" + " " +  character.radiationLevel);
                console.log("character Raditated?" + " " +  character.radiated);
            },
        },
    ]
}
]

As you can see , I have a function update() that is going to change a character object once the function is called.

I am currently calling the function like... textNodes[1].options[1].logic();

Of course, I do not want to do this, because I am building a rpg decision game. The user will be given a question and some choices, and allowed to create their own path. If the user gets 3 options, and the user picks option 2, I will run option 2's logic() / update() function.

Each game choice will have a function attached to it that does something different, and each time that I choose the option, I want the function to run automatically. I am not sure if this is even possible, but it seems like the most logical option.

The card decision game I am building is similar to https://www.youtube.com/watch?v=ByBUsBxPrZ4.

as you can see in this video, each card that is chosen ( tinder app style ) will update the game and the characters stats.

I want those update function to run as soon as an object option is called. I am not sure if this is possible, and a peer told me my hint to you is to use classes, but I do not often use classes unless I am coding in java, which I do not like frankly.

Sorry if this is hard to follow and thanks in advance.


Here is what I have tried.

const textNodes = [
    {
        id: 1,
        faction: "Greaser",
        text: "Do you want to help this person?",
        options: [
           {
            text: "Yes",
            nextText: 2
           },
           {
            text: "No",
            nextText: 2
           },
        ]
    },
    {
        id: 2,
        faction: "greaser",
        text: "It was a trap, do you run or kill them?",
        options: [
           {
            text: "Run",
            nextText: 3,
            damage: 0,
           },
           {
            text: "Kill",
            nextText: 5,
            damage: 8,
            moneyDrop: 20,
            radiationDamage: 2,
            logic: function update(){
                console.log("update function worked")
                if(character.greaser == true && this.faction == "greaser"){
                    console.log("greaser check worked");
                }
            character.health -= this.damage;
            character.cash += this.moneyDrop;
            character.radiationLevel += this.radiationDamage;
            character.maxHP -= this.radiationDamage;
            if(this.radiationDamage >= 1 ){
                addRadiatedStatus();
            }
            console.log("character HP" + " " +  character.health);
            console.log("character maxHP" + " " +  character.maxHP);
            console.log("moneyDrop " + " " +  this.moneyDrop);
            console.log("character cash" + " " +  character.cash);
            console.log("radiation level" + " " +  character.radiationLevel);
            console.log("character Raditated?" + " " +  character.radiated);

            },
            run2:  () =>{
                this.logic();
            }
           },
        ]
    }
]

4
  • 1
    I think you can help proxy Commented Jun 22, 2020 at 14:07
  • Can you elaborate more on "as soon as an object option is called". What do you mean "called"? To my understanding you want to avoid explicitly calling the logic function and have it be called automatically. I just don't understand the trigger. Commented Jun 22, 2020 at 14:08
  • Do you know which option is selected by the user? If yes, did you try to call logic method directly on selected option? You can even check if object has logic property defined like this: jsbin.com/nuyenagiwe/1/edit?js,console Commented Jun 22, 2020 at 14:28
  • @ΣπύροςΓούλας thank you for your comment. When i mean "called", I mean that whenever the user selects an "option" for that question ID, I want to run any and all functions that are within my object. So if the question ( id 2 ) is "Do you want to run or fight", and the user selects the option "fight", any function within that option will be run. If the user chooses to fight, maybe my function will subtract health from a player object. I am using this tutorial as a starting point, and might help understand what I am trying to do. youtube.com/watch?v=R1S_NhKkvGA&t=709s . Commented Jun 22, 2020 at 15:40

1 Answer 1

1

The simplest thing is to put the call to logic (aka update) at the end of the functions that you want to have do an update after they've done their work.

If for some reason you don't want to do that, you can wrap them in another function that will do it. After creating textNodes:

for (const {options} of textNodes) {
    for (const option of options) {
        const original = option.theOtherFunction;
        option.theOtherFunction = function(...args) {
            const result = original.apply(this, args);
            this.logic();
            return result;
        };
    }
}

Now, calling textNodes[i].options[1].theOtherFunction() will do theOtherFunction's work, and then do a call to logic (unless an error is thrown).

Or in ES5:

textNodes.forEach(function(textNode) {
    textNode.options.forEach(function(option) {
        var original = option.theOtherFunction;
        option.theOtherFunction = function() {
            var result = original.apply(this, arguments);
            this.logic();
            return result;
        };
    });
});

Re calling this.logic from the function, as you can see it works just fine:

const textNodes = [{
    id: 1,
    faction: "Greaser",
    text: "Do you want to help this person?",
    options: [{
        text: "Yes",
        nextText: 2
      },
      {
        text: "No",
        nextText: 2
      },
    ]
  },
  {
    id: 2,
    faction: "greaser",
    text: "It was a trap, do you run or kill them?",
    options: [{
        text: "Run",
        nextText: 3,
        damage: 0,
      },
      {
        text: "Kill",
        nextText: 5,
        damage: 8,
        moneyDrop: 20,
        radiationDamage: 2,
        logic: function update() {
          console.log("update function worked")
          /*
          if (character.greaser == true && this.faction == "greaser") {
            console.log("greaser check worked");
          }
          character.health -= this.damage;
          character.cash += this.moneyDrop;
          character.radiationLevel += this.radiationDamage;
          character.maxHP -= this.radiationDamage;
          if (this.radiationDamage >= 1) {
            addRadiatedStatus();
          }
          console.log("character HP" + " " + character.health);
          console.log("character maxHP" + " " + character.maxHP);
          console.log("moneyDrop " + " " + this.moneyDrop);
          console.log("character cash" + " " + character.cash);
          console.log("radiation level" + " " + character.radiationLevel);
          console.log("character Raditated?" + " " + character.radiated);
          */
        },
        run2: function() {
          console.log("This is run2");
          this.logic();
        }
      },
    ]
  }
];

textNodes[1].options[1].run2();

Sign up to request clarification or add additional context in comments.

8 Comments

thank you for the response T.J. However, I am a little confused here. I tried adding a key to my option called runFunction: logic(), but I get the error that logic does not exist. I also tried this.logic and that also didn't work. Is there a way to do this ( not the way you show after you say "if for some reason you don't want to do that", but just adding the function call at the end ).
@ETHan - To help further, I need a minimal reproducible example of the problem showing not just where/how logic is defined, but also where/how the function you want to call it from is defined. If it were on the option like logic is, this.logic(); would work.
I am defining logic here logic: function update() { console.log("update function worked") and then adding another key pair to that option like run: this.logic() and that doesn’t work. Let me send a JS fiddle for you to see.
@ETHan - No, not a jsFiddle. Put the code necessary to answer the question in the question, not just linked. But run: this.logic() calls this.logic() an assigns the result to the run property, just like foo: 42 assigns 42 to the foo property. If you meant that to be a function, you have to create a function: run: function() { this.logic(); }.
I edited the post and added what I have been trying to do.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.