PEPSIOTAKU'S DYNRPG PLUGIN EMPORIUM!

Posts

I've got a long anecdote here. When I was out of college (no career track, so I worked odd jobs I was overqualified for), I worked for some jerk at some carpet cleaning thing. Anyway, I figured out his floor cleaning powder was basically OxyClean, and blurted that out to a customer. He gave me a scolding "don't ever tell trade secrets again" and denied it to the lady. But that got me thinking, would the lady have still wanted his business anyway? The answer is yes. Human beings are notoriously lazy, and given the choice of doing carpentry themselves, or hiring someone else to do it, they hire someone else. Same for McDonald's, despite the fact that the ingredients are in some sense secret, you'd have to be a pretty pathetic person not to be able to make a better burger.

How does this has relevance? I don't need the code. I don't need (or want) to use C++ for something I already proved I can do myself without it. So what's this (basically a shortcut) for? It's because, I could in fact make a template under utilities (and probably will, just for cheap M points), but based on the complexity of the matter (I made roughly four or five pages of common events just to make it someone easy to digest so I could edit it properly, and heaven help me if I typed anything wrong), it'd be far easier to make a plugin tutorial for custom battle skills. So, no, you're not doing plugins for me. Every time I request (unless it's clear I genuinely don't know, as in Skill ID below), I'm recognizing that a process is complicated enough that for everyone else, it'd be useful, and you're doing it for them. Think of those poor children starving for plugins... ;O_O;

Anyway, the skill code is basically part of this larger Battle ID code. This I actually can't do just with rpgmaker code, hence trying with C++.

#define AUTO_DLLMAIN
#include <DynRPG/DynRPG.h>
#include <iostream>
#include <string>
using namespace std;

std::map<std::string, std::string> configuration;



bool onStartup(char *pluginName) {
// We load the configuration from the DynRPG.ini file here
configuration = RPG::loadConfiguration(pluginName);
return true; // Don't forget to return true so that the start of the game will continue!
}

bool onComment( const char* text,
const RPG::ParsedCommentData* parsedData,
RPG::EventScriptLine* nextScriptLine,
RPG::EventScriptData* scriptData,
int eventId,
int pageId,
int lineId,
int* nextLineId )
{
std::string cmd = parsedData->command;


if(!cmd.compare("item_id"))
{
int ItemAmt = parsedData->parameters[0].number;
int ItemVar = parsedData->parameters[1].number;
int ItemSwitch = parsedData->parameters[2].number;

RPG::variables[ItemVar] = ItemAmt; //feels very roundabout, but I'm rusty

return false;
}
if(!cmd.compare("skill_id"))
{
int SkillAmt = parsedData->parameters[0].number;
int SkillVar = parsedData->parameters[1].number;
int SkillSwitch = parsedData->parameters[2].number;

RPG::variables[SkillVar] = SkillAmt;

return false;
}

return true;
}

//I'm REALLY doubtful this passes to the ActionDone

bool onBattlerActionDone ( RPG::Battler * battler,
bool success )
{
if(battler->action->kind == RPG::AK_SKILL && battler->action->skillId == RPG::variables[SkillVar])
{
RPG::switch[SkillSwitch] = true;
}
else
{
RPG::switch[SkillSwitch] = false;
}

if(battler->action->kind == RPG::AK_ITEM && battler->action->itemId == RPG::variables[ItemVar])
{
RPG::switch[ItemSwitch] = true;
}
else
{
RPG::switch[ItemSwitch] = false;
}

return true;
}

But that's not the completed version. I declared the variables globally, here.

The "Item_ID" part works without a hitch (well, there's one hitch, you basically can't overload the item ID, and have to make a new page for each ID). The "skill_id" I dunno maybe I'm doing it wrong or something. It compiles fine like this btw, but when it's time to try the skill, it doesn't check.
Just popping in to add that I would find the ability to read skill IDs, and store them into variables or something, to be a huge advantage in terms of custom battle processes. It could directly serve as a way to circumvent skill canceling. Of which I'm still awaiting a solution for before I move on.
Ok, I finally took a look at this. I don't think you really need the onComment code at all to be honest. Would someone mind testing this code? I won't be able to until later this evening.

