extensions/sdktools/outputnatives.cpp
author Scott Ehlert <ds@alliedmods.net>
Fri Apr 11 17:16:36 2008 +0000 (2008-04-11)
changeset 1990 de135d1f05b1
parent 1987 0534b0a2ffda
child 2026 03b4a9c4a70e
permissions -rw-r--r--
Added more missing svn:keywords properties to some files (this should be the last of them before I never have to do this again)
Moved sm_memtable files in sqlite extension to sdk directory (to be consistent with topmenus)
Some extension source files had an incorrect extension name in their headers
pred@1958
     1
/**
pred@1958
     2
 * vim: set ts=4 :
pred@1958
     3
 * =============================================================================
pred@1958
     4
 * SourceMod SDKTools Extension
ds@1990
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
pred@1958
     6
 * =============================================================================
pred@1958
     7
 *
pred@1958
     8
 * This program is free software; you can redistribute it and/or modify it under
pred@1958
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
pred@1958
    10
 * Free Software Foundation.
pred@1958
    11
 * 
pred@1958
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
pred@1958
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
pred@1958
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
pred@1958
    15
 * details.
pred@1958
    16
 *
pred@1958
    17
 * You should have received a copy of the GNU General Public License along with
pred@1958
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
pred@1958
    19
 *
pred@1958
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
pred@1958
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
pred@1958
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
pred@1958
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
pred@1958
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
pred@1958
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
pred@1958
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
pred@1958
    27
 * or <http://www.sourcemod.net/license.php>.
pred@1958
    28
 *
ds@1987
    29
 * Version: $Id$
pred@1958
    30
 */
pred@1958
    31
pred@1958
    32
#include "extension.h"
pred@1958
    33
#include "output.h"
pred@1958
    34
pred@1958
    35
// HookSingleEntityOutput(ent, const String:output[], function, bool:once);
pred@1958
    36
cell_t HookSingleEntityOutput(IPluginContext *pContext, const cell_t *params)
pred@1958
    37
{
pred@1958
    38
	if (!g_OutputManager.IsEnabled())
pred@1958
    39
	{
pred@1958
    40
		return pContext->ThrowNativeError("Entity Outputs are disabled - See error logs for details");
pred@1958
    41
	}
pred@1958
    42
pred@1958
    43
	edict_t *pEdict = engine->PEntityOfEntIndex(params[1]);
pred@1958
    44
	if (!pEdict)
pred@1958
    45
	{
pred@1958
    46
		return pContext->ThrowNativeError("Invalid Entity index %i", params[1]);
pred@1958
    47
	}
pred@1958
    48
	const char *classname = pEdict->GetClassName();
pred@1958
    49
pred@1958
    50
	char *outputname;
pred@1958
    51
	pContext->LocalToString(params[2], &outputname);
pred@1958
    52
pred@1958
    53
	OutputNameStruct *pOutputName = g_OutputManager.FindOutputPointer((const char *)classname, outputname, true);
pred@1958
    54
pred@1958
    55
	//Check for an existing identical hook
pred@1958
    56
	SourceHook::List<omg_hooks *>::iterator _iter;
pred@1958
    57
pred@1958
    58
	omg_hooks *hook;
pred@1958
    59
pred@1958
    60
	IPluginFunction *pFunction;
pred@1958
    61
	pFunction = pContext->GetFunctionById(params[3]);
pred@1958
    62
pred@1958
    63
	for (_iter=pOutputName->hooks.begin(); _iter!=pOutputName->hooks.end(); _iter++)
pred@1958
    64
	{
pred@1958
    65
		hook = (omg_hooks *)*_iter;
pred@1958
    66
		if (hook->pf == pFunction && hook->entity_filter == pEdict->m_NetworkSerialNumber)
pred@1958
    67
		{
pred@1958
    68
			return 0;
pred@1958
    69
		}
pred@1958
    70
	}
pred@1958
    71
pred@1958
    72
	hook = g_OutputManager.NewHook();
pred@1958
    73
pred@1958
    74
	hook->entity_filter = pEdict->m_NetworkSerialNumber;
pred@1958
    75
	hook->entity_index = engine->IndexOfEdict(pEdict);
pred@1958
    76
	hook->only_once= !!params[4];
pred@1958
    77
	hook->pf = pFunction;
pred@1958
    78
	hook->m_parent = pOutputName;
pred@1958
    79
	hook->in_use = false;
pred@1958
    80
	hook->delete_me = false;
pred@1958
    81
pred@1958
    82
	pOutputName->hooks.push_back(hook);
pred@1958
    83
pred@1958
    84
	g_OutputManager.OnHookAdded();
pred@1958
    85
pred@1958
    86
	IPlugin *pPlugin = plsys->FindPluginByContext(pContext->GetContext());
pred@1958
    87
	SourceHook::List<omg_hooks *> *pList = NULL;
pred@1958
    88
pred@1958
    89
	if (!pPlugin->GetProperty("OutputHookList", (void **)&pList, false) || !pList)
pred@1958
    90
	{
pred@1958
    91
		pList = new SourceHook::List<omg_hooks *>;
pred@1958
    92
		pPlugin->SetProperty("OutputHookList", pList);
pred@1958
    93
	}
pred@1958
    94
pred@1958
    95
	pList->push_back(hook);
pred@1958
    96
pred@1958
    97
	return 1;
pred@1958
    98
}
pred@1958
    99
