Left 4 Dead 2

Left 4 Dead 2

29 ratings
[VScript AutoLoader] How to make any script mod compatible with loader
By .
VScript AutoLoader

I am so stupid, I should have made this guide a few months ago
If you have tried to modify the priority and it still does not work, please try these methods
Modify mod priority aka. Deal with conflicts
   
Award
Favorite
Favorited
Unfavorite
Create folder
Related guide:
https://steamhost.cn/steamcommunity_com/sharedfiles/filedetails/?id=626387296

You need to create a folder, it can be anywhere



Then, create the scripts folder, and then create the vscripts folder in the scripts folder



Then, create the autorun folder in the vscripts folder



Then, you need to create a file in the folder

If you only need to make compatible, create a file named lib_(any number 1-1000).nut (example: lib_2.nut)



Or if you want to make your own script, please change it to script_(any number 1-1000).nut, because the file at the beginning of lib_ will not automatically call hook function

File prefixes currently supported:
  • script_ (auto call hook func)
  • loader_ (auto call hook func)
  • lib_ (will not call hook func)
  • weapon_ (will not call hook func)
  • server_ (will not call hook func)
  • (map name)_ (auto call partial hook func)
    example: c1m1_hotel_1.nut, c2m1_highway_2.nut
  • (game mode name)_ (auto call partial hook func)
    example: coop_1.nut, versus_2.nut
  • (map name)_(game mode name)_ (auto call partial hook func)
    example: c1m1_hotel_coop_1.nut, c2m1_highway_versus_2.nut
Compatible mod
Open the lib_(any number).nut file
You can open the file with noteped++[notepad-plus-plus.org]

Unpack incompatible mod

How to pack or unpack vpk files:
https://steamhost.cn/steamcommunity_com/sharedfiles/filedetails/?id=625844973

Example: Admin System



Check the file inside, you will find a scriptedmode.nut file
All script mods will include this file, which is why all script mods are not compatible.
You can delete scriptedmode.nut, because VScript AutoLoader already contains all the contents of scriptedmode.nut

Then, the compatibility is complete, repackage it into a vpk file, and put it in the addons folder




As you can see, this mod also has scriptedmode.nut file
But, please don't delete it yet, let's see the file content



This file adds a new script file based on the content of the original file
So how to fix this problem?
Very simple, open the lib_(any number).nut file you created earlier



Then add a line of content, save the file, and the compatibility is complete
Repackage this mod, and then repackage the folder you created



This is just an example, VScript AutoLoader already includes compatibility, you only need to delete the scriptedmode.nut file to complete the compatibility

Example: World Items



Similarly, open the scriptedmode.nut file and search for world_items



Copy these three lines into the lib_(any number).nut file



Compatible complete

In short, what you need to do is to add a new script file in the file content and delete the scriptedmode.nut file

Contains compatible mods (but still need to delete scriptedmode.nut file)
Create a custom script file
First you need to create a file with the prefix script_ in the scripts\vscripts\autorun\ path




Then, write what you want

Advanced: Automatic call function or variable
var table Command
Add command, same like qtgloader.addcommand

Example:
Command <- { function test(p,a = [],as = ""){ if (!p.IsAdmin()) return IncludeScript("qtg_test") } function hp(p,a = [],as = ""){ if (!p.IsAdmin()) return if (a.len() < 1) return local n = a[0].tointeger() if (isint(n)){ p.SetHealth(n) } } }

void Init()
Called after VScript AutoLoader is loaded

void Precache()
Called when precache

void Think()
Call every 0.5 seconds

void Update()
called from C++ on the main script update clock

void OnGameEvent_(hook name)(hook args)
Game Events
Please check the FAQ for how to get the name of the game event
Call at start event

obj OnGameplayStart(string modename, string mapname)
Call when the game start

void AddCriteria(table criteria)
Call when adding criteria

void SetupModeHUD()
Call when the hud is initialized

void OnActivate(string modename, string mapname)
Call when the script is activated

bool AllowTakeDamage(table damageTable)
Call when there is any damage
Return false to prevent damage, return table to change damage

