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

Posts

Thanks for the help once again, bugmenot.
author=bugmenot
Or fiddle around with RPG::terrains[ID]->gridInclination

author=raonak
Hello, is there any way to change the position of heroes in battle?
Anyhow, download dyn.20 if someone is gonna submit a plugin or not.

You can also try to reverse the angle of inclination. Apply the dyn.20 patch, open the DynRPG.ini and add the following below [QuickPatches]:
RevInc=47FB33,44,47FB72,44,47FBA3,44,47FBE4,44,47FB4B,00,47FB8A,00,47FBBB,00,47FBFC,E0
The blue numbers are a change of the x coordinate towards the left. 8 bit hexadecimal values. 00 -> 7F is 0 -> 127 and 80 -> FF is -128 -> -1
First blue one is for back attack, 2nd = surround (left flank), 3rd = surround (right flank), 4th = normal/initiative.

edit:
This doesn't apply to autoplaced enemies.

Wow, Thank you a lot! That worked perfectly :D

So I used the RowSwap patch to remove the terribad row command, but problem is that my game is kinda long running, and people who have save files from older versions might have shifted their rows, is there any way to set everybody to the front row?

Just starting getting into DynRPG and it's amazing how it breaks so many limitations and annoyances with RPG2003. love it so much!
Can someone explain this? The number pointer number thing lost me, and I'm trying to figure how to make it right edge for normal, mirror for back, and extend out. I assume the numbers in question are the starting location but i'm not really following what bugmenot gave of how to do stuff like spacing outstuff. I assume I was supposed to use loose formation in conjunction with this because it doesn't work on its own, but I'm not really following mainly because I don't know the dimensions of the battle screen.
In may i created a plugin for GhostRider named "CortiItemProperties".

Here's an upgrade.
http://share.cherrytree.at/showfile-21422/cortiitempropertiesv03.zip

The commands to set conditions and attributes have been changed from a zeroBased condition and attribute id to a oneBased that fits the numbers shown in the database.

author=Example
Database:
0001:Dead ( Old ID:0 ; New ID 1 )
0002:Poison ( Old ID:1 ; New ID 2 )

@GhostRider: Using the right IDs should solve your problems. Send me a letter if something still bugs.
author=Corti
In may i created a plugin for GhostRider named "CortiItemProperties".

Here's an upgrade.
http://share.cherrytree.at/showfile-21422/cortiitempropertiesv03.zip

The commands to set conditions and attributes have been changed from a zeroBased condition and attribute id to a oneBased that fits the numbers shown in the database.

author=Example
Database:
0001:Dead ( Old ID:0 ; New ID 1 )
0002:Poison ( Old ID:1 ; New ID 2 )


@GhostRider: Using the right IDs should solve your problems. Send me a letter if something still bugs.


thanks man :)))))
i'm going to test it ASAP :)
So there is this little window, that shows the mana points requirement as part pof the skill selection. It is only shown in tradition battle mode and it seems to be part of RPG::WindowMenuSkill. However, RPG::WindowMenuSkill does not have a reference to that special window.

A) How do i get a reference to that thing?
B) I don't like it anyway. A QuickPatch that sets its X value to 320 would be fine.
B)
That thing I mentioned a page ago?
[QuickPatches]
MP-Window(y)=4C8CDA,40010000,4C8D42,40010000

As for A)
RPG::Window *winMP;
winMP = (RPG::Window*)( reinterpret_cast<int *> (RPG::battleData->winSkill) )[36];

edit:
...
Does anyone happen to know any way to read a file header?
Nevermind. Although, I am curious about that.
To whom it may concern, DynBattleDisplay has been updated. Mainly I had to do this because I discovered a game-crashing bug when I tried to use it in my own project (it was related to transforming monsters and the fact that they keep their current HP/MP even if their new form has a lower maximum for those values). Also fixed a minor bug in the configuration.

While I was at it, I also added the capability to display exact numbers along with the HP/MP gauges, and I took bugmenot's suggestion of allowing an option to force displays to show while the player has a particular battler selected (that turned out to be a relatively quick addition thanks to PepsiOtaku's update to the Window class in DynRPG, thanks!). Finally, I decided bugmenot was right about it being annoying that the displays popped up briefly at the start of battle then disappeared, and altered it so that doesn't happen.
author=AubreyTheBard
DynBattleDisplay
... decent, I think.

Also, you can't really use

