Skip to content

Commit d6c8ce6

Browse files
Add several natives for managing with class (#13)
1 parent 81ad398 commit d6c8ce6

8 files changed

Lines changed: 290 additions & 16 deletions

File tree

gamedata/vscript.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,18 @@
4242
"windows" "0"
4343
}
4444

45+
"ScriptClassDesc_t::m_pszClassname"
46+
{
47+
"linux" "4"
48+
"windows" "4"
49+
}
50+
51+
"ScriptClassDesc_t::m_pszDescription"
52+
{
53+
"linux" "8"
54+
"windows" "8"
55+
}
56+
4557
"ScriptClassDesc_t::m_pBaseDesc"
4658
{
4759
"linux" "12"
@@ -54,6 +66,18 @@
5466
"windows" "16"
5567
}
5668

69+
"ScriptClassDesc_t::m_pNextDesc"
70+
{
71+
"linux" "48"
72+
"windows" "48"
73+
}
74+
75+
"sizeof(ScriptClassDesc_t)"
76+
{
77+
"linux" "52"
78+
"windows" "52"
79+
}
80+
5781
"ScriptFunctionBinding_t::m_pszScriptName"
5882
{
5983
"linux" "0"

scripting/include/vscript.inc

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,10 +254,37 @@ methodmap VScriptClass < Address
254254
{
255255
// Gets the script name
256256
//
257-
// @param buffer Buffer to store name.
257+
// @param buffer Buffer to store script name.
258258
// @param length Size of buffer.
259259
public native void GetScriptName(char[] buffer, int length);
260260

261+
// Sets the script name
262+
//
263+
// @param value Script name to set.
264+
public native void SetScriptName(const char[] value);
265+
266+
// Gets the class name
267+
//
268+
// @param buffer Buffer to store class name.
269+
// @param length Size of buffer.
270+
public native void GetClassName(char[] buffer, int length);
271+
272+
// Sets the class name
273+
//
274+
// @param value Class name to set.
275+
public native void SetClassName(const char[] value);
276+
277+
// Gets the description
278+
//
279+
// @param buffer Buffer to store name.
280+
// @param length Size of buffer.
281+
public native void GetDescription(char[] buffer, int length);
282+
283+
// Sets the description
284+
//
285+
// @param value Description to set.
286+
public native void SetDescription(const char[] value);
287+
261288
// Get all of the functions used for this class
262289
//
263290
// @return Arrays of VScriptFunction, handle must be deleted when not needed.
@@ -275,6 +302,12 @@ methodmap VScriptClass < Address
275302
// @return Address of VScriptFunction.
276303
public native VScriptFunction CreateFunction();
277304

305+
// Register this class as an instance. This does not require calling VScript_ResetScriptVM unless if modifications were made afterward.
306+
//
307+
// @param instance Name of an instance in script.
308+
// @return Created HSCRIPT instance.
309+
public native HSCRIPT RegisterInstance(const char[] instance);
310+
278311
// Gets the class that this is based on, Address_Null if does not have base class
279312
property VScriptClass Base
280313
{
@@ -436,6 +469,15 @@ native ArrayList VScript_GetAllClasses();
436469
*/
437470
native VScriptClass VScript_GetClass(const char[] className);
438471

472+
/**
473+
* Gets VScriptClass from class or creates one if don't exist. VScriptClass.RegisterInstance must be called after params are filled.
474+
*
475+
* @param className Class name.
476+
*
477+
* @return Address of VScriptClass, either existing or newly created
478+
*/
479+
native VScriptClass VScript_CreateClass(const char[] className);
480+
439481
/**
440482
* Gets VScriptFunction from class
441483
*

scripting/vscript.sp

Lines changed: 101 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#include "include/vscript.inc"
44

5-
#define PLUGIN_VERSION "1.8.7"
5+
#define PLUGIN_VERSION "1.9.0"
66
#define PLUGIN_VERSION_REVISION "manual"
77

88
char g_sOperatingSystem[16];
@@ -18,6 +18,7 @@ int g_iScriptVariant_union;
1818
int g_iScriptVariant_type;
1919

2020
static Handle g_hSDKCallCompileScript;
21+
static Handle g_hSDKCallRegisterInstance;
2122
static Handle g_hSDKCallGetInstanceEntity;
2223

2324
const HSCRIPT INVALID_HSCRIPT = view_as<HSCRIPT>(-1);
@@ -94,9 +95,15 @@ public APLRes AskPluginLoad2(Handle hMyself, bool bLate, char[] sError, int iLen
9495
CreateNative("VScriptFunction.Class.get", Native_Function_ClassGet);
9596

9697
CreateNative("VScriptClass.GetScriptName", Native_Class_GetScriptName);
98+
CreateNative("VScriptClass.SetScriptName", Native_Class_SetScriptName);
99+
CreateNative("VScriptClass.GetClassName", Native_Class_GetClassName);
100+
CreateNative("VScriptClass.SetClassName", Native_Class_SetClassName);
101+
CreateNative("VScriptClass.GetDescription", Native_Class_GetDescription);
102+
CreateNative("VScriptClass.SetDescription", Native_Class_SetDescription);
97103
CreateNative("VScriptClass.GetAllFunctions", Native_Class_GetAllFunctions);
98104
CreateNative("VScriptClass.GetFunction", Native_Class_GetFunction);
99105
CreateNative("VScriptClass.CreateFunction", Native_Class_CreateFunction);
106+
CreateNative("VScriptClass.RegisterInstance", Native_Class_RegisterInstance);
100107
CreateNative("VScriptClass.Base.get", Native_Class_BaseGet);
101108
CreateNative("VScriptClass.IsDerivedFrom", Native_Class_IsDerivedFrom); // legacy native, to be removed later
102109

@@ -120,6 +127,7 @@ public APLRes AskPluginLoad2(Handle hMyself, bool bLate, char[] sError, int iLen
120127
CreateNative("VScript_CreateTable", Native_CreateTable);
121128
CreateNative("VScript_GetAllClasses", Native_GetAllClasses);
122129
CreateNative("VScript_GetClass", Native_GetClass);
130+
CreateNative("VScript_CreateClass", Native_CreateClass);
123131
CreateNative("VScript_GetClassFunction", Native_GetClassFunction);
124132
CreateNative("VScript_GetAllGlobalFunctions", Native_GetAllGlobalFunctions);
125133
CreateNative("VScript_GetGlobalFunction", Native_GetGlobalFunction);
@@ -163,6 +171,7 @@ public void OnPluginStart()
163171
List_LoadGamedata(hGameData);
164172

165173
g_hSDKCallCompileScript = CreateSDKCall(hGameData, "IScriptVM", "CompileScript", SDKType_PlainOldData, SDKType_String, SDKType_String);
174+
g_hSDKCallRegisterInstance = CreateSDKCall(hGameData, "IScriptVM", "RegisterInstance", SDKType_PlainOldData, SDKType_PlainOldData, SDKType_String);
166175
g_hSDKCallGetInstanceEntity = CreateSDKCall(hGameData, "IScriptVM", "GetInstanceValue", SDKType_CBaseEntity, SDKType_PlainOldData, SDKType_PlainOldData);
167176

168177
delete hGameData;
@@ -339,7 +348,7 @@ public any Native_Function_SetScriptName(Handle hPlugin, int iNumParams)
339348
char[] sBuffer = new char[iLength + 1];
340349
GetNativeString(2, sBuffer, iLength + 1);
341350

342-
// Check if script name dont already exist
351+
// Check if script name not already exist
343352
if (Function_GetFlags(pFunction) & SF_MEMBER_FUNC)
344353
{
345354
VScriptClass pClass = List_GetClassFromFunction(pFunction);
@@ -525,6 +534,57 @@ public any Native_Class_GetScriptName(Handle hPlugin, int iNumParams)
525534
return 0;
526535
}
527536

537+
public any Native_Class_SetScriptName(Handle hPlugin, int iNumParams)
538+
{
539+
VScriptClass pClass = GetNativeCell(1);
540+
541+
int iLength;
542+
GetNativeStringLength(2, iLength);
543+
544+
char[] sBuffer = new char[iLength + 1];
545+
GetNativeString(2, sBuffer, iLength + 1);
546+
547+
// Check if script name not already exist
548+
if (List_GetClass(sBuffer))
549+
ThrowNativeError(SP_ERROR_NATIVE, "Global function named '%s' already exists", sBuffer);
550+
551+
Class_SetScriptName(pClass, 2);
552+
return 0;
553+
}
554+
555+
public any Native_Class_GetClassName(Handle hPlugin, int iNumParams)
556+
{
557+
int iLength = GetNativeCell(3);
558+
char[] sBuffer = new char[iLength];
559+
560+
Class_GetClassName(GetNativeCell(1), sBuffer, iLength);
561+
SetNativeString(2, sBuffer, iLength);
562+
return 0;
563+
}
564+
565+
public any Native_Class_SetClassName(Handle hPlugin, int iNumParams)
566+
{
567+
// Could add an already exist check like SetScriptName, meh
568+
Class_SetClassName(GetNativeCell(1), 2);
569+
return 0;
570+
}
571+
572+
public any Native_Class_GetDescription(Handle hPlugin, int iNumParams)
573+
{
574+
int iLength = GetNativeCell(3);
575+
char[] sBuffer = new char[iLength];
576+
577+
Class_GetDescription(GetNativeCell(1), sBuffer, iLength);
578+
SetNativeString(2, sBuffer, iLength);
579+
return 0;
580+
}
581+
582+
public any Native_Class_SetDescription(Handle hPlugin, int iNumParams)
583+
{
584+
Class_SetDescription(GetNativeCell(1), 2);
585+
return 0;
586+
}
587+
528588
public any Native_Class_GetAllFunctions(Handle hPlugin, int iNumParams)
529589
{
530590
ArrayList aList = Class_GetAllFunctions(GetNativeCell(1));
@@ -550,6 +610,26 @@ public any Native_Class_CreateFunction(Handle hPlugin, int iNumParams)
550610
return Class_CreateFunction(GetNativeCell(1));
551611
}
552612

613+
public any Native_Class_RegisterInstance(Handle hPlugin, int iNumParams)
614+
{
615+
int iLength;
616+
GetNativeStringLength(2, iLength);
617+
618+
char[] sBuffer = new char[iLength + 1];
619+
GetNativeString(2, sBuffer, iLength + 1);
620+
621+
// Second param is void *, but we can just pass string to it
622+
HSCRIPT pInstance = SDKCall(g_hSDKCallRegisterInstance, GetScriptVM(), GetNativeCell(1), sBuffer);
623+
624+
// Not sure if this is the correct way to do it, but it works
625+
ScriptVariant_t pValue = new ScriptVariant_t();
626+
pValue.nType = FIELD_HSCRIPT;
627+
pValue.nValue = pInstance;
628+
HScript_SetValue(HSCRIPT_RootTable, sBuffer, pValue);
629+
630+
return pInstance;
631+
}
632+
553633
public any Native_Class_BaseGet(Handle hPlugin, int iNumParams)
554634
{
555635
return Class_GetBaseDesc(GetNativeCell(1));
@@ -796,6 +876,25 @@ public any Native_GetClass(Handle hPlugin, int iNumParams)
796876
return pClass;
797877
}
798878

879+
public any Native_CreateClass(Handle hPlugin, int iNumParams)
880+
{
881+
int iLength;
882+
GetNativeStringLength(1, iLength);
883+
884+
char[] sBuffer = new char[iLength + 1];
885+
GetNativeString(1, sBuffer, iLength + 1);
886+
887+
VScriptClass pClass = List_GetClass(sBuffer);
888+
if (pClass)
889+
return pClass;
890+
891+
pClass = Class_Create();
892+
Class_Init(pClass);
893+
Class_SetScriptName(pClass, 1);
894+
Class_SetClassName(pClass, 1);
895+
return pClass;
896+
}
897+
799898
public any Native_GetClassFunction(Handle hPlugin, int iNumParams)
800899
{
801900
int iClassNameLength, iFunctionNameLength;

scripting/vscript/class.sp

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,98 @@
11
static int g_iClassDesc_ScriptName;
2+
static int g_iClassDesc_ClassName;
3+
static int g_iClassDesc_Description;
24
static int g_iClassDesc_BaseDesc;
35
static int g_iClassDesc_FunctionBindings;
6+
static int g_iClassDesc_NextDesc;
7+
static int g_iClassDesc_sizeof;
48

59
static int g_iFunctionBinding_sizeof;
610

711
void Class_LoadGamedata(GameData hGameData)
812
{
913
g_iClassDesc_ScriptName = hGameData.GetOffset("ScriptClassDesc_t::m_pszScriptName");
14+
g_iClassDesc_ClassName = hGameData.GetOffset("ScriptClassDesc_t::m_pszClassname");
15+
g_iClassDesc_Description = hGameData.GetOffset("ScriptClassDesc_t::m_pszDescription");
1016
g_iClassDesc_BaseDesc = hGameData.GetOffset("ScriptClassDesc_t::m_pBaseDesc");
1117
g_iClassDesc_FunctionBindings = hGameData.GetOffset("ScriptClassDesc_t::m_FunctionBindings");
12-
18+
g_iClassDesc_NextDesc = hGameData.GetOffset("ScriptClassDesc_t::m_pNextDesc");
19+
g_iClassDesc_sizeof = hGameData.GetOffset("sizeof(ScriptClassDesc_t)");
1320
g_iFunctionBinding_sizeof = hGameData.GetOffset("sizeof(ScriptFunctionBinding_t)");
1421
}
1522

23+
VScriptClass Class_Create()
24+
{
25+
// TODO proper way to handle with memory?
26+
27+
MemoryBlock hClass = new MemoryBlock(g_iClassDesc_sizeof);
28+
29+
VScriptClass pClass = view_as<VScriptClass>(hClass.Address);
30+
31+
hClass.Disown();
32+
delete hClass;
33+
34+
List_AddClass(pClass);
35+
return pClass;
36+
}
37+
38+
void Class_Init(VScriptClass pClass)
39+
{
40+
for (int i = 0; i < g_iClassDesc_sizeof; i++) // Make sure that all is cleared first
41+
StoreToAddress(pClass + view_as<Address>(i), 0, NumberType_Int8);
42+
43+
// Set strings as empty, but not null
44+
Address pEmptyString = GetEmptyString();
45+
StoreToAddress(pClass + view_as<Address>(g_iClassDesc_ScriptName), pEmptyString, NumberType_Int32);
46+
StoreToAddress(pClass + view_as<Address>(g_iClassDesc_ClassName), pEmptyString, NumberType_Int32);
47+
StoreToAddress(pClass + view_as<Address>(g_iClassDesc_Description), pEmptyString, NumberType_Int32);
48+
49+
// Add to the list for m_pNextDesc to register all.
50+
// Correct way to do this is to fetch ScriptClassDesc_t::GetDescList and update function's retrun.
51+
// But we can instead just look through existing list and update the last class in list to point at this class instead.
52+
53+
VScriptClass pOther = List_GetAllClasses().Get(0);
54+
VScriptClass pNext = pOther;
55+
56+
do
57+
{
58+
pOther = pNext;
59+
pNext = LoadFromAddress(pOther + view_as<Address>(g_iClassDesc_NextDesc), NumberType_Int32);
60+
}
61+
while (pNext);
62+
63+
StoreToAddress(pOther + view_as<Address>(g_iClassDesc_NextDesc), pClass, NumberType_Int32);
64+
}
65+
1666
void Class_GetScriptName(VScriptClass pClass, char[] sBuffer, int iLength)
1767
{
1868
LoadPointerStringFromAddress(pClass + view_as<Address>(g_iClassDesc_ScriptName), sBuffer, iLength);
1969
}
2070

71+
void Class_SetScriptName(VScriptClass pClass, int iParam)
72+
{
73+
StoreNativePointerStringToAddress(pClass + view_as<Address>(g_iClassDesc_ScriptName), iParam);
74+
}
75+
76+
void Class_GetClassName(VScriptClass pClass, char[] sBuffer, int iLength)
77+
{
78+
LoadPointerStringFromAddress(pClass + view_as<Address>(g_iClassDesc_ClassName), sBuffer, iLength);
79+
}
80+
81+
void Class_SetClassName(VScriptClass pClass, int iParam)
82+
{
83+
StoreNativePointerStringToAddress(pClass + view_as<Address>(g_iClassDesc_ClassName), iParam);
84+
}
85+
86+
void Class_GetDescription(VScriptClass pClass, char[] sBuffer, int iLength)
87+
{
88+
LoadPointerStringFromAddress(pClass + view_as<Address>(g_iClassDesc_Description), sBuffer, iLength);
89+
}
90+
91+
void Class_SetDescription(VScriptClass pClass, int iParam)
92+
{
93+
StoreNativePointerStringToAddress(pClass + view_as<Address>(g_iClassDesc_Description), iParam);
94+
}
95+
2196
ArrayList Class_GetAllFunctions(VScriptClass pClass)
2297
{
2398
ArrayList aList = new ArrayList();

scripting/vscript/function.sp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,11 @@ VScriptFunction Function_Create()
4646

4747
void Function_Init(VScriptFunction pFunction, bool bClass)
4848
{
49-
static Address pEmptyString;
50-
if (!pEmptyString)
51-
{
52-
MemoryBlock hMemory = new MemoryBlock(1);
53-
pEmptyString = hMemory.Address;
54-
hMemory.Disown();
55-
delete hMemory;
56-
}
57-
5849
for (int i = 0; i < g_iFunctionBinding_sizeof; i++) // Make sure that all is cleared first
5950
StoreToAddress(pFunction + view_as<Address>(i), 0, NumberType_Int8);
6051

6152
// Set strings as empty, but not null
53+
Address pEmptyString = GetEmptyString();
6254
StoreToAddress(pFunction + view_as<Address>(g_iFunctionBinding_ScriptName), pEmptyString, NumberType_Int32);
6355
StoreToAddress(pFunction + view_as<Address>(g_iFunctionBinding_FunctionName), pEmptyString, NumberType_Int32);
6456
StoreToAddress(pFunction + view_as<Address>(g_iFunctionBinding_Description), pEmptyString, NumberType_Int32);

0 commit comments

Comments
 (0)