Author Topic: [solved] How do I tint a character portrait?  (Read 409 times)

[solved] How do I tint a character portrait?
« on: 01 Jun 2018, 15:05 »
I need to tint a character portrait - single frame speech view, and no limp sync and no blinking.

I have thought about, but I am not sure how to do it. :(
« Last Edit: 01 Jun 2018, 21:24 by eri0o »

Crimson Wizard

  • AGS Project Tracker Admins
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    •  
    • Lifetime Achievement Award Winner
    •  
    • Crimson Wizard worked on a game that was nominated for an AGS Award!
      Crimson Wizard worked on a game that won an AGS Award!
Re: How do I tint a character portrait?
« Reply #1 on: 01 Jun 2018, 15:19 »
Clone portrait into dynamic sprite, then DynamicSprite.Tint, then set ViewFrame.Graphic to one of dynamic sprite.

Re: How do I tint a character portrait?
« Reply #2 on: 01 Jun 2018, 15:54 »
So something like below?

Code: Adventure Game Studio
  1. int originalGraphic;
  2. DynamicSprite * dyn_spr;
  3.  
  4. void tintPortrait(Character * chr, int r, int g, int b, int s,  int l){
  5.   ViewFrame * chr_vf = Game.GetViewFrame(chr.SpeechView, 0, 0);
  6.   originalGraphic = chr_vf.Graphic;
  7.   dyn_spr = DynamicSprite.CreateFromExistingSprite(originalGraphic, true);
  8.   dyn_spr.Tint(r, g, b, s, l);
  9.   chr_vf.Graphic = dyn_spr.Graphic;
  10. }
  11.  
  12. void untintPortrait(Character * chr){
  13.   ViewFrame * chr_vf = Game.GetViewFrame(chr.SpeechView, 0, 0);
  14.  
  15.   chr_vf.Graphic = originalGraphic;
  16.   dyn_spr.Delete();
  17. }
  18.  

But now I need to track the original graphic since tint is definitive and clean the dyn_spr before exiting game to avoid warning logs. But since it's only at some very isolated points, it will be ok.
« Last Edit: 01 Jun 2018, 19:16 by eri0o »

Crimson Wizard

  • AGS Project Tracker Admins
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    •  
    • Lifetime Achievement Award Winner
    •  
    • Crimson Wizard worked on a game that was nominated for an AGS Award!
      Crimson Wizard worked on a game that won an AGS Award!
Re: How do I tint a character portrait?
« Reply #3 on: 01 Jun 2018, 16:20 »
But now I need to track the original graphic since tint is definitive and clean the dyn_spr before exiting game to avoid warning logs.

warning.log is only created in Debug build, that's notification for developer only.
There is no 100% guaranteed way to clean dynamic sprites  on exit as far as I know, because user may hit alt+X or click on the close window button, which cannot be detected in script.

Re: How do I tint a character portrait?
« Reply #4 on: 01 Jun 2018, 16:42 »
Ah ok, since it's only on Debug build it's alright :]

Re: How do I tint a character portrait?
« Reply #5 on: 01 Jun 2018, 19:28 »
Add spoiler tag for Hidden:
Code: Adventure Game Studio
  1. int originalGraphic;
  2. DynamicSprite * dyn_spr;
  3.  
  4. void tintPortrait(Character * chr, int r, int g, int b, int s,  int l){
  5.   ViewFrame * chr_vf = Game.GetViewFrame(chr.SpeechView, 0, 0);
  6.   if(originalGraphic==0){
  7.     originalGraphic = chr_vf.Graphic;
  8.   }
  9.   dyn_spr = DynamicSprite.CreateFromExistingSprite(originalGraphic, true);
  10.   dyn_spr.Tint(r, g, b, s, l);
  11.   chr_vf.Graphic = dyn_spr.Graphic;
  12. }
  13.  
  14. void untintPortrait(Character * chr){
  15.   ViewFrame * chr_vf = Game.GetViewFrame(chr.SpeechView, 0, 0);
  16.  
  17.   chr_vf.Graphic = originalGraphic;
  18.   dyn_spr.Delete();
  19. }
  20.  
  21. void repeatedly_execute_always(){
  22.   if(player.Speaking) tintPortrait(player, Random(255), Random(255), Random(255), 50, 100);  
  23. }
  24.  

