[ZScript] Crosshair based on weapon spread

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

Please bear in mind that the people helping you do not automatically know how much you know. You may be asked to upload your project file to look at. Don't be afraid to ask questions about what things mean, but also please be patient with the people trying to help you. (And helpers, please be patient with the person you're trying to help!)
Post Reply
User avatar
Boondorl
Posts: 137
Joined: Wed Jul 11, 2018 10:57 pm

[ZScript] Crosshair based on weapon spread

Post by Boondorl »

I'm currently trying to implement a crosshair that will adjust itself dynamically to match a weapon's spread (it uses the standard 4 individual lines whose distance widens as the spread gets larger). My weapons are using cone-based spread, so it'll need to be based on a circle instead of a rectangle. The inside edge of the lines mark the furthest point of spread in that direction. One thing I can't figure out is how to get it to actually scale properly e.g. if the weapon's spread range is -2.5 to 2.5 degrees, I need to calculate a radius based off a cone with an opening angle of 5 degrees. What would be the simplest way to do this such that it also scales with the player's FOV?
Chipper35
Posts: 10
Joined: Mon Nov 11, 2019 12:22 pm
Location: Texas

Re: [ZScript] Crosshair based on weapon spread

Post by Chipper35 »

I'd love to read the answer to this! Oh: and howdy! I'm new here.
Jarewill
 
 
Posts: 1759
Joined: Sun Jul 21, 2019 8:54 am

Re: [ZScript] Crosshair based on weapon spread

Post by Jarewill »

An incredibly cheap way to do it would be to make a new custom crosshair and change to it in the weapon's select state using A_SetCrosshair.
Example:

Code: Select all

  Select:
    SHTG A 0 A_SetCrosshair(8);
    SHTG A 1 A_Raise();
    Goto Select+1;
User avatar
Boondorl
Posts: 137
Joined: Wed Jul 11, 2018 10:57 pm

Re: [ZScript] Crosshair based on weapon spread

Post by Boondorl »

This one works ok but could probably use some optimization:

Code: Select all

int x1, y1, x2, y2; // x1 = starting x position of virtual window, y1 = starting y position of virtual window, x2 = width of virtual window, y2 = height of virtual window
[x1, y1, x2, y2] = Screen.GetViewWindow();
int width = x2 / 2;
int centerX = x1 + (x2 / 2);
int centerY = y1 + (y2 / 2);
int offset = (rw.zoomed ? rw.zoomSpread : (rw.spread + rw.spreadFactor*rw.bloom)) *  (1. / atan(1. / (width/tan(viewer.player.FOV/2.))));
			
Screen.DrawThickLine(centerX + offset, centerY, centerX + offset + 20, centerY, 3, "FF FF FF"); // DrawThickLine(starting x, starting y, ending x, ending y, thickness of line, color)
Screen.DrawThickLine(centerX - offset, centerY, centerX - offset - 20, centerY, 3, "FF FF FF");
Screen.DrawThickLine(centerX, centerY + offset, centerX, centerY + offset + 20, 3, "FF FF FF");
Screen.DrawThickLine(centerX, centerY - offset, centerX, centerY - offset - 20, 3, "FF FF FF");
rw is the player's ReadyWeapon and and the rest are properties on my custom weapon class that determine how much spread the weapon has. The spread values are stored in terms of angle offset e.g. a value of 2.5 would be a 2.5 degree horizontal and vertical offset. This formula:

Code: Select all

(1. / atan(1. / (width/tan(viewer.player.FOV/2.))))
is the important part, albeit not very efficient which is why I didn't feel fully comfortable posting the solution. This is taking the player's field of view and using it to get the number of pixels per degree and then multiplying it by the number of degrees in our spread value.
Post Reply

Return to “Scripting”