New account registration is temporarily disabled.

KAZESUI'S PROFILE

Doing Super Programming
on Super Computers
for Super Performance
The Curse of Cpt. Lovele...
Nautical-themed cephalopod-pirate-based action-shmup.

Search

Filter

[RM2K3] DynRPG Compiling Error

Conventionally, what you do when you want to get the value within a pointer, you want to do something like this:

int a = 8;  // declares an integer variable and sets it value to 8
int* b = &a;  // declares a pointer to an integer variable and points it to the address of variable a
int c = *b; // declares an integer variable and sets its value to the value stored at the address of pointer b


The * is called a dereference operator, and is used to the get the value at the end of an address.

Keep in mind however that
actor = battler->id;  // this
actor = (*battler).id; // is the same as this


the -> operator is an dereference and access member operator in the same go, which is why you get the value straight when using the arrows, while with a struct you'd make, you'd might just use foo.member to access the value.
so when you do battler->id, you're already getting the value stored at the end of the address.

[RM2K3] DynRPG Compiling Error

Battler is not an int. There is no obvious way to turn a collection of variables and methods into a single int value, so this doesn't work (Unless you extend the classes with operator overloading to allow for that, but please don't try to do this).

Are you sure that it's the battler your want and not the id? i.e.
actor = battler->id;  // "Actor" should be "actor" since it's not a class definition

Aremen's Prophecy - Community Game Sign up!

Name: Kazesui
Portrait: E5
Personality: Rational, Amoral, Trickster
Team: 2k
Class: Nothing, I'll use my mind
Stats
Strength: 0
Intelligence: 9
Vitality: 5
Agility: 6
Rock, Paper, Scissors: Paper

[RM2K3] DynRPG Compiling Error

author=McBick
So that's why some classes are referred to with a lower case starting letter! This makes so much sense now!

When I mention instantiated objects, I meant specifically the ones the coder refers to and not the one that is declared in Dyn RPG, but now I have another question regarding this. In the header, the BattleData class has no static members. It is the same in the other header for the WindowMenuSkill class. Aside from the lower case letter needed for battleData the class object winSkill and winInfo are identical, though the latter inherits the Window class properties. So how and why are these two members so different to work with? Am I misunderstanding something here? There is a static reinterpret cast for BattleData, but does that change the class members to static?


It is not a requirement for the letter to be lowercase, but rather it's following a common naming convention. BattleData is the class and battleData is an instance of BattleData. On line 136 of BattleData.h you'll find
static RPG::BattleData *&battleData = (**reinterpret_cast<RPG::BattleData ***>(0x4CDD38));

Now, I'm sure this line can be rather confusing as this is some rather advance stuff where you'd possibly run into some issues trying to google it. You'll be forgiven if you're not able to follow what I'm about to describe. Essentially, the class "RPG::BattleData" has been written in such a way, that the member variables fit perfectly on top of pre-existing memory as defined by the original RPG Maker software. "reinterpret_cast" here, dictates that you should take the address (0x4CDD38) and treat it as if it is an object of the class "RPG::BattleData".

In a sense, the original software has already defined the class RPG::BattleData, but this is normally not accessible because it's given as an already compiled binary, so this data has to be extracted from the memory through memory mapping (which is what is done here). This is why you shouldn't make another instance of RPG::BattleData either, as it's only existing once in the memory anyway, and it has already been mapped into the object RPG::battleData.

Again, RPG::battleData is an object, not a class. Because it is an object of the class, you can access all it's members. The fact that it's declared as static is of little interest here, as does not mean that anything inside the class has been converted to static.
I imagine you might be a little confused because you don't understand how C++ classes work, because you're learning from DynRPG, where most classes only have a single object (the global one accessible from DynRPG itself), but usually, classes are there to be treated as variable types which you can create as many as you like of, which is where the difference of a static member of a class kicks in, versus a normal member variable of the class, which belongs to the specific object itself.

All of this aside, I didn't read properly when I was skimming over the documentation, so I didn't see that "WindowMenuSkill" actually refers to the skill sub-window from the "menu". I thought it was the battle skill menu because I recall you've been working with that one so far, but that doesn't seem to be the case, so no wonder things seemed a bit weird.
The proper way of accessing it should be
RPG::menu->winSkills->winInfo->y = 120;

probably while checking to make sure with an if statement that the skill menu is currently the active window.

This does render your question of "how winskill and wininfo" are different a bit moot, but it has to do with polymorphism. It is a bit involved to explain this, and it will probably just confuse you more than it will help you, so I'll leave this be for now.

[RM2K3] DynRPG Compiling Error

