Page 2 of 3

Re: +weapon.alwaysbob

PostPosted: Wed Dec 28, 2016 11:17 am
by Major Cooke
The main point of what Graf suggested is, you can further break it open to do what you like. Such as using the player Tick virtual to perform some sort of bobbing, not using the internal version. That or use an overlay on the weapon which measure's the player's speed and letting the overlay do some sin/cos. Brush up on your trig skills, because rather than cater to one specific need, Graf opened up a realm of possibilities with zscript.

Although, you could use the OverlayX/Y functions in Decorate if you want to stick to that. But you won't have access to things like weapon/player vars.

Re: +weapon.alwaysbob

PostPosted: Wed Dec 28, 2016 11:26 am
by Caligari87
Just a brief DECORATE sidebar: Can the Ready state be used as an invisible constant bobbing loop, with bob-following overlays for the visual functionality, while Fire/Reload/Etc jump the main weapon logic back to Ready where flags and fallthroughs are used to allow/disallow those functions until the overlays finish? Logically that seems workable for an always-bobbing weapon if you're not moving to ZScript yet.

8-)

Re: +weapon.alwaysbob

PostPosted: Wed Dec 28, 2016 12:29 pm
by Major Cooke
Check out D4D's super shotgun. Only thing is, I had to do it a little differently. The firing mechanism is actually an overlay that uses GetPlayerInput instead.

You don't want to be mixing and matching fire states with overlay created states because that can quickly get out of control.

In this situation of DJ2K's, his best bet would be to have an overlay which just does the manual offsetting via measuring velocity rather than what happens below. Don't go mixing and matching simpler things with more complex ideas unless you want to risk tying your fingers in knots.

Code: Select allExpand view
   Ready:
      M666 A 0
      {
         A_Overlay(SwitchWatcher,"SwitchWatcher",true);
         if (CountInv("SSGUpgrade4"))
         {   
            A_Overlay(RGun,"SSR.Ready",true);
            A_Overlay(LGun,"SSL.Ready",true);
            A_Overlay(GunWatcher,"SSG.Listen");
            return ResolveState("ReadyLoop");
         }
         return ResolveState(1);
      }
      DW4A A 0;
      Goto ReadyLoop;
   ReadyLoop:
      "----" A 1
      {
         if (!CountInv("SSGUpgrade4"))
         {   A_WeaponReady((!CountInv("BusyToken")) ? WRF_NOSECONDARY|WRF_ALLOWRELOAD|WRF_ALLOWUSER2 : WRF_NOSWITCH);   }
         else
         {   
            // Follow the weapon.
            A_OverlayFlags(LGun,WeapMove,true);
            A_OverlayFlags(RGun,WeapMove,true);
            A_Overlay(GunWatcher,"SSG.Listen",true);
            if (CountInv("SSLSecondShotToken") > 1 && CountInv("SSRSecondShotToken") > 1)
            {   // Both are reloading.
               A_OverlayFlags(LGun,WeapBob,false);
               A_OverlayFlags(RGun,WeapBob,false);   
               A_WeaponReady(WRF_NOFIRE);
            }
            else if (CountInv("SSLSecondShotToken") > 1)
            {   // Left is reloading. Right is ready.
               A_OverlayFlags(LGun,WeapBob,false);
               A_OverlayFlags(RGun,WeapBob,true);
               A_WeaponReady(WRF_NOFIRE);
            }
            else if (CountInv("SSRSecondShotToken") > 1)
            {   // Right is reloading. Left is ready.
               A_OverlayFlags(LGun,WeapBob,true);
               A_OverlayFlags(RGun,WeapBob,false);
               A_WeaponReady(WRF_NOFIRE);
            }
            else
            {   // Both are ready.
               A_OverlayFlags(LGun,WeapBob,true);
               A_OverlayFlags(RGun,WeapBob,true);
               A_WeaponReady((!CountInv("BusyToken")) ? WRF_NOFIRE|WRF_ALLOWRELOAD|WRF_ALLOWUSER2 : WRF_NOFIRE|WRF_NOSWITCH);
            }
         }
         return ResolveState(null);
      }
      Goto Ready;


What I used for 'listening':