int getSelectedMonster() {
if (RPG::battleData->winMonTarget->choiceActive) {
return RPG::battleData->winMonTarget->currentChoice;
} else return -1;
}
It works for Heroes but not for Monsters since it only returns the selected choice in the window. The target window for monsters removes invalid entries (dead/escaped/invisible).
You kill off choice#1 / monster#1
Now monster#2 is at choice#1
If you select choice#1, your plugin tries to draw the HUD on monster#1 (which is dead, hence nothing is shown)
If you select choice#2, your plugin shows the HUD on monster#2 (but monster#3 is actually selected)


Instead, try
int getSelectedMonster() { 
if (RPG::battleData->winMonTarget->choiceActive) {
int monPartySlot;
asm volatile("call *%%esi"
: "=a" (monPartySlot)
: "S" (0x4953E4), "a" (RPG::battleData->winMonTarget)
: "cc", "memory");
return (monPartySlot +1);
//calls getMonTarget()
//Built-in RM2k3 function that returns the enemy's partySlot (0..7) selected by the cursor in target window

//monPartySlot +1 is the enemy's ID in the monster group (it includes dead/escaped/invisible enemies) not in the target menu
//works for all battle layouts (Gauge layout has the target window open off-screen)
} else return -1;
}
DynRPG has RPG::getSelectedMonsterIndex(). It returns the index of the currently selected monster or -1.
Is there a quickpatch to shift all battlers to the front row?

(I asked before, but seems to have gotten overlooked)
author=Corti
RPG::getSelectedMonsterIndex()
Yeah, it would be better to use this. Does the exact same thing even.
... now how do I open / extract .a files / libraries? (on Windows, 7 or 8-ish)


@front row
Try this:
download forceFrontRow


#include <DynRPG/DynRPG.h>

bool __cdecl onStartup (char *pluginName)
{
//keeps x-Pos offset in front row
*reinterpret_cast<unsigned short *>(0x4BBDF2) = 0xE990;
*reinterpret_cast<unsigned short *>(0x4B49C6) = 0x9090;
*reinterpret_cast<unsigned short *>(0x4B4C6C) = 0x9090;
return true;
}

void __cdecl onFrame (RPG::Scene scene)
{
if (scene == RPG::SCENE_BATTLE)
{
for (int i = 0; i < RPG::inventory->party.size; i = i++)
{ RPG::actors[(i)+1]->setRow(RPG::ROW_FRONT); }
}
}
Hey PepsiOtaku, i saw that you added your own values to the RPG::Scene enum.
How do you switch between scenes? Settings RPG::system->scene works but leads to little bugs like a black screen until i press a key when i entered the menu that way.
Any tipps for working with custom scenes?
EDIT: THIS POST IS NO LONGER TRUE. PLEASE IGNORE THE CONTENT.
Reason:
I found out that i had some uimod-settings for my rm ultimate, that changed the properties of the int-infl. slider. Because of that, the maker had shown me that the Int.Infl. as '0' while it was actually higher in game.

#################### IGNORE THIS ####################
@Bugmenot:
I have a very strange bug in the damage calculation.

author=I'm using this:
PlayerDmgRevamp=4B9847,D1E0,4B985F,909090
EnemyDmgRevamp=4C0B3E,D1E0,4C0B54,909090
SkillDmgRevamp=4C0DE4,#5,4C0DF8,#10,4C0E1A,#10,4C0E2F,#20
This should lead to ( Atk*2 - Def ) = Damage

A skill with 10 Atl.Influence should hit as hard as a melee hit, with a number matching the formular. ( row influence on melee patched away ).

Example value: Atk of hero and monster is 400, def is 1.

SkillDmgRevamp=4C0DE4,#5,4C0DF8,#10,4C0E1A,#10,4C0E2F,#20
Player Attack: ~800
Player Skill: ~790
Monster Skill: ~825


SkillDmgRevamp=4C0DE4,#5,4C0DF8,#10,4C0E1A,#5,4C0E2F,#5
Player Attack: ~800
Player Skill: ~744
Monster Skill: ~816


SkillDmgRevamp=4C0DE4,#5,4C0DF8,#10,4C0E1A,#50,4C0E2F,#50
Player Attack: ~790
Player Skill: ~800
Monster Skill: ~829


So, obviously, i can trade missing hero damage for increased enemy damage by changing int_formular numbers in skills with an intellect influence of 0.

The differences are not very dependent on the actal numbers. If i'm missing 10 player skill damage, its missing 10, like 790 instead of 800 and 40 instead of 50.
Also, my monster does deal 830 istead of 800 and 131 instead of 100.

And why the hell do heroes lose while monsters gain? O_O

None of my skills uses intellect, so i don't really need that part of the formular. Is it possible to create a formular with less rounding errors if you don't calculate the int part of the formular? I guess you only have a few bytes of space where the formular is, so dropping int completely frees some space, doesn't it?