author=McBick
I understand about instantiated rm2k3 objects, so I stay away from that. I am not sure what you mean by having an instance of WindowMenuSkill which has been instantiated as Window. As far as I can tell the objects in that class are static and can only be called, not instanced.

I tried using the dynamic cast operation, but get the error "not a polymorphic source". Ill continue to try using that type of method to see if I can get it to work.


Time for some terminology again.
An object is an instance of a class. Let's take string as an example again
std::string some_text;  // The object here is "some_text" which is an instance of the class "std::string"


If you look up the documentation of RPG::Window and RPG::WindowMenuSkill, you'll see that the keyword "static" does not appear anywhere. This means that nothing in these classes are static and cannot be called upon or used without an instance of that class.

RPG::WindowMenuSkill is a class, and not an object. You need to find an instance of the class to be able to use it (because of how DynRPG works).
This is why
RPG::battleData->winCommand->width = 96;  // winCommand here is not as static object, but rather an instance of the object. By using this, you are using an instance of the underlying class.
RPG::WindowMenuSkill->winInfo->y = 120;  // This does not work since this is not static and not an instance of WindowMenuSkill


The thing about DynRPG is that you are not allowed to create new instances of the classes mentioned, but you will have to use instances already made of these classes.
A quick way to discern these two are if the first letter following RPG:: is lower or uppercase. If it is lowercase, this means that this is an instance already made (by mapping it specifically to the existing memory in RPG Maker, which is the only way to create an instance for almost all DynRPG classes), and can be manipulated upon. If the first letter is uppercase, it means it's a class, and only static members (which are defined as such in the documentation) can be used, like RPG::Image::create(), which is labelled as a static public member in the documentation.
As you can see
RPG::battleData is an instance of RPG::BattleData, while RPG::WindowMenuSkill is simply a class definition (and the class has no static members, so you can't access anything in it without a pre-existing instance.

Again, you need to consult
http://www.rewking.com/dynrpg/group__game__objects.html
as to what instances already exist, since you can't create new instances yourself generally.

As for the dynamic cast operation, I figured that it probably wouldn't work (since DynRPG classes are anything but normal). My next best guess is that you'll have to use reinterpret cast and find the exact memory location of the window, and possibly toss in some dereference and address operators akin to what is done in the header files. I can't really say what would work here without experimentation as this is not the kind of code I'm particularly experienced with myself. Again, this should only be important if you actually need access to the specific variables members of RPG::WindowMenuSkill specifically. If all you want to do is mess with the y member, which is part of RPG::Window, you will not need this, and if you don't get access to it, is for different reasons, which has nothing to do with being able to cast the instance as the correct class (casting something, generally means to change the underlying type of the variable / object, and only works for cases where there is support for this. This will not help you directly, because all conventional wisdom will not work for DynRPG, but conceptually, you can learn more about this by reading about "polymorphism").

[RM2K3] DynRPG Compiling Error

author=McBick
Does anyone know what is expected for this line of code?

RPG::WindowMenuSkill->winInfo->y = 120;
//Error: Expected unqualified-id before '->winInfo->y = 120' token

This is the code I am pointing to in the DynRPG Window.h;

class WindowMenuSkill : public Window {
		public:
			int heroId; //!< Database ID of the hero selected
			Window *winInfo; //!< The sub-window for the skill description
			Window *winHeroInfo; //!< The sub-window for the selected hero information
				int _unknown_84;
			DList<int> *skillSubsets; //!< Zero-based Array of skill subsets. Unsure about this though...
			bool isSkillSubset; //!< Is the selected skill a subset?
			//Window *winHeroMp; // ????

			void refreshSkills();
	};
I am guessing because WindowMenuSkill has the properties of class Window I have to point to the object in a different way than what I am currently using, but I have tried pointing to it several different ways, all of which results in the same error.

RPG::WindowMenuSkill is a class. A class is kind of like an advanced variable type, with multiple fields and methods belonging to it.
std::string is also a class, and you need to instantiate an object of the type std::string before you can use it. An exception to this is static methods and variables. This is why RPG::Image::create(); works, but RPG::Image->free() would not work. Still, remember that in DynRPG, you should normally not instantiated your own objects from the classes.

Instead vou need to consult this page:
http://www.rewking.com/dynrpg/group__game__objects.html
to see what instantiated objects you have to work with.

In your case, what you're trying to do should probably be something along the line of
RPG::battleData->winSkill->winInfo->y = 120;

Can't guarantee that it won't cause issues though, as I don't know if rm2k3 will like you messing with it's variables.
Also worth noting here is that "winSkill" is defined as a "RPG::Window" class, not a RPG::WindowMenuSkill class, meaning you should not really have access to the member variables specific to RPG::WindowMenuSkill.
In good C++ fashion, you would normally be able to get this access by
skill_subset_0 = dynamic_cast<RPG::WindowMenuSkill*>(RPG::battleData->winSkill)->skillSubsets[0];
No idea if this would actually work here though, as these classes are not very conventional. (I expect this not to work, but this would be the general idea of how you would normally get access to those member variables).

related note: WindowMenuSkill is another class which "inherits" from the class Window. What this means is that WindowMenuSkill expands upon the class Window by adding extra member variables and methods, sometimes overwriting old methods from the original class with a new one. If you have an instance of WindowMenuSkill which has been instantiated as Window, and you only need members and methods from Window, there should be no problem. If you need access to the specifics of WindowMenuSkill, you need to start thinking along the paths described above.

[RM2K3] DynRPG Compiling Error

author=McBick
Is there a difference between non-static and static global variables? From my understanding, static is only initiated once, but if it's a global variable that is declared at the beginning of my header or plugin(cpp), outside all functions and structures, then wouldn't it only ever be declared once anyways, making it the same as a static variable?

Example:
//PluginName
#include DynRPG/DynRPG.h
static int myVar = 99;
//... the rest of the plugin.

//vs

//PluginName
#include DyNRPG/DynRPG.h
int myVar = 99;
//... the rest of the plugin.

In the example, would both variables only be declared once, and only at the start of the plugin? If so then is there any reason to use a static global variable? Sorry for the noob question, I just want to clarify my understanding on exactly how these variables work as it would make a big difference in how I declare them in my code.


As long as you have all of your code in a single file, there is no real difference between having a global variable and a global static variable. The difference comes into effect when you start splitting your code across multiple .cpp files. The difference being that you can access the same global variable in another .cpp file with the help of the keyword "extern", but the same won't work for a static variable.

Note this is not quite the same for header files, as a declared variable there, will be accessible to all files which includes them.

Bottom line, as long as you work on a single file there will be no real difference whether you declare them as static or not. It makes a bigger difference when used in classes and functions. It's pretty much up to you whether you want to use it or not.

[RM2K3] DynRPG Compiling Error

Yes the global variable would receive the initial value set whenever you load the plugin, which would be when you open the application. I would be quite surprised if adding the static keyword would change that. If you want to have variables which persist, you'll probably have to look into storing the data into files instead.

[RM2K3] DynRPG Compiling Error

author=McBick
So basically for manipulating Rm2k3 objects I should, and need to, use std map, but for integer arrays I should use vectors? I thought vectors could store other values such as with std::vector<Rpg::Image> myImage, but I guess not.

both std::map and std::vector can store any type of object (as defined by what you put in the <>). Accessing the entries of a std::vector is only done with integers, while with std::map you can access them with almost anything.

std::map<std::string, std::string> example;
example["foo"] = "bar";

This is possible with std::map but not with std::vector. With std::vector it's easy to do this however

std::vector<RPG::Image*> images;

...

for(int i = 0; i < images.size(); i++)
{
    RPG::screen->canvas->draw(x[i], y[i], images[i]);
}

This is not something which is guaranteed to work if you're using std::map, and if you use it this way, it might work, but it will look a bit weird (but the concept ought to still work).


author=McBick
When I get a compiling error with strings it always refers to them as chars or const chars despite only using static std string and std string variables, so I thought that maybe they were the same.

std::string most likely stored the actual string as a char* so that could be a possible reason for it. I have to admit, I haven't been actively coding in C++ for a rather long time now, so I don't remember what compile errors ought to look like when it comes to std::string any longer. As mentioned, they are similar, but not exactly the same. A simple char* is a bit more bare-bones than std::string.

author=McBick
For global variables I must use static or const outside the main() and all functions correct? That is what I have been doing anyways. I've also used static variables inside functions, so it only initiates the value once and can be changed within the function later if need be.

Nope, there is no need to declare global variables as static. The reason to do so would be to make sure that the global variable is only global to the file in which it is defined only, which is only of concern if you're actually compiling more than one file, or are building a code base which is meant for others to expand upon (with more files). If this is not the case, there is no need to declare any of these variables as static. At least that's what I read. I've never used static in this way myself. File also likely means .cpp file here, not .h file, as these are kind of added to the .cpp file at compile time.
Bottom line is still the same though, you probably won't need them for global variables.

It's also not necessary to declare anything as const, unless you want it to be unchangeable. There are very good reasons for using const, but I don't believe it is something you need to worry about at this point. The biggest thing you need to know is that there will be variables which are given as const which will throw a compile error if you try to alter their values, meaning if you want to manipulate those values, you need to make a copy of that variable first (one which is not const).

author=McBick
For arrays why does something like int N = RPG::monsters.size(), not work? I am trying to find a way to easily keep track of the size of certain rm2k3 arrays without using a loop every time I need their array size. As it is now I have created a function just to count array sizes as I am tired of constantly using loops every time I need the array size.

I can't give you the exact syntax, but it ought to be something along the lines of
RPG::dbMonsterGroups[group_id]->monsterList->count()

It is possible that you need to substitute the -> with a . at the last one, and it's possible there is something else I'm forgetting. As mentioned, haven't done much C++ in quite a while, and haven't done any DynRPG in even longer. Also note that this value should be the number of enemies in the group as given by the database, not the monsters still alive in the battle. I didn't see any obvious reference to the number of currently living monsters.

[RM2K3] DynRPG Compiling Error

author=McBick
@Kazesui
Could you explain the differences of std::map and vector? From what I understand they can both be used for the same thing? So when would I use one over the other?

For instance what is the difference or limitation between these two types of arrays, if any?
std::map<int, RPG::Image*> images
//and
std::vector<RPG::Image*> images


Also what is the difference between these arrays?
const char* myText[3] = {A, B, C};
//and
static std::string myText[3] = {A, B, C};


Both std::map and std::vector store data, so they can be used for the same thing in terms of accessing and using the data. Where there's a relevant difference in terms of how the access is done and how you add and remove data.

std::vector is in essence a simple array. You generally add elements with the "push" method, and access them with square brackets and the integer index. Note that these integers here will always be contiguous since the memory is listed from 0 to n, with n being the size of the array (n is excluded from the loop since the last element will be at position n - 1).

removing single elements from std::vector is considered slow, and should be avoided unless it is at the end of the array... but this will likely not matter too much within the context of usage for DynRPG. I would be very surprised if you managed to run into performance issue because of this.

std::map is a binary tree which store two values, the "key" and the "value", and is sorted on the former. Important difference here is that you do not need to use integers as key values, and they do not need to be contiguous. e.g. you could have an RPG::Image* associated with the keys 1, 3, 42, and that would be perfectly fine. You could also use "battler1", "battler2", "hero1" as keys, and it would give you an easier time manipulating specific pictures as you don't have to remember the integer index assigned to them. If you don't need to manipulate individual images much, this is not really needed.

There are some performance considerations here, where std::vector will likely outperform std::map if you don't manipulate the images and you just want to show all them in a specific order (with the order being easier to enforce in an std::vector), but ultimately, you can use what you're comfortable with as non of these performance issues are likely going to impact you in a meaningful way at this stage. The code will be simpler for std::vector if it provides all the functionality you need, and that would be my incentive to use it.

As an example, for the text plugin however, I also used std::map, because I think it's easier for the user to give specific names to their images and allow them to manipulate each individually. This is of course different if the plugin is for private use, or supposed to contain a full system using images rather than giving users control of the individual images.

as for the differences of your strings.
Using char* for strings is the C way of doing things, while std::string is the C++ way of doing things.
char* is just a pointer to an array of 8bit values used to represent characters (or letters and symbols if you'd like), which under normal circumstances should be terminated with "\0" to signify the end of the string.

std::string is a class which holds a similar array, but also provides some more functionality out of the box by holding methods which can operate on the string directly.

For a lot of intents and purposes, they are quite similar in terms of behavior as strings, and the biggest difference is in terms of how you manipulate them, which generally require C libraries for char* strings, and C++ libraries for std::string.

const and static are more generic and don't deal with text variables specifically but operate on mutability and scope. const implies that you're not allowed to change the following variable, though special care must be taken when using pointers as where you place the const relates to whether it's the address stored in the pointer you're not allowed to change, or the contents at the end of that address. There's a lot of nuance here, so further reading is probably best to properly understand it.

static is used in a couple of ways in C++.
You can use static in a class member to make sure that all objects created of that class will share the value of this member variable, or a method might be belonging to the class itself rather than objects instantiated with it (like RPG::Image::create() which does not belong to a single RPG::Image object, unlike with RPG::Window::create() which does belong to the object, at least as defined in the documentation).

It can also be used within a function to add persistence to that variable without being declared initially in global scope.

int foo()
{
    static int counter = 0;
    counter = counter + 1;
    return counter
}

the "counter" variable in this case would always return 1 if not for the static keyword. The static keyword makes this variable instantiated the first time the function is called, and reused whenever this function is called again, meaning the second time you would call this function, it would return "2". This does not mean that you can use this variable as you'd like outside of this function however. In other words, statics make the variable not be "destroyed" upon leaving a function, but is not quite the same as making the variable global.