Code: Select allExpand view
   SSG.Listen:
      M666 A 1
      {
         // Have ammo?
         if (!A_JumpIfNoAmmo("Null") && !CountInv("BusyToken"))
         {
            // Primary shoots left
            if ((CountInv("SSLSecondShotToken") < 2) &&
               (GetPlayerInput(MODINPUT_BUTTONS) & BT_ATTACK) &&
               !(GetPlayerInput(MODINPUT_OLDBUTTONS) & BT_ATTACK))
            {   A_Overlay(LGun,"SSL.Fire");   }
            
            // Secondary shoots right
            if ((CountInv("SSRSecondShotToken") < 2) &&
               (GetPlayerInput(MODINPUT_BUTTONS) & BT_ALTATTACK) &&
               !(GetPlayerInput(MODINPUT_OLDBUTTONS) & BT_ALTATTACK))
            {   A_Overlay(RGun,"SSR.Fire");   }
         }
      }
      Loop;

Re: +weapon.alwaysbob

PostPosted: Wed Dec 28, 2016 12:34 pm
by Caligari87
Awesome, thanks for sharing! I hadn't considered using GetPlayerInput instead of the built-in fire/reload functionality. brb, refactoring code...

8-)

Re: +weapon.alwaysbob

PostPosted: Wed Dec 28, 2016 12:48 pm
by Major Cooke
Good luck. :P

Re: +weapon.alwaysbob

PostPosted: Wed Dec 28, 2016 1:40 pm
by D2JK
Yeah, I guess manual bobbing control is the way to go now, I've been thinking about that myself recently. Though rather than using flags, I'll probably use a float variable to multiply the bobbing range instead, setting it to zero to disable the bobbing as needed. Another neat trick might be to use an extra "old velocity" variable, so the bobbing motion could be smoothly averaged out when you bump into something.

Re: +weapon.alwaysbob

PostPosted: Wed Dec 28, 2016 2:10 pm
by Major Cooke
There is oldx and oldy in the PSprites which you can modify.

Re: +weapon.alwaysbob

PostPosted: Fri Dec 30, 2016 2:39 pm
by D2JK
Here's a code for a bobbing motion, which follows a figure of eight path. It looks great to me, but it's going to take quite a bit of thinking to make this compatible with the various weapon offset shifts I've applied here and there.

Code: Select allExpand view
Bobbing:
 TNT1 A 1
  {
   float V = sqrt(vel.x * vel.x + vel.y * vel.y);
   A_WeaponOffset(V * Cos(12 * level.maptime)  ,  32 + V * (Sin(24 * level.maptime) + 1));
  }
 Loop;

Re: +weapon.alwaysbob

PostPosted: Fri Jan 06, 2017 1:21 pm
by D2JK
Well, I've replaced the default bobbing with my custom code, but now after updating GzDoom, I see that weapon sprite interpolation has been disabled.

Were there any options added that lets me take control of the interpolation?

Re: +weapon.alwaysbob

PostPosted: Fri Jan 06, 2017 1:24 pm
by Major Cooke
Use oldx and oldy for storing the previous coordinates so it can interpolate.

Re: +weapon.alwaysbob

PostPosted: Fri Jan 06, 2017 3:32 pm
by Leonard2
D2JK wrote:after updating GzDoom, I see that weapon sprite interpolation has been disabled.

Pretty sure it got broken by this.

Re: +weapon.alwaysbob

PostPosted: Fri Jan 06, 2017 3:47 pm
by Major Cooke
I wouldn't call it broken, just altered.

Re: +weapon.alwaysbob

PostPosted: Fri Jan 06, 2017 3:55 pm
by Graf Zahl
I think what I said in the comment was pretty clear. This has been used in so many ways that interfere with interpolation that it's impossible to guess right.

Re: +weapon.alwaysbob

PostPosted: Fri Jan 06, 2017 3:58 pm
by D2JK
Well, I see there is now a WOF_INTERPOLATE flag. It allowed me to re-enable the interpolation, so that takes care of that.

Re: +weapon.alwaysbob

PostPosted: Fri Jan 06, 2017 11:52 pm
by Nash
D2JK wrote:Well, I've replaced the default bobbing with my custom code, but now after updating GzDoom, I see that weapon sprite interpolation has been disabled.

Were there any options added that lets me take control of the interpolation?


Can you post the full code? For educational purposes. Particularly curious as to WHERE this function needs to be placed in the pipeline, what functions need to be overwritten, etc. Thanks!