pred@1958
   100
// HookEntityOutput(const String:classname[], const String:output[], function);
pred@1958
   101
cell_t HookEntityOutput(IPluginContext *pContext, const cell_t *params)
pred@1958
   102
{
pred@1958
   103
	if (!g_OutputManager.IsEnabled())
pred@1958
   104
	{
pred@1958
   105
		return pContext->ThrowNativeError("Entity Outputs are disabled - See error logs for details");
pred@1958
   106
	}
pred@1958
   107
pred@1958
   108
	//Find or create the base structures for this classname and the output
pred@1958
   109
	char *classname;
pred@1958
   110
	pContext->LocalToString(params[1], &classname);
pred@1958
   111
pred@1958
   112
	char *outputname;
pred@1958
   113
	pContext->LocalToString(params[2], &outputname);
pred@1958
   114
pred@1958
   115
	OutputNameStruct *pOutputName = g_OutputManager.FindOutputPointer((const char *)classname, outputname, true);
pred@1958
   116
pred@1958
   117
	//Check for an existing identical hook
pred@1958
   118
	SourceHook::List<omg_hooks *>::iterator _iter;
pred@1958
   119
pred@1958
   120
	omg_hooks *hook;
pred@1958
   121
pred@1958
   122
	IPluginFunction *pFunction;
pred@1958
   123
	pFunction = pContext->GetFunctionById(params[3]);
pred@1958
   124
pred@1958
   125
	for (_iter=pOutputName->hooks.begin(); _iter!=pOutputName->hooks.end(); _iter++)
pred@1958
   126
	{
pred@1958
   127
		hook = (omg_hooks *)*_iter;
pred@1958
   128
		if (hook->pf == pFunction && hook->entity_filter == -1)
pred@1958
   129
		{
pred@1958
   130
			//already hooked to this function...
pred@1958
   131
			//throw an error or just let them get away with stupidity?
pred@1958
   132
			// seems like poor coding if they dont know if something is hooked or not
pred@1958
   133
			return 0;
pred@1958
   134
		}
pred@1958
   135
	}
pred@1958
   136
pred@1958
   137
	hook = g_OutputManager.NewHook();
pred@1958
   138
pred@1958
   139
	hook->entity_filter = -1;
pred@1958
   140
	hook->pf = pFunction;
pred@1958
   141
	hook->m_parent = pOutputName;
pred@1958
   142
	hook->in_use = false;
pred@1958
   143
	hook->delete_me = false;
pred@1958
   144
pred@1958
   145
	pOutputName->hooks.push_back(hook);
pred@1958
   146
pred@1958
   147
	g_OutputManager.OnHookAdded();
pred@1958
   148
pred@1958
   149
	IPlugin *pPlugin = plsys->FindPluginByContext(pContext->GetContext());
pred@1958
   150
	SourceHook::List<omg_hooks *> *pList = NULL;
pred@1958
   151
pred@1958
   152
	if (!pPlugin->GetProperty("OutputHookList", (void **)&pList, false) || !pList)
pred@1958
   153
	{
pred@1958
   154
		pList = new SourceHook::List<omg_hooks *>;
pred@1958
   155
		pPlugin->SetProperty("OutputHookList", pList);
pred@1958
   156
	}
pred@1958
   157
pred@1958
   158
	pList->push_back(hook);
pred@1958
   159
pred@1958
   160
	return 1;
pred@1958
   161
}
pred@1958
   162
