Jump to content
Eternal Lands Official Forums
Torg

Emotions

Recommended Posts

I think the idea of queuing the emotes until the actor gets in idle state is good. Instead of using a timeout of 1 sec which is generally low for big lags

Yeah, that's fair.

 

you can maybe also decide if you have to queue an emote by testing the last action in the queue of the concerned actor. This way, you can see if the actor is fighting, moving or something else...

Yeah, that's fair. I guess we can determine how necessary that is when I get closer to implementing it.

 

BTW, if only arms are going to move, we can also maybe authorize the emotes when an actor is walking?

That's what I was thinking. I think it would depend on the emote. If it is something like a wave of the hand, then it could occur while walking. This naturally would depend on how possible it is to merge animations and how they would interact with each other, which would take a bunch of testing.

Share this post


Link to post
Share on other sites
head_draegonimblue_blink.gif

1.bmp.jpg

2.bmp.jpg

3.bmp.jpg

Thanks to kirianthis for the blending and creation of the gif animation.

 

As for the coding side, adding this is trivial and would require no server support.

 

I find that the blinking is to fast- not a long enough pause, i blink once every 5+sec, i counted this is 3-sec,

Just my opinion- a longer pause would make it more natural. :P

Share this post


Link to post
Share on other sites

it is just a gif animation on that to show that the blinking looks fairly realistic. Coding it to work ingame would be random time based rather than every x seconds.

Share this post


Link to post
Share on other sites

I have just committed to cvs the initial batch of work for this under the define EMOTES.

 

It requires the additional emotes.xml file which is to be placed in the root of the data directory. It can be found here: http://el.grug.redirectme.net/emotes.xml

 

The actor defs files will need to be updated (probably player_frames.xml) and additional animations provided, however for anyone wishing to test this, I can provide an adjusted player_frames.xml which links to existing animations.

 

Currently the format for emotes is *name_of_emote* where name_of_emote must not contain any spaces. This of course could be changed according to Roja's wishes. This will be detected at any point in a sentence said in local so you can string multiple emotes together (to play one after the other).

 

I have added support for the emotes mentioned here in this thread (including LV's "bow") with the additional feature that emotes can be specified to work with a specific actor type, or all actors. This opens up the possibility of some minor race specialisation.

E.g. An emote could be configured for Gnomes to rub their bellies or some such thing.

Edited by Torg

Share this post


Link to post
Share on other sites
Could I get a *yum* emote added where I grab the nearest Gnome, roast, and eat it?

Hehehe, I was going to ask Roja for that one myself. ;-)

Share this post


Link to post
Share on other sites
Could I get a *yum* emote added where I grab the nearest Gnome, roast, and eat it?

Hehehe, I was going to ask Roja for that one myself. ;-)

 

Objection!

Share this post


Link to post
Share on other sites

Back to this thread again...

 

I have now run out of time and gone overseas so I won't be able to complete this code (which is a great shame). If anyone else has the chance, it would be great to see this in-game.

 

Most of the code is written, with the only parts remaining being:

1. Using the hand waving/nodding/etc animations for both sitting and standing positions. This requires either merging 2 animations or only animating part of the skeleton. Apparently it is possible with Cal3D, but I was not able to find out how (and there is almost no documentation).

 

2. Removing the animations from the queue if they have not played within a timeout period (2 seconds?).

 

3. Extending the definition code to support properties for the animations. Eg: Position => Standing/Sitting/Both, which can then have a check in the code to only play that animation based on that property being correct.

Share this post


Link to post
Share on other sites

I have hopefully completed the work on emotes.

- here is the patch (with console debug msgs)

- here are the xml files

- here are the animations

 

patch and compile the client, uncompress xml.tgz and emotes.tgz in the root dir (beware, player_frames.xml is overwritten!) and test it :)

 

The rest of this long post is for programming details, skip as needed.

 

How emotes work

 

- Emotes are triggered when some text is typed in local. The text is specified inside a <command> tag in emotes.xml where all emotes are defined. An emote can have more than one triggering command. I removed the *emote* syntax to make it more flexible...you can always add the * in the xml.

