+++ DYNRPG - THE RM2K3 PLUGIN SDK +++

Posts

author=bulmabriefs144
There is no rush. My game is essentially done, so it would mainly be to get things to run better. Pepsi or you could work on it, even if it was three weeks later.


You are writing that there "is no rush", but your posting behaviour tells me something different. If you can wait, i might solve your problem in the future.

I'm working on a plugin that replaces the makers atb with custom atb calculations.
I want to include "atb", "turn-based" and "turn-based in agi-dependend order", which is required for my ctb-look-alike plugin.

It already works for my project, but getting it to work for me and making it resilient enought to deal with you people out there are different things and the latter is not the fun part. I can not even guarantee, that it will work.

It will probably take some weeks, or whenever i find time and delight for doing that. And maybe never, if it does not live up to my expectations.

I post to everything anyway, because the plugins section is all on subscribe.

But yeah I don't mind waiting awhile. For either you or the Bard. My posting behavior comes from the fact that while I can wait in theory, this sorta thing has been on the block for years. Pepsi kinda figured his ATB overhaul with its variables was enough, when I was like "what we actually need is something that does the turn based without all that" he was like "ummm yeah I got a demo to finish, do it yourself". So working on it myself, I realized that I would either need some major schooling on what to put where (which most people won't do) and even still pretty much totally confused.

I guess it's like this. I have another game to work on so I can technically wait. I also know that I don't know enough about what you said to figure out how I should proceed, and I know I have a chance at this only by spending time researching how this code works. Given that other people are likely to do this right, I have the notion that rushing them will probably get nothing accomplished (based on how stopping what I was doing and being neurotic seemed to backfire in the case of stuff getting done for the new 2k3, the higher my expectations the worse it seemed).
So I guess where I'm coming from is similar to a book I submitted to my library hoping to be accepted. I wrote a book, and gave it to the library I work at. I know being a nagging pain is not going to work, as it kinda got stalled in the catalog phase. But at the same time I'd be super-upset if it got lost in the mix and we couldn't get it done. Having something done at all, is way more important than when. Be Mr Rogers, take your time and do it right. Same with Aubrey.
Okay, I did a quick-and-dirty improvement of Cerberus's plugin, and it seems to take action-preventing statuses without any trouble. You can download it here. Since it's a quick-and-dirty thing and Corti's possibly turning out something better in the future (not to mention it's mostly Cerberus's code), I won't be submitting this to the Utilities section.
I'll check it out. I'll check the other one out, when it comes out too.

Tested it. The plugin still freezes (I tested with one party member asleep, and two active, which I tried defending) BUT it allows the party to finish its turn, which means you can potentially end the battle. It also seems to allow for a check whether the party is in fact game over. So yes, it's much smoother. Uhhh, maybe a deal where after the party moves, it switches to monster party.

It probably needs something or other still, but it's enough that I'll swap out for my game for now. Thanks Aubrey! I'll take a look at the code myself, and see if I can do something about that.

I'm gonna try adding this code

// Count the battler as having completed their move
actmoved|=1<<(RPG::Actor::partyMember(i)->id-1);

right below or above where it adds to the counter for no action, to the code. While they are inactive, the code would be possibly testing them and running into the "stopped yet ATB" issue so the best workaround I can think of is that we add to the condition counter, and treat it as a skipped turn (tell me if there are any logic flaws with this, but it appears to help the issue).

...Not sure I did it right. =_=; Didn't seem to do any different. But yea, skipping a turn would be how I'd do it.

Anyway, I'm not sure I personally need Corti's plugin (I like simple codes, and I feel like this is almost right), but I think it will help out some people. Knowing as I do about custom plugins, there are all sorts of programmers that want all sorts of things. I think getting this code to work with no freeze is step 1, and step two is making a fully customizable deal so people can start to be able to have battles where the turns are pretty much up to the creators.
i have a question about CortiXCustomCrit plugin (so i guess this makes it a question for corti himself, but... oh well xD )

i'm currently using mode n°2 (basic a.int - b.int = crit%), i know that there are some command lines that change how critical works for certain skills, but was wondering if there is a way to completely disable critical for all skills except for some specific skills of my chosing.
So you only want some skills to benefit. Do you want to use the int-stat to calculate crit chance?

author=Corti
So you only want some skills to benefit. Do you want to use the int-stat to calculate crit chance?