pred@1958
   163
// UnHookEntityOutput(const String:classname[], const String:output[], EntityOutput:callback);
pred@1958
   164
cell_t UnHookEntityOutput(IPluginContext *pContext, const cell_t *params)
pred@1958
   165
{
pred@1958
   166
	if (!g_OutputManager.IsEnabled())
pred@1958
   167
	{
pred@1958
   168
		return pContext->ThrowNativeError("Entity Outputs are disabled - See error logs for details");
pred@1958
   169
	}
pred@1958
   170
pred@1958
   171
	char *classname;
pred@1958
   172
	pContext->LocalToString(params[1], &classname);
pred@1958
   173
pred@1958
   174
	char *outputname;
pred@1958
   175
	pContext->LocalToString(params[2], &outputname);
pred@1958
   176
pred@1958
   177
	OutputNameStruct *pOutputName = g_OutputManager.FindOutputPointer((const char *)classname, outputname, false);
pred@1958
   178
pred@1958
   179
	if (!pOutputName)
pred@1958
   180
	{
pred@1958
   181
		return 0;
pred@1958
   182
	}
pred@1958
   183
pred@1958
   184
	//Check for an existing identical hook
pred@1958
   185
	SourceHook::List<omg_hooks *>::iterator _iter;
pred@1958
   186
pred@1958
   187
	omg_hooks *hook;
pred@1958
   188
pred@1958
   189
	IPluginFunction *pFunction;
pred@1958
   190
	pFunction = pContext->GetFunctionById(params[3]);
pred@1958
   191
pred@1958
   192
	for (_iter=pOutputName->hooks.begin(); _iter!=pOutputName->hooks.end(); _iter++)
pred@1958
   193
	{
pred@1958
   194
		hook = (omg_hooks *)*_iter;
pred@1958
   195
		if (hook->pf == pFunction && hook->entity_filter == -1)
pred@1958
   196
		{
pred@1958
   197
			// remove this hook.
pred@1958
   198
			if (hook->in_use)
pred@1958
   199
			{
pred@1958
   200
				hook->delete_me = true;
pred@1958
   201
				return 1;
pred@1958
   202
			}
pred@1958
   203
pred@1958
   204
			pOutputName->hooks.erase(_iter);
pred@1958
   205
			g_OutputManager.CleanUpHook(hook);
pred@1958
   206
pred@1958
   207
			return 1;
pred@1958
   208
		}
pred@1958
   209
	}
pred@1958
   210
pred@1958
   211
	return 0;
pred@1958
   212
}
pred@1958
   213
pred@1958
   214
// UnHookSingleEntityOutput(entity, const String:output[], EntityOutput:callback);
pred@1958
   215