Btw. i dont trust that QuickPatcher anymore. How do i translate QuickPatches into this stuff?
*reinterpret_cast<unsigned short *>(0x4BBDF2) = 0xE990;
#################### IGNORE THIS ####################
author=Corti
Hey PepsiOtaku, i saw that you added your own values to the RPG::Scene enum.
How do you switch between scenes? Settings RPG::system->scene works but leads to little bugs like a black screen until i press a key when i entered the menu that way.
Any tipps for working with custom scenes?


Hmmm... that's a can of worms. I added my own scenes to RPG::Scene to avoid conflicts between plugin developers. For instance, if I were to create a menu, and you were to create a menu, both with the same scene #, there would be obvious conflicts if someone were to use both plugins. I added a little blurb about that in the documentation. I should have made that a "Note" actually so it was more visible. Basically, if you are making a scene of some kind, let me know what # you want to use, and I'll update the source.

Switching between scenes is easy enough. It sounds like you figured that part out. You use "RPG::system->scene = #", but you have to keep some stuff in mind. The normal scenes use transitions, but if it's a new scene, it's not going to, so I ended up writing my own transitions. If you are transitioning from a standard scene (SCENE_MAP-SCENE_DEBUG, or 0-8) to your custom scene, you need to use onFrame for the fade out, and onDrawScreen for the fade in. This is because onFrame is only called during standard scenes, so it will never recognize the new one, even if you try using "if (RPG::system->scene == MY_SCENE)." With that in mind, transitioning from your scene back to one of the regular scenes will fade out onDrawScreen, and fade in onFrame.

You could potentially use onDrawScreen instead of onFrame in both scenarios, but Cherry mentioned something about onDrawScreen being called more than once per frame during normal screen transitions. I could have that wrong, but it's not a huge issue anyway. Just time your code only to the frames you need for it. :P

After you have get to your custom scene, you must do everything onDrawScreen. To fade in/out, use RPG::canvas->screen->brightness, but don't set it under 0 or over 100, or you'll get some weird color flashes and/or artifacts. To copy the screen before the transition, you can save the scanlines to a buffer before the RPG::system->scene switch, save it to a bg image, and then show the bg image after the transition. In the gamejolt plugin, I do this, and then overlay a 2nd image on top of it that has colorControl settings (the translucent tint essentially).

Now, what I did in my other screens was use a brightTimer variable to determine if input gets detected. I think I had it go from a negative to 0 for a fade in, and a positive value to 0 for fade out. But basically, all of my input commands are contained within a "if (brightTimer == 0)". Keep in mind, that if you were iterate by 1 every frame, it would take a 1.4 seconds for a full fade, so you'll need to calculate what to iterate by.

For input, just make sure you set a boolean to true if a key is being held down so that your code only runs once. onDrawScreen works the same way as onFrame in that it's called every frame. The first thing you'll want to add is a check for the esc key, so you can jump back and forth between your custom menu and your menu's initial entry point.

From there you can pretty much work your magic and do what you need to do. I can send you the code for some of this if you want. I built a crude template for it.
author=bugmenot
It works for Heroes but not for Monsters since it only returns the selected choice in the window. The target window for monsters removes invalid entries (dead/escaped/invisible).


Gah, fixed. Thanks for pointing that out, and sorry for not paying closer attention the first time you mentioned it, I misunderstood a bit. Also thanks to Corti for suggesting RPG::getSelectedMonsterIndex().
Updated:

Hey, PepsiOtaku! Thanks for taking the time to explain that to me.

Hey, AubreyTheBard. Can your plugin deal with battler->getMaxHp() return 0 and battler->atbValue being negative? Both can happen in combination with plugins and patches.

I made a plugin that does the same. One of the first things my 'customers'* demanded was drawing all the hud-elements on top of all battlers, because huge monster sprites have the habit of hiding other monsters hud-elements. This was the first but not the last time i encountered that problem. I also needed it for selection cursors and custom damage numbers and all that stuff one would draw over battler's heads.

This is my solution. I created my own overlay-layer with functions for actors and monsters that are called according to y-position on screen. Maybe you could use that.