http://rpgmaker.net/media/content/users/40/locker/store_item_skill.dll

#define AUTO_DLLMAIN
#include <DynRPG/DynRPG.h>
#include <string>

std::map<std::string, std::string> configuration;

int confSkillIdSwitch;
int confSkillIdVar;
int confItemIdSwitch;
int confItemIdVar;

bool onStartup (char *pluginName) {
// Get configuration settings
configuration = RPG::loadConfiguration(pluginName);
confSkillIdSwitch = atoi(configuration["SkillIdSwitch"].c_str()); // Convert String to Int
confSkillIdVar = atoi(configuration["SkillIdVar"].c_str());
confItemIdSwitch = atoi(configuration["ItemIdSwitch"].c_str()); // Convert String to Int
confItemIdVar = atoi(configuration["ItemIdVar"].c_str());
return true;
}

bool onBattlerActionDone (RPG::Battler* battler, bool success) {
if (battler->action->kind == RPG::AK_SKILL) {
RPG::variables[confSkillIdVar] = battler->action->skillId;
RPG::switches[confSkillIdSwitch] = true;
} else {
RPG::switches[confSkillIdSwitch] = false;
}
if (battler->action->kind == RPG::AK_ITEM) {
RPG::variables[confItemIdVar] = battler->action->itemId;
RPG::switches[confItemIdSwitch] = true;
} else {
RPG::switches[confItemIdSwitch] = false;
}

return true;
}

Add this to DynRPG.ini (feel free to change values):

[store_item_skill]
SkillIdSwitch = 0001
SkillIdVar = 0001
ItemIdSwitch = 0002
ItemIdVar = 0002

From there, make a battle and 2 pages - one with the "on switch" condition for your SkillIdSwitch and one for your ItemIdSwitch, each with some kind of "Hello World" message box. You'll need to turn the switch off afterwards though, or else it'll just repeatedly display.

Once you get hello world to appear, you can add conditionals that check for specific skill ids or item ids, and then add whatever code you want.

Keep in mind this doesn't differentiate yet between heroes & monsters.

Skie: You might be able to get Cherry to help you with the skill cancelling bug if you poke/prod him enough.
Actually, assuming that code works the way I think it does, this is a huge step forward towards making skills like cover, hide & jump... I feel inspired to work on these now.
So, it's just If (Skill_ID) or whatever you name it is 132, then if (SkillIsOn) is ON? Or am I reading this right?

Well, hopefully this has a tutorial coming soon.
Oh change the 4 "unsigned char" variables to ints and recompile. It didn't work for me at first because I was using switch/var values higher than 255. It should work correctly after that.

Say you have a fire spell with an ID of 102. After you get the hello world message to come up, you can just use a conditional in your battle page to say if "SkillIdVar" is 102, do stuff applicable to the fire spell.

