CERBERUS'S PROFILE
Cerberus
0
Search
Filter
+++ DynRPG - The RM2k3 Plugin SDK +++
author=bulmabriefs144Strange. Started it in Battle Test with one monster animated and one not - had a bug too (not a crash, though). Ingame this battle worked fine.
Uh oh.
Haven't tested it yet vs the stuff on my list, but this is what it did on stuff that wasn't on the list.
+++ DynRPG - The RM2k3 Plugin SDK +++
Looks like I've understood the source. Won't be able to replicate it by myself, though :)
That's the code modification I've tested. Only a bit, because have to run now, but it seems to work.
onFrame remains unchanged, in onDrawBattler and onBattlerDrawn there are several new conditions, and new onStartup.
Hope that's what you want. And sorry if something is wrong in the comments :)
That's the code modification I've tested. Only a bit, because have to run now, but it seems to work.
/* animated_monsters.cpp A dynRPG plugin to animate your monsters with the DBS! Feel free to use or modify this as you see fit. Your safety is not guaranteed. --dragonheartman 6 JUN 2012 */ /* Modification by Cerberus: only several monsters are animated 26 JAN 2013 */ #define AUTO_DLLMAIN #define NUM_POSES 7 #define MAX_MONSTERS 8 #include <DynRPG/DynRPG.h> #include <sstream> RPG::Image* monsterPoses[MAX_MONSTERS][NUM_POSES]; /* table containing all images created */ RPG::Image* oldPose; /* rm2k3's old monster pose, saved off */ boolean resetTable = false; /* reset table flag */ int frameTimer = 0; /* global frame updater */ int hurtTimer[MAX_MONSTERS]; /* a timer for how many frames we ought to show the hurt pose */ int oldHP[MAX_MONSTERS]; /* old hp vals to check for damaged enemy */ int poseIndex[MAX_MONSTERS]; /* which monster pose do we show? */ int animationCycle[NUM_POSES] = {1, 2, 3, 2, 4, 5, 6}; /* index for which animation file to display */ /* 1-3 idle, 4 (RPG::monsters[id]->databaseId<=maxnum) && (Animate[RPG::monsters[id]->databaseId]))dead, 5-6 hurt */ int maxnum=0; //in fact, it's the size of Animate array; basely, it means "no animations at all" bool *Animate; //if Animate[i]=true, the monster which DB number is i+1 is to be anmated std::map<std::string, std::string> configuration; bool in_use=false; //is the battler drawn now animated? bool onStartup(char *pluginName) { int i, len, curnum=0; // We load the configuration from the DynRPG.ini file here configuration = RPG::loadConfiguration(pluginName); if (configuration["Animate"][1]) // i.e. found the list { for (i=0, len=configuration["Animate"].length(); i<len; i++) { if (isdigit(configuration["Animate"][i])) curnum=curnum*10+configuration["Animate"][i]-'0'; else { if (curnum>maxnum) maxnum=curnum; curnum=0; } } if (curnum>maxnum) maxnum=curnum; curnum=0; //we run through the list and found the highest number //better would be to know how many monster are in DB, but I haven't found this Animate=(bool *)malloc((maxnum+1)*sizeof(bool)); memset (Animate, 0, (maxnum+1)*sizeof(bool)); // all the array is filled with "false" curnum=0; for (i=0, len=configuration["Animate"].length(); i<len; i++) { if (isdigit(configuration["Animate"][i])) curnum=curnum*10+configuration["Animate"][i]-'0'; else { Animate[curnum]=true; //it's correct, because curnum<=maxnum curnum=0; } } Animate[curnum]=true; //it's correct, because 0<=curnum<=maxnum curnum=0; } //now, we have an array of booleans, where true means "animate this" return true; } // destroy ALL the images!! void initializeBattle() { // update our initial pose indexes (0-3) for (int i=0; i<MAX_MONSTERS; i++) { poseIndex[i]=i%4; hurtTimer[i]=0; oldHP[i]=0; // destroy any remaining images -- no leaks pls for (int j=0; j<NUM_POSES; j++){ if(monsterPoses[i][j]) { RPG::Image::destroy(monsterPoses[i][j]); } } } } // called every time a batter is drawn bool onDrawBattler(RPG::Battler *battler, bool isMonster, int id) { // we will be updating the battler dynamically iff the battler is of type RPG::Monster if ((isMonster) && (RPG::monsters[id]->databaseId<=maxnum) && (Animate[RPG::monsters[id]->databaseId])) // first, as mentioned above, is that we check is it the monster or the actor // second, we check whether the third will be correct // third, we check whether the monster have to be animated (according to DynRPG.ini) // if one of conditions isn't met, we simply don't do anything { in_use=true; //this monster is animated, so we need to perform actions after it's drawn // if the current HP is less than old HP, we need to set the appropriate hurt timer // else: reset oldhp in the case where the enemy is healed if(battler->hp < oldHP[id]) { hurtTimer[id] = 30; oldHP[id] = battler->hp; } else if(battler->hp > oldHP[id]) { oldHP[id] = battler->hp; } // if the monster has hurt poses to display, we need to hard set the frame index to 5 (HURT) if(hurtTimer[id] > 0) { poseIndex[id] = 5 + (frameTimer-1)/5; hurtTimer[id]--; } // if the monster dies, we want to hard set the frame index to 4 (DEAD) if(battler->hp <= 0) { poseIndex[id]=4; } if(!monsterPoses[id][animationCycle[poseIndex[id]]]) { // create the new blank image monsterPoses[id][animationCycle[poseIndex[id]]] = RPG::Image::create(); monsterPoses[id][animationCycle[poseIndex[id]]]->useMaskColor = true; // load the image file into our image we created std::stringstream fileName; fileName << "Monster\\" << battler->getName() << "\\" << animationCycle[poseIndex[id]] << ".png"; monsterPoses[id][animationCycle[poseIndex[id]]]->loadFromFile(fileName.str(), true); } // we do this (UGLY) cast to update the monster's image to the image in the loader table oldPose = static_cast<RPG::Monster*>(battler)->image; static_cast<RPG::Monster*>(battler)->image = monsterPoses[id][animationCycle[poseIndex[id]]]; } return true; } // after the battler is drawn, we need to set the monster's default image to point back to the saved off image bool onBattlerDrawn(RPG::Battler *battler, bool isMonster, int id) { if ((isMonster) && (in_use)) { static_cast<RPG::Monster*>(battler)->image = oldPose; } else in_use=false; return true; } // called every frame refresh void onFrame(RPG::Scene scene) { // for battle scenes only, we update a frame timer if(RPG::system->scene == RPG::SCENE_BATTLE) { frameTimer++; // every ten frames, update the index to be displayed in our monster's image if(frameTimer > 10) { frameTimer=0; for(int i=0; i<MAX_MONSTERS; i++) { if(hurtTimer[i]==0) { poseIndex[i] = (poseIndex[i]+1)%4; } } } // set a flag notifying that we need to reset the loader table after combat resetTable = true; } else if (resetTable) { // reset the loader table post-battle initializeBattle(); resetTable = false; in_use=false; } }
onFrame remains unchanged, in onDrawBattler and onBattlerDrawn there are several new conditions, and new onStartup.
Hope that's what you want. And sorry if something is wrong in the comments :)
+++ DynRPG - The RM2k3 Plugin SDK +++
What can I advise:
1. Use the configuration in this way: Animated=1,3,5,10... (numbers of monsters which are to be animated in database). This format (if it's followed correctly) is very easy to parse. I can't write it now (limited in time), but if you want, I'll do it when I'm free.
2. Make the global variable bool *Animate (or, maybe, char *) and int maxnum. Alloc memory for it by the largest number in config (that will be maxnum), and then set to true (or 1) all the elements which numbers are in list above, and to false (or 0) all another ones.
3. So, is the monster to be animated - is checked easily:
- animate, else - nothing to do.
Of course, it's not the ultimate truth. It's simply how I would do this.
1. Use the configuration in this way: Animated=1,3,5,10... (numbers of monsters which are to be animated in database). This format (if it's followed correctly) is very easy to parse. I can't write it now (limited in time), but if you want, I'll do it when I'm free.
2. Make the global variable bool *Animate (or, maybe, char *) and int maxnum. Alloc memory for it by the largest number in config (that will be maxnum), and then set to true (or 1) all the elements which numbers are in list above, and to false (or 0) all another ones.
3. So, is the monster to be animated - is checked easily:
if ((battler->databaseId>maxnum) && (Animate[battler->databaseId-1]))
Of course, it's not the ultimate truth. It's simply how I would do this.
+++ DynRPG - The RM2k3 Plugin SDK +++
By the way:
author=bulmabriefs144What's the initialiseBattle? It's not documented. Or I simply didn't find it?
Be specific. I have onStartup, initializeBattle, onDrawBattler, onBattlerDrawn, and onFrame.
+++ DynRPG - The RM2k3 Plugin SDK +++
It seems I understand. So, what format would you like to use for ini? Number=1, or Name=1? (To set what monsters are to be animated, I mean) First variant is, I think, a bit easier in programming, second - a bit easier in use (for game makers), but may result in something strange when the national symbols are used. Maybe better would be the first variant.
Another possible format is: Animated=1,3,6,14... (just a list of numbers, which monsters have to be animated) or Unanimated=... (the same list). Possibly it can be read faster - it doesn't make much sense, though, because it's read once and then saved into the boolean array.
As for me, I don't use the atoi, instead written a simple function which (without any checking at the moment) read the number written at the beginning of the std::string (the same may be with standart char*, I did in that way just for less convertations) or leave it unchanged, if string is empty. That's its code:
Is it what you need?
Yes, maybe it's not optimal, but it works :)
By the way, about the national symbols. I'm Russian, so my games use messages in Russian. It seems that they are incorrectly shown in patched games - symbols are printed too close, which hardens reading. Fonts are OK - in unpatched games text is correct. English symbols are correct too. Cherry, may it be the DynRPG issue, or I'm doing something wrong?
Another possible format is: Animated=1,3,6,14... (just a list of numbers, which monsters have to be animated) or Unanimated=... (the same list). Possibly it can be read faster - it doesn't make much sense, though, because it's read once and then saved into the boolean array.
author=bulmabriefs144
Can someone teach me about atoi?
As for me, I don't use the atoi, instead written a simple function which (without any checking at the moment) read the number written at the beginning of the std::string (the same may be with standart char*, I did in that way just for less convertations) or leave it unchanged, if string is empty. That's its code:
bool strtoint (std::string str, int *num) { int i; if (!(str.empty)()) { *num=0; for (i=0; str[i]; i++) (*num)=(*num)*10+(char)(str[i])-'0'; return true; } else return false; }
Is it what you need?
Yes, maybe it's not optimal, but it works :)
By the way, about the national symbols. I'm Russian, so my games use messages in Russian. It seems that they are incorrectly shown in patched games - symbols are printed too close, which hardens reading. Fonts are OK - in unpatched games text is correct. English symbols are correct too. Cherry, may it be the DynRPG issue, or I'm doing something wrong?
+++ DynRPG - The RM2k3 Plugin SDK +++
+++ DynRPG - The RM2k3 Plugin SDK +++
One more strange moment. In documentation you say:
Monster id is zero-based. Actor - seems to be one-based.
bool __cdecl onDrawBattler ( RPG::Battler * battler,
bool isMonster,
int id
)
...
id Zero-based party member ID of the battler
Monster id is zero-based. Actor - seems to be one-based.
+++ DynRPG - The RM2k3 Plugin SDK +++
Interesting fact. If I set the battleSpeed to 0 and then set some actors' atbValue to 300000, the ATB gauge is visually filled, but no actions are performed. If atbValue is 300001 (or, I think, any number above 300000) - action is performed immediately. It seems that internally RPG Maker checks "atbValue>300000", not >=.
+++ DynRPG - The RM2k3 Plugin SDK +++
author=Cherry
It's not relevant for the hero, there is another object "fieldScene" which is not implemented in DynRPG yet (the corresponding internal RPG Maker class is TLcfgFieldScene). X, Y and Map ID are stored in the fieldScene object too, and they are releveant. If you change Map ID there, the hero would be teleported.
If you change the value at RPG::hero, nothing will happen, but I think when you save and load the game, there might be strange effects if the map ID of the hero object and the fieldScene object are not in sync.
Thanks for explayning. It seems that this value is in fact read-only.
+++ DynRPG - The RM2k3 Plugin SDK +++
A small question: Cherry, in the documentation (class Character) you say:
upd: I don't know, is it a bug or my misunderstanding, so I'm asking. In the map event there are Teleport command, which moves hero to the another map. After thet, in onComment callback, I look at the eventId argument and suddenly see that it is 0 - that's not true, of course. It seems that on another map this event looks like common, because it doesn't belong to the map. If that's a bug - can it be fixed, or it's some kind of internal restrictions? If that's my mistake - please tell me, where I'm wrong :)
author=CherryIt's relevant to hero, too. Is it dangerous to look at (not to change) this attribute, or you simply doesn't mention this?
int mapId
Map ID (only relevant for vehicles which are not supported yet)
upd: I don't know, is it a bug or my misunderstanding, so I'm asking. In the map event there are Teleport command, which moves hero to the another map. After thet, in onComment callback, I look at the eventId argument and suddenly see that it is 0 - that's not true, of course. It seems that on another map this event looks like common, because it doesn't belong to the map. If that's a bug - can it be fixed, or it's some kind of internal restrictions? If that's my mistake - please tell me, where I'm wrong :)













