Frostorm

[]D[][]V[][]D
Veteran
Joined
Feb 22, 2016
Messages
2,283
Reaction score
1,922
First Language
English
Primarily Uses
RMMV
So I use LeTBS (LeCode's Tactical Battle System) and need help getting Custom/Conditional Scopes working. Originally, a skill's scope is defined in its notebox like so:
JavaScript:
<letbs>
scope: circle(1)
</letbs>
But let's say I want the scope to change depending on a conditional. For example, I made a custom function to do so:

JavaScript:
TBSEntity.prototype.customRanged = function () {
    if (user.isLearnedSkill(45))
    {return "4";}
    else
    {return "3";}
};

...meaning, if Skill 45 is learned, the range will be 4, else it'll be 3. So far so good...the issue shows up in the RegExp portion of the .makeScope() function:
JavaScript:
BattleManagerTBS.makeScope = function (data, center, param) { //Modified by PHX
    var str, min, size;
    var e = param.user;
    if (e)
        var a = e.battler();

    if (data.match(/(circle|line|square|cross)\((.+)\)/i)) {
        console.log(data);
        console.log(RegExp.$2);
        if (RegExp.$2.includes(",")) {
            str = RegExp.$2.split(",");
            size = Math.floor(Number(eval(str[0])));
            min = Math.floor(Number(eval(str[1])));
        } else if (RegExp.$2.match(/(\(.*\))/i)) {
            //This checks if a function is used instead of the normal circle(x)/circle(x,y) format to return a number or x,y
            //This will only be used if it does not use function(),function() as that will get picked up by the first statement.
            //Afterwards, it essentially clones the original function with checking if comma delimited, or not.
        R2 = eval(RegExp.$2);
               if (R2.includes(",")) {
               str = R2.split(",");
               size = Math.floor(Number(eval(str[0])));
               min = Math.floor(Number(eval(str[1])));
        }
        else {
            size = Math.floor(Number(eval(RegExp.$2)));
            }
        }
        else {
            size = Math.floor(Number(eval(RegExp.$2)));
        }
    }

    if (data.match(/custom\((.+)\)/i)) {
        var scopeData = Lecode.S_TBS.Config.Custom_Scopes[String(RegExp.$1)];
        scope = this.getScopeFromRawData(scopeData, center, param);
    } else if (data.match(/circle\((.+)\)/i)) {
        scope = this.makeCircleScope(center, size, min, param);
    } else if (data.match(/line\((.+)\)/i)) {
        scope = this.makeLineScope(center, size, min, param);
    } else if (data.match(/square\((.+)\)/i)) {
        scope = this.makeSquareScope(center, size, min, param);
    } else if (data.match(/cross\((.+)\)/i)) {
        scope = this.makeCrossScope(center, size, min, param);
    } else if (data.match(/path/i)) {
        scope = this.makePathScope(param);
    } else {
        var cx = center.x;
        var cy = center.y;
        var aoe = eval("[" + data + "]");
        for (var i = 0; i < aoe.length; i++) {
            var cell = this.getCellAt(aoe[i][0], aoe[i][1]);
            if (cell)
                scope.push(cell);
        }
    }
    return LeUtilities.uniqArray(scope);
};

Specifically, I get an error saying "Cannot read property 'includes' of undefined". This refers to line 4179: if (R2.includes(",")) {
This leads me to believe there's an issue w/ the line above that: R2 = eval(RegExp.$2);

eval(RegExp.$2) SHOULD give us the result of the .customRange() function from earlier. I made sure by checking the console.log and saw console.log(data) returned circle(e.customRanged()) and console.log(RegExp.$2) returned e.customRanged() respectively. However, I get the error mentioned earlier.

In short, I need to get "R2" to return the results of e.customRanged(). Ofc, "customRanged" is just 1 example, it should theoretically work w/ any other custom scope function.

For reference, this I what I put in the notebox of the skill:
JavaScript:
<letbs>
scope: circle(e.customRanged())
</letbs>
1634499791895.png

Also, here's the original/unmodified .makeScope() function: (no custom/conditional scope feature)
JavaScript:
BattleManagerTBS.makeScope = function (data, center, param) {
    var str, min, size;
    var e = param.user;
    if (e)
        var a = e.battler();

    if (data.match(/(circle|line|square|cross)\((.+)\)/i)) {
        if (RegExp.$2.includes(",")) {
            str = RegExp.$2.split(",");
            size = Math.floor(Number(eval(str[0])));
            min = Math.floor(Number(eval(str[1])));
        } else {
            size = Math.floor(Number(eval(RegExp.$2)));
        }
    }

    if (data.match(/custom\((.+)\)/i)) {
        var scopeData = Lecode.S_TBS.Config.Custom_Scopes[String(RegExp.$1)];
        scope = this.getScopeFromRawData(scopeData, center, param);
    } else if (data.match(/circle\((.+)\)/i)) {
        scope = this.makeCircleScope(center, size, min, param);
    } else if (data.match(/line\((.+)\)/i)) {
        scope = this.makeLineScope(center, size, min, param);
    } else if (data.match(/square\((.+)\)/i)) {
        scope = this.makeSquareScope(center, size, min, param);
    } else if (data.match(/cross\((.+)\)/i)) {
        scope = this.makeCrossScope(center, size, min, param);
    } else if (data.match(/path/i)) {
        scope = this.makePathScope(param);
    } else {
        var cx = center.x;
        var cy = center.y;
        var aoe = eval("[" + data + "]");
        for (var i = 0; i < aoe.length; i++) {
            var cell = this.getCellAt(aoe[i][0], aoe[i][1]);
            if (cell)
                scope.push(cell);
        }
    }
    return LeUtilities.uniqArray(scope);
};

@Pharonix Hey, if u see this I could really use your help! (Pharonix is the author of this modification)
 
Last edited:

ATT_Turan

Forewarner of the Black Wind
Veteran
Joined
Jul 2, 2014
Messages
2,746
Reaction score
1,611
First Language
English
Primarily Uses
RMMV
This is hard to help with because the plugin is no longer available for download in the thread you linked to (or if it is, it's not in the original post and I'm not reading 166 pages...).

Edit: I just saw you did include the original function in spoilers. Are you sure that e=param.user is setting it to a TBSEntity? We can't see the part of the code that would deal with that, and so that would make sense if you were calling e.customRanged on the wrong data type, then the eval would be returning undefined.
 
Last edited:

Frostorm

[]D[][]V[][]D
Veteran
Joined
Feb 22, 2016
Messages
2,283
Reaction score
1,922
First Language
English
Primarily Uses
RMMV
The e = param.user is definitely correct, as it's part of LeCode's original code (w/o @Pharonix's edits), which I'll attach below:

Edit: Also, I think it's something to do w/ R2 = eval(RegExp.$2); and not e = param.user since the previous if statement works fine. As in, if (data.match(/(circle|line|square|cross)\((.+)\)/i)) { as well as if (RegExp.$2.includes(",")) { both return the correct results. I've tested it w/ the default scopes like so:
JavaScript:
<letbs>
scope: circle(1)
</letbs>

Relevant post in LeTBS thread start at pg149.

Oh actually, here's the original untouched demo project:
 

Attachments

  • LeTBS.js
    424.1 KB · Views: 1
Last edited:

ATT_Turan

Forewarner of the Black Wind
Veteran
Joined
Jul 2, 2014
Messages
2,746
Reaction score
1,611
First Language
English
Primarily Uses
RMMV
The e = param.user is definitely correct, as it's part of LeCode's original code
That's not what I asked. I asked if you're sure the user member variable is of the type you're treating it as.
 

Frostorm

[]D[][]V[][]D
Veteran
Joined
Feb 22, 2016
Messages
2,283
Reaction score
1,922
First Language
English
Primarily Uses
RMMV
That's not what I asked. I asked if you're sure the user member variable is of the type you're treating it as.
Ok, I just tried a console.log(e) to verify.
1634508415454.png
 

ATT_Turan

Forewarner of the Black Wind
Veteran
Joined
Jul 2, 2014
Messages
2,746
Reaction score
1,611
First Language
English
Primarily Uses
RMMV
Okay...is your function inside of a scope in the plugin that creates a variable named "user"? Because you're looking at user.isLearnedSkill but you're not passing an actor in as an argument, so where is user coming from? It seems to me you should be looking at this.battler().isLearnedSkill
 

Frostorm

[]D[][]V[][]D
Veteran
Joined
Feb 22, 2016
Messages
2,283
Reaction score
1,922
First Language
English
Primarily Uses
RMMV
Okay...is your function inside of a scope in the plugin that creates a variable named "user"? Because you're looking at user.isLearnedSkill but you're not passing an actor in as an argument, so where is user coming from?
In that case, let's try a simpler conditional statement...like if (2 > 1) lol
Brb, gonna try it now.

Edit: So if this works, it should give me a scope w/ a 4 tiles radius...
JavaScript:
TBSEntity.prototype.customRanged = function () {
    if (2 > 1)
    {return "4";}
    else
    {return "3";}
};

Edit2: Damn, didn't work...same error. I think the issue is that eval(RegExp.$2) is not returning "4" or "3" as per the customRange() function suggests it should.
 
Last edited:

ATT_Turan

Forewarner of the Black Wind
Veteran
Joined
Jul 2, 2014
Messages
2,746
Reaction score
1,611
First Language
English
Primarily Uses
RMMV
You responded while I was editing...if you don't know whether there's some global user variable, then there isn't. user isn't just a term that exists everywhere, it has to be defined. See my edit above for syntax that should work.
 

Frostorm

[]D[][]V[][]D
Veteran
Joined
Feb 22, 2016
Messages
2,283
Reaction score
1,922
First Language
English
Primarily Uses
RMMV
Ok, I tried this.battler().isLearnedSkill but to no avail. I don't think it's even getting to the point of reading the conditional statement in the customRange() function tbh... It doesn't seem like it's getting passed into the eval (the line w/ "R2"). Well, I'm not surprised this didn't work since if (2 > 1) didn't work either lol.
JavaScript:
TBSEntity.prototype.customRanged = function () {
    if (this.battler().isLearnedSkill(45))
    {return "4";}
    else
    {return "3";}
};

Edit: Whoa! I just noticed something weird/freaky... I placed a couple of console.log() like so:
JavaScript:
    if (e)
        var a = e.battler();
        console.log(e);
    if (data.match(/(circle|line|square|cross)\((.+)\)/i)) {
        console.log(data); //line 4168
        console.log(RegExp.$2); //line 4169
        if (RegExp.$2.includes(",")) {
            str = RegExp.$2.split(",");
            size = Math.floor(Number(eval(str[0])));
            min = Math.floor(Number(eval(str[1])));
        } else if (RegExp.$2.match(/(\(.*\))/i)) {
            //This checks if a function is used instead of the normal circle(x)/circle(x,y) format to return a number or x,y
            //This will only be used if it does not use function(),function() as that will get picked up by the first statement.
            //Afterwards, it essentially clones the original function with checking if comma delimited, or not.
        console.log(RegExp.$2); //line 4178
        R2 = eval(RegExp.$2);
               if (R2.includes(",")) {
            str = R2.split(",");
               size = Math.floor(Number(eval(str[0])));
               min = Math.floor(Number(eval(str[1])));
        }
Notice how the console.log(RegExp.$2); on line 4169 returns the correct value, but the console.log(RegExp.$2); on line 4178 shows blank! Why is this?? It's gotta be the source of the issue!
1634510180347.png
 
Last edited:

ATT_Turan

Forewarner of the Black Wind
Veteran
Joined
Jul 2, 2014
Messages
2,746
Reaction score
1,611
First Language
English
Primarily Uses
RMMV
I think the issue is that eval(RegExp.$2) is not returning "4" or "3" as per the customRange() function suggests it should.
Well...yes, obviously, the error window is telling you it's returning undefined. Where are you putting your customRange function? If you test run that in the console, what happens?

Incidentally, this won't affect your problem, but in your else statements 7 lines and 12 lines down, why do you run the whole eval again instead of using Math.floor on R2?
 

Frostorm

[]D[][]V[][]D
Veteran
Joined
Feb 22, 2016
Messages
2,283
Reaction score
1,922
First Language
English
Primarily Uses
RMMV
Incidentally, this won't affect your problem, but in your else statements 7 lines and 12 lines down, why do you run the whole eval again instead of using Math.floor on R2?
I didn't write this code, credit goes to @Pharonix. As to why he wrote it like that? Beats me lol. Anyway, I placed the customRanged() function at the bottom of the file, within the same LeTBS.js as the rest of the code. When I run it, I get "4"...which is good since I currently have the conditional statement set to:
JavaScript:
TBSEntity.prototype.customRanged = function () {
    if (2 > 1)
    {return "4";}
    else
    {return "3";}
};

Edit: @ATT_Turan Haha! I fixed it, check it out!
JavaScript:
BattleManagerTBS.makeScope = function (data, center, param) {
    var str, min, size;
    var e = param.user;
    if (e)
        var a = e.battler();

    if (data.match(/(circle|line|square|cross)\((.+)\)/i)) {
        var R1 = RegExp.$2;
        if (RegExp.$2.includes(",")) {
            str = RegExp.$2.split(",");
            size = Math.floor(Number(eval(str[0])));
            min = Math.floor(Number(eval(str[1])));
        } else if (RegExp.$2.match(/(\(.*\))/i)) {
            var R2 = eval(R1);
               if (R2.includes(",")) {
                str = R2.split(",");
                   size = Math.floor(Number(eval(str[0])));
                   min = Math.floor(Number(eval(str[1])));
            } else {
                size = Math.floor(Number(eval(RegExp.$2)));
            }
        } else {
            size = Math.floor(Number(eval(RegExp.$2)));
        }
    }
For some reason, the issue was that the value of RegExp.$2 was getting lost after the 1st conditional statement for some reason. At least that's what the console.log() seemed to suggest. Anyway, I got around that by simply making a var called "R1" and set that to RegExp.$2. From there, I simply used @Pharonix's given code. No errors so far, and hopefully there are no underlying bugs I'm unaware of...
 
Last edited:

Latest Threads

Latest Profile Posts

Just read the forum rules just for kicks and rule 14 reminds me of this:
150.jpg
I'm in the process of converting all locks and intimidate/persuade dialogue options into D20 DC based success/fail (modified by player skill). Before, it required a certain flat amount you had to meet, but with rolls, it offers more freedom. For instance, you can repeatedly try to unlock a door instead of just not meeting the requirement to unlock it.
Since we get very close: If you want to enjoy the advent calendar as it is intended, wait til your date and the day in the URL line up, so you have the final day on actual christmas and not the day before... time zones ;3
1638170340913.png
Crossover Inn is getting very crowded, and I love it
Climbing to the top #mapping
1638160732198.png

Forum statistics

Threads
117,049
Messages
1,104,132
Members
153,002
Latest member
Barabian
Top