CHERRY'S PROFILE

Search

Filter

PepsiOtaku's DynRPG Plugin Emporium!

Could be further improved with this undocumented way to access the vocabulary:

static RPG::DStringPtr *&vocabulary = (**reinterpret_cast<RPG::System ***>(0x4CDCB4));

// indexes are:
// ATK: vocabulary[66]
// DEF: vocabulary[67]
// INT: vocabulary[68]
// AGI: vocabulary[69]

PepsiOtaku's DynRPG Plugin Emporium!

A few things:

1) You don't need to write the whole {{0, 0, 0, 0}, {0, 0,......}} array initialization. A special syntactic sugar in C++ allows you to write
myArray[5][4] = {0};
2) I don't see any point in the battlerStat array, you could just store the changed amount in a local variable. Would be less to write too.
3) Your big problem is that you have the
g_targetHero[statId][id] = stat;
line (same for monsters) inside of the if(setingsPlus), etc.! This is why MonMpMinus doesn't work correctly. Think about it for a minute!

My suggestions to simplify everything:

Create a function getBattler(id) which takes IDs from 0 to 11 where 0-3 are players and 4-11 are monsters:

RPG::Battler *getBattler(int id) {
return id < 4 ? RPG::Actor::partyMember(id) : RPG::monsters[id - 4];
}

The same thing can be done for stats:
First, we create an enum so it's easier to read:
enum Stat {
STAT_MP,
STAT_ATK,
STAT_DEF,
STAT_INT,
STAT_AGI
}

And then a function to retrieve the right stat value:

int getStat(RPG::Battler *battler, Stat stat) {
switch(stat) {
case STAT_MP: return battler->mp;
case STAT_ATK: return battler->getAttack();
case STAT_DEF: return battler->getDefense();
case STAT_INT: return battler->getIntelligence();
case STAT_AGI: return battler->getAgility();
default: return 0;
}
}

Then you just need one array like this ("short int" will slow things down, by the way. Always use "int" for numbers):

int g_battlerStats[11][5] = {0};
I have used the battlers as first index here, because it seems more logical to me.

Now this code to initialize the stats array:
for(int battlerId = 0; battlerId < 12; battlerId++) {
for(Stat statId = 0; statId < 5; statId++) {
RPG::Battler *battler = getBattler(battlerId);
g_battlerStats[battlerId][statId] = battler ? getStat(battler, statId) : 0;
}
}

Let's create another function to do the popup:

void showPopup(RPG::Battler *battler, Stat statId, int difference) {
if(statId == STAT_MP) {
battler->damagePopup(abs(difference), difference > 0 ? confColorPlus : confColorMinus);
} else {
std::string statNames[] = {"ATK", "DEF", "INT", "AGI"};
std::stringstream text;
if(difference > 0) text << "+";
text << difference << " " << statNames[statId - 1];
battler->damagePopup(text.str());
}
}


And a function which determines whether the popup should be shown (according to configuration) or not:

bool shouldPopupBeShown(RPG::Battler *battler, Stat statId, int difference) {
if(difference > 0) {
if(statId == STAT_MP) {
return battler->isMonster() ? confMonMpPlus : confShowMpPlus;
} else {
return confStatsPlus;
}
} else if(difference < 0) {
if(statId == STAT_MP) {
return battler->isMonster() ? confMonMpMinus : confShowMpMinus;
} else {
return confStatsMinus;
}
} else {
return false;
}
}

And this simple code to check and display changes (including the queueing I mentioned):

for(int battlerId = 0; battlerId < 12; battlerId++) {
RPG::Battler *battler = getBattler(battlerId);
if(!battler) continue;
for(Stat statId = 0; statId < 5; statId++) {
int newValue = getStat(battler, statId);
int difference = newValue - g_battlerStats[battlerId][statId];
if(shouldPopupBeDisplayed(battler, statId, difference)) {
if(battler->damagePopupTimer == 0) {
showPopup(battler, statId, difference);
g_battlerStats[battlerId][statId] = newValue;
}
} else {
g_battlerStats[battlerId][statId] = newValue;
}
}
}

This should make the code a lot more readable and expandable!

Disclaimer: I didn't test this code.

[DynRPG Plug-in] Main Menu Game Playtime Clock

Depends on whether the RPG::Window class will be included or not, at the moment I would tend to first release a lot of bugfixes and after that concentrating on adding the new features like RPG::Window.

