MCBICK'S PROFILE
McBick
1339
Search
Filter
[RM2K3] DynRPG Compiling Error
I understand what you mean and after reading what you said I think I can fix it or rather make it cleaner. As I have it now, I am reusing Image objects by destroying them each time a new Window box is made, so I don't have hundreds of Image objects existing at any one time, but I see now that this is an incorrect method to use. It would be better to have every image have its own object for the remainder of the battle and destroy them after the battle, like you said. This will probably take me some time to fix as I now have to give every Image it's own id instead and make sure I don't miss any code. My biggest concern of doing this is keeping track of this. It would be easier if I used a vector instead of a map, so I could more easily make sure I am not reusing the same image object for something else. Ideally I would just unload all these Image objects at the start of the battle, but that would require a lot of recoding on my part and seeing how this plugin already functions properly it wouldn't be worth the time, but we'll see.
[RM2K3] DynRPG Compiling Error
Does anyone know which object this is or how to access it, the skill description?

I want to specifically gain access to that top window, the skill description. I have manipulated every window listed here: http://www.rewking.com/dynrpg/functions_w.html#index_w
After testing every Window object it seems that none of them relate to that skill description Window. I can access the one listed in RPG::WindowMenuSkill, but that doesn't affect the one in battle. I initially thought the object I am looking for was actually part of the winCommand object, but when I destroy the Image objects related to that Window, the skill description still exists which means it is in fact its own object. Anyone have any ideas?
@Kazesui
I am cleaning up some of my code and I was wondering how bad is leaving something like this?
Basically my question is, how bad is it to create and destroy the same objects every frame, especially considering these are Image objects and will be redrawn every frame? It actually only destroys the Image if it exists, but it will always exist since they're created right after the destroy function is called, so it is an endless cycle until the condition to call getCustomWindows becomes false. I have this destroy function at the beginning of all my functions that create Image objects, so I don't have to worry about memory leaks or keeping track of them. Something to note is that the Images aren't dynamic, so I can't just call the function once as it needs to be updated constantly to take into account any changes.
After reviewing this code I have noticed it is a very crude way of doing what I want. Right now I am almost finished with this plugin and just want to fix any bug fixes and release it, at least the first iteration of it. I want to know if this current method I have will cause issues for people who use it though. In my current testing I haven't run into any more issues, but I also haven't done extensive testing with battle events. I plan to do some battle event testing as well, but only things related to message boxes and battle animations as they are the most likely to break my plugin.

