New account registration is temporarily disabled.

MCBICK'S PROFILE

Search

Filter

[RM2K3] DynRPG Compiling Error

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.

[RM2K3] DynRPG Compiling Error

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);
        }

[RM2K3] DynRPG Compiling Error

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?

[RM2K3] DynRPG Compiling Error

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.

[RM2K3] DynRPG Compiling Error

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.

[RM2K3] DynRPG Compiling Error

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.

[RM2K3] DynRPG Compiling Error

// 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.

[RM2K3] DynRPG Compiling Error

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.

[RM2K3] DynRPG Compiling Error

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;

[RM2K3] DynRPG Compiling Error

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.