Edit: Possibilities open up from here. You can either use common events in conjuction with battle pages to shorten the amount of code you'll have to work with, you can make some additional plugins with that code if you wanted to. Just play around with it.
Okay, the way AK_ITEM works is bizarre. Instead of activating the battle page at the end of the item being used, it does it at the beginning of the next turn (regardless of who's action it is). WEIRD. UGH. You also have to comment this out and recompile:
RPG::switches[confItemIdSwitch] = false;


Otherwise, the battle page won't do anything. I'll experiment with this more later in the week when I can figure this out.
I know. I programmed the battle ID.

But I can't get the other part (skills) to work with my code. I'd suggest you split your code concerning skills, since that works to the correct timing, right?

Mine works like so... You basically reuse a switch, called ItemUsed which works for any switch item (bye bye excess battle switches). Then I made a true switch for if it matches up, and a false switch if it is any other item. Because it requires the switch to be on, it waits until it gets turned off, which is exactly what I need. I suppose I could have done it as false, but I instead split it into two switches because of the nuisance of trying to turn it off afterwards versus having an entirely different operation. I am not sure whether you can have nesting within the false switch and have other options.



(You can also do Turn 1x, but it sometimes fails)

So unless it can be massively improved, I'm fine with this.

I'd say split off the code you got with just skills, and call it battle skill ID. That also simplifies the code since many people are likely to use only one or the other.
Well, I don't think it matters if it's in one plugin or two. I think keeping in the one plugin is fine. If you choose to not use skills, or not use items, that's fine. It's not going to impact performance.
Well, the the question becomes if the item code doesn't work for yours, would keeping the item part interfere with the way that the other plugin does the item processes? I'm not sure because I haven't tested it yet. If it does, then it probably matters or something. Holdon, I'll work on making a "lite" version of yours...

#define AUTO_DLLMAIN

#include <DynRPG/DynRPG.h>
#include <string>

std::map<std::string, std::string> configuration;

int confSkillIdSwitch;
int confSkillIdVar;

bool onStartup (char *pluginName) {
// Get configuration settings
configuration = RPG::loadConfiguration(pluginName);
confSkillIdSwitch = atoi(configuration["SkillIdSwitch"].c_str()); // Convert String to Int
confSkillIdVar = atoi(configuration["SkillIdVar"].c_str());
return true;
}

bool onBattlerActionDone (RPG::Battler* battler, bool success) {
if (battler->action->kind == RPG::AK_SKILL) {
RPG::variables[confSkillIdVar] = battler->action->skillId;
RPG::switches[confSkillIdSwitch] = true;
} else {
RPG::switches[confSkillIdSwitch] = false;
}

return true;
}


Yay, now I'm satisfied.
It shouldn't interfere with anything. It technically works, but the timing of the event code is wrong (due to 2k3's sheisty battle system).
Mkay, then. Let's see... oh, before we mark this as totally done and make some demo utility, what about an IsMonster effect? Can we track monster skills too? That would definitely help with my special monster "basic" attacks (I've got a series of skill attacks that deal damage directly through that random damage formula, so as to avoid reflect). It'd be something like

RPG::variables[confMonsterSkillIdVar] = [b]battler->action->skillId[/b];

What do we change the (supposedly) bolded area to, to track monsters?

...Nevermind, I forgot to read up top.
Oh sure. That's easy. You can just add a "battler->isMonster() == true/false" to your if statement. Here you go:
#define AUTO_DLLMAIN
#include <DynRPG/DynRPG.h>
#include <string>

std::map<std::string, std::string> configuration;

int confSkillIdSwitch;
int confSkillIdVar;
int confMonsterSkillIdSwitch;
int confMonsterSkillIdVar;
int confItemIdSwitch;
int confItemIdVar;

bool onStartup (char *pluginName) {
// Get configuration settings
configuration = RPG::loadConfiguration(pluginName);
confSkillIdSwitch = atoi(configuration["SkillIdSwitch"].c_str()); // Convert String to Int
confSkillIdVar = atoi(configuration["SkillIdVar"].c_str());
confMonsterSkillIdSwitch = atoi(configuration["MonSkillIdSwitch"].c_str()); // Convert String to Int
confMonsterSkillIdVar = atoi(configuration["MonSkillIdVar"].c_str());
confItemIdSwitch = atoi(configuration["ItemIdSwitch"].c_str()); // Convert String to Int
confItemIdVar = atoi(configuration["ItemIdVar"].c_str());
return true;
}

bool __cdecl onBattlerActionDone(RPG::Battler *battler, bool success){
if (battler->action->kind == RPG::AK_SKILL && battler->isMonster() == false) {
RPG::variables[confSkillIdVar] = battler->action->skillId;
RPG::switches[confSkillIdSwitch] = true;
} else {
//RPG::switches[confSkillIdSwitch] = false;
}
if (battler->action->kind == RPG::AK_SKILL && battler->isMonster() == true) {
RPG::variables[confMonsterSkillIdVar] = battler->action->skillId;
RPG::switches[confMonsterSkillIdSwitch] = true;
} else {
//RPG::switches[confMonsterSkillIdSwitch] = false;
}
if (battler->action->kind == RPG::AK_ITEM && battler->isMonster() == false) {
RPG::variables[confItemIdVar] = battler->action->itemId;
RPG::switches[confItemIdSwitch] = true;
} else {
//RPG::switches[confItemIdSwitch] = false;
}
return true;
}

And add this to your DynRPG.ini:
MonSkillIdSwitch=XXXX
MonSkillIdVar=XXXX
Yay! Let's see if I can get this working.