yeah, i would like only character's "Limit" skills and some other spells to be able to crit, while elemental spells will inflict 400% damage to weak-against-element enemies (already done with standard f8 database attributes), just like a critical hit (basically what i want to do is that hitting an enemy with an element to which he his weak, it's like scoring a "free" critical).

yeah, the "int" stats is fine, since the standard skill damage formula is crap because of the fact that is used both as magic defense and magic attack, using it for your custom critical is a lot more useful :)
I'll put it on my list and will see what i can do for you.
What about melee attacks?
author=Corti
I'll put it on my list and will see what i can do for you.
What about melee attacks?


thanks :)

Melee attack it's fine the way your plugin already works, i'm using the 2nd method and i'm doing fine (if i didn't have to completely overhaul the whole BS i'd try 3rd method to, but for now it's perfectly fine) :)
i have another problem that just came outta nowhere (like the RKO sorta..)

i have been using a patch that bugmenot kindly send me, to change battle hud elements, sames as the visugauge, but for "big numbers" (example 4digits MP)

it always worked perfectly up to now, i loaded an old backup because i wanted to check some things, and as soon as i put the new one back, the gauge messed up and now the face is far away from the actual character hud, here is a pic i took:



i didn't change any value, apparently face x suddenly decided not to work with negative numbers O:

Face(y)=496AB8,#190
Face(dx)=496AC0,%80
Face(x)=496AC3,#-5

here are the values, i use -5 for the face X so that is perfectly aligned with that small bar on top of the HUD, and up to one hour ago it worked...

edit: Also, the normal visugauge, with the normal exe (patched with dynrpg alone) and the old configuration i always used, gives me a "Range Checking Error" in battle, and crashes ò_ò
here is what's in the config file below QuickPatches:
Face(y)=496ABB,#190
HPB(y)=496B08,#190
HPD(y)=496B3B,#190,496B6E,#190,496B9E,#190,496BC9,#190
MPB(y)=496C02,#206,496C48,#206
MPD(y)=496C7B,#206,496CAD,#206,496CDA,#206
ATB(y)=496D1F,#222
Face(dx)=496AC2,6BC9,496AC4,%80
Face(Far-x)=496ACB,034B14A174DB4C008B008BD6E8F4FF00008BC78B10FF5228508B4714
Face(x)=496AC5,81C1,496AC7,#-5
HPB(Far-x)=496AF6,81C2,496AFC,8BC6
HPB(x)=496AF8,#43
HPD(Far-x)=496B29,81C2,496B2F,8BC6,496B5C,81C2,496B62,8BC6,496B8C,81C2,496B92,8BC6,496BB7,81C2,496BBD,8BC6
HPD(x)=496B2B,#35,496B5E,#43,496B8E,#53,496BB9,#61
MPB(Far-x)=496BEE,81C2,496BF4,8BC6,496C34,81C2,496C3A,8BC6
MPB(x)=496BF0,#48,496C36,#43
MPD(Far-x)=496C67,81C2,496C6D,8BC6,496C99,81C2,496C9F,8BC6,496CC6,81C2,496CCC,8BC6
MPD(x)=496C69,#43,496C9B,#51,496CC8,#59
ATB(Far-x)=496D0A,81C2,496D10,8BC6
ATB(x)=496D0C,#43