- Once triggered, emotes wait in a queue until they can be processed or until they expire (2 sec timeout). Conditions that can be specified are:

* sex: played only if actor is of a certain sex

* race: played only if actor is of a certain race

* held: played only if actor is riding

* barehanded: played only if actor has left, right, or both hands free

* current idle position: sitting, walking, running, standing. Test for current position is done

by looking at the current animation frame.

(more details in emotes.xml)

 

- A emote is made of a bone animation and/or of a facial expression (for future expansion). Basically a emote is made of two animations played simultaneously.

- Animations files for emotes are under animations/emotes and are generated using calstripper (more later)

- There is a #emotes command to display available emotes

 

 

How cal3d works

There is little documentation for this library on how to blend animations, so here it is what I learnt:

 

- cal3d animations can be Cycles or Actions and they are blended together in the CalMixer

- Cycles have a wight of 0, Actions of 1 so if an action is in the mixer the cycle is not played

- animations are lists of traslations and rotations associated to bones. If a bone is not defined in an Action it gets the traslations and rotations of the Cycle.

- once an Action is ended it must be removed from the CalMixer because the last keyframes are still used (the actor remains still on the position defined by them)

- For these reasons emotes are not stored in the actor.cur_anim and also can't be played while ranging or fighiting. Indeed the idle ranging and idle fighting anims are Actions, not Cycles.

- Actions can be blended together, but the result is weird. Maybe there is a way to set the relative weights but I didn't find anything about.

 

How calstripper works

Blender has an incorrect cal3d exporter. Indeed, even if a bone is not moving, keyframes are created for it. This makes impossible to export a "local" animation, i.e. an Action that can be blended with a Cycle.

I coded a little program, calstripper (.exe and code inside), that takes:

- a source animation (emote exported by blender)

- a dest animation (our localized emote)

- the skeleton file used by the animation (medium.csf for players)

- an optional blending animation (b_anim)

 

Then, for each bone in source, it asks if the bone should be placed in dest. For convenience it displays if the bone is moving or not.

If the optional blending animation is given, you can also Blend or Force bones:

- When you blend a bone, you basically take the b_anim corresponding bone and add to it the difference between each keyframe of the source. This is useful to generate, as an example, the wave_sit emote animation. Indeed *wave* is exported with the bones in standing position. Even if unmoving bones are removed the "back2" bone (which is used to move the torso slightly to the right) is still in a wrong position (not rotated toward the front). By blending it with player_sit_idle.caf as b_anim, it is moved to the front (as while sitting) but the rotations to the right are preserved.

- When you force a bone, you set the first and last keyframes to the ones of the b_anim corresponding bone. This is useful to generate wave_sit once again. Indeed the arm bones start from the standing position, go up and down again. If you sit and wave, your arm goes underground. By forcing the arm to the player_sit_idle.caf starting position, this issue is solved.

 

 

Should be all, please test and report bugs :P

 

wave.jpg

Edited by Fedora

Share this post


Link to post
Share on other sites

Wow, that's a lot of work and a nice explanation! I've tried to apply the patch to a clean CVS but text.c fails badly. I don't have time to take a closer look tonight but if there was something simple you could do to fix it.....

Share this post


Link to post
Share on other sites

I've commited the changes to CVS. I've also including the data files which I have placed in a temporary CVS directory tmp_1_8_0; the intention here is to remove them when the final files are released with a client update. The contents of that directory tree can simply be copied/linked into the client update/1_8_0 directory "~/.elc/updates/1_8_0/" on Linux.

 

For now I have left the EMOTES #def unset and have kept the debug printf().

Share this post


Link to post
Share on other sites

I get these errors when trying to compile, any ideas?

 