bool BotQuery(int queryflag, handle entity, bool defaultvalue) (Doesn't seem to work)
Hook to control survivor bot behavior.

bool CanPickupObject(handle object) (Not tested)
Hook function for deciding whether a given prop should be pickupable (HL2 style). Returning true makes the players able to pick up the object. Only functional for server side props. If this is defined it must return true in order the PickupObject() function to work.

void InterceptChat(sting message, CTerrorPlayer speaker) (Not tested)
If you put a function with this name in your script, C++ will call it on all chat messages. Passing in the (annotated) chat string and the handle of the speaker.

void UserConsoleCommand(handle playerScript, arg)
when a user does a <scripted_user_func argument> at console (or bound to a key) this function is called (if it exists). The playerscript is which players console it came from. You can pass strings or whatever, of course. So could do a switch statement off <arg> to give players special controls, etc.
(This hook is not recommended, you should use the qtgloader.addcommand function to add commands)

void OnShutdown(int reason,string nextmap)
Call when server shutdown

table OnEntityCreate(table info, entity entityAt = null)
Call when generating entity
Only the script generating entity will call

entity OnEntityCreated(QEntity)
Call after entity generation
Only the script generating entity will call
Advanced: Custom functions
bool istype(Object, string ...)
Returns whether the object type matches

Example:
printa(istype(1,"integer")) printa(istype(1.0,"float")) local s = "" local i = 1 local b = false b = true printa(istype(b ? s : i,"integer","string"))

bool isstring(Object)
Returns whether the object is an string

bool istable(Object)
Returns whether the object is an table

bool isarray(Object)
Returns whether the object is an array

bool isbool(Object)
Returns whether the object is an bool

bool isclass(Object)
Returns whether the object is an class

bool isfloat(Object)
Returns whether the object is an float

bool isinstance(Object)
Returns whether the object is an instance

bool isint(Object)
Same like isinstance

bool isnum(Object)
Returns whether the object is an instance or float

bool isvector(Object)
Returns whether the object is an vector

bool tobool(Object)
Cast object to boolean

void printtable((table,array) to print table, string space = "", bool Is it second call = false)
Print array or table on the console

void printarray((table,array) to print table, string space = "", bool Is it second call = false)
Same like printtable

void printa(Object ...)
Same like print, but allow arbitrary variables

bool IsValid(Object ...)
Returns whether the object is valid

Example:
printa(IsValid(ent(1)), IsValid(ent(0), ent(2)))

string Color
Same like QTGLIB.Util.Color

Library: qtgloader

void qtgloader.addcommand(string name, function callfunction)
callfunction args(QEntity player, array argsarray = [], string argsstring = "")

Add custom commands

Example:
qtgloader.addcommand("qtgloader_reload",function(p,a = [],as = ""){ if (!p.IsAdmin()) return IncludeScript("qtg_loader") })

Is not really an add command

Console command is scripted_user_func qtgloader_reload
Chat command is !qtgloader_reload

Note! Entering variables in the console needs to replace spaces with ".."

void qtgloader.addconvar(string name, (integer string float) defult value, string Help text, function callfunction = function(){})
callfunction args(QEntity player, string convar name, (integer string float) old value, (integer string float) new value)

Example:
qtgloader.addconvar("qtg_printevent",0,"print all gameevent",function(p,n,ov,nv){ if (IsValid(p) && !p.IsAdmin()) return false QTGLIB.Util.Say("Server cvar \""+n+"\" changed to "+nv,"ConVar") })

string qtgloader.getmapname()
Return current map

string qtgloader.getmodename()
Return current game mode

void qtgloader.call(string hook func name)
Call all script functions

obj qtgloader.calla(string hook func name, obj any obj)
Same like qtgloader.call, but need args

obj qtgloader.calla2(string hook func name, obj any obj, obj any obj)
Same like qtgloader.call, but need args

obj qtgloader.calla3(string hook func name, obj any obj, obj any obj, obj any obj)
Same like qtgloader.call, but need args

bool qtgloader.convarexists(string convar name)
Check convar exists

void qtgloader.load()
Initialization function
Warning: It takes at least 5 seconds to initialize, do not use this function arbitrarily

void qtgloader.loadwep()
Need Custom weapon base
Initialization custom weapon

class qtgloader.convar(string convar name)

Example:
printa(qtgloader.convar("qtg_changemaptime").getfloat())

string gettype()
Return type of convar

Example:
printa(qtgloader.convar("qtg_changemaptime").gettype())

string getdeftype()
Return type of convar default value

bool getbool()
Returns boolean value of convar

(integer string float) getdefault()
Returns default value of convar

string gethelp()
Returns help text of convar

float getfloat()
Returns float value of convar

instance getint()
Returns instance value of convar

string getname()
Returns convar name of convar

void setbool()
Set convar boolean

void setfloat()
Set convar float

void setint()
Set convar float

void setstring()
Set convar float

Library: math

math.abs same like abs
math.acos same like acos
math.asin same like asin
math.atan same like atan
math.atan same like atan
math.ceil same like ceil
math.cos same like cos
math.exp same like exp
math.fabs same like fabs
math.floo same like floo
math.log same like log
math.log1 same like log1
math.pow same like pow
math.rand same like rand
math.sin same like sin
math.sqrt same like sqrt
math.tan same like tan

number math.min(number min, number max)
Returns the minimum value of a number

number math.max(number min, number max)
Returns the maximum value of a number

number math.center(number center, number min, number max)
Returns center number

Library: string

string.split same like split
string.strip same like strip
string.rstrip same like rstrip
string.lstrip same like lstrip
string.format same like format

string string.lower(string)
Return lowercase

string string.upper(string)
Return uppercase

string string.find(string, string find)
Same like (string class).find

string string.replace(string, string original string, string replaced string)
Replace specified string

bool string.startwich(string, string Start string)
Returns whether the string starts with the beginning string

Library: table

array table.toarray(table)
table table.copy(table)
void table.empty(table)
object table.remove(table, object = key)
void table.merge(table, table source)

Library: arrayf

table arrayf.totable(array)
array arrayf.new(array, int id = 0, int id2 = -1)
string arrayf.tostring(array, string space = "")

Library: QTGLIB.Util

string QTGLIB.Util.Color(number red, number green, number blue, number alpha = 255)
Return color string

void QTGLIB.Util.Say(string msg, string msgname = "", player e = null, bool team = false)
Same like Say, but more convenient

void QTGLIB.Util.ConVarChangedMsg(string convar name, number new var)
QTGLIB.Util.Say package function

void QTGLIB.Util.PrecacheModel(string model path)
Pre-cache model

void QTGLIB.Util.PrecacheCSSWeapons()
Pre-cache css weapons

void QTGLIB.Util.PrecacheSurvivors()
Pre-cache survivors models

void QTGLIB.Util.ShowHint(string show text, string icon = "icon_info", string color = "255 255 255 255", number time = 2, entity activator = null, string hint id = show text+"")
Quick show hint

void QTGLIB.Util.ShowBar(string bar name, float var, float bar max, string icon = "icon_info", string color = "255 255 255 255", number time = 2, entity activator = null, string hint id = show text+"", bool display current value and maximum value)
QTGLIB.Util.ShowHint package function, show a custom progress bar
Advanced: Custom functions 2
Library: qtgloader.hook

void qtgloader.hook.add(string hookname,string hookid,function hookfunc)
Add hooks, can be used anywhere
If a file does not automatically call functions, you can use this
Note: Please remove events prefix for all game events (OnGameEvent_)

Example:
qtgloader.hook.add("AllowTakeDamage","qcsa_1",function(d){ local att = ent(d.Attacker) if (att.GetClass() != "env_explosion" || att.GetVar("QCSAOwner") == null) return d.Attacker = att.GetVar("QCSAOwner").toent() d.Weapon = att.GetVar("QCSAWep").toent() local vic = ent(d.Victim) if (vic.IsPlayer() && vic.IsSurvivor()) d.DamageDone *= 0.1 else d.DamageDone *= 5 return d }) qtgloader.hook.add("player_say",function(d){ printa(d) })

void qtgloader.hook.remove(string hookname,string hookid)
Remove specified hook

Example:
qtgloader.hook.remove("AllowTakeDamage","qcsa_1")

obj qtgloader.hook.call(string hookname)
Call hook
Not recommended, qtgloader.call function will automatically call hook
You should use qtgloader.call

Example:
// Call all hooks named "Custom Hook Name" qtgloader.hook.call("Custom Hook Name")

obj qtgloader.hook.calla(string hookname,obj args)
Same like qtgloader.hook.call, but need args

obj qtgloader.hook.calla2(string hookname,obj args,obj args)
Same like qtgloader.hook.call, but need args

obj qtgloader.hook.calla3(string hookname,obj args,obj args,obj args)
Same like qtgloader.hook.call, but need args

Library: QTGLIB.PLY

array QTGLIB.PLY.GetAll(bool Conversion QEntity = false)
Get all players

QEntity QTGLIB.PLY.Get(string survivor name)
Get survivors

QEntity QTGLIB.PLY.GetViewModel(entity player, int id = 1)
Get player first-person model entity

Library: QTGLIB.ENT
Library: QTGLIB.Timer
Library: timer
Same like QTGLIB.Timer

class QTGLIB.ENTC(Object)
class QEntity(Object)
Same like QTGLIB.ENTC
class ent(Object)
Same like QTGLIB.ENTC

class QTGLIB.Menu(string name, function callback = function(){}, string back = "")
Not recommended, because everyone can see the menu
This will conflict with other custom menus

Example: (Need VSLib)
qtgloader.addcommand("killmenu",function(p,a = [],as = ""){ local m = QTGLIB.Menu("Kill players menu",function(p,n,v){ if (n > 0 && n < 8){ if (IsValid(v)){ if (v.IsAlive()){ v.tovslib("Player").Kill() QTGLIB.Util.Say("Killed "+v.GetName()) } } else { foreach (p in QTGLIB.PLY.GetAll()){ p.tovslib("Player").Kill() } QTGLIB.Util.Say("Killed everyone") } } }) foreach (v in QTGLIB.PLY.GetAll()){ m.AddItem(v) } m.AddItem("Everyone") m.Display(p) })
Advanced: Make Custom Scripted Weapons
About Custom Scripted Weapons:
https://steamhost.cn/steamcommunity_com/sharedfiles/filedetails/?id=634628292

This guide will not specifically describe how to make custom weapons

VScript AutoLoader adds compatibility support for custom weapons, you can create files with weapon_ prefix



Add these contents to the file, and the custom weapon will be registered



You still need to write other content of the custom weapon, but you no longer need to modify the scriptedmode.nut file
FAQ
Q: How to get the event name of the game
A: You can try the code
qtgloader.addconvar("qtg_printevent",0,"print all gameevent",function(p,n,ov,nv){ if (IsValid(p) && !p.IsAdmin()) return false QTGLIB.Util.Say("Server cvar \""+n+"\" changed to "+nv,"ConVar") }) ::__oldRunEventCallbacks <- ("__oldRunEventCallbacks" in getroottable()) ? __oldRunEventCallbacks : __RunEventCallbacks ::__RunEventCallbacks = function(e,p,pr,g,b){ if (qtgloader.convar("qtg_printevent").getbool()){ printl(pr+e) } return __oldRunEventCallbacks(e,p,pr,g,b) }
Known issues
  1. The id of each script mod must be inconsistent, otherwise there will still be conflicts
  2. Because it is impossible to get all the files in the directory, every initialization will try to load 1000 files, which also causes the lag every time initialization
3 Comments
♫Miku♫ 16 Sep, 2021 @ 11:27am 
das a lotta words
hanocat 25 Jul, 2020 @ 8:14pm 
Very useful.
pls come get yr bitch 24 Jul, 2020 @ 10:48pm 
idk what any of this means but i bet its really really gamer