+++ DynRPG - The RM2k3 Plugin SDK +++


... for disabling the use of "skill scroll" items in battle/field, e.g. if the linked Skill inflicts a regenerative/stat-doubling Condition/Buff (which should only apply inside of battle, but would normally be usable on the field as well).

+++ DynRPG - The RM2k3 Plugin SDK +++

How can you understand assembly but be hopeless at C++?
Because I stopped delving further into C++ when I realized I can pull all desired values or call (yet) inaccessible RT functions from memory. Also I don't use 2k3, so there's no real reason yet.

If it was just save.lsd files you wanted to check for.
edit: I know a simple way:
int eax = ( *reinterpret_cast<int **> (0x4CDF20) )[0];
int edx = SaveId;
int out = 0;
asm volatile("call *%%esi"
: "=a" (out)
: "S" (0x4A5484), "a" (eax), "d" (edx)
: "cc", "memory");
RPG::variables[ID] = out; //0|1 = false|true existence
Should compile into less code than using Pepsi's method. Doesn't really make a difference though.
Probably shouldn't execute that when inside of any of the save/load screens.

I just (pre-edit) noticed that this RT-internal function returns a boolean value for the (non)existence of save files. I can backtrack it to whatever checks for a certain filename. But I'm dead tired now. I'll come back to that later. (if you find a solution by then, ignore what I said.)

+++ DynRPG - The RM2k3 Plugin SDK +++

There were incompatibility issues with DirectMenuPatch and VisuMenuPatch. Replace the old VisuMenu.ips file with this one:

download VisuMenu(fix)

@above me:
I know less about C++ than you. Try google
... I doubt a degree in computer science would help much with what those numbers I posted mean.
It might help with getting started, though. Since it's extended inline assembly.

+++ DynRPG - The RM2k3 Plugin SDK +++

