[RM2K3] DYNRPG COMPILING ERROR

Posts

int a = 8;
int b = *(&a);  // this set b to 8
int c = &(*a);  // this will fail since it tries to dereference a, which is not an address
int* d = &a;
int* e = &(*d); // this will give the address of a
int f = *(&(*d)); // this should set f to 8
int g = *d;  // this is should also set g to 8
I didn't realize you could do things like that too.

author=Kazesui
1. RPG::Battler is a class definition, not a variable. You cannot take the address of a class definition
This confuses me. To clarify, doing this would not work:
Namespace::Class* Ptr;

author=Kazesui
2. RPG::Battler is not an int, so trying to store it as an int pointer won't work. The underlying address might be stored in an unsigned 32 or 64 bit integer, but the compiler still expects the pointer type to be correct, such that derefererncing would still make sense.
Would something like this be okay:
battler* actor; //I'm pretty sure this will error.
int hp = actor->hp;
If not, is there a good way to copy pointers? For example making PtrA reference the same address as PtrB? I am guessing I would have to do something like this:
int n = 8;
int* PtrA = &n;
int* PtrB = &(*PtrA); //This should give PtrB the same address as PtrA?

author=Kazesui
Now, if you're really bent on converting it to something else, what you could do is

int* actor = reinterpret_cast<int*>(battler);
int actor_value = *actor;
This looks interesting. I will have to experiment with this to see if I can use this for anything or cut some of my code down with it.
author=McBick
author=Kazesui
1. RPG::Battler is a class definition, not a variable. You cannot take the address of a class definition
This confuses me. To clarify, doing this would not work:
Namespace::Class* Ptr;
This would work (assuming namespace and class are both valid)
RPG::Battler* battler_ptr_a; // this should work
RPG::Battler* battler_ptr_b = battler_ptr_a; // this should also work
RPG::Battler* battler_ptr_c = &RPG::Battler  // this does not work
int* battler_ptr_d = &battle_ptr_a  // this does also not work
int* battler_ptr_e = battle_ptr_a  // nor should this
The third line is equivalent with the code you wrote

author=McBick
Would something like this be okay:
battler* actor; //I'm pretty sure this will error. 
// NOTE: (Correct, battler is not a class definition, but an object of RPG::Battler. You cannot declare a variable as the type of another variable)
int hp = actor->hp;

If you change the code to this, it should work (added callback for clarity)
bool onBattlerDrawn(RPG::Battler *battler, bool isMonster, int id)
{
    RPG::Battler* actor;
    actor = battler;
    int hp = actor->hp;
}
Side note here
RPG::Battler* battler;
RPG::Battler *battler;
These two things are exactly the same as seen from the compiler. I personally prefer putting the dereference operator next to the variable type when declaring pointers as I find that to be more clear, but a lot of people prefer putting it next to the variable during declaration. Either way, there are no differences between these two in terms of functionality

author=McBick
If not, is there a good way to copy pointers? For example making PtrA reference the same address as PtrB? I am guessing I would have to do something like this:
int n = 8;
int* PtrA = &n;
int* PtrB = &(*PtrA); //This should give PtrB the same address as PtrA?
No need for the extra layers or & and * since they negate each other. What I showed up there was to demonstrate the differences while also showing how they are kind of the inverse of each other.
int n = 8;
int* ptrA = &n;  // Again, these are variables, so they should start with a lowercase letter
int* ptrB = ptrA; //This this copies the address of ptrA into ptrB

author=Kazesui
Now, if you're really bent on converting it to something else, what you could do is

author=McBick
int* actor = reinterpret_cast<int*>(battler);
int actor_value = *actor;
This looks interesting. I will have to experiment with this to see if I can use this for anything or cut some of my code down with it.
If that "anything" is not memory mapping, then no, you should not use this. You're only going to confuse yourself further without gaining much from it, and it will most certainly not cut down code length. If anything, it will add code length and complexity and severely decrease readability of the code, even when done right.
Okay, it is all starting to make a lot more sense to me now. I was needlessly confusing myself it seems, but I think I am starting to get a better understanding of it. I tried experimenting with the different ways to implement "&" and "*".
author=Kazesui
These two things are exactly the same as seen from the compiler. I personally prefer putting the dereference operator next to the variable type when declaring pointers as I find that to be more clear, but a lot of people prefer putting it next to the variable during declaration. Either way, there are no differences between these two in terms of functionality
I feel the same way. It just feels wrong to do RPG::Battler *battler, to me.