as for now, i would like to find a solution for the second problem (Range Checking Error + Crash) with normal VisuGauge (as i don't plan on switching to 4digits mp again, i think i like the classic 999 limit better).

edit edit: actually... forget i said anything, it started working again by himself just as suddenly as it stopped working...
Today i learned something the hard way.

GCC compiler optimizations can corrupt some of DynRPGs functions.

Today i worked on my CustmCrit plugin and since DynRPG now has a function to call the rpg makers random number generator, i wanted to replace my seed-based version with that. For some reason i didn't unterstand, this did not work.

int rnd = RPG::getDiceRoll(100);
if(rnd<=currentCritChance)
{
// The crit never happened at 50% crit chance.
}


Once i put in debug message boxes, everything worked, saving the random number into a variable and everything worked. Removing the debug outputs and it was broken again. "Oh a heisenbug i thought.", and then i turned off compiler optimizations~ et voila it works fine again.

This little piece of code__attribute__((optimize("O0"))) put in the right place can prevent the compiler from optimizing into madness.

	

// 2k3 function that gets a random number from 0 to maxValue
static __attribute__((optimize("O0"))) int getDiceRoll(int maxValue) {
int out;
asm volatile("call *%%esi" : "=a" (out) : "S" (0x403054), "a" (maxValue) :"cc", "memory");
// If maxValue is 20, by default, 19 is the actual max that will be returned by the function,
// so out+1 is returned below
// This also ensures 1 is returned instead of 0, to simulate actual dice rolls
return out+1;
}


How do other developers deal with this? I'm not sure yet whats best. Disable all optimizations or just flag all dynRPG asm-calls.
Hmm, I don't remember why I did this, but at some point I commented out that function and replaced it with the below. I might have had some issues with it myself, or just wanted less code. I didn't update github or anything with it yet.

int getDiceRoll(int maxValue) { 
return rand() % maxValue +1;
}

The problem with flagging all DynRPG asm calls is that there are a lot of functions compiled in the libDynRPG.a file that I don't have the source for. It's basically why I had to add a Image::drawString() function to replace the broken Image::drawText().

How would you know if an asm function is corrupted? I've used Image::drawString countless times within a sitting, and it's never produced anything unexpected...
I never had this kind of errors before, so i don't know which functions are influenced, but whenever i find something strange now, i know what to test first.
GCC's inline assembly is pretty horrific. There are really annoying rules about it. I seriously recommend never using inline assembly (GCC has very annoying rules, MSVC doesn't support it in amd64), just use separate assembly files and either GAS or a different assembler like yasm or nasm.
It looks to me like the problem is that you forgot to add "edx", "ecx" next to "cc", "memory" since you are using edx and ecx neither as input nor as output so C++ doesn't know that they will be modified by the RM function you call.
author=Cherry
It looks to me like the problem is that you forgot to add "edx", "ecx" next to "cc", "memory" since you are using edx and ecx neither as input nor as output so C++ doesn't know that they will be modified by the RM function you call.

Hmmm, I think I understand. So those should be added because eax is used? Would something like goToTitle or quitGame require edx, ecx and eax since there's no output? Essentially, would those 3 registers always need to be somewhere in the asm volatile statement, or only in specific ones?

What they are now:
static void goToTitle() {
asm volatile("call *%%esi"
:
: "S" (0x46BC00)
: "cc", "memory");
}

static void quitGame() {
asm volatile("push $0"); //nExitCode
asm volatile("call *%%esi"
:
: "S" (0x40729C)
: "cc", "memory");
}

so that last part would be:
: "edx","ecx","eax",cc", "memory");
This is an example of the annoying rules about GCC's inline asm (MSVC doesn't need this kind of mollycoddling). If you use a separate assembler, you wouldn't have to do this.
@PepsiOtaku:

Right, since RM uses eax, edx and ecx (additionally to cc and memory), those always have to be in either output or scratch.

There is one more annoying thing, though:

If a register is used only in input, but not in output, I can't put it in the scratch list (gives a compilation error). However, C++ won't consider the register modified. Therefore, for these situations, I used the undocumented unused variables RPG::_eax, RPG::_edx, RPG::_ecx.

Example:

asm volatile("call *%%esi" : "=a" (something) : "S" (address), "a" (something), "d" (something) : "ecx", "cc", "memory");
...This will cause problems because the compiler thinks EDX won't be modified.

asm volatile("call *%%esi" : "=a" (something) : "S" (address), "a" (something), "d" (something) : "edx", "ecx", "cc", "memory");
...This will cause a compilation error.

asm volatile("call *%%esi" : "=a" (something), "=d" (RPG::_edx) : "S" (address), "a" (something), "d" (something) : "ecx", "cc", "memory");
...This is how I solved the problem.


By the way, the "push $0" and the "call *%%esi" in your example can go into one statement, like "push %0; call *%%esi".
Great info. Cherry! Thank you!

I updated the added functions that use asm volatile, and they should hopefully be more stable:
https://github.com/PepsiOtaku/DynRPG
http://www.rewking.com/dynrpg/

Changes are listed here if you want to look them over:
https://github.com/PepsiOtaku/DynRPG/commit/ce1a1ce55cf289ddfff7f6c70e368eeca140369f

The biggest change being that I moved doesSaveExist, loadFile, saveFile, etc. to SceneFile.h since a few of them actually use the object (fileSaveLoad). So instead of RPG::loadFile(#), it would be RPG::fileSaveLoad->loadFile(#). It's a little bit more to type for the same thing, but it makes sense for the function. I also finished up the documentation for those.

Corti, let me know if you still have issues with RPG::getDiceRoll(#)