I want to specifically gain access to that top window, the skill description. I have manipulated every window listed here: http://www.rewking.com/dynrpg/functions_w.html#index_w
After testing every Window object it seems that none of them relate to that skill description Window. I can access the one listed in RPG::WindowMenuSkill, but that doesn't affect the one in battle. I initially thought the object I am looking for was actually part of the winCommand object, but when I destroy the Image objects related to that Window, the skill description still exists which means it is in fact its own object. Anyone have any ideas?
@Kazesui
I am cleaning up some of my code and I was wondering how bad is leaving something like this?
void destroyImages() //Checks and destroys any existing Image objects { if(myImage[0]) //Is there a better way of doing this? { RPG::Image::destroy(myImage[0]); myImage[0] = NULL; } if(myImage[1]) { RPG::Image::destroy(myImage[1]); myImage[1] = NULL; } for(int i=0; i<8; i++) { if(myText[i]) { RPG::Image::destroy(myText[i]); myText[i] = NULL; } } } void getCustomWindows(std::string loc[], RPG::Window* currentWindow) { //This function is called every frame, I think? it exists in onBattleStatusWindowDrawn CBS::destroyImages(); if(!myImage[0]) //Load Window Image { myImage[0] = RPG::Image::create(); myImage[0]->loadFromFile(loc[3]); myImage[0]->useMaskColor = true; } RPG::screen->canvas->draw(0, 140, myImage[0]); if(!myText[0]) //Load Text Image { myText[0] = RPG::Image::create(320, 80); myText[0]->setSystemPalette(); myText[0]->useMaskColor = true; } //The rest of the script builds the text onto the window and such. ... }
After reviewing this code I have noticed it is a very crude way of doing what I want. Right now I am almost finished with this plugin and just want to fix any bug fixes and release it, at least the first iteration of it. I want to know if this current method I have will cause issues for people who use it though. In my current testing I haven't run into any more issues, but I also haven't done extensive testing with battle events. I plan to do some battle event testing as well, but only things related to message boxes and battle animations as they are the most likely to break my plugin.
[RM2K3] DynRPG Compiling Error
author=Kazesui
I added in the array on the assumption that there is a way to query how many monsters and heroes are already given in the battle, but given how you can spawn new monsters I guess there might not be a good way of getting just getting the monsters in a neat fashion.
The is the reason I went for the method I showed earlier instead. Since I have to loop 12 times anyways just to check if the battler exists and I need a vector or an array of 12 elements, I decided to integrate max_element() and distance() into my loop.
author=Kazesui
Finding the instruction memory is also not trivial to find, since it does not change. I don't think hex viewer is going to cut it, since you need to monitor the execution flow the assembly code of the rm2k3 program itself to figure out where the damage calculation instructions are stored. Most likely you would need something along the lines of a debugger or a disassembly program.
I am quite certain that it is beyond my abilities for now, but I would like to get to the point where I can do that type of stuff. For now I will just study up on assembly language, dissassembly, and debuggers. If DynRPG is open source I will look into that as well and try to learn what it does.
It is quite clear I still have a lot to learn. No matter how much I learn, it always feels like there is still so much more to learn. I'd like to eventually be able to code an entire game engine by myself, but I'm probably still very far away from that, so for now I'll continue tinkering with plugins and scripts. Thanks for all your help so far, without it I would probably still be on google trying to figure out what I did wrong and my code would be much uglier than it is now!
[RM2K3] DynRPG Compiling Error
author=KazesuiI am confused now. If I am to understand, a basic array will work for the following code then? If I don't use a vector and use an array variable then wouldn't it not have a size method?
There is no need for the std::vector, as you could directly do the stuff in priority_queue.
int speed[12]; //Will the following code work with this variable? ... std::priority_queue<int> queue; for(int i = 0; i < speed.size(); i++) //Won't speed.size() break the code? { int value = i value += 100 * speed[i] queue.push(value) } ... int temp = queue.top(); int currentId = temp % 100; queue.pop(); accessible if(queue.empty()){ }
author=KazesuiI didn't think about that. Perhaps I will leave it as is then. I have noticed that every time I change a section of my plugin, it creates new issues that need to be fixed. This process has caused me to rewrite much of my code, albeit much more cleanly and efficient, but it has delayed the release of my plugin.
Personally, I think using it, can lead to cleaner and nicer code which is easier to keep bug-free, but that assumes that you'll be able to use it that way, and it's hard to dictate how you're supposed to use it from snippets, so I'm just trying to guide you as to how you could use it, but using it wrong will probably lead to less maintainable code, which is another reason why I say just go with what seems right to you at the moment as long as it doesn't break things, and then write another plugin later where you try something new, using new data structures and the like, and as you keep doing this, you'll learn more stuff and figure out why stuff you did in the past was weird. This happens to everyone and I'm not sure it helps trying to rush into the path of "clean code" since you need to go through dirty code to get why clean code is clean in the first place.
author=KazesuiIs it not possible to do this in DynRPG? For example:
The way I imagine this would be dealt with, would be to inject assembly code at the point where the damage calculation is supposed to happen
void onFrame(RPG::Scene* scene) { if(scene == RPG::SCENE_BATTLE && 00884800 == 0021) //Random memory value for example { 00884800 = 0031; //new memory value ... } }
[RM2K3] DynRPG Compiling Error
author=KazesuiI am trying to write efficient/good code as it is good practice. I would rather rewrite the entire plugin and do it right then write bad code and continue to do so in the future.
This also looks perfectly fine. There are many ways to solve a problem, and I just provided one which I could think of from the top of my mind, but this is no worse if you like the looks of this.
author=KazesuiSo if I am to understand it would be more efficient to do something like this then?
All arrays have a size, but not a size method. The size method of e.g. std::vector<int> will return the number of elements in the array, not the number of bytes.
std::vector<int> speed; for(int i=0; i<12; i++) { if(i<4 &&RPG::Actor::partyMember(i)) speed.push_back(RPG::Actor->partyMember(i)->getAgility()) if(i>3 &&RPG::monsters[i]) speed.push_back(RPG::monsters->getAgility()) } std::priority_queue<int> queue; for(int i = 0; i < speed.size(); i++){ int value = i value += 100 * speed[i] queue.push(value) } ... int temp = queue.top(); int currentId = temp % 100; queue.pop(); accessible if(queue.empty()){ }
author=KazesuiI checked and this is in fact the battler's agility and not the database value.
This probably returns the database agility not the agility for the battle.
author=KazesuiI am trying to write new variables to be used in the battle calculations in the default battle system. Once I find the memory values that calculate damage in rm2k3 I would like to convert them into pointers, so that I can change those values and write my own battle algorithm. So I need to find a way to write to memory addresses. For example:
Depending on what you want to achieve, there are a couple of ways to go about it.
int damage = algorithm; //This would be the new formula for damage. 00681422 = damage; //I am aware this would not work, but how would I do something like this? //This is a random memory value to show what I am trying to do //Ideally I would overwrite values that exist in rm2k3, so I can //create my own damage algorithm. I am aware I would have to change multiple //memory values to get this to work, but I need to know the proper way //to alter memory values first
[RM2K3] DynRPG Compiling Error
After doing some research would something like this be even better then?
How is this:
different from this?
The latter method seems to be cleaner, to me at least, but perhaps I am not understanding the method you listed? Also due to custom skills it is important to keep track of each battler's turn. For example, if a condition or skill allows a battler to take multiple turns it is important that the switch/bool actionTaken, can be changed. That boolean array controls the values of bAGI, so it is easier to give battlers multiple turns in one round.
So I just combined my two different functions, as there was no reason for two to exist. This is the complete function for determining turn order now:
Does this look good? Or should I implement the method you listed into this function? The problem with your method is that I am unsure what you mean by bAGI must be a data structure with a size method. From my understanding, all arrays have a size, size being the number of bytes in the memory of the array?
On another note, I have a question about memory. How is memory allocated in general, specifically when declaring a variable during run time? For example:
Where would the memory value of "v" be stored and how would I locate that memory besides pointing to "v"? Also is there a way to convert a memory location into a pointer? For example, I want to store 0x28 in memory address XXXXXXX. Is it possible to convert that memory location into a pointer so I could do something like:
How would this be done?
//In this example speed[] stores the agility values of all battlers mValue = *std::max_element(speed, speed+12); //Finds the highest value in the array? currentBattler = std::distance(speed, std::find(speed, speed+12, mValue)); //Finds the index value for speed which is the battler id
How is this:
std::priority_queue<int> queue; for(int i = 0; i < bAGI.size(); i++){ int value = i value += 100 * bAGI[i] queue.push(value) } ... int temp = queue.top(); int currentId = temp % 100; queue.pop(); accessible if(queue.empty()){ }
std::priority_queue<int> bTurn; for(int n : {bAGI[0], bAGI[1]... BAGI[11]} bTurn.push(n); for(int i=0; i<12; i++) if(bAGI[i] == bTurn) curBattler = i;
So I just combined my two different functions, as there was no reason for two to exist. This is the complete function for determining turn order now:
static int currentBattler; static bool getTurn; static bool isMon; static bool actionTaken[12]; //Switch for turns taken, index 0-3 for hero and 4-11 for monster namespace CBS { ... void getCurrentBattler() { int speed[12] = {}; //Stores all battler's agility values //indexes 0-3 for hero and 4-11 for monster //If battler doesn't exist, their value is set to 0 int mValue = 0; //Max agility value bool run = true; while(run == true) { for(int i=0; i<8; i++) { //Check if hero exists if(i < 4 &&RPG::Actor::partyMember(i)) { //Check if hero has taken a turn or is dead if(actionTaken[i] ||RPG::Actor::partyMember(i)->conditions[1] > 0) { speed[i] = 0; Hero_ATB = 0; //Set battler's atb to 0 } else speed[i] = RPG::Actor::partyMember(i)->getAgility(); } //Check if monster exists or if hidden if(RPG::monsters[i] &&RPG::monsters[i]->notHidden) { //Check if monster has taken a turn or is dead if(actionTaken[i+4] ||RPG::monsters[i]->conditions[1] > 0) { speed[i+4] = 0; Mon_ATB = 0; //Set battler's atb to 0 } else speed[i+4] = RPG::monsters[i]->getAgility(); } } mValue = *std::max_element(speed, speed+12); //Find the highest agility value if(mValue != 0) run = false; else //If all agility values are 0 std::fill_n(actionTaken, 12, false); //Reset actionTaken to get new agility values } currentBattler = std::distance(speed, std::find(speed, speed+12, mValue)); //Find the index value for speed which will be the battler id if(currentBattler >= 0 &&Battler < 4) //Sets the battler's turn { RPG::Actor::partyMember(currentBattler)->atbValue = 300001; isMon = false; } else if(currentBattler > 3 &&Battler < 12) { currentBattler -= 4; RPG::monsters[currentBattler]->atbValue = 300001; currentBattler += 4; isMon = true; } getTurn = false; //Global bool/switch to determine if this function should be called } ...
On another note, I have a question about memory. How is memory allocated in general, specifically when declaring a variable during run time? For example:
void function() { int v = 5; }
ptr = 0x28;
[RM2K3] DynRPG Compiling Error
The code for the first issue you mentioned is actually in the previous code I posted. Also if there aren't 12 battlers then the default value of 0 is used and ignores the nonexistent battler.
I am unfamiliar with the use of std::priority_queue structure. Is something like this what you mean?
As for my issue with the incorrect turn order, I think I have narrowed it down to the order of operations during battle. I think I have to change which callback the battle initiation takes place, this is what sets up the switches at the start of the battle for the turn order to be called and properly function. I think the issue is that the function getCurrentBattler is being called too early and due to the way the rm2k3 battle code is executed it messes up the synchronicity of my code.
void getBattlerSpeed() { for(int i=0; i<8; i++) { if(RPG::Actor::partyMember(i)) { if(actionTaken[i] ||RPG::Actor::partyMember(i)->conditions[1] > 0) //If battler has taken an action reduce value to 0. { bAGI[i] = 0; Hero_ATB = 0; } else bAGI[i] = RPG::Actor::partyMember(i)->getAgility(); if(i == 0) RPG::variables[706] = actionTaken[i]; } if(RPG::monsters[i] &&RPG::monsters[i]->notHidden) { if(actionTaken[i+4] ||RPG::monsters[i]->conditions[1] > 0) { bAGI[i+4] = 0; Mon_ATB = 0; } else bAGI[i+4] = RPG::monsters[i]->getAgility(); } } }
I am unfamiliar with the use of std::priority_queue structure. Is something like this what you mean?
std::priority_queue<int> bTurn; for(int n : {bAGI[0], bAGI[1]... BAGI[11]} bTurn.push(n); for(int i=0; i<12; i++) if(bAGI[i] == bTurn) curBattler = i; //Battlers are stored as Hero(0-3) and Monster(4-11) //for the variables of bAGI[Battler Index] and curBattler
As for my issue with the incorrect turn order, I think I have narrowed it down to the order of operations during battle. I think I have to change which callback the battle initiation takes place, this is what sets up the switches at the start of the battle for the turn order to be called and properly function. I think the issue is that the function getCurrentBattler is being called too early and due to the way the rm2k3 battle code is executed it messes up the synchronicity of my code.
[RM2K3] DynRPG Compiling Error
author=KazesuiDoes that mean if I use a map variable like myImage and create several Images without destroying them inbetween, I will run a memory leak? For example this:
Note that if you assign RPG::Image::create() to a pointer variable before having used destroy on the previous image (assuming there was one), you will have a memory leak since none of the other methods will fully deallocate the memory.
if(!myImage[0]) //Load Window frame { myImage[0] = RPG::Image::create(); myImage[0]->loadFromFile(loc[0]); } if(!myImage[1]) //Load Window cursor { myImage[1] = RPG::Image::create(); myImage[1]->loadFromFile(loc[1]); myImage[1]->useMaskColor = true; }
author=KazesuiI added this to it now:
As for your third error, it could have something do with the fact that there's maximum 4 party members, but that code is trying to access party member number 5, 6, 7 and 8 as well. This is likely going to cause issues if the bytes after the array containing the ids of the party members start containing anything except the value 0.
if(RPG::Actor::partyMember(i) &&i < 4)
temp = 0; for(int i=0; i<12; i++) { if(bAGI[i] > temp) { temp = bAGI[i]; curBattler = i; } }
void getCurrentBattler() { getBattlerSpeed(); temp = 0; for(int i=0; i<12; i++) //Checks if every battler has taken a turn for the round. { if(bAGI[i] == 0) temp++; } if(temp == 12) //Resets the array that tracks each battler's turn for the round. { std::fill_n(actionTaken, 12, false); } //Determine the current battler's turn. else { temp = 0; for(int i=0; i<12; i++) //Checks for the highest agility value among battlers. { if(bAGI[i] > temp) { temp = bAGI[i]; curBattler = i; } } if(curBattler <= 3)//Sets the turn for the Hero { RPG::Actor::partyMember(curBattler)->atbValue = 300001; isMon = false; } else if(curBattler >= 4)//Sets the turn for the monster { curBattler -= 4; RPG::monsters[curBattler]->atbValue = 300001; curBattler += 4; isMon = true; } getTurn = false; } } bool onBattleStatusWindowDrawn(int x, int selection, bool selActive, bool isTargetSelection, bool isVisible) { if(CBS::getTurn) { CBS::getCurrentBattler(); } } bool onBattlerActionDone(RPG::Battler* battler, bool success) { if(success) RPG::variables[801]++; //According to the above, the following if statement is executed //twice during the first battler's action and causes the array of actionTaken //to be set twice. if(success) { if(CBS::curBattler == 5) RPG::variables[709]++; CBS::actionTaken[CBS::curBattler] = true; //The above code seems to be executed twice, but with two differen index values, //CBS::curBattler and CBS::curBattler+1. It only occurs when the //first battler, a monster, completes an action. This makes me believe there is a memory overflow somewhere. CBS::getTurn = true; } return true; }
[RM2K3] DynRPG Compiling Error
author=KazesuiI did not take that into consideration and I have been testing with the same monster group, so I did not notice any errors. Upon testing with 3 different monster groups, with varying sizes and monster types, I have run into several errors.
Unless these images are freed somewhere else in the code, then this should mean that you should be running into issues after having gone through one battle with one set of enemies and then encountering a new set of enemies. (If you have the same enemies, i.e. 4 king slimes in every battle, you'll probably not notice this issue).
The first error is the incorrect monster names when selecting a monster target. The monster names from the previous monster group appear instead of the new monster group when selecting a target. I am unsure why this is happening as this code should clear/destroy all relevant battle images.
void onFrame(RPG::Scene scene) { if(scene == RPG::SCENE_BATTLE) { ... if(RPG::battleData->battlePhase == RPG::BPHASE_END ||RPG::battleData->navLevel == RPG::BNAV_IN_FIGHT_ESCAPE_WINDOW) { if(myImage[0]) //This Image is the window frame for all custom windows { myImage[0]->free(); RPG::Image::destroy(myImage[0]); myImage[0] = NULL; } if(myImage[1]) //This Image is the window cursor for all custom windows { myImage[1]->free(); RPG::Image::destroy(myImage[1]); myImage[1] = NULL; } for(int i=0; i<8; i++) { if(myText[i]) //This image is used for name selection for all custom window selections. { myText[i]->free(); RPG::Image::destroy(myText[i]); myText[i] = NULL; } } } ...
This window is immediately exited out of upon the start of battle and is not even seen by the player at all. Therefore the fight/escape window check should only happen once and thus the following code should be executed at the start of every battle only once, as well as once during the end of battle when the other if statement is true.
The second error occurs randomly when attempting to load the new monster selection window(this is not a Window object, but an Image) or rather when calling the function getMonsterSelection(the function I show a few posts ago). It seems to occur more often when I spam the action key to speed up the action Window though.
The last error I believe is with my turn based algorithm and probably occurs because it does not properly take into account the changes of the number of enemies between different monster groups. This is the code it uses to check for the battlers turn order.
#define Hero_ATB RPG::Actor::partyMember(i)->atbValue #define Mon_ATB RPG::monsters[i]->atbValue void getBattlerSpeed() { for(int i=0; i<8; i++) { if(RPG::Actor::partyMember(i)) { if(actionTaken[i] ||RPG::Actor::partyMember(i)->conditions[1] > 0) { bAGI[i] = 0; Hero_ATB = 0; } else bAGI[i] = RPG::Actor::partyMember(i)->getAgility(); if(i == 0) RPG::variables[706] = actionTaken[i]; } if(RPG::monsters[i] &&RPG::monsters[i]->notHidden) //The issue lies here I think? { if(actionTaken[i+4] ||RPG::monsters[i]->conditions[1] > 0) { bAGI[i+4] = 0; Mon_ATB = 0; //This crashes due to invalid true statement mentioned prior? } else bAGI[i+4] = RPG::monsters[i]->getAgility(); } } }
if(monsters[i])
Edit: I fixed the first problem. I had initially changed the navLevel prior to checking if
RPG::battleData->navLevel == RPG::BNAV_IN_FIGHT_ESCAPE_WINDOW
[RM2K3] DynRPG Compiling Error
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.
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.













