Hack&slash/rpg switchable equipment

Started by lafouine88, Tue 28/11/2023 20:07:08

Previous topic - Next topic

lafouine88

Hey guys!

Like so many before me, I want to push my ags creations a bit further and I am thinking of adding some diablo2-like hack and slash actions in it(why teleport from one place to the other when you can walk killing monsters😅?)

I ve read many things about rpg games but this question still isn t clear so far: how to organize things so that switching equipment can be visible? Meaning that if you equip an axe instead of a sword this shows on screen?

Creating views for every combination is out of the question since that makes the possibilities exponential.

 I found on the rpg topic something about singling out every limb (head,arms etc.) By using different characters using follow(0) the body. I haven t tried it yet since I don t have ags with me at the moment but it seems a bit weird.

Since the conversation was outdated I m mainly looking for an update on this, do you think this is the best option? Any ideas what else could be done?

One last thing, say this is the way, how would you arrange priority for limbs(the arm gets in front of the head...? Maybe there is no priority,just "holes" in the sprites?

Thanks a lot and sorry I ve been a bit long😅

Crimson Wizard

#1
Quote from: lafouine88 on Tue 28/11/2023 20:07:08I found on the rpg topic something about singling out every limb (head,arms etc.) By using different characters using follow(0) the body. I haven t tried it yet since I don t have ags with me at the moment but it seems a bit weird.

This is how it's done normally in ags.

In any way you would need multiple objects sticked together with each object having its own graphics.
Following objects are available in AGS:
- characters, free to move between the rooms, can animate
- objects, can animate, but fixed to a single room,
- room overlays (since 3.6.0), may be created dynamically anytime, but also automatically removed on room change. These are simplistic objects that can have a graphic, but don't have animation, so animating them will require more scripting.

Of all the above character is simpler to put to use. Room overlays are perhaps another alternative, with more scripting.

lafouine88

Hi crimson, thanks for the quick reply
Ok so I didn't know about overlays(still working on 3.5) but i ll check it. I'm definitely more atracted to using characters than objects (unlimited and moveable easily).
Though, if I guess for mere walking the follow instruction could work out with a 0 tikerance and stick to the other parts, I can't figure how you would do for striking actions. Over the top of my head I'm thinking something like :

///on mouse click
Cbody.setview(1);
cbody.animate(0,5,eOnce,eNoBlock);

Chead.setview(2);
chead.animate(0,5,eOnce,eNoBlock);

Crightarm.setview(3);
crightarm.animate(0,5,eOnce,eNoBlock);
....

but that seems very tedious. Especially if I'm gonna repeat that in the repeatedly execute function
-->
if(cbody.animating==false&&cbody.view==1){
cbody.unlockview();
}
if(chead...)
...

Again I understand that ags is not designed for such things so I'm prepared to do a lot of tedious coding for that project, but still, any time I could spare is good to take :)

Thanks

Crimson Wizard

#3
There are always ways to make tedious things less tedious.

1. You can write functions to call them instead of duplicating same code all over the place.
2. You can store similar things in lists called "arrays", and process these in a batch.
3. You can group stuff together in "structs". And make lists (arrays) of structs too.
4. You can declare named constants (enums) to use instead of plain numbers (which are easy to forget or mistype).

For a quick example:

Code: ags
enum BodyParts
{
    eBodyPart_Main = 0,
    eBodyPart_LeftArm = 1,
    eBodyPart_RightArm = 2,
    // etc
    eBodyPart_Count
};

int WalkingViews[eBodyPart_Count];

function SetupWalkingViews()
{
    // assign view numbers for each hero part
    WalkingViews[eBodyPart_Main] = VWALKINGMAIN;
    WalkingViews[eBodyPart_LeftArm ] = VWALKINGLARM;
    WalkingViews[eBodyPart_RightArm ] = VWALKINGRARM;
    // etc
}

Character* WalkingChars[eBodyPart_Count];

function SetupWalkingChars()
{
    // assign characters for each hero part
    WalkingChars[eBodyPart_Main] = cHeroMain;
    WalkingChars[eBodyPart_LeftArm ] = cHeroLeftArm;
    WalkingChars[eBodyPart_RightArm ] = cHeroRightArm;
}

function RunWalkingAnim()
{
    // Run "walking" animation for each Hero part
    for (int i = 0; i < eBodyPart_Count; i++)
    {
       WalkingChars[i].LockView(WalkingViews[i]);
       WalkingChars[i].Animate(HeroDirection /* fantasy variable */, 5, eRepeat, eNoBlock);
    }
}


I am only touching this subject here. But this may be both expanded and optimized further.
Although I would of course suggest experimenting with these concept first, and find ways to simplify things as much as possible before starting an actual game.

Related sections of the manual:
https://adventuregamestudio.github.io/ags-manual/ScriptingTutorialPart2.html
https://adventuregamestudio.github.io/ags-manual/ScriptingLanguage.html

Khris

Instead of using multiple views and characters one can also dynamically compose the necessary view frames.
When the player switches a piece of equipment, you simply run a function that redraws all walk and attack frames.

This way you can use a single view for the walk cycle and another view for the attack animations, just like you would with a regular character.

To create a dynamic view you need to fill up the view with dummy frames, then create a bunch of persistent DynamicSprites and assign them to the ViewFrame.Graphic of each of the view's frames.

lafouine88

Thanks guys.
 I've never used dynamic sprites but I'll definitely take a look at that, it seems very promising. I'll give this topic an update once I've figured out an easy way to use them.
 Otherwise I ll stick to the limb by limb method trying to arrange things as much as possible🙂
As crimson says I m still preparing things before getting into it but I m really excited about this possibility.

Please leave the topic open,I ll add things on it as they arrive, that way maybe we can have a similar topic to the rpg one

Thanks again and See you later👍


Khris

#7
@lafouine88
The code in that thread shows how to do this in general, but you can't really use it as-is for what you are trying to do.

If you have a bunch of equipment, you should use structs to store the type of equipment (like "left arm", "torso") and its sprite indexes.
You basically need to make sure to keep the code that composes the view frames generic enough for you to be able to add new pieces of equipment at any point without having to rewrite it or add to it.

The drawing order is also important; bracers for instance probably require a kind of per-frame z-index, since they can appear in front of or behind the torso even within a single loop.

Drawing order example for a frame of the facing left loop:
1a) right arm
1b) right bracer
2a) character without arms
2b) helmet, armor, pants
3a) left arm
3b) left bracer

For a frame of the front facing loop you might have to switch up the order mid-loop even, since the arms will alternate between being behind or in front of the torso.

This six-layered approach only makes sense if you want to equip different characters. If it's just a single, fixed player character, you can combine a) and b) into a single sprite and use three layers instead, I guess.

lafouine88

Thanks a lot for the advice. I ll try to make things as clean as possible and post again once I ve figured it put. Could be helpful for others

Crimson Wizard

Quote from: Khris on Wed 29/11/2023 02:43:35Instead of using multiple views and characters one can also dynamically compose the necessary view frames.
When the player switches a piece of equipment, you simply run a function that redraws all walk and attack frames.

It depends...
If your game implies quick or often switch of parts, then redrawing all views whenever anything changes may be suboptimal.

SMF spam blocked by CleanTalk