Agh, I basically copy pasted your code, and called it battle_skill_id (since it's mainly for skills). I cast Dark 1, and nothing seems to happen. Dunno what's wrong.



Does it have to be a switch skill? No, that doesn't work for me either. Maybe the way I have turns set up is preventing it or something. Oh well, I can probably just work around it with coding anyway.
Update time!

Over the long weekend I updated a couple of my existing plugins (not yet uploaded), fixing some bugs and filling in functionality gaps. The big one that needed fixing was my "faster ATB 2" plugin since there's actually a lot of issues with it, for instance the bar still moves if you are dead, or if you're performing an action. That's obviously not the way it should work.

One of the new plugins I made is kind of hard to explain. It's basically a better version of "Key Input Processing" that can detect if a key is still being held down. With this, In my CMS'es I simulated the effect where you hold up or down on a menu and it repeats through the options with a short delay after the first movement. This basically makes my menus impossible to tell apart from the default menus, which feels awesome!

I've also been having issues with the default fullscreen mode. I would say 50% of the time, it either minimizes the game when you first start up, or triggers a DirectDraw error. Needless to say, this was wicked annoying, so I did some experimenting, and noticed that if you boot the game in windowed mode, it always boots fine. I then built a "Better Fullscreen" plugin (similar to ragnadyn) that forces the game to start in windowed mode, and then at the earliest possible moment, simulates an F4 keypress. It's also controlled via a separate .ini file from DynRPG so a user can easily set it to either windowed mode or fullscreen mode without having to view DynRPG ini settings. I still have to add configurable things to the plugin before it's posted, but the game boots so nicely now!

The biggest plugin I finished was an auto-switch plugin. There have been variations of this before (DynVarStorage, Database Extended), but I found they were all unnecessarily difficult to use. My plugin is similar to my global save data plugin, but it's coded better and easier to understand (hopefully). It automatically gets the Map ID (via variable), Event ID , and the switch value (0/1), and via comment, you can export it to an ini file (that you can define with your own filename and extension). So if your Map ID was 0001, event ID was 0005, and the switch value was "ON," the ini would read:

[1] (Map)

5=1


For importing, comment code will get the event information from the ini in order to check if it's there. If it is and the value is 1, it will set a master switch to ON. You can basically use that any way you want in-game. For instance, I added searchable barrels and things that I don't want to keep track of by normal means, so I can literally just copy and paste the event into various locations using the same code and they will all be checked independently from one another. The best part is, the files are extremely low in filesize. I did a stress test with 50 events, and the filesize was only around 200 bytes.

The files this creates are named according to the save file used (or 00 if you haven't saved yet). It also uses 00 as sort of a "buffer" inbetween saving/loading This gets hard to explain because you have to think about the nature of save files, so I'll just cut it short and say that it works the way it should. :)
author=PepsiOtaku
Update time!

Over the long weekend I updated a couple of my existing plugins (not yet uploaded), fixing some bugs and filling in functionality gaps. The big one that needed fixing was my "faster ATB 2" plugin since there's actually a lot of issues with it, for instance the bar still moves if you are dead, or if you're performing an action. That's obviously not the way it should work.

What else got changed about this one with this patch? Also, do you still plan on creating that version that allows for individual hero and monster ATB changes?

It's not that I personally am in need of an updated version of it, as it currently works perfectly well with my current turn-based combat system, but I'm curious.
Well, there are certain instances where the bar should not move. For example, when it fills up and a hero performs an action, the bar immediately gets reset and should not move again until the hero finishes that action. The issue was that the bar still moves. This causes heroes & monsters to perform their next actions quicker. This situation is also true for when a hero dies, or is afflicted with a condition where the bar shouldn't move (like shock, stone or sleep).

When I iron out those kinks (I feel like there's still scenarios to fix), I'll tackle individual ATB bar changes.
I see. I'll try out the new version, because there's a few rare instances where the system didn't 100% work perfectly (not in gamebreaking ways, though). Maybe those got fixed now.
I'm interested in the individual ATB bar changes, because that could open up some new options for an even more advanced system.
so the auto-switch plugin is like the RPGXP-VX local switch?
I can use that plugin for chests?
You sure can! It doesn't support multiple pages or multiple switches per-event yet like VX, but that should be easy to add.