## [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.

### [ZScript] Crosshair based on weapon spread

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?

Boondorl

Joined: 12 Jul 2018

### Re: [ZScript] Crosshair based on weapon spread

I'd love to read the answer to this! Oh: and howdy! I'm new here.
Chipper35

Joined: 11 Nov 2019
Location: Texas
Operating System: Windows Vista/7/2008 32-bit
OS Test Version: No (Using Stable Public Version)

### Re: [ZScript] Crosshair based on weapon spread

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;`
Jarewill

Joined: 21 Jul 2019

### Re: [ZScript] Crosshair based on weapon spread

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.

Boondorl

Joined: 12 Jul 2018

Return to Scripting

### Who is online

Users browsing this forum: No registered users and 0 guests