gl_init.c: In function `setup_video_mode':
gl_init.c:127: warning: implicit declaration of function `MonitorFromWindow'
gl_init.c:127: error: `MONITOR_DEFAULTTOPRIMARY' undeclared (first use in this function)
gl_init.c:127: error: (Each undeclared identifier is reported only once
gl_init.c:127: error: for each function it appears in.)
gl_init.c:127: warning: assignment makes pointer from integer without a cast

make.exe: *** [gl_init.o] Error 1

Share this post


Link to post
Share on other sites
I get these errors when trying to compile, any ideas?

 

gl_init.c: In function `setup_video_mode':
gl_init.c:127: warning: implicit declaration of function `MonitorFromWindow'
gl_init.c:127: error: `MONITOR_DEFAULTTOPRIMARY' undeclared (first use in this function)
gl_init.c:127: error: (Each undeclared identifier is reported only once
gl_init.c:127: error: for each function it appears in.)
gl_init.c:127: warning: assignment makes pointer from integer without a cast

make.exe: *** [gl_init.o] Error 1

I did quickly test building on windows and it was fine (most testing done on Linux). gl_init.c has not changed for months so I'm not sure what the problem is. That function MonitorFromWindow is defined by including windows.h, I expect I'm getting it indirectly but you could try adding "#include <windows.h>" in the top part of gl_init.c to see if that fixes it.

Share this post


Link to post
Share on other sites

While we are testing emotes I'd like to suggest some enhancements.

 

First, the barehanded test needs to be modified to take into account quivers and gloves which are not considered as barehanded atm. I'll do it soon.

 

Second, the test to check if the current emote can be played assumes that an actor can change sex and/or race (via shapeshifting) and waits 2 secs before being removed. If the sex/race change feature is not planned in the shapeshifting, I will rewrite the test to avoid losing time for not playable emotes.

 

Third, I noticed the client already has server commands for some actions not yet linked to animations (from client_serv.h):

pick = 6,

drop = 7,

harvest = 9,

cast = 10,

 