I should have clarified better, or rather gave a better example for the copying of pointers. What I meant to ask was if there was a way to copy different types of pointers.
//For Example
int n = 8;
int* ptrA = &n;
bool b = true;
bool* ptrB = &b;
ptrA = &ptrB; //I would like to convert ptrA to the address of PtrB here. 

//Would the following do what I want?
reinterpret_cast<bool*>(ptrA);
ptrA = &ptrB;
ptrB is already a pointer so there's no need to use the & operator when wanting to copy the address. You can change from one type to another using reinterpret_cast, but the results might not be too intuitive.

A better approach might be to get into "why" you want to do this, or what you want to achieve with this

For the concrete example
bool b = true;
bool* ptrB = &b;
int* ptrA = reinterpret_cast<int*>(ptrB);
int a = *ptrA;  // if the step above works, 'a' might now be set to 1 (or something random)
Note that there is a good chance that the third line will fail, since a bool will generally have 1 byte allocated to it, while an integer expects 4 bytes, meaning it might try to read 4 bytes of data, which can lead to a segmentation fault, or to some very peculiar errors if the memory has been allocated.
Better yet would be to do (I think there's a good chance that it will compile, but that int a will receive an undefined value. I just don't remember exactly how this would play out)

bool b = true;
bool* ptrB = &b;
uint8* ptrA = reinterpret_cast<int*>(ptrB);
uint8 a = *ptrA;  // a should be set to 1

uint8 means an unsigned integer of 1 byte. That it is unsigned means that it can store no negative values (does not apply to float types) and int8 refers to 8 bits beings used for the integer.
Note however that uint8 can only store numbers from (and including) 0 to 255
I didn't even think about converting the value stored in ptrB. I was actually just trying to change ptrA into a bool and copy the address of ptrB. The reason for this is so I can use a single pointer to copy static, or rather constant, pointers and not have to deal with a new pointer for each different type of pointer I wish to copy. This is mostly useful to me for loops and directives. Would there be an easy way to do this, ideally a method that is easy to loop with?

It is interesting to know you can actually convert the address value of pointers though. I'm not sure what you could use this for, but it is good to know that it can be done.

Theoretically, if you want to store an array of pointers of different types, you can convert all of these pointer to "void*". But once you want to access the content of the pointer, you need to know the type of the pointer.

// Store relevant pointer types here
enum ptr_types{
    INT,
    BOOL
};

// Define struct which contains arbitrary pointer type and what type it is
struct t_ptr{
   void* ptr;
   ptr_types ptr_type;
};

int a = 42;
bool b = True

t_ptr ptr_a;
t_ptr ptr_b;

ptr_a.ptr = reinterpret_cast<void*>(&a);
ptr_b.ptr = reinterpret_cast<void*>(&b);
ptr_a.ptr_type = ptr_types::INT;
ptr_b.ptr_type = ptr_types::BOOL;

std::vector<t_ptr> ptr_list;  // declares a common array for all your funky pointers
ptr_list.append(ptr_a);
ptr_list.append(ptr_b);
int a2;
bool b2;
for(int i = 0; i < ptr_list.size(); i++)
{
    switch(ptr_list[i].ptr_type)  // The switch statement tells the code to continue to execute
    {
        case ptr_types::INT  // If ptr_type is an int, convert the void* to an int*
            a2 = *reinterpret_cast<int*>(ptr_list[i]);  // a2 should now be set to 42
            break;  // tells the code to exit the switch. Code will break otherwise
        case ptr_types::BOOL
            b2 = *reinterpret_cast<bool*>(ptr_list[i]);  // b2 should now be set to true
            break;
        default
            break; // in case the ptr_list[i].ptr_type contains a ptr_type not listed
    }        
}
Note that the example is more pedagogical than practical, but that would be a conceptual way to deal with arbitrary pointer types. Also, beware that there could be some syntax errors in there, as I don't have a compiler at hand to actually test the code at the moment. This is pretty much what Polymorphism is about as well, expect that this is a more common C way of doing things rather than C++.