cell_t UnHookSingleEntityOutput(IPluginContext *pContext, const cell_t *params)
pred@1958
   216
{
pred@1958
   217
	if (!g_OutputManager.IsEnabled())
pred@1958
   218
	{
pred@1958
   219
		return pContext->ThrowNativeError("Entity Outputs are disabled - See error logs for details");
pred@1958
   220
	}
pred@1958
   221
pred@1958
   222
	// Find the classname of the entity and lookup the classname and output structures
pred@1958
   223
	edict_t *pEdict = engine->PEntityOfEntIndex(params[1]);
pred@1958
   224
	if (!pEdict)
pred@1958
   225
	{
pred@1958
   226
		return pContext->ThrowNativeError("Invalid Entity index %i", params[1]);
pred@1958
   227
	}
pred@1958
   228
pred@1958
   229
	const char *classname = pEdict->GetClassName();
pred@1958
   230
pred@1958
   231
	char *outputname;
pred@1958
   232
	pContext->LocalToString(params[2], &outputname);
pred@1958
   233
pred@1958
   234
	OutputNameStruct *pOutputName = g_OutputManager.FindOutputPointer((const char *)classname, outputname, false);
pred@1958
   235
pred@1958
   236
	if (!pOutputName)
pred@1958
   237
	{
pred@1958
   238
		return 0;
pred@1958
   239
	}
pred@1958
   240
pred@1958
   241
	//Check for an existing identical hook
pred@1958
   242
	SourceHook::List<omg_hooks *>::iterator _iter;
pred@1958
   243
pred@1958
   244
	omg_hooks *hook;
pred@1958
   245
pred@1958
   246
	IPluginFunction *pFunction;
pred@1958
   247
	pFunction = pContext->GetFunctionById(params[3]);
pred@1958
   248
pred@1958
   249
	for (_iter=pOutputName->hooks.begin(); _iter!=pOutputName->hooks.end(); _iter++)
pred@1958
   250
	{
pred@1958
   251
		hook = (omg_hooks *)*_iter;
pred@1958
   252
		if (hook->pf == pFunction && hook->entity_index == engine->IndexOfEdict(pEdict))
pred@1958
   253
		{
pred@1958
   254
			// remove this hook.
pred@1958
   255
			if (hook->in_use)
pred@1958
   256
			{
pred@1958
   257
				hook->delete_me = true;
pred@1958
   258
				return 1;
pred@1958
   259
			}
pred@1958
   260
pred@1958
   261
			pOutputName->hooks.erase(_iter);
pred@1958
   262
			g_OutputManager.CleanUpHook(hook);
pred@1958
   263
pred@1958
   264
			return 1;
pred@1958
   265
		}
pred@1958
   266
	}
pred@1958
   267
pred@1958
   268
	return 0;
pred@1958
   269
}
pred@1958
   270
pred@1958
   271
#if 0
pred@1958
   272
static cell_t GetVariantType(IPluginContext *pContext, const cell_t *params)
pred@1958
   273
{
pred@1958
   274
	Handle_t hndl = static_cast<Handle_t>(params[1]);
pred@1958
   275
	HandleError err;
pred@1958
   276
	varhandle_t *pInfo;
pred@1958
   277
	HandleSecurity sec;
pred@1958
   278
 
pred@1958
   279
	sec.pOwner = NULL;
pred@1958
   280
	sec.pIdentity = myself->GetIdentity();
pred@1958
   281
pred@1958
   282
	if ((err=handlesys->ReadHandle(hndl, g_OutputManager.VariantHandle, &sec, (void **)&pInfo))
pred@1958
   283
		!= HandleError_None)
pred@1958
   284
	{
pred@1958
   285
		return pContext->ThrowNativeError("Invalid variant handle %x (error %d)", hndl, err);
pred@1958
   286
	}
pred@1958
   287
pred@1958
   288
	return pInfo->crab.FieldType();
pred@1958
   289
}
pred@1958
   290
pred@1958
   291
static cell_t GetVariantInt(IPluginContext *pContext, const cell_t *params)
pred@1958
   292
{
pred@1958
   293
	Handle_t hndl = static_cast<Handle_t>(params[1]);
pred@1958
   294
	HandleError err;
pred@1958
   295
	varhandle_t *pInfo;
pred@1958
   296
	HandleSecurity sec;
pred@1958
   297
 
pred@1958
   298
	sec.pOwner = NULL;
pred@1958
   299
	sec.pIdentity = myself->GetIdentity();
pred@1958
   300
pred@1958
   301
pred@1958
   302
	if ((err=handlesys->ReadHandle(hndl, g_OutputManager.VariantHandle, &sec, (void **)&pInfo))
pred@1958
   303
		!= HandleError_None)
pred@1958
   304
	{
pred@1958
   305
		return pContext->ThrowNativeError("Invalid variant handle %x (error %d)", hndl, err);
pred@1958
   306
	}
pred@1958
   307
pred@1958
   308
	if (pInfo->crab.FieldType() != FIELD_INTEGER)
pred@1958
   309
	{
pred@1958
   310
		return pContext->ThrowNativeError("Variant is not an integer");
pred@1958
   311
	}
pred@1958
   312
pred@1958
   313
	return pInfo->crab.Int();
pred@1958
   314
}
pred@1958
   315
