Skip to content
This repository has been archived by the owner on Aug 15, 2022. It is now read-only.

Commit

Permalink
feat: added fov & fovconvert commands and fov helper functions (#133)
Browse files Browse the repository at this point in the history
* feat: added fov command and fov helper functions

* feat: added fovconvert command and associated helper functions

* docs: added relevant documentation for fovconvert command
  • Loading branch information
animafps committed Oct 15, 2021
1 parent a72b928 commit 8c21582
Show file tree
Hide file tree
Showing 10 changed files with 188 additions and 20 deletions.
1 change: 0 additions & 1 deletion docs/CNAME

This file was deleted.

2 changes: 1 addition & 1 deletion docs/commands/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Below is a shortlist of all the bot commands.
| [`deg`](math.md#deg) | Converts Sensitivity to deg/mm |
| [`mpi`](math.md#mpi) | Converts Sensitivity to MPI |
| [`focal`](math.md#focal) | Focal Length Scales a desired sens between 2 fov values of the same type |
| [`fov`](math.md#fov) | Finds the true vertical and horizontal FOVs for certain aspect ratio and game/FOV scaling method\(FILM notation\) |
| [`fov`](math.md#fov) | Finds the true vertical and horizontal FoV that is being displayed on screen |
| [`fovconvert`](math.md#fovconvert) | Converts a FOV value from one game or film notation to another |
| [`inch`](math.md#inch) | Converts Sensitivity to inch/rev |
| [`sens`](math.md#sens) | Converts cm/rev\|deg/mm\|MPI\|inch/rev\|arcmin to a game sensitivity default cm/rev |
Expand Down
26 changes: 22 additions & 4 deletions docs/commands/math.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,31 @@ fps-focal <sens> <old fov> <new fov>

### fov

!!! error
Command not implemented yet
Finds the true vertical and horizontal FoV that is being displayed on screen

#### Usage

```text
fps-fov <FoV> <game|FILM notation> <screen aspect ratio>
```

#### Aliases

`fov-scaling`, `film`

### fovconvert

!!! error
Command not implemented yet
Converts a FoV value from one game or FILM notation to another.

#### Usage

```text
fps-fovconvert <FoV> <input game|FILM notation> <output game|FILM notation> <screen aspect ratio>
```

#### Aliases

`fov-convert`, `film-convert`, `convert-fov`

### inch

Expand Down
2 changes: 1 addition & 1 deletion docs/games.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
title: 'Supported Games'
title: Supported Games
---

All the games that FPSMath supports and the features that are available for certain commands
Expand Down
26 changes: 26 additions & 0 deletions src/arguments/aspect-ratio.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Argument, PieceContext, ArgumentContext } from '@sapphire/framework'

export default class GameArgument extends Argument<number> {
public constructor(context: PieceContext) {
super(context, { name: 'aspectRatio' })
}

public run(parameter: string, context: ArgumentContext) {
if (/\d{1,4}:\d{1,4}/.test(parameter)) {
const split = parameter.split(':')
return this.ok(Number(split[0]) / Number(split[1]))
}
return this.error({
parameter,
message: 'Not valid aspect ratio',
identifier: 'aspectRatioNoSupport',
context,
})
}
}

declare module '@sapphire/framework' {
interface ArgType {
aspectRatio: number
}
}
9 changes: 6 additions & 3 deletions src/arguments/film.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Argument, PieceContext, ArgumentContext } from '@sapphire/framework'
import { getObject } from '../helpers/array'

export class UserArgument extends Argument<string> {
public constructor(context: PieceContext) {
Expand All @@ -7,11 +8,13 @@ export class UserArgument extends Argument<string> {

public run(parameter: string, context: ArgumentContext) {
if (
/^hm[lfi]$|^vm[lfi]$|^\d{1,2}m[lfi]\d{1,2}$/i.test(
parameter.toLowerCase()
/^HM[LFI]$|^VM[LFI]$|^\d{1,2}M[LFI]\d{1,2}$/.test(
parameter.toUpperCase()
)
) {
return this.ok(parameter.toLowerCase())
return this.ok(parameter.toUpperCase())
} else if (getObject(parameter, 'film')) {
return this.ok(getObject(parameter, 'film') as string)
}
return this.error({
parameter,
Expand Down
21 changes: 15 additions & 6 deletions src/commands/Math/fov.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Command, CommandOptions } from '@sapphire/framework'
import { Args, Command, CommandOptions } from '@sapphire/framework'
import type { Message } from 'discord.js'
import { ApplyOptions } from '@sapphire/decorators'
import { filmToTrue } from '../../helpers/fovHelper'

@ApplyOptions<CommandOptions>({
aliases: ['fov-scaling', 'film'],
description:
'Finds the true vertical and horizontal FOV that is being displayed on screen',
'Finds the true vertical and horizontal FoV that is being displayed on screen',
detailedDescription: `
📝 **| Command Usage**
→ fps-fov *FoV* *GameName* *AspectRatio*
Expand All @@ -14,7 +15,7 @@ import { ApplyOptions } from '@sapphire/decorators'
🖇️ **| Aliases**: \`fov-scaling\` and \`film\`
🔍 **| Extended Help**
Finds the true vertical and horizontal FOV for certain aspect ratio that the game is being rendered at plus game's FoV scaling method
Finds the true vertical or horizontal FoV for certain aspect ratio that the game is being rendered at plus game's FoV scaling method
⚙ **| Explained usage**
→ **FoV**: The in-game FoV value or equivalent FoV value.
Expand All @@ -29,8 +30,16 @@ import { ApplyOptions } from '@sapphire/decorators'
generateDashLessAliases: true,
requiredClientPermissions: ['SEND_MESSAGES'],
})
export class UserCommand extends Command {
public async run(message: Message) {
return message.reply('Not fully implemented yet')
export default class UserCommand extends Command {
public async run(message: Message, args: Args) {
const fov = await args.pick('float')
const film = await args.pick('film')
const aspect = await args.pick('aspectRatio')
const { horizontalFOV, verticalFOV } = filmToTrue(fov, film, aspect)
return message.reply(
`Horizontal FoV: ${parseFloat(
horizontalFOV.toFixed(5)
)}°\nVertical FoV: ${parseFloat(verticalFOV.toFixed(5))}°`
)
}
}
12 changes: 9 additions & 3 deletions src/commands/Math/fovConvert.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Command, CommandOptions } from '@sapphire/framework'
import { Args, Command, CommandOptions } from '@sapphire/framework'
import type { Message } from 'discord.js'
import { ApplyOptions } from '@sapphire/decorators'
import { filmToFilm } from '../../helpers/fovHelper'

@ApplyOptions<CommandOptions>({
aliases: ['fov-convert', 'film-convert', 'convert-fov'],
Expand Down Expand Up @@ -32,7 +33,12 @@ import { ApplyOptions } from '@sapphire/decorators'
requiredClientPermissions: ['SEND_MESSAGES'],
})
export class UserCommand extends Command {
public async run(message: Message) {
return message.reply('Not fully implemented yet')
public async run(message: Message, args: Args) {
const fov = await args.pick('float')
const inFILM = await args.pick('film')
const outFILM = await args.pick('film')
const aspect = await args.pick('aspectRatio')
const output = filmToFilm(fov, inFILM, outFILM, aspect)
return message.reply(`${parseFloat(output.toFixed(5))}°`)
}
}
2 changes: 1 addition & 1 deletion src/helpers/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const array: {
aliases: ['apex-legends', 'apex'],
film: '4ML3',
},
Valorant: { yaw: 0.07, aliases: ['valorant', 'val'] },
Valorant: { yaw: 0.07, aliases: ['valorant', 'val'], film: '16MS9' },
Overwatch: {
yaw: 0.0066,
aliases: ['overwatch', 'ow'],
Expand Down
107 changes: 107 additions & 0 deletions src/helpers/fovHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
export function convertFOV(
fov: number,
inputAspect: number,
outputAspect: number
) {
return (
(Math.atan(
(outputAspect / inputAspect) * Math.tan((fov * Math.PI) / 360)
) *
360) /
Math.PI
)
}

export function filmToAspect(filmNotation: string) {
const startString = filmNotation.split(/M/)[0]
const endString = filmNotation.split(/M[FLI]/)[1]
return Number(startString) / Number(endString)
}

export function filmToTrue(
fov: number,
film: string,
aspectRatio: number
): fovValues {
const filmAspect = filmToAspect(film)
if (/^\d{1,2}MS\d{1,2}$/.test(film)) {
return {
horizontalFOV: fov,
verticalFOV: convertFOV(fov, filmAspect, 1),
}
} else if (film.startsWith('H')) {
return lockHorizontal(fov, aspectRatio)
} else if (film.startsWith('V')) {
return lockVertical(fov, aspectRatio)
} else if (/^\d{1,2}ML\d{1,2}$/.test(film)) {
return lockVertical(fov, aspectRatio, filmAspect)
} else if (/^\d{1,2}MF\d{1,2}$/.test(film)) {
if (aspectRatio > filmAspect) {
return lockHorizontal(fov, aspectRatio)
}
return lockVertical(fov, aspectRatio, filmAspect)
} else if (/^\d{1,2}MI\d{1,2}$/.test(film)) {
if (aspectRatio < filmAspect) {
return lockHorizontal(fov, aspectRatio)
}
return lockVertical(fov, aspectRatio, filmAspect)
}
throw Error('parsing failed')
}

export function trueToFILM(
{ horizontalFOV, verticalFOV }: fovValues,
film: string,
aspectRatio: number
): number {
const filmAspect = filmToAspect(film)
if (/^\d{1,2}MS\d{1,2}$/.test(film) || film.startsWith('H')) {
return horizontalFOV
} else if (film.startsWith('V')) {
return verticalFOV
} else {
return convertFOV(horizontalFOV, filmAspect, aspectRatio)
}
}

export function lockVertical(
fov: number,
aspectRatio: number,
filmAspect?: number
): fovValues {
if (filmAspect) {
return {
horizontalFOV: convertFOV(fov, filmAspect, aspectRatio),
verticalFOV: convertFOV(fov, filmAspect, 1),
}
}
return {
horizontalFOV: convertFOV(fov, 1, aspectRatio),
verticalFOV: fov,
}
}

export function lockHorizontal(fov: number, aspectRatio: number): fovValues {
return {
horizontalFOV: fov,
verticalFOV: convertFOV(fov, aspectRatio, 1),
}
}

export interface fovValues {
horizontalFOV: number
verticalFOV: number
}

export function filmToFilm(
fov: number,
inFILM: string,
outFILM: string,
aspectRatio: number
): number {
return trueToFILM(
filmToTrue(fov, inFILM, aspectRatio),
outFILM,
aspectRatio
)
}

0 comments on commit 8c21582

Please sign in to comment.