Void pointers can be useful for writing more general functions, but keep in mind that you cannot dereference a void pointer. You need to convert it to something else before trying to read the value of the address (otherwise, the program won't know how many bytes are needed to interpret the value stored at that address).

Also note that if the value itself is const, it won't matter if you create a copy of the pointer pointing to the address of the value, as the value will still be const.
const int a = 42;
int* ptr_a = &a;
int* ptr_b = ptr_a;
*ptr_a = 1337; // This is not allowed
*ptr_b = 1337; // This is also not allowed for the same reason

int c = a; // This sets 'c' to 42
int* ptr_c = &c;
*ptr_c = 1337; // This is allowed and sets 'c' to 1337. 'a' remains 42

Edit: changed the first code snippet a little bit to make it somewhat more practical for the actual use-case
// Store relevant pointer types here
enum ptr_types{
    INT,
    BOOL
};

// Define struct which contains arbitrary pointer type and what type it is
struct t_ptr{
   void* ptr;
   ptr_types ptr_type;
};

int a = 42;
bool b = True

t_ptr ptr_a;
t_ptr ptr_b;

ptr_a.ptr = reinterpret_cast<void*>(&a);
ptr_b.ptr = reinterpret_cast<void*>(&b);
ptr_a.ptr_type = ptr_types::INT;
ptr_b.ptr_type = ptr_types::BOOL;

std::vector<t_ptr> ptr_list;  // declares a common array for all your funky pointers
ptr_list.append(ptr_a);
ptr_list.append(ptr_b);
int a2;
bool b2;
for(int i = 0; i < ptr_list.size(); i++)
{
    switch(ptr_list[i].ptr_type)  // The switch statement tells the code to continue to execute
    {
        case ptr_types::INT  // If ptr_type is an int, convert the void* to an int*
            a2 = *reinterpret_cast<int*>(ptr_list[i]);  // a2 should now be set to 42
            break;  // tells the code to exit the switch. Code will break otherwise
        case ptr_types::BOOL
            b2 = *reinterpret_cast<bool*>(ptr_list[i]);  // b2 should now be set to true
            break;
        default
            break; // in case the ptr_list[i].ptr_type contains a ptr_type not listed
    }        
}

Thanks, this is what I was looking for. I guess wanting a single operator to do all this would be asking too much, but this works all the same. Time to start implementing all this info now.
author=Kazesui
That said, I want to highlight something about that if statement of yours as well, i.e. the

if(!myImage[img])

What it does, is not not to check if there is an image in std::map myImage, but rather if there is a key with the same value as "img" in myImage. The reason this is relevant is because it doesn't say anything about whether the RPG::Image* has been allocated or not. This should not be a problem right now, but something to keep in mind when you start removing images because you're transitioning from battle to non battle and back. The best thing to do is probably to make sure to completely empty myImage inbetween these, while remembering to destroying each instance of RPG::Image first.
I had a question regarding this. If I were to transition back and forth between battles using this "if" statement to check if the image exists or not will the images automatically be destroyed after a battle ends, since the battle event ends the stack should be cleared? From what you're saying this isn't the case?

I am almost finished with my battle plugin, but I am checking for any errors that might exist now, such as memory leaks or invalid pointers for things I didn't take into account.

For battles I use this to check if an image has been created:
if(!myImage[i])
        {
            myImage[i] = RPG::Image::create();
            myImage[i]->loadFromFile(loc);
        }
I currently do not destroy any images created via this method as I think the stack will be cleared after battle and it uses up so little memory in battle it shouldn't ever be a problem, but now I am not so sure if the image objects are actually getting cleared. At the very least these image objects should be cleared when the game is closed though, right?

I have used task manager to observe any memory leaks and as far as I could tell I didn't see much of a difference after a 100 battles, but it could be because the memory used is so little and wouldn't be noticeable until 1000s of battles.
RPG::Image::create() allocates memory on the heap, not in the stack. Also transitioning from between scenes (for example from Battle to the Map) does not destroy any RPG::Image data. If you do not call free() before calling RPG::Image::create() again, you will create a memory leak.

That said, as long as you keep the image creation behind and if like this and you simply re-use the images already drawn with some logic as to when they are supposed be drawn, you do not really need to delete them manually. While scene changes will not remove any images, closing the game will free this memory as well.

If you want to test this a little bit more easily, find a really big picture which you load into your plugin, and then monitor the task manager. The bigger the better, as this will help you notice if there's anything there (as long as your logic is generic enough to allow for a test like this without becoming too artificial). That said, it might be safe as is as well, even if there is a memory leak if it is that tiny.
I thought transitioning through scenes cleared the canvas and any graphical objects were also cleared away as well, but it seems I was wrong. If I were to do something like this:
if(myImage[i])
{
            RPG::Image::destroy(myImage[i]);
}
if(!myImage[i])
        {
            myImage[i] = RPG::Image::create();
            myImage[i]->loadFromFile(loc);
        }
This should essentially destroy the Image before creating a new one. The point of this would be if the battle ended without destroying the Image object then it would be destroyed during the next battle when the relevant Image is to be created again, so there won't be duplicates, or a memory leak.
author=McBick
I thought transitioning through scenes cleared the canvas and any graphical objects were also cleared away as well, but it seems I was wrong. If I were to do something like this:
if(myImage[i])
{
            RPG::Image::destroy(myImage[i]);
}
if(!myImage[i])
        {
            myImage[i] = RPG::Image::create();
            myImage[i]->loadFromFile(loc);
        }




This should essentially destroy the Image before creating a new one. The point of this would be if the battle ended without destroying the Image object then it would be destroyed during the next battle when the relevant Image is to be created again, so there won't be duplicates, or a memory leak.


Rather than doing this, maybe you use the callback "onInitFinished", Then you create all the images you intend to use (assuming you do not want to use too many different types of images). Doing this means you do not have to check with an if statement if there is an image in your array and you will not have to delete it. If RPG::Image::create is only used within this callback it will not cause any memory leaks. This is probably the easiest and safest way to do it (at the expense of eating a little bit more RAM than if you would allocate this dynamically as the need arises, but with the sizes used by rm2k3 and the setups of today, this is unlikely going to be a problem anyway).

You could try it your way as well, but that would be the point where you will start running it runtime errors, exactly because your if statement does not check if you've allocated a space for your image, it just checks if the pointer is set to 0 / NULL. It is possible that "RPG::Image::destroy" does this for you, but there is no guarantee of this, and there's a good chance the pointer will have the address of where the image used to be, but no is not anymore because it was destroyed. This address is not equal to 0 / NULL, so it will pass the if and try to destroy an image which has already been destroyed and will fail since there is no more image there.

You should add
myImage[i] = NULL;


or something similar after you call RPG::Image::destroy to be more certain.
Of course, I assume these two if statements of yours are not placed that close in the real code, as destroying and creating an image each frame is not good either, which is what would happen if they were this close.
I was thinking of using this:
if(RPG::battleData->battlePhase == RPG::BPHASE_END) //This would be in the callback onFrame
{
            RPG::Image::destroy(myImage[0]);
            RPG::Image::destroy(myImage[1]); //And so forth...
}
I would do like you said and create all the Image objects at the start and use this code to clean it up after the battle ends.

My original code uses dynamic Image objects, but that was because I wasn't sure how many Image objects I would need, but now I am almost done with the plugin, so I don't have to worry about that anymore.
This is fine as long as you keep in mind what I mentioned, i.e.
RPG::Image* img = RPG::Image::create();
img->loadFromFile(loc);
RPG::Image::destroy(img);
if(img)
    RPG::screen->canvas->draw(x, y, img);  // This will probably crash


For this reason, and because it is a good habit as well, I would adjust your code to
if(RPG::battleData->battlePhase == RPG::BPHASE_END) //This would be in the callback onFrame
{
    RPG::Image::destroy(myImage[0]);
    RPG::Image::destroy(myImage[1]);
    ...  

    myImage[0] = NULL;
    myImage[1] = NULL;
    ...
}


since doing this, ensures that your if(img) will always be valid (or whatever other pointer you might be using at some point).
RPG::Image::destroy(myImage[0]);
...
myImage[0] = NULL; //Won't this crash?
...
Won't this try to change the value of an object that doesn't exist and crash?
author=McBick
RPG::Image::destroy(myImage[0]);
...
myImage[0] = NULL; //Won't this crash?
...
Won't this try to change the value of an object that doesn't exist and crash?


Let me try to illustrate with code
RPG::Image* img;  // at this point, img contains random numbers
img = NULL;  // Sets the address in img to NULL, meaning it is not pointing at anything
img = RPG::Image::create();  // create() allocates memory for an image, and returns the address to that memory
RPG::Image::destroy(img);  // destroy() goes to the address stored in img, and deallocates the memory. Probably does not remove address at this point
img = NULL;  // Manually sets the address to NULL to reaffirm that the pointer is not pointing at anything.

Note that img never has the value of an object, but just the address to a point in memory which can be used to retrieve the object, and values within it. Of course, when you set a pointer to NULL, you cannot access anything from the object either (as there is no object), but you can't do that after destroying the image anyway (accessing deallocated memory will cause the program to crash).

The benefit of doing this is that
RPG::Image* img = NULL;
if(img)  // img is NULL, which evaluates as false, so this branch will never be entered
    RPG::screen->canvas->draw(x, y, img);  // This would normally crash, but here will never be executed
img = RPG::Image::create();
RPG::Image::destroy(img);
if(img)  //img is likely not NULL, which evaluates as true, so this branch will be entered
    RPG::screen->canvas->draw(x, y, img);  // This will likely crash

You can use if statements to check if the pointer has been allocated like this.
Also note that NULL is a value which can be set to every pointer variable, regardless of type.
I misunderstood. I thought the function destroy() would terminate the variable. Is it necessary to use NULL twice, once before create() and after destroy()?

Is this a bad method to use for checking if an Image object exists?
if(!myImage[i]) //Is there a better check method?
        {
            myImage[i] = RPG::Image::create();
            myImage[i]->loadFromFile(loc);
        }
To be honest, I just copied this method from another script as I couldn't think of another way to check if the object was created yet or not, but now it seems like this isn't a good method too use. I could use something like this instead, but it seems less efficient:
if(isCreated[i] == false) //Checks with a bool instead
        {
            isCreated[i] = true; 
            myImage[i] = RPG::Image::create();
            myImage[i]->loadFromFile(loc);
        }
It's perfectly fine to use if statements this way, and is even a standard way of doing it (I do this in my plugins as well). I'm just stressing the importance of setting it to NULL after calling destroy since the if statement won't generally work if you don't do this. The program itself does not know if there is an object or not at the end of the address during runtime, it just goes to wherever the address points and tries to access data as if it would be an object of the type defined by the pointer type. Upon trying to access data which the OS tells the program it does not have access to (because it has been de-allocated or never allocated in the first place), it will throw an exception and crash the program.
If you make sure to always reallocate memory for the image before this becomes a problem, you won't run into issues, but then you don't need the if statement either.

You do not need to initialize a pointer to NULL if you give it an address shortly after creation. You DO need to set it to NULL if you have an if statement checking the content of the pointer before it has been given an address however, because variables in c++ do not assume 0 or NULL as a default value.

e.g. if we alter the code from my previous example accordingly, we'll crash at the first if already
RPG::Image* img;
if(img)  // img is not NULL, which evaluates as true, so this branch will now be entered
    RPG::screen->canvas->draw(x, y, img);  // This should crash now
img = RPG::Image::create();
RPG::Image::destroy(img);
if(img)  //img is likely not NULL, which evaluates as true, so this branch will be entered
    RPG::screen->canvas->draw(x, y, img);  // This will likely crash


Telling you exactly what to do is hard without having the full source / context itself, but assuming that the if statements make sense, then you should probably also set the pointers to NULL after you destroy them.
I was under the impression any declared variable, for example ( int i; ), would be set to NULL or 0, but I see now that isn't the case. For creating Image objects, this is literally my code:
std::map<int, RPG::Image*> myImage;
...
namespace CBS
...
voidGetMonsterSelection(std::string loc [])
{
if(!myImage[1]) //This exists inside a function that is called when certain states of battle exist, ie monster/hero selection, action taken, etc
        {
            myImage[1] = RPG::Image::create();
            myImage[1]->loadFromFile(loc[1]);
            myImage[1]->useMaskColor = true;
        }
}
I use a lot of Image objects for text, so it isn't convenient to create them all at run time as the number of Image objects varies based on what happens in battle. This is a snippet of how I deal with text created in battle:
std::map<int, RPG::Image*> myText //Exists outside namespace.
//The following exists within its own function which is called from the callback onBattleStatusWindow when winMonTarget->choiceVisible == true
        for(int i=0; i<8; i++)
        {
            if(!myText[i]
               &&RPG::monsters[i]) //Checks is there is a valid Image object and associated Monster exists.
            {
                myText[i] = RPG::Image::create(320, 80);
                myText[i]->useMaskColor = true;
                int t = 0;
                bool isMultiple = false;
                for(int j=0; j<8; j++) //Check if multiple monsters with the same name exists.
                {
                    if(RPG::monsters[i]
                       &&RPG::monsters[j]
                       &&RPG::monsters[i]->getName() == RPG::monsters[j]->getName())
                    {
                        if(i >= j)
                            t++;
                        if(i != j)
                            isMultiple = true;
                    }
                }
                if(!isMultiple) //Adjusts variables if multiple monsters with the same name exists.
                    t = 0;
                myText[i]->drawString(0, 0, RPG::monsters[i]->getName(), 1);
                myText[i]->drawString(136, 0, monLtr[t], 1);
                myText[i]->setSystemPalette();
            }
            int x = 8;
            int y = 160;
            id = i; //Set to current monster being checked.
            for(int j=0; j<8; j++) //Cycle through all monsters to check if they exist and are still alive then adjust for the correct lettering if multiples of the same monster exists.
            {
                if(RPG::monsters[i]
                   &&RPG::monsters[j]
                   &&RPG::monsters[j]->conditions[1] > 0
                   &&RPG::monsters[i]->id > RPG::monsters[j]->id)
                {
                    id--;
                }
            }
            if(id == 1 ||id == 3 ||id == 5 ||id == 7)
            {
                x = 168;
            }
            if(id == 0 ||id == 1)
            {
                y = 168;
            }
            if(id == 2 ||id == 3)
            {
                y = 184;
            }
            if(id == 4 ||id == 5)
            {
                y = 200;
            }
            if(id == 6 ||id == 7)
            {
                y = 216;
            }
            if(myText[i]
               &&RPG::monsters[i]
               &&RPG::monsters[i]->conditions[1] == 0
               &&RPG::monsters[i]->notHidden) //Checks if monster exists, alive, and is not hidden then draws the text of their name and a letter from A-H if there are multiple of the same monsters.
               {
                   RPG::screen->canvas->draw(x, y, myText[i]);
               }
I know this isn't very efficient or good code, but I have to come back to it and tweak it later anyways, so I'll clean it up then. This is for the most part how all my Image objects are handled. These run in a function that is called when certain states of battle exist. In this example the function is called when RPG::battleData->winMonTarget->choiceVisible == true and serves as a new form for targeting monsters. Here is what it looks like when targeting a monster with a spell/skill/item/etc:

Do you know if it is possible to manipulate the damage a battler takes? The only feasible way I have found to alter damage is to alter the skill itself, but this doesn't help me with things like altering the critical damage formula or adding a multiplier to damage right after damage is calculate, but before damage is received. I've looked for some sort of variable that tracks damage, but the only thing I found is the damageImage, which can be altered, but changing the number it shows doesn't actually change the damage.

As it is now, when a battler uses the attack command and triggers a critical I have the action changed to a skill which has the new critical damage formula. The new attack will ignore defense and evasion and apply the battler's power stat as damage. I would like to do something similar with spells, but then I would have to create 2 spell entries for every spell that exists, one for normal and one for criticals.
Can't address too many of the earlier points mentioned, as scope is pretty important for these questions, and the scope is not contained in these snippets.
The code presented looks fine I would say. No need for optimization at this point.

And no, I don't see any obvious way to alter the damage itself, though instead of swapping the skill, you might be able to just alter the skill / spell itself directly for when a critical is supposed to happen, and change it back afterwards.
e.g. Do the check if it is supposed to cause a critical with onDoBattlerAction(), and change the skill if so, and then change it back to default with onBattlerActionDone(). This might even be safer than swapping skills during the battle, though I'm not sure how this would be best implemented, or the exact order in which calculations take place, so a different order of things might be required.
I'm not sure what you mean by scope, but I assume you mean the entirety of the plugin? The snippet I gave is pretty much the whole function that is called, except for a few unrelated lines of code that alters other stuff in the battle, like Window objects or battler sprites and such. As you can see the code could be organized better in terms of which lines of code to execute first and the use of cycling through all 8 monsters every time is redundant as I believe there is better way to do this, so I will be changing the order of the line of codes and trying a different method to check for every monster instead of running several loops 8 times each. If there is only one monster then I am literally processing an extra several hundred lines of codes which is very inefficient.

I could try changing the properties of the skill when it is used, but I am not sure if those changes will work properly when the battler executes them and it might even cause memory errors during battle, but that is something I will try to explore.