pred@1958
   316
static cell_t GetVariantBool(IPluginContext *pContext, const cell_t *params)
pred@1958
   317
{
pred@1958
   318
	Handle_t hndl = static_cast<Handle_t>(params[1]);
pred@1958
   319
	HandleError err;
pred@1958
   320
	varhandle_t *pInfo;
pred@1958
   321
	HandleSecurity sec;
pred@1958
   322
 
pred@1958
   323
	sec.pOwner = NULL;
pred@1958
   324
	sec.pIdentity = myself->GetIdentity();
pred@1958
   325
pred@1958
   326
	if ((err=handlesys->ReadHandle(hndl, g_OutputManager.VariantHandle, &sec, (void **)&pInfo))
pred@1958
   327
		!= HandleError_None)
pred@1958
   328
	{
pred@1958
   329
		return pContext->ThrowNativeError("Invalid variant handle %x (error %d)", hndl, err);
pred@1958
   330
	}
pred@1958
   331
pred@1958
   332
	if (pInfo->crab.FieldType() != FIELD_BOOLEAN)
pred@1958
   333
	{
pred@1958
   334
		return pContext->ThrowNativeError("Variant is not a boolean");
pred@1958
   335
	}
pred@1958
   336
pred@1958
   337
	return pInfo->crab.Bool();
pred@1958
   338
}
pred@1958
   339
pred@1958
   340
static cell_t GetVariantEntity(IPluginContext *pContext, const cell_t *params)
pred@1958
   341
{
pred@1958
   342
	Handle_t hndl = static_cast<Handle_t>(params[1]);
pred@1958
   343
	HandleError err;
pred@1958
   344
	varhandle_t *pInfo;
pred@1958
   345
	HandleSecurity sec;
pred@1958
   346
 
pred@1958
   347
	sec.pOwner = NULL;
pred@1958
   348
	sec.pIdentity = myself->GetIdentity();
pred@1958
   349
pred@1958
   350
	if ((err=handlesys->ReadHandle(hndl, g_OutputManager.VariantHandle, &sec, (void **)&pInfo))
pred@1958
   351
		!= HandleError_None)
pred@1958
   352
	{
pred@1958
   353
		return pContext->ThrowNativeError("Invalid variant handle %x (error %d)", hndl, err);
pred@1958
   354
	}
pred@1958
   355
pred@1958
   356
	if (pInfo->crab.FieldType() != FIELD_EHANDLE)
pred@1958
   357
	{
pred@1958
   358
		return pContext->ThrowNativeError("Variant is not an entity");
pred@1958
   359
	}
pred@1958
   360
pred@1958
   361
	edict_t *pEdict = g_OutputManager.BaseHandleToEdict((CBaseHandle)pInfo->crab.Entity());
pred@1958
   362
pred@1958
   363
	return engine->IndexOfEdict(pEdict);
pred@1958
   364
}
pred@1958
   365
pred@1958
   366
