[PLUG-IN] [RM2K3] ANIMATED MONSTERS PLUGIN

Posts

dragonheartman
Developer, Starless Umbra / Heroes of Umbra
2966
I wanted to share with you a plugin I’ve been working on with Cherry’s DynRPG. This plugin enables some basic animations--idle, hurt, and dead--for the monsters in the default battle system, as demonstrated in this video:


(note, this video is old so it doesn't include the hurt and dead animations. You can get Starless Umbra if you want to see it in-game.)

Installation Instructions

To use the plugin, first patch your project with DynRPG.

After that, download my plugin and put it in your DynPlugins folder.

Lastly, you need to do a bit of prep work for the animations to work. The plugin expects six images per monster:

1.png – Idle frame 1
2.png – Idle frame 2
3.png – Idle frame 3 (note: idle animations follow a 1-2-3-2 pattern)
4.png – Dead
5.png – Hurt frame 1
6.png – Hurt frame 2

These images need to be in a subfolder within your monsters directory. So, you should have something like this for a monster’s death pose:

\Monsters\<Monster Name>\4.png

<Monster Name> is simply the name you gave the monster in the database.

Thanks!

In the future I might have configurable animations, or something else I haven’t thought of yet. Let me know what you think.

EDIT: This might crash for back attacks/pincer attacks. I never really got around to completely testing this but it has the dhm seal of approval™ nonetheless.
yesyesyesyesyes thank you so much! I'm going to try it out right now.

Thanks a ton :D
dragonheartman
Developer, Starless Umbra / Heroes of Umbra
2966
Not a problem. You are free to modify/study/make fun of my code too.

https://www.dropbox.com/s/si7cfu0imsjm3yy/animated_monsters.cpp
Craze
why would i heal when i could equip a morningstar
15150
I like how you've played with the battle status window. Must be nice to have all that control. =3 (Especially since SU has been pretty intensely customized even when it was... DRAGON HEART or something terrible like that.)
dragonheartman
Developer, Starless Umbra / Heroes of Umbra
2966
author=Craze
I like how you've played with the battle status window. Must be nice to have all that control. =3 (Especially since SU has been pretty intensely customized even when it was... DRAGON HEART or something terrible like that.)

Oh we don't use the D-word around here. :)

I was half expecting "stop using 2k3" replies, so I appreciate the positive feedback.
This is awesome! Thanks a lot for sharing, dhm! =) ...But all this really means for me is more graphics to rip and edit. Oh noes! =(

(Also, should this really be on the Game development forum? xD)
Nice work, DHM! Finally got it out, eh? :D
Wonderful Dragonheartman! I like it so much that my hand itches, and wants to add it and make monster animations (oh damn! now I need to sprite 6 times each monster! -I'll leave it for a latter version >=D-).

It's a lot of work, but I don't care! Uwahahah ahahah,
Orochii Zouveleki
Nice, you have to try if its possible make a speed system like in rpg maker xp,
(work with up speed, up speed, down speed for events and charas give a lot of headache) but maybe its possible make with events too.

edit: lol I made a engine of that with events
#define MAX_MONSTERS 8


This line looks suspicous... Couldn't you use a configuration and a dynamic array instead?

Apart from that: GREAT, thank you!!

(I will add it to the plugin directory after the MAX_MONSTERS thing is clarified...)

EDIT:

Oh, I think there is another problem... You are creating a memory leak because you don't free the images. I can also explain the access violations to you.

The RPG Maker doesn't know that you are playing around with the monster image. So it thinks the image which is in the RPG::Monster::image member belongs to the RPG Maker, and it frees it after battle (or when a monster is transformed!!!)

So my suggestion would be: Store the old image pointer and the RPG::Battler pointer of the last monster which you modifie d somewhere. Then, change the image pointer at onDrawBattler, and change it back at the next onDrawBattler (of the next monster) and/or onFrame. Then, a simple RPG::Image* array would be enough, where you have NULL for "not yet loaded".
@Cherry, not to threadjack, but where is this plugin directory located?
dragonheartman
Developer, Starless Umbra / Heroes of Umbra
2966
author=Cherry
#define MAX_MONSTERS 8
This line looks suspicous... Couldn't you use a configuration and a dynamic array instead?

Apart from that: GREAT, thank you!!

(I will add it to the plugin directory after the MAX_MONSTERS thing is clarified...)

EDIT:

Oh, I think there is another problem... You are creating a memory leak because you don't free the images. I can also explain the access violations to you.

The RPG Maker doesn't know that you are playing around with the monster image. So it thinks the image which is in the RPG::Monster::image member belongs to the RPG Maker, and it frees it after battle (or when a monster is transformed!!!)

So my suggestion would be: Store the old image pointer and the RPG::Battler pointer of the last monster which you modifie d somewhere. Then, change the image pointer at onDrawBattler, and change it back at the next onDrawBattler (of the next monster) and/or onFrame. Then, a simple RPG::Image* array would be enough, where you have NULL for "not yet loaded".

Cherry, that is the max number of monsters that you can have in a battle. (I thought was eight?) I know there is a way to get the length of the enemy party array, but I couldn't figure out the syntax. :<

Your explanation makes some sense... so you save the "original" monster image pointer before you overwrite it with a new image and then set the monster image back to the original pointer AFTER the frame has been drawn (onBattlerDrawn())?

Or am I misunderstanding? Pseudo-code would be really helpful. I had a feeling there was a memory leak here but as mentioned in the code I kept getting access violations (which are segfaults correct?)

Thanks for your feedback.
Oh, sorry, my bad...

Firstly, I misunderstood MAX_MONSTERS... I thought you were caching the monster images for each monster in the database, not for each monster in battle, so I thought monsters with an ID > 8 couldn't be used. So, forget my objection ^^

Secondly, I actually forgot that onBattlerDrawn exists, so forget what I said about "next onDrawBattler and/or onFrame" - onBattlerDrawn will do the job just fine.

You still understood my thoughts correctly...

Let me explain what happens at your current version:

The RPG Maker loads the original image. You load 6 other images.
Then, you overwrite the monster's image pointer with one of yours.
At then end, the RPG Maker frees the monster's image - which is now one of yours!
So, the effect is that the original image leaked (it never gets freed), and one of your images was freed by the RPG Maker, but 5 are still loaded. If you would now try to free all your 6 images, the one which was unloaded by the RPG Maker would cause an Access Violation (segfault, yes) when you try to free it, because it was already freed! However, you currently don't free any images at all, so you are leaking the original image plus 5 of yours.

To solve that problem, my suggestion is changing the image pointer in onDrawBattler while saving the old pointer, and changing it back in onBattlerDrawn. As far as I know, the RPG Maker never frees the image between these two callbacks, so at the end, the RPG Maker will always free its own image, and you should free your 6 images after battle.

Also please take into account that monsters could have the ability to transform, so you better save the monster ID too, and if it changed after a frame, unload the old images and load the new ones.

By the way, I remember that somebody suggested changing color during fading in the other thread - this would be possible using the colorControl1 and/or colorControl2 members of the image. You have to call the applyPalette method after changing the color parameters, though.

Best regards,
Cherry

EDIT: For attack poses, you could move the monster using the x and y members of the RPG::Battler, and update the screen using RPG::Screen::update while moving (so that the battle won't continue before you are finished moving)... However keep in mind that the onDrawBattler/onBattlerDrawn handler will be called again during RPG::Screen::update!

EDIT2: To avoid confusion: When I talked about "freeing an image", I actually meant using RPG::Image::destroy(image), not image->free() which only frees the image's pixel data, not the whole RPG::Image structure.

EDIT3: The RPG::Image::destroy function automatically sets the pointer to NULL after destroying the image... however if you assign the image pointer to the "image" member of the RPG::Monster, you have two copies of that pointer, so that even though the RPG Maker also sets the pointer to NULL when it destroys the image, you weren't able to find that out before.

EDIT4: Oh, I found another mistake of yours, which might also cause bugs or crashes: for(int i=0; i<9; i++) << this loops from 0 to 8 (including), although I assume you want to loop from 0 to MAX_MONSTERS-1. Currently you are accessing the index 8 which doesn't exist and which thus causes memory corruption.
dragonheartman
Developer, Starless Umbra / Heroes of Umbra
2966
It seems I have a lot of changes I'd like to do before you put this plugin in your directory. :)

Your explanation makes sense. I was under the impression it was leaking, but my implementation was the only one I could get that "worked" for more than one battle without the access violations.

Thanks for taking the time to look through the code too.
iddalai
RPG Maker 2k/2k3 for life, baby!!
1194
I'm just here to congratulate dragonheartman on the first release of this plugin. I know your still gonna change it a bit (according to the above posts), but congratulations are still in order!

And thanks for DynRpg cherry!

Keep on making this stuff guys, we appreciate it.
Nightowl
Remember when I actually used to make games? Me neither.
1577
Looks fairly cool, it would be even more awesome if there could be frames for attacking and using a skill.
Nightowl - There are already ways to "fake" animated enemy skills and attacks, it just takes work.

Short version: Use battle events for targeting, set the enemy sprite to a transparent/blank one, run the desired animation through a battle event, restore the enemy sprite when you're done.

An example:



If you combined those tricks with the plugin's ability to display idle and injured frames, things would start looking downright good in a hurry.

Note-You can also split one animation up into multiple shorter animations and use their delay to test for timed button presses, as I did to allow the player to block the enemy attacks. This means that with a little planning, you can easily fake a Judgment Ring type setup right inside of the DBS!
Loving the plug-in! Here's hoping the alterations are made to get Cherry's seal of approval man! Definitely going to have to put this to good use! If this is ever joined by a large charasets plug-in for 2k3 I'll be a very happy man.