gmod-typescript icon indicating copy to clipboard operation
gmod-typescript copied to clipboard

Missing Globals, Realms / States

Open TIMONz1535 opened this issue 3 years ago • 3 comments

There is no way to control script workflow with a SERVER/CLIENT realms. Its not exists in TypeScript.

https://wiki.facepunch.com/gmod/States

There are also some global variables, such as ENT, SWEP, GM. However, I have no idea how to implement them correctly, because they will be visible in the entire TypeScript code. TypeScriptToLua uses globalThis for _G alias. globalThis implemented by TypeScript itself.

https://wiki.facepunch.com/gmod/Global_Variables

Minor. Garry's mod also have some constants (vector_origin, vector_up) at the bottom of the page. I don't like their names, I'd rather make my own like ZeroVector, ForwardVector and other. But perhaps it can be useful to someone. I think you will decide for yourself whether you need to spend time on this.

TIMONz1535 avatar Jan 23 '22 22:01 TIMONz1535

Adding server/client bools should is easy. They can just be added to https://github.com/lolleko/gmod-typescript/blob/master/types/extras.d.ts

ENT, SWEP, GM are a different story, however. These have some weird file based scoping. So declaring them globally can cause issues. Additionally, even if they would exist, it is impossible to access them properly in vanilla TS, in the way Gmod requires (function ENT:Spawn() end .....) again because of the odd file based scoping. We had some discussions about this on discord: https://discord.com/channels/515854149821267971/515854150257344524/571792067324280832 https://discord.com/channels/515854149821267971/515854150257344524/719667301086920717

I think we will need a custom decorator, similar to this one for DotA abilities https://github.com/ModDota/TypeScriptAddonTemplate/blob/master/src/vscripts/lib/dota_ts_adapter.ts#L34 https://github.com/ModDota/TypeScriptAddonTemplate/blob/master/src/vscripts/abilities/heroes/meepo/earthbind_ts_example.ts to attach functions from entity files to the ENT/SWEP table. Maybe even a custom TSTL plugin.

lolleko avatar Jan 28 '22 17:01 lolleko

I found this solution https://github.com/glua-addon-types/glua-types

https://github.com/SupinePandora43/Trailers-Reborn - there are no entities here... https://github.com/rwilliaise/gmodtf2sweps - it's almost empty here, but it gave me an idea how to implement a weapon class (see below)

declare const SERVER: boolean
declare const CLIENT: boolean
declare const MENU: boolean
declare const GAMEMODE: Gamemode
declare const GM: Gamemode

This means that they are available everywhere, and you must understand where you write your code. In general, it was the same on Lua...

I had to modify the declarations a bit

declare const SWEP: Weapon
declare const ENT: Entity
type Entity = IEntity & EntityFuncs & EntityHooks
type Weapon = IWeapon & WeaponFuncs & WeaponHooks

this allowed me to write like this

AddCSLuaFile()

SWEP.ViewModel = Model("models/weapons/c_arms_animations.mdl")
SWEP.WorldModel = Model("models/MaxOfS2D/camera.mdl")

SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = "none"

and this

ENT.Spawnable = true
ENT.AdminOnly = true
ENT.PrintName = "Fog Editor"
ENT.Category = "Editors"

ENT.Initialize = function () {
	this.SetMaterial("gmod/edit_fog")

	if (CLIENT) {
	}

	this.UpdateTransmitState = function (this: Entity): TRANSMIT {
		return TRANSMIT.TRANSMIT_ALWAYS
	}
}

ENT.UpdateTransmitState = function () {
	return TRANSMIT.TRANSMIT_ALWAYS
}

ENT.SetMaterial = function (): string {
	return "wtf"
}

but all the functions that I write completely ignore the original declarations (except when some value is returned, like UpdateTransmitState), an example I can write anything in SetMaterial

I can write something more interesting, like this. In theory, it should automatically redirect everything to SWEP. I didn't test, just watched the Lua code. The constructor is needed only if I don't declare all values as static. The main thing is not to forget that this is a fake, not a real class.

declare const set: LuaTableSet<AnyNotNil, AnyNotNil, any>
interface ScriptedWeapon extends Entity { }
class ScriptedWeapon {
	// redirect for class methods from prototype and constructor
	__newindex(k: any, v: any) {
		if (k != "____constructor")
			set(SWEP, k, v)
	}
	// redirect for static variables from class
	static __newindex(k: any, v: any) {
		set(SWEP, k, v)
	}
}

class Pistol extends ScriptedWeapon {
	constructor(name: string) {
		super()

		this.Initialize = function () {
			this.SetMaterial("gmod/edit_fog")
		}
		this.PrintName = name
		this.AdminOnly = true
		this.Spawnable = true
	}

	Initialize(this: Entity): void {
	}

	UpdateTransmitState(this: Entity): TRANSMIT {
		return TRANSMIT.TRANSMIT_ALWAYS
	}

	SetupDataTables(this: Entity): void {
	}

	// you can easily make your own variables and methods
	// with SWEP/ENT you will have to cast it to `any` or `unknown`
	MyOwnValue1?: string
	MyOwnValue11: string = "kek"

	AdminOnly: boolean;
	PrintName: string = "Kek"
	static Category: string = "Kek2"
}
new Pistol("kekos")

Lua provides an opportunity to mutate the ENT methods/hooks, but I would like to implement the Entity. In a TypeScript, the implements requires all methods/properties... I'm not good at this :(

Oh yes, I haven't come up with anything smarter for client/server separation.

if (CLIENT) {
	class Pistol2 extends ScriptedWeapon {
		static Category: string = "Kek2"
		Initialize(this: Entity): void { }
		DrawModel(this: Entity): void { }
	}
	new Pistol2()
}
else {
	class Pistol2 extends ScriptedWeapon {
		static Category: string = "Kek2"
		Initialize(this: Entity): void { }
		OnRemove(this: Entity): void { }
	}
	new Pistol2()
}

TIMONz1535 avatar Jan 29 '22 20:01 TIMONz1535

I added

declare const SERVER: boolean;
declare const CLIENT: boolean;
declare const MENU: boolean;
declare const GAMEMODE: Gamemode;
declare const GM: Gamemode;

declare const SWEP: Weapon;
declare const ENT: Entity;

in v0.3.0 unitl we can come up with something better. Also keep in mind that declarations for hooks are not yet generated.

lolleko avatar Feb 05 '22 12:02 lolleko