Of course, let me try to add repeatedly_execute_always to the mix. I have a problem that it doesn't work, the graphics for the portrait is updated in a different rate then the rest of the screen, and after 3 seconds it doesn't update anymore.

I created a minimum game to reproduce this bug, download it here. :X

Crimson Wizard

  • AGS Project Tracker Admins
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    •  
    • Lifetime Achievement Award Winner
    •  
    • Crimson Wizard worked on a game that was nominated for an AGS Award!
      Crimson Wizard worked on a game that won an AGS Award!
Re: How do I tint a character portrait?
« Reply #6 on: 01 Jun 2018, 19:35 »
Did you check if player.Speaking is still true when it stops updating?
It looks like it returns false when speech is waiting for the skip key.

Re: How do I tint a character portrait?
« Reply #7 on: 01 Jun 2018, 19:39 »
I removed the if player.Speaking and the same thing happens...

Crimson Wizard

  • AGS Project Tracker Admins
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    •  
    • Lifetime Achievement Award Winner
    •  
    • Crimson Wizard worked on a game that was nominated for an AGS Award!
      Crimson Wizard worked on a game that won an AGS Award!
Re: How do I tint a character portrait?
« Reply #8 on: 01 Jun 2018, 20:26 »
You are modifying frames in SpeechView, but these frames need to be copied into portrait overlay by AGS.
It might simply be that AGS does not update the portrait overlay after speech waiting time has finished. That will also explain why it updates not every frame.

E: I found you may hack this by setting game.messagetime to something greater than 1, but if you do that, it also stops skipping speech by time.
« Last Edit: 01 Jun 2018, 20:41 by Crimson Wizard »

Re: How do I tint a character portrait?
« Reply #9 on: 01 Jun 2018, 20:46 »
I only skip on Mouse click, so no problem not skipping with Timer... But... I placed game.messagetime = 65535 on game_start at the global script and it didn't work. :/

Edit: If the message is longer, this time is indeed longer, and if the message is short, this time is shorter... So updating it indeed has something to do with speaking the text...
« Last Edit: 01 Jun 2018, 20:59 by eri0o »

Crimson Wizard

  • AGS Project Tracker Admins
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    •  
    • Lifetime Achievement Award Winner
    •  
    • Crimson Wizard worked on a game that was nominated for an AGS Award!
      Crimson Wizard worked on a game that won an AGS Award!
Re: How do I tint a character portrait?
« Reply #10 on: 01 Jun 2018, 21:18 »
I only skip on Mouse click, so no problem not skipping with Timer... But... I placed game.messagetime = 65535 on game_start at the global script and it didn't work. :/

Ok, I was not clear enough.
game.messagetime is a dynamically changed value. You need to keep setting it in rep_exec. I set it to 2, and it updates tint very fast.

Code: Adventure Game Studio
  1. void repeatedly_execute_always(){
  2.   if(player.Speaking)
  3.   {
  4.       tintPortrait(player, Random(255), Random(255), Random(255), 50, 100);  
  5.       game.messagetime = 2;
  6.   }
  7. }
  8.  

I think messagetime is related to how fast speech is animated and portrait updated.
Therefore you may choose different values to control the speed of tinting.
« Last Edit: 01 Jun 2018, 21:22 by Crimson Wizard »

Re: How do I tint a character portrait?
« Reply #11 on: 01 Jun 2018, 21:23 »
whoa! That's magic! Damn! It worked! :-D

Thank you! This is amazing! (laugh)