This gets awfully close into 'customization territory' (meaning I will not do that or else everyone and their brother would ask me to customize stuff just because they don't like something and want to have 6 more of something else).

**To (un)equip an Item via C++ :
        int eax = (int)RPG::actors[HeroId];
int edx = EquipSlot; //starts with zero: 0|1|2|3|4
int ecx = ItemId; //zero to unequip
asm volatile("call *%%esi"
: "S" (0x4B7DB4), "a" (eax), "d" (edx), "c" (ecx)
: "cc", "memory");
//equips ItemId (or unequips current Item) in specified EquipSlot of an Actor
Figure out all the logic from there.
**Dyn.30 added RPG::ItemType (if the logic doesn't have to be handled by ItemId)
Also, you don't need multiples of a weapon just to have elemental properties.
**Dyn.30 added DArray<bool> RPG::Item::attributes. Just set new values and you are done.
(just has to be tested for and re-assigned before every battle)

**considering someone takes the time to just compile a few (less than 10?) lines of code.

However, there is an easy way you could think about:
Replace the old Armor(Slot#2) and Armor(Slot#2+4) lines with these new ones.
(add ,49EF72,20,49EF2C,20 behind one of the QuickPatches if you are too lazy to rename all slots into the same vocabulary)

Shield type equipment fits into Slot#2, Slot#3, Slot#4
Armor type equipment fits into Slot#3, Slot#4
Helm type equipment fits into Slot#4

Rename the equipment vocabulary:
Slot#2 = Mod(A)
Slot#3 = Mod(B)
Slot#4 = Mod(C)

So if you give the player some:
...low level "stuff" (shield / Mod(A) type), it can be assigned into Slots A-C, up to three "stuffs" in whatever order.
...mid level "stuff" (armor / Mod(B) type), it is limited to Slots B-C, up to two "stuffs" in whatever order.
...high level "stuff" or elemental affinities (helm / Mod(C) type), it is limited to Slot C.

Also have all the (C)Items above all (B)Items (in the F8 database) and all (B)Items above all (A)Items.
Just so that the player won't miss where some of the "stuff" goes in case the first 12 items shown are (A)Items and the rest is further down the list in that equip pool window thingie.

Sure, it wouldn't be an item ranking system exactly like... erm, lack of examples... Dissidia FF?
Meaning you can't equip 2 (B)Items and 1 (C)Item at the same time.

+++ DynRPG - The RM2k3 Plugin SDK +++

In terms of the ini [...] set condition 14 to change elemental resist.

You can do that yourself, if you want. That's what the ExtBug-in.cpp is there for.

It adds a pseudo-callback right before the damage multiplier of an attribute or the susceptibility of a condition is requested. For easier accessibility and less headaches figuring out when to change the database copy and change it back to default and so on.

There's a party ID to access RPG::actors[ID] or RPG::monsters[ID] and an Attribute ID / Condition ID with the default A-E numerals so you can go check out the new dyn.30 source update that also added RPG::Attributes and RPG::Conditions.

Just put in some C++ code that asks if the target has conditions[status_ID] (e.g. "Fire DeBuff") and add 100 to int attribPercentage = RPG::attributes[X]->dmgA-E (where X is the attribute "Fire" and also int AttributeId of the callback, A-E from int defaultABCDE) or whatever you had planned.

+++ DynRPG - The RM2k3 Plugin SDK +++

Example? What do you mean 'example'?
@set_arc_hero V32, 5, -70
will have the hero from Var[0032] change his/her damage multiplier of Attribute 5 into -70%
Att#5 damage will be calculated with a 70% multiplier, negative damage / heal.

@get_arc_hero 1, 5, 2
get current damage multiplier (of Hero#1) of Attribute #5 into Var[0002]. Let's say it's 80% by default
(event code)
<> Change Variable: [0002] / 2
@set_arc_hero 1, 5, V2
sets new damage multiplier (80% /2 = 40%). Effectively halving all further incoming damage from Att#5.

Or have an ability of a character increase the damage all monsters take from fire by a factor of 1.5
@get_arc_monster 1, 1, 1
(event code)
<> Change Variable: [0001] * 150
<> Change Variable: [0001] / 100
@set_arc_monster 1, 1, V1
repeat for monsters 2 through 8 (the plugin has a fail-safe to not crash if an enemy does not exist).

Or inflict dummy-conditions with Skills. After the turn (monster or hero) ends, remove the dummy-condition and apply a comment command to buff/debuff received elemental damage / chances of receiving certain conditions.

Conditional branches kind of need an update, since they can't detect crap in battle.
Or write a small plugin that gets DArray<short, 1> RPG::Battler::conditions values into a variable, so logic can be applied.

it would fit together better defining the status in the ini
No. No, it wouldn't.

[RM2K3] What exactly does "Observe Battle" do in RPG MAKER 2003 for enemies?

observe battle
Wait 40 frames, flash Monster, play a sound; shows that a turn was wasted

do nothing
no Waits, no flash, no sound, resets idle pose (effectively does nothing on monsters)

charge up
lose a turn, forced regular attack on next turn with 200% damage; classic FF nonsense

deals damage to party: [1.0]Str(user) - [0.5]Def(target)
20% damage variance, 100% hit chance, 100% chance to cure conditions with "cured by damage"

the "attempts to run away" is somewhat misleading:
if the monster is surrounded -> escape message is shown, escaping fails, turn wasted
if not surrounded -> 100% escape chance

I was hoping it actually observed the battle so the enemy does skills based on what they saw of you.

It can still turn a Switch ON, and that's all you need to run an assessment of the situation / players party. In the background. Yourself.

(this is the game design sub-forum, isn't it?)
Check who's in the party, what equipment they have, turn Switches ON depending on elemental weaknesses, have higher priority behaviors pre-set which are only available if a certain Switch is ON.

You can make a lot out of the vanilla DBS, it just takes some effort. (and effort to ignore / reduce the abysmal speed issues)
Such as making multi-step charge-up Skills (with SkillType = Switch) that open up higher priority actions in the ememy's behavior pool. You know, so that the player can actually notice that and prepare for it or launch countermeasures.

available enemy actions:
behaviors with priorities ranging from the highest priority (with all conditions met) to -10 priority (from that highest priority)

Also, the AI for auto-battle / AI-controlled Heroes does try to prioritize actions that cumulate the most damage (or heal the most damage on your side). But checking for the amount of dealt/healed damage on a single target is borked up anyways (only uses the value from the last (enemy) party member)

[RM2K3] Patch Consolidation Help

There's actually an .ips version of the betterAutoEnterPatch right here. For easier mixing of different patches and such.

(default readme-stuff)
download LunarIPS: http://fusoya.eludevisibility.org/lips/

First step: make a backup of your RPG_RT.exe (just in case)
open Lunar IPS -> apply IPS patch -> select the .ips file (this patch) -> file type: all types -> select the RPG_RT.exe

Or put this patch into your DynPatches folder.

+++ DynRPG - The RM2k3 Plugin SDK +++

because this is a cool plugin
Well first off, it's not really a plugin. It needs/overwrites already existing space.
And my resource management is all over the place with that thing considering that free space is a (somewhat) limited resource.

I'll try to port it into a plugin and expand upon it. *When I find some time.
Primarily so you can go and bug others or yourself with it and/or with learning C++ or taking a look into the dynDocumentation.

I'm still trying to sort out what can be salvaged and see what callbacks need to be, so that ...stuff can be managed more comfortably instead of having to work around your workarounds to implement some of the things listed above with the help of new 0.30 features.
E.g. you can temporarily add a death condition with DArray<bool> RPG::Item::conditions or DArray<bool> RPG::Skill::conditions, and temporarily set its int RPG::Condition::susA up to susE to 100%.
It needs to trigger properly onDoBattlerAction, store the default values and reset back to the default values when the turn's done.
Now that's confusing and convoluted. That's where things can be changed.


But yeah, the chance of causing a status was a formula that factored in SkillHit%, the user's Hit% (lowered by blind) and the condition's susceptibility% on top.
I've put that on a piece of digital paper for later.

Anyway, here's a thing:

Attribute/Condition Resistance Control
download ResistControlBug-in

Allows to control attribute and condition resistances of heroes and enemies.


Use a comment with the contents:

@set_arc_hero [1], [2], [3]

[1] = Hero_ID (from actor/hero tab in F8-database)
[2] = Attribute_ID
[3] = new damage multiplier (in percent) (min = -10000% | max = +10000%)

Substitute [x] with numbers or a Var_ID with a "V" in front
"@set_arc_hero V32, 5, -70"

will have the hero from Var[0032] change his/her damage multiplier of Attribute 5 into -70%

@get_arc_hero [1], [2], [3]

[1] = Hero_ID
[2] = Attribute_ID
[3] = Var_ID to store current damage multiplier (in percent)

@get_adefault_hero [1], [2], [3]

[1] = Hero_ID
[2] = Attribute_ID
[3] = Var_ID to store default damage multiplier (in percent; includes JobClass and AttributeResistance from equipment)

@set_crc_hero [1], [2], [3]

[1] = Hero_ID (from actor/hero tab in F8-database)
[2] = Condition_ID
[3] = new susceptibility (in percent) (min = -10000% | max = +10000%)

@get_crc_hero [1], [2], [3]

[1] = Hero_ID
[2] = Condition_ID
[3] = Var_ID to store current susceptibility (in percent)

@get_cdefault_hero [1], [2], [3]

[1] = Hero_ID
[2] = Condition_ID
[3] = Var_ID to store default susceptibility (in percent; includes JobClass and ConditionResistance from equipment)

@set_arc_monster [1], [2], [3]

[1] = Enemy_Party_ID (#1 .. #8 by number in MonsterGoup)
[2] = Attribute_ID
[3] = new damage multiplier (in percent) (min = -10000% | max = +10000%)

@get_arc_monster [1], [2], [3]

[1] = Enemy_Party_ID
[2] = Attribute_ID
[3] = Var_ID to store current damage multiplier (in percent)

@get_adefault_monster [1], [2], [3]

[1] = Hero_ID
[2] = Attribute_ID
[3] = Var_ID to store default damage multiplier (in percent)

@set_crc_monster [1], [2], [3]

[1] = Enemy_Party_ID (#1 .. #8 by number in MonsterGoup)
[2] = Condition_ID
[3] = new susceptibility (in percent) (min = -10000% | max = +10000%)

@get_crc_monster [1], [2], [3]

[1] = Enemy_Party_ID
[2] = Condition_ID
[3] = Var_ID to store current susceptibility (in percent)

@get_cdefault_monster [1], [2], [3]

[1] = Enemy_Party_ID
[2] = Condition_ID
[3] = Var_ID to store default susceptibility (in percent)

@somewhere on page 42
I'm quite curious, is it possible to make a plugin that lets you put in custom values for the level up curve instead of using the default 2k3 EXP Level Up Curve which is terrible and I'm using because I don't have too much choice in the matter? I originally was going to make my EXP level ups be similar to FFV/FFVII, but couldn't do it due to this dumb table. I'm going to assume it's a no-go though...but thought I'd ask.

Ask someone who knows how to use KazString to add entire EXP sheets for each character. I made a plugin that adds in a pseudo-callback for when the required total EXP for a certain level is requested:
download ExtBug-in.cpp
int onGetLevelEXP ( int HeroId, int Level )
int onGetAttributeResist ( int AttributeId, int DefaultABCDE, int TargetPartyId, bool TargetIsMonster )
int onGetConditionResist ( int ConditionId, int DefaultABCDE, int TargetPartyId, bool TargetIsMonster )

Here's an example how to work altered EXP values:
download ExpBug-in
(changes the EXP-curve progression to be more 'exponential'. It's in fact based on RM2k, but the growth rate can be adjusted so the curves don't go through the roof around level 50)

RPGmaker 2000/2003 battle defeat/victory case

Oh boy, these posts are several years old...
Anyway, if someone still has similar problems or blames the tool he/she's working with:

rm2k3 has an annoying habit of checking to see if your party's dead before it processes the defeat handler
No, it doesn't? What's in the defeat handler is what causes the problem.

Let me guess: the Hero you are adding to the party was already dead?

Adding / removing someone to / from the party (in addition to updating HP/MP stuff) triggers the game to check whether or not everyone in the party is dead. So you can't even remove any character if the resulting party has only fainted people in it.

Either have that person not be dead before removing him/her from the party... to have him/her be added to the party alive in those DEFEAT handlers. Or save some time from tracking down all the <ChangeParty> commands:

download KillSwitch

Shove the 2k3 v1.08.ips file into the folder named DynPatches, open the DynRPG.ini (config file), just add the KillSwitch=4A43F1,#999 under the line with [QuickPatches]. Change the #999. Or better yet:

Hex Converter (or windows calculator and Alt+3)
Put the number into the rightmost box next to (big-endian) and copy the content from the left box next to (little-endian)

For example: KillSwitch=4A43F1,E7030000 would equal #999.

Make sure you have dyn 0.20 if that does not work ('cause patch support was added at 0.17)