namespace BattleOverlay
{
/* BATTLE OVERLAY README:
BattleOverlay is a little helper to draw on top of all battlers.
Sometimes drawing in the onBattlerDrawn-callback has the disadvantage that bigger monster sprites may hide UI elements drawn on top of other monsters.

To draw that kind of UI elements like lifebars and condition icons, we would want to draw them on top of all battlers,
but in an ordner that matches the y-coordinate of the battler-sprites.

This component does that by saving the IDs of drawn actors into an array and executing a custom callback cycle after all actors are drawn.
The array method was chosen in favor of manually checking the party and monsters-arrays and sorting them by y-coordinate.
The rpg maker actually did that for us as part of the original drawing order.

HOW TO USE:
- Function 'RememberBattlerDrawn' needs to be called in dyn-callback 'onBattlerDrawn'
- Function 'DrawOverlay' needs to be called in dyn-calback 'onDrawBattleActionWindow' with its 'selActive' parameter being false.
- Implement your own code in the OnOverlayDrawActor() and OnOverlayDrawMonster() functions.

Author: Corti, 2015
*/

// Called when the actor's overlay is drawn.
void OnOverlayDrawActor(RPG::Actor *actPtr)
{
// NYI: Do your stuff here.
}

// Called when the monsters's overlay is drawn.
void OnOverlayDrawMonster(RPG::Monster *monPtr)
{
// NYI: Do your stuff here.
}

// The number of battlers drawn this frame and the numbr of valid entrys in the id-array.
unsigned int battlersDrawn = 0;
// Contains the id of battler that were drawn according to onBattlerDrawn callbacks this frame.
int drawnBattlerIds[8+4] = { 0,0,0,0,0,0,0,0,0,0,0,0};

// Needs to be called directly on top of all actors and before the HUD and Menus are drawn.
// Called in onDrawBattleActionWindow's first call, in which the 'selActive' parameter is false.
void DrawOverlay()
{
for(int iBattler = 0; iBattler < battlersDrawn ; iBattler++) // Call OnOverlayDraw function according to battler type.
{
int thisId = drawnBattlerIds[iBattler];
// Heros are taken by database ID. Monsters were saved as ( -1 to -8 ) and are accessed as ( 0 to 7 ).
thisId > 0 ? OnOverlayDrawActor(RPG::actors[thisId]) : OnOverlayDrawMonster(RPG::monsters[(-thisId) -1]);
}

battlersDrawn = 0;
}

// When a battler is drawn, this function is called. The battlers ID is saved into an array.
// Called in onBattlerDrawn for both heros and monsters.
void RememberBattlerDrawn ( RPG::Battler *battler )
{
// For Heroes, this is the Database-ID ( 1-based ), for Monsters it's the 1-based monsterGroup-ID. Both are > 0.
int id = battler->id;
// Save the ID into the array with monster-IDs saved as negative values.
drawnBattlerIds[battlersDrawn] = battler->isMonster() ? -id : id;
battlersDrawn++;
}
}

*talking about my 'customers' feels so professional at work, but writing it on the internet makes me feel like a drug dealer/prostitute O_O.
author=bugmenot
author=Corti
RPG::getSelectedMonsterIndex()
Yeah, it would be better to use this. Does the exact same thing even.
... now how do I open / extract .a files / libraries? (on Windows, 7 or 8-ish)


@front row
Try this:
download forceFrontRow


#include <DynRPG/DynRPG.h>

bool __cdecl onStartup (char *pluginName)
{
//keeps x-Pos offset in front row
*reinterpret_cast<unsigned short *>(0x4BBDF2) = 0xE990;
*reinterpret_cast<unsigned short *>(0x4B49C6) = 0x9090;
*reinterpret_cast<unsigned short *>(0x4B4C6C) = 0x9090;
return true;
}

void __cdecl onFrame (RPG::Scene scene)
{
if (scene == RPG::SCENE_BATTLE)
{
for (int i = 0; i < RPG::inventory->party.size; i = i++)
{ RPG::actors[(i)+1]->setRow(RPG::ROW_FRONT); }
}
}


Thank you! It works perfectly!
DynRPG is so awesome
author=Corti
Hey, AubreyTheBard. Can your plugin deal with battler->getMaxHp() return 0 and battler->atbValue being negative? Both can happen in combination with plugins and patches.


Hmm, the max HP one could cause trouble. I'll put it on a list of things to fix when I get around to another update.

author=Corti
I made a plugin that does the same. One of the first things my 'customers'* demanded was drawing all the hud-elements on top of all battlers, because huge monster sprites have the habit of hiding other monsters hud-elements. This was the first but not the last time i encountered that problem. I also needed it for selection cursors and custom damage numbers and all that stuff one would draw over battler's heads.


It sounds like you've already done some of the things I was figuring I'd have to tackle eventually, like simulating the selection interface. X) Why aren't there plugins for these things posted in Utilities already? ;) Did your 'customers' insist on owning the code, or did the plugins you created for them just seem too tailored to their project to be generally useful? I'll bet I could save a lot of time if could see some more of your source.