static cell_t GetVariantFloat(IPluginContext *pContext, const cell_t *params)
pred@1958
   367
{
pred@1958
   368
	Handle_t hndl = static_cast<Handle_t>(params[1]);
pred@1958
   369
	HandleError err;
pred@1958
   370
	varhandle_t *pInfo;
pred@1958
   371
	HandleSecurity sec;
pred@1958
   372
 
pred@1958
   373
	sec.pOwner = NULL;
pred@1958
   374
	sec.pIdentity = myself->GetIdentity();
pred@1958
   375
pred@1958
   376
	if ((err=handlesys->ReadHandle(hndl, g_OutputManager.VariantHandle, &sec, (void **)&pInfo))
pred@1958
   377
		!= HandleError_None)
pred@1958
   378
	{
pred@1958
   379
		return pContext->ThrowNativeError("Invalid variant handle %x (error %d)", hndl, err);
pred@1958
   380
	}
pred@1958
   381
pred@1958
   382
	if (pInfo->crab.FieldType() != FIELD_FLOAT)
pred@1958
   383
	{
pred@1958
   384
		return pContext->ThrowNativeError("Variant is not a float");
pred@1958
   385
	}
pred@1958
   386
pred@1958
   387
	return sp_ftoc(pInfo->crab.Float());
pred@1958
   388
}
pred@1958
   389
pred@1958
   390
static cell_t GetVariantVector(IPluginContext *pContext, const cell_t *params)
pred@1958
   391
{
pred@1958
   392
	Handle_t hndl = static_cast<Handle_t>(params[1]);
pred@1958
   393
	HandleError err;
pred@1958
   394
	varhandle_t *pInfo;
pred@1958
   395
	HandleSecurity sec;
pred@1958
   396
 
pred@1958
   397
	sec.pOwner = NULL;
pred@1958
   398
	sec.pIdentity = myself->GetIdentity();
pred@1958
   399
pred@1958
   400
	if ((err=handlesys->ReadHandle(hndl, g_OutputManager.VariantHandle, &sec, (void **)&pInfo))
pred@1958
   401
		!= HandleError_None)
pred@1958
   402
	{
pred@1958
   403
		return pContext->ThrowNativeError("Invalid variant handle %x (error %d)", hndl, err);
pred@1958
   404
	}
pred@1958
   405
pred@1958
   406
	if (pInfo->crab.FieldType() != FIELD_VECTOR)
pred@1958
   407
	{
pred@1958
   408
		return pContext->ThrowNativeError("Variant is not a vector");
pred@1958
   409
	}
pred@1958
   410
		
pred@1958
   411
	cell_t *r;
pred@1958
   412
	pContext->LocalToPhysAddr(params[2], &r);
pred@1958
   413
pred@1958
   414
	Vector temp;
pred@1958
   415
	pInfo->crab.Vector3D(temp);
pred@1958
   416
pred@1958
   417
	r[0] = sp_ftoc(temp[0]);
pred@1958
   418
	r[1] = sp_ftoc(temp[1]);
pred@1958
   419
	r[2] = sp_ftoc(temp[2]);
pred@1958
   420
pred@1958
   421
	return 0;
pred@1958
   422
}
pred@1958
   423
pred@1958
   424
static cell_t GetVariantColour(IPluginContext *pContext, const cell_t *params)
pred@1958
   425
{
pred@1958
   426
	Handle_t hndl = static_cast<Handle_t>(params[1]);
pred@1958
   427
	HandleError err;
pred@1958
   428
	varhandle_t *pInfo;
pred@1958
   429
	HandleSecurity sec;
pred@1958
   430
 
pred@1958
   431
	sec.pOwner = NULL;
pred@1958
   432
	sec.pIdentity = myself->GetIdentity();
pred@1958
   433
pred@1958
   434
	if ((err=handlesys->ReadHandle(hndl, g_OutputManager.VariantHandle, &sec, (void **)&pInfo))
pred@1958
   435
		!= HandleError_None)
pred@1958
   436
	{
pred@1958
   437
		return pContext->ThrowNativeError("Invalid variant handle %x (error %d)", hndl, err);
pred@1958
   438
	}
pred@1958
   439
pred@1958
   440
	if (pInfo->crab.FieldType() != FIELD_COLOR32)
pred@1958
   441
	{
pred@1958
   442
		return pContext->ThrowNativeError("Variant is not a colour");
pred@1958
   443
	}
pred@1958
   444
		
pred@1958
   445
	cell_t *r;
pred@1958
   446
	pContext->LocalToPhysAddr(params[2], &r);
pred@1958
   447
pred@1958
   448
	color32 temp = pInfo->crab.Color32();
pred@1958
   449
pred@1958
   450
	r[0] = temp.r;
pred@1958
   451
	r[1] = temp.g;
pred@1958
   452
	r[2] = temp.b;
pred@1958
   453
	r[4] = temp.a;
pred@1958
   454
pred@1958
   455
	return 0;
pred@1958
   456
}
pred@1958
   457