List of changes I have added already (ignore the Doxygen/HTML markup, I don't have time to reformat it for the forum):

\page changelog Changelog
\section v0_20 Version 0.20 (2013/??/??)
<ul><li>On-the-fly patching using IPS files or quick patches
in DynRPG.ini added. </li>
<li>\c AUTO_DLLMAIN define removed, now a \c DllMain function is always
inserted by default, use <tt>#define CUSTOM_DLLMAIN</tt> to prevent
this behaviour.</li>
<li>The automatic \c DllMain function now stores the plugin's instance
handle in the global variable \c hInstance (only if \c CUSTOM_DLLMAIN
is not defined).</li>
<li><b>Critical bug fixed:</b> Game could hang when loading a game after
a new plugin has been added due to an infinite loop bug during \c Save??.dyn
file parsing.</li>
<li><b>Critical bug fixed:</b> Transparency of events (including the hero)
behaved weirdly (changed depending on Y position) and was thus unusable.
This bug also slowed down the event rendering a lot.</li>
<li><b>Bug fixed:</b> Class RPG::DList had members \c count and \c items
swapped. Because DynRPG classes need to have the same memory layout as the
%RPG Maker's internal Delphi counterparts, all accesses of DList classes
(most notably RPG::monsters) crashed the game.</li>
<li><b>Bug fixed:</b> RPG::Catalog::count didn't work (tried to access
\c list.count where it should have been \c list.list->count, causing a
compiler error.</li>
<li><b>Bug fixed:</b> RPG::Image::copy was broken (didn't set the new image
size but silently leaked an RPG::Image instance instead).</li>
<li><b>Bug fixed:</b> RPG::Actor and RPG::System methods sometimes returned
wrong strings (i.e. for RPG::Actor::getName) if they encountered a default
value in the database.</li>
<li><b>Bug fixed:</b> Due to missing string termination, the
RPG::ParsedCommentParameter::text member of a comment command's last
parameter often had garbage appended at the end.</li>
<li><b>Bug fixed:</b> Negative numbers in comment command parameters were
parsed as RPG::PARAM_TOKEN instead of RPG::PARAM_NUMBER.</li>
<li><b>Bug fixed:</b> RPG::Event::doesEventPageExist was broken.</li>
<li><b>Bug fixed:</b> RPG::transparentWindowsEverywhere was
broken.</li>
<li>Modified library to work with newer GCC compilers. Now GCC version
4.7.1 is required. (For tech-guys: Why the hell can GCC now use the ESP
register for an inline asm parameter with the \c "g" constraint?!)</li>
<li><b>Bug fixed:</b> The "cross-map" pictures #1001 to #2000 were not
erased when a new game was started.</li>
<li>Fixed an %RPG Maker bug which caused the HP display in the save menu
to be misaligned when the HP had 4 digits.</li>
<li>Removed the longer skill/item window visibility "improvement" for most
scenarious because it turned out to disrupt battle event processing.
Only the info window shown when a monster executes a skill is still shown
longer, but now only for 50 frames (old DynRPG used 90 frames which
turned out to be annoyingly long, original %RPG Maker used 30 frames which
I think is too short to be readable).</li>
<li>Fixed an %RPG Maker bug which would cause the game to crash when
a "Link to Event" battle command was used right after the item menu
has been opened and then closed with ESC.</li>
<li>Added RPG::Actor::twoWeapons, RPG::Actor::lockEquipment,
RPG::Actor::autoBattle and RPG::Actor::mightyGuard fields.</li>
<li>RPG::System::pedestrianBGM added. Funny name, I know.</li>
<li>The maximum number of plugins has been raised from 30 to 50.</li>
<li><b>Bug fixed:</b> Under some circumstances, the game would crash
during event command execution. It's hard to describe the exact triggers,
but they included "Erase event" commands in common events, loading a game
which was saved while a "Wait until key press" was active and some other,
rarer situations.</li>
<li>Fixed two %RPG Maker bugs with "Small window" mode in battle: The
action, item and skill selection windows had an empty line at the bottom
even though there would have been enough space. This was especially
confusing for the battle action window because it looked like the actor
had only 3 commands available. Also, the selection cursor for "Show choice"
windows in battle was not correctly aligned with the choice texts.</li>
<li>Removed the "higher action window" workaround for the small battle
window mode because a real fix has been implemented now.</li>
<li><b>Bug fixed:</b> DynRPG would sometimes refuse to load a plugin
if additional non-plugin files containing the string ".dll" were in the
DynPlugins directory.</li></ul>

PepsiOtaku's DynRPG Plugin Emporium!

What exactly did you do? Maybe I can spot the mistake.

[DynRPG Plug-in] Main Menu Game Playtime Clock

Actually, the condition is wrong, it should always execute the "else" case because otherwise a RECT from, let's say, 0/0 to 100/100 will update the whole screen instead of the upper-left 100x100 pixel corner.

PepsiOtaku's DynRPG Plugin Emporium!

PepsiOtaku, in this case you would need to have kind of a "queue" for each battler, for popups, so that if the damagePopupTimer value is > 0 you "queue" your popup and wait. Actually, it should be quite easy if you just don't set your buffer variable (which stores the old value) to the new value so every frame it will try again to show the popup until it succeeds.

PepsiOtaku's DynRPG Plugin Emporium!

About stats: What about popping up "+23 DEF", "-4 ATK", etc. as text? The down side is that there is no color option for text, you can only use color 0.

PepsiOtaku's DynRPG Plugin Emporium!

@PepsiOtaku: First, why are you using .c_str() all the time, even when you pass an std::string to your function which expects an std::string parameter? You are converting it to a char* and then implicitly back to std::string (thus creating a new temporary string object), I don't see the point.

Anyway, I'd do it like this:

confShowMpPlus = configuration["ShowMpPlus"] == "true";

This considers "true" as true and everything else as false. The other way round (only "false" as false and everything else as true, which would be counter-intuitive for me, though) would work like that:
confShowMpPlus = configuration["ShowMpPlus"] != "false";


Personally, I'd use "1" instead of "true" (so you put 0 or 1 in the INI) because that's more common at INI files... but that's a matter of taste.

PepsiOtaku's DynRPG Plugin Emporium!

The image doesn't show because it requires registration at www.shrinemaiden.org...

[DynRPG] CMS Tools: Save Cleanup

Right... but not everybody knows if some plugin uses dyn-files or not!