Apart from harvest (problems with resources, harvest area, orientation and so on), all the others can be easily and naturally implemented as emotes (using the emotes code triggered by a server command instead of a local chat string). If you want such animations playable I can easily change the code to handle server commands. Another animation which is not there but can be handled as an emote, is the summon one (yeah, I'm biased :P ), simply by reading local chat for the corresponding text.

Edited by Fedora

Share this post


Link to post
Share on other sites

I tried adding that line, still I get the same error. Is windows.h a file that should be added to the project? If so where do I find the file?

Share this post


Link to post
Share on other sites
I get these errors when trying to compile, any ideas?

 

gl_init.c: In function `setup_video_mode':
gl_init.c:127: warning: implicit declaration of function `MonitorFromWindow'
gl_init.c:127: error: `MONITOR_DEFAULTTOPRIMARY' undeclared (first use in this function)
gl_init.c:127: error: (Each undeclared identifier is reported only once
gl_init.c:127: error: for each function it appears in.)
gl_init.c:127: warning: assignment makes pointer from integer without a cast

make.exe: *** [gl_init.o] Error 1

 

As pointed out this has been in CVS for quite some time, actually since over a year. The monitor API is only available when -DWINVER=0x500 is defined and maybe the installed Windows header files are to old to include the monitor API

Share this post


Link to post
Share on other sites

Sorry I'm not a programmer so all this stuff is over my head. Well I have no clue what to do..and I can't test this stuff until I can compile the thing :P

Share this post


Link to post
Share on other sites
I get these errors when trying to compile, any ideas?

 

gl_init.c: In function `setup_video_mode':
gl_init.c:127: warning: implicit declaration of function `MonitorFromWindow'
gl_init.c:127: error: `MONITOR_DEFAULTTOPRIMARY' undeclared (first use in this function)
gl_init.c:127: error: (Each undeclared identifier is reported only once
gl_init.c:127: error: for each function it appears in.)
gl_init.c:127: warning: assignment makes pointer from integer without a cast

make.exe: *** [gl_init.o] Error 1

 

As pointed out this has been in CVS for quite some time, actually since over a year. The monitor API is only available when -DWINVER=0x500 is defined and maybe the installed Windows header files are to old to include the monitor API

Then the code needs to be enhanced so that it can still compile when the monitor API is not evailable.

Share this post


Link to post
Share on other sites
Then the code needs to be enhanced so that it can still compile when the monitor API is not evailable.

 

That API is part of Windows since at least Windows 98

 

Anyway, they are defined in winuser.h from the w32api package for Dev-Cpp. I have version 3.2 which includes all the definitions.

The version can be checked in packages\w32api.entry in the Dev-Cpp folder.

 

Can you please post the command that compiles gl_init.c? I get this with WINVER defined correctly

 

gcc -march=i686 -Wall -Wdeclaration-after-statement -O2 -fomit-frame-pointer -ffast-math -pipe -mwindows -DWINDOWS -DELC -DWINVER=0x500 -DATTACHED_ACTORS -DCLUSTER_INSIDES -DCONTEXT_MENUS -DCUSTOM_LOOK -DCUSTOM_UPDATE -DFUZZY_PATHS -DMINIMAP2 -DNEW_CAMERA_MOTION -DNEW_SELECTION -DNEW_SOUND -DNEW_TEX -DNEW_WEATHER -DPNG_SCREENSHOT -DSKY_FPV -DTEXT_ALIASES -DUSE_INLINE -DUSE_SHADER -DVARIABLE_SPEED -DZLIB -DUSER_MENUS -DSIMPLE_LOD -DECDEBUGWIN -DEMOTES -fno-strict-aliasing -I../../Dev-Cpp/Include/AL -I../../Dev-Cpp/Include/SDL -c -o gl_init.o gl_init.c

Share this post


Link to post
Share on other sites
Then the code needs to be enhanced so that it can still compile when the monitor API is not evailable.

 

That API is part of Windows since at least Windows 98

 

Anyway, they are defined in winuser.h from the w32api package for Dev-Cpp. I have version 3.2 which includes all the definitions.

The version can be checked in packages\w32api.entry in the Dev-Cpp folder.

 

Can you please post the command that compiles gl_init.c? I get this with WINVER defined correctly

 

gcc -march=i686 -Wall -Wdeclaration-after-statement -O2 -fomit-frame-pointer -ffast-math -pipe -mwindows -DWINDOWS -DELC -DWINVER=0x500 -DATTACHED_ACTORS -DCLUSTER_INSIDES -DCONTEXT_MENUS -DCUSTOM_LOOK -DCUSTOM_UPDATE -DFUZZY_PATHS -DMINIMAP2 -DNEW_CAMERA_MOTION -DNEW_SELECTION -DNEW_SOUND -DNEW_TEX -DNEW_WEATHER -DPNG_SCREENSHOT -DSKY_FPV -DTEXT_ALIASES -DUSE_INLINE -DUSE_SHADER -DVARIABLE_SPEED -DZLIB -DUSER_MENUS -DSIMPLE_LOD -DECDEBUGWIN -DEMOTES -fno-strict-aliasing -I../../Dev-Cpp/Include/AL -I../../Dev-Cpp/Include/SDL -c -o gl_init.o gl_init.c

You should NEVER include a windows API in any project! Not even as a work around.

 

My point is that the compiling needs to be bullet proof. It's obvious that at least one critical person doesn't have it.

Share this post


Link to post
Share on other sites

Ok, this it?

 

gcc -march=i686 -Wall -Wdeclaration-after-statement -O0 -ggdb -pipe -DWINDOWS -DELC -mwindows -DATTACHED_ACTORS -DCLUSTER_INSIDES -DCONTEXT_MENUS -DCUSTOM_LOOK -DCUSTOM_UPDATE -DFUZZY_PATHS -DMINIMAP2 -DNEW_CAMERA_MOTION -DNEW_SELECTION -DNEW_SOUND -DNEW_TEX -DNEW_WEATHER -DPNG_SCREENSHOT -DSKY_FPV -DTEXT_ALIASES -DUSE_INLINE -DUSE_SHADER -DVARIABLE_SPEED -DZLIB -DUSER_MENUS -DBANDWIDTH_SAVINGS -fno-strict-aliasing -IC:\\Dev-Cpp\\Include\\AL -IC:\\Dev-Cpp\\Include\\SDL -c -o gl_init.o gl_init.c

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×