pred@1958
   458
static cell_t GetVariantString(IPluginContext *pContext, const cell_t *params)
pred@1958
   459
{
pred@1958
   460
	Handle_t hndl = static_cast<Handle_t>(params[1]);
pred@1958
   461
	HandleError err;
pred@1958
   462
	varhandle_t *pInfo;
pred@1958
   463
	HandleSecurity sec;
pred@1958
   464
 
pred@1958
   465
	sec.pOwner = NULL;
pred@1958
   466
	sec.pIdentity = myself->GetIdentity();
pred@1958
   467
pred@1958
   468
	if ((err=handlesys->ReadHandle(hndl, g_OutputManager.VariantHandle, &sec, (void **)&pInfo))
pred@1958
   469
		!= HandleError_None)
pred@1958
   470
	{
pred@1958
   471
		return pContext->ThrowNativeError("Invalid variant handle %x (error %d)", hndl, err);
pred@1958
   472
	}
pred@1958
   473
		
pred@1958
   474
	char *dest;
pred@1958
   475
	const char *src = pInfo->crab.String();
pred@1958
   476
	size_t len;
pred@1958
   477
 
pred@1958
   478
	pContext->LocalToString(params[2], &dest);
pred@1958
   479
 
pred@1958
   480
	/* Perform bounds checking */
pred@1958
   481
	len = strlen(src);
pred@1958
   482
	if (len >= (unsigned)params[3])
pred@1958
   483
	{
pred@1958
   484
		len = params[3] - 1;
pred@1958
   485
	} else {
pred@1958
   486
		len = params[3];
pred@1958
   487
	}
pred@1958
   488
 
pred@1958
   489
	/* Copy */
pred@1958
   490
	memmove(dest, src, len);
pred@1958
   491
 
pred@1958
   492
	dest[len] = '\0';
pred@1958
   493
 
pred@1958
   494
	return 0;
pred@1958
   495
}
pred@1958
   496
#endif
pred@1958
   497
pred@1958
   498
sp_nativeinfo_t g_EntOutputNatives[] =
pred@1958
   499
{
pred@1958
   500
	{"HookEntityOutput",			HookEntityOutput},
pred@1960
   501
	{"UnhookEntityOutput",			UnHookEntityOutput},
pred@1958
   502
	{"HookSingleEntityOutput",		HookSingleEntityOutput},
pred@1960
   503
	{"UnhookSingleEntityOutput",	UnHookSingleEntityOutput},
pred@1958
   504
#if 0 //Removed because we don't need them
pred@1958
   505
	{"GetVariantType",				GetVariantType},
pred@1958
   506
	{"GetVariantInt",				GetVariantInt},
pred@1958
   507
	{"GetVariantFloat",				GetVariantFloat},
pred@1958
   508
	{"GetVariantBool",				GetVariantBool},
pred@1958
   509
	{"GetVariantString",			GetVariantString},
pred@1958
   510
	{"GetVariantEntity",			GetVariantEntity},
pred@1958
   511
	{"GetVariantVector",			GetVariantVector},
pred@1958
   512
	{"GetVariantColour",			GetVariantColour},
pred@1958
   513
#endif
pred@1958
   514
	{NULL,							NULL},
pred@1958
   515
};
pred@1958
   516
pred@1958
   517
#if 0
pred@1958
   518
//Include file stuff that wasn't needed:
pred@1958
   519
pred@1958
   520
enum FieldType
pred@1958
   521
{
pred@1958
   522
	FieldType_Float = 1,
pred@1958
   523
	FieldType_String = 2,
pred@1958
   524
	FieldType_Vector = 3,
pred@1958
   525
	FieldType_Int = 5,
pred@1958
   526
	FieldType_Bool = 6,
pred@1958
   527
	FieldType_Colour = 9,
pred@1958
   528
	FieldType_Entity = 13
pred@1958
   529
}
pred@1958
   530
pred@1958
   531
/**
pred@1958
   532
 * Gets the current type of a variant handle
pred@1958
   533
 *
pred@1958
   534
 * @param variant		A variant handle.
pred@1958
   535
 * @return				Current type of the variant.
pred@1958
   536
 */
pred@1958
   537
native FieldType:GetVariantType(Handle:variant);
pred@1958
   538
pred@1958
   539
/**
pred@1958
   540
 * Retreives a Float from a variant handle.
pred@1958
   541
 *
pred@1958
   542
 * @param variant		A variant handle.
pred@1958
   543
 * @return				Float value.
pred@1958
   544
 * @error				Variant handle is not type FieldType_Float
pred@1958
   545
 */
pred@1958
   546
native Float:GetVariantFloat(Handle:variant);
pred@1958
   547
pred@1958
   548
/**
pred@1958
   549
 * Retreives an Integer from a variant handle.
pred@1958
   550
 *
pred@1958
   551
 * @param variant		A variant handle.
pred@1958
   552
 * @return				Int value.
pred@1958
   553
 * @error				Variant handle is not type FieldType_Int
pred@1958
   554
 */
pred@1958
   555
native GetVariantInt(Handle:variant);
pred@1958
   556
pred@1958
   557
/**
pred@1958
   558
 * Retreives a bool from a variant handle.
pred@1958
   559
 *
pred@1958
   560
 * @param variant		A variant handle.
pred@1958
   561
 * @return				bool value.
pred@1958
   562
 * @error				Variant handle is not type FieldType_Bool
pred@1958
   563
 */
pred@1958
   564
native bool:GetVariantBool(Handle:variant);
pred@1958
   565
pred@1958
   566
/**
pred@1958
   567
 * Retreives an entity from a variant handle.
pred@1958
   568
 *
pred@1958
   569
 * @param variant		A variant handle.
pred@1958
   570
 * @return				Entity Index.
pred@1958
   571
 * @error				Variant handle is not type FieldType_Entity
pred@1958
   572
 */
pred@1958
   573
native GetVariantEntity(Handle:variant);
pred@1958
   574
pred@1958
   575
/**
pred@1958
   576
 * Retreives a Vector from a variant handle.
pred@1958
   577
 *
pred@1958
   578
 * @param variant		A variant handle.
pred@1958
   579
 * @param vec			buffer to store the Vector.
pred@1958
   580
 * @noreturn
pred@1958
   581
 * @error				Variant handle is not type FieldType_Vector
pred@1958
   582
 */
pred@1958
   583
native GetVariantVector(Handle:variant, Float:vec[3]);
pred@1958
   584
pred@1958
   585
/**
pred@1958
   586
 * Retreives a String from a variant handle.
pred@1958
   587
 *
pred@1958
   588
 * @note 	This native does not require the variant to be FieldType_String,
pred@1958
   589
 *			It can convert any type into a string representation.
pred@1958
   590
 *
pred@1958
   591
 * @param variant		A variant handle.
pred@1958
   592
 * @param buffer		buffer to store the string in
pred@1958
   593
 * @param maxlen		Maximum length of buffer.
pred@1958
   594
 * @noreturn
pred@1958
   595
 */
pred@1958
   596
native GetVariantString(Handle:variant, String:buffer[], maxlen);
pred@1958
   597
pred@1958
   598
/**
pred@1958
   599
 * Retreives a Colour from a variant handle.
pred@1958
   600
 *
pred@1958
   601
 * @note Colour is in format r,g,b,a
pred@1958
   602
 *
pred@1958
   603
 * @param variant		A variant handle.
pred@1958
   604
 * @param colour		buffer array to store the colour in.
pred@1958
   605
 * @noreturn
pred@1958
   606
 * @error				Variant handle is not type FieldType_Colour
pred@1958
   607
 */
pred@1958
   608
native GetVariantColour(Handle:variant, colour[4]);
pred@1958
   609
#endif