core/smn_events.cpp
author Scott Ehlert <ds@alliedmods.net>
Sun Mar 04 04:05:03 2007 +0000 (2007-03-04)
changeset 576 50696154c0b8
child 577 39a746736a0f
permissions -rw-r--r--
Initial import of event stuff: Natives to hook and fire game events
Also made some minor internal changes to convars
ds@576
     1
/**
ds@576
     2
* ===============================================================
ds@576
     3
* SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
ds@576
     4
* ===============================================================
ds@576
     5
*
ds@576
     6
* This file is not open source and may not be copied without explicit
ds@576
     7
* written permission of AlliedModders LLC.  This file may not be redistributed 
ds@576
     8
* in whole or significant part.
ds@576
     9
* For information, see LICENSE.txt or http://www.sourcemod.net/license.php
ds@576
    10
*
ds@576
    11
* Version: $Id$
ds@576
    12
*/
ds@576
    13
ds@576
    14
#include "sm_globals.h"
ds@576
    15
#include "sourcemm_api.h"
ds@576
    16
#include "HandleSys.h"
ds@576
    17
#include "EventManager.h"
ds@576
    18
ds@576
    19
static cell_t sm_HookEvent(IPluginContext *pContext, const cell_t *params)
ds@576
    20
{
ds@576
    21
	char *name;
ds@576
    22
	IPluginFunction *pFunction;
ds@576
    23
ds@576
    24
	pContext->LocalToString(params[1], &name);
ds@576
    25
	pFunction = pContext->GetFunctionById(params[2]);
ds@576
    26
ds@576
    27
	if (!pFunction)
ds@576
    28
	{
ds@576
    29
		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
ds@576
    30
	}
ds@576
    31
ds@576
    32
	if (g_EventManager.HookEvent(name, pFunction, static_cast<EventHookMode>(params[3])) == EventHookErr_InvalidEvent)
ds@576
    33
	{
ds@576
    34
		return pContext->ThrowNativeError("Game event \"%s\" does not exist", name);
ds@576
    35
	}
ds@576
    36
ds@576
    37
	return 1;
ds@576
    38
}
ds@576
    39
ds@576
    40
static cell_t sm_UnhookEvent(IPluginContext *pContext, const cell_t *params)
ds@576
    41
{
ds@576
    42
	char *name;
ds@576
    43
	IPluginFunction *pFunction;
ds@576
    44
ds@576
    45
	pContext->LocalToString(params[1], &name);
ds@576
    46
	pFunction = pContext->GetFunctionById(params[2]);
ds@576
    47
ds@576
    48
	if (!pFunction)
ds@576
    49
	{
ds@576
    50
		return pContext->ThrowNativeError("Invalid function id (%X)", params[2]);
ds@576
    51
	}
ds@576
    52
ds@576
    53
	EventHookError err = g_EventManager.UnhookEvent(name, pFunction, static_cast<EventHookMode>(params[3]));
ds@576
    54
ds@576
    55
	/* Possible errors that UnhookGameEvent can return */
ds@576
    56
	if (err == EventHookErr_NotActive)
ds@576
    57
	{
ds@576
    58
		return pContext->ThrowNativeError("Game event \"%s\" has no active hook", name);
ds@576
    59
	} else if (err == EventHookErr_InvalidCallback) {
ds@576
    60
		return pContext->ThrowNativeError("Invalid hook callback specified for game event \"%s\"", name);
ds@576
    61
	}
ds@576
    62
ds@576
    63
	return 1;
ds@576
    64
}
ds@576
    65
ds@576
    66
static cell_t sm_CreateEvent(IPluginContext *pContext, const cell_t *params)
ds@576
    67
{
ds@576
    68
	IGameEvent *pEvent;
ds@576
    69
	EventInfo *pInfo;
ds@576
    70
	char *name;
ds@576
    71
ds@576
    72
	pContext->LocalToString(params[1], &name);
ds@576
    73
ds@576
    74
	pEvent = gameevents->CreateEvent(name, true);
ds@576
    75
ds@576
    76
	if (pEvent)
ds@576
    77
	{
ds@576
    78
		pInfo = new EventInfo;
ds@576
    79
		pInfo->pEvent = pEvent;
ds@576
    80
		pInfo->canDelete = true;
ds@576
    81
ds@576
    82
		return g_HandleSys.CreateHandle(g_EventManager.GetHandleType(), pInfo, pContext->GetIdentity(), g_pCoreIdent, NULL);
ds@576
    83
	}
ds@576
    84
ds@576
    85
	return BAD_HANDLE;
ds@576
    86
}
ds@576
    87
ds@576
    88
static cell_t sm_FireEvent(IPluginContext *pContext, const cell_t *params)
ds@576
    89
{
ds@576
    90
	Handle_t hndl = static_cast<Handle_t>(params[1]);
ds@576
    91
	HandleError err;
ds@576
    92
	EventInfo *pInfo;
ds@576
    93
ds@576
    94
	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
ds@576
    95
		!= HandleError_None)
ds@576
    96
	{
ds@576
    97
		return pContext->ThrowNativeError("Invalid GameEvent Handle %x (error %d)", hndl, err);
ds@576
    98
	}
ds@576
    99
ds@576
   100
	if ((params[3] & EVENT_PASSTHRU_ALL) == false)
ds@576
   101
	{
ds@576
   102
		/* Set whether or not SourceMod plugins should be notified */
ds@576
   103
		g_EventManager.SetNotifyState(false);
ds@576
   104
	}
ds@576
   105
ds@576
   106
	/* Fire game event */
ds@576
   107
	gameevents->FireEvent(pInfo->pEvent, params[2] ? true : false);
ds@576
   108
ds@576
   109
	pInfo->canDelete = false;
ds@576
   110
ds@576
   111
	/* Free handle on game event */
ds@576
   112
	HandleSecurity sec = { pContext->GetIdentity(), g_pCoreIdent };
ds@576
   113
	g_HandleSys.FreeHandle(hndl, &sec);
ds@576
   114
ds@576
   115
	/* Free EventInfo memory */
ds@576
   116
	delete pInfo;
ds@576
   117
ds@576
   118
	return 1;
ds@576
   119
}
ds@576
   120
ds@576
   121
static cell_t sm_CancelCreatedEvent(IPluginContext *pContext, const cell_t *params)
ds@576
   122
{
ds@576
   123
	Handle_t hndl = static_cast<Handle_t>(params[1]);
ds@576
   124
	HandleError err;
ds@576
   125
	EventInfo *pInfo;
ds@576
   126
ds@576
   127
	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
ds@576
   128
		!= HandleError_None)
ds@576
   129
	{
ds@576
   130
		return pContext->ThrowNativeError("Invalid GameEvent Handle %x (error %d)", hndl, err);
ds@576
   131
	}
ds@576
   132
ds@576
   133
	gameevents->FreeEvent(pInfo->pEvent);
ds@576
   134
ds@576
   135
	// Free GameEventInfo memory
ds@576
   136
	delete pInfo;
ds@576
   137
ds@576
   138
	// Free handle on game event
ds@576
   139
	HandleSecurity sec = { pContext->GetIdentity(), g_pCoreIdent };
ds@576
   140
	g_HandleSys.FreeHandle(hndl, &sec);
ds@576
   141
ds@576
   142
	return 1;
ds@576
   143
}
ds@576
   144
ds@576
   145
static cell_t sm_GetEventName(IPluginContext *pContext, const cell_t *params)
ds@576
   146
{
ds@576
   147
	Handle_t hndl = static_cast<Handle_t>(params[1]);
ds@576
   148
	HandleError err;
ds@576
   149
	EventInfo *pInfo;
ds@576
   150
ds@576
   151
	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
ds@576
   152
		!= HandleError_None)
ds@576
   153
	{
ds@576
   154
		return pContext->ThrowNativeError("Invalid GameEvent Handle %x (error %d)", hndl, err);
ds@576
   155
	}
ds@576
   156
ds@576
   157
	pContext->StringToLocalUTF8(params[2], params[3], pInfo->pEvent->GetName(), NULL);
ds@576
   158
ds@576
   159
	return 1;
ds@576
   160
}
ds@576
   161
ds@576
   162
static cell_t sm_GetEventBool(IPluginContext *pContext, const cell_t *params)
ds@576
   163
{
ds@576
   164
	Handle_t hndl = static_cast<Handle_t>(params[1]);
ds@576
   165
	HandleError err;
ds@576
   166
	EventInfo *pInfo;
ds@576
   167
ds@576
   168
	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
ds@576
   169
		!= HandleError_None)
ds@576
   170
	{
ds@576
   171
		return pContext->ThrowNativeError("Invalid GameEvent Handle %x (error %d)", hndl, err);
ds@576
   172
	}
ds@576
   173
ds@576
   174
	char *key;
ds@576
   175
	pContext->LocalToString(params[2], &key);
ds@576
   176
ds@576
   177
	return pInfo->pEvent->GetBool(key);
ds@576
   178
}
ds@576
   179
ds@576
   180
static cell_t sm_GetEventInt(IPluginContext *pContext, const cell_t *params)
ds@576
   181
{
ds@576
   182
	Handle_t hndl = static_cast<Handle_t>(params[1]);
ds@576
   183
	HandleError err;
ds@576
   184
	EventInfo *pInfo;
ds@576
   185
ds@576
   186
	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
ds@576
   187
		!= HandleError_None)
ds@576
   188
	{
ds@576
   189
		return pContext->ThrowNativeError("Invalid GameEvent Handle %x (error %d)", hndl, err);
ds@576
   190
	}
ds@576
   191
ds@576
   192
	char *key;
ds@576
   193
	pContext->LocalToString(params[2], &key);
ds@576
   194
ds@576
   195
	return pInfo->pEvent->GetInt(key);
ds@576
   196
}
ds@576
   197
ds@576
   198
static cell_t sm_GetEventFloat(IPluginContext *pContext, const cell_t *params)
ds@576
   199
{
ds@576
   200
	Handle_t hndl = static_cast<Handle_t>(params[1]);
ds@576
   201
	HandleError err;
ds@576
   202
	EventInfo *pInfo;
ds@576
   203
ds@576
   204
	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
ds@576
   205
		!= HandleError_None)
ds@576
   206
	{
ds@576
   207
		return pContext->ThrowNativeError("Invalid GameEvent Handle %x (error %d)", hndl, err);
ds@576
   208
	}
ds@576
   209
ds@576
   210
	char *key;
ds@576
   211
	pContext->LocalToString(params[2], &key);
ds@576
   212
ds@576
   213
	float value = pInfo->pEvent->GetFloat(key);
ds@576
   214
ds@576
   215
	return sp_ftoc(value);
ds@576
   216
}
ds@576
   217
ds@576
   218
static cell_t sm_GetEventString(IPluginContext *pContext, const cell_t *params)
ds@576
   219
{
ds@576
   220
	Handle_t hndl = static_cast<Handle_t>(params[1]);
ds@576
   221
	HandleError err;
ds@576
   222
	EventInfo *pInfo;
ds@576
   223
ds@576
   224
	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
ds@576
   225
		!= HandleError_None)
ds@576
   226
	{
ds@576
   227
		return pContext->ThrowNativeError("Invalid GameEvent Handle %x (error %d)", hndl, err);
ds@576
   228
	}
ds@576
   229
ds@576
   230
	char *key;
ds@576
   231
	pContext->LocalToString(params[2], &key);
ds@576
   232
ds@576
   233
	pContext->StringToLocalUTF8(params[3], params[4], pInfo->pEvent->GetString(key), NULL);
ds@576
   234
ds@576
   235
	return 1;
ds@576
   236
}
ds@576
   237
ds@576
   238
static cell_t sm_SetEventBool(IPluginContext *pContext, const cell_t *params)
ds@576
   239
{
ds@576
   240
	Handle_t hndl = static_cast<Handle_t>(params[1]);
ds@576
   241
	HandleError err;
ds@576
   242
	EventInfo *pInfo;
ds@576
   243
ds@576
   244
	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
ds@576
   245
		!= HandleError_None)
ds@576
   246
	{
ds@576
   247
		return pContext->ThrowNativeError("Invalid GameEvent Handle %x (error %d)", hndl, err);
ds@576
   248
	}
ds@576
   249
ds@576
   250
	char *key;
ds@576
   251
	pContext->LocalToString(params[2], &key);
ds@576
   252
ds@576
   253
	pInfo->pEvent->SetBool(key, params[3] ? true : false);
ds@576
   254
ds@576
   255
	return 1;
ds@576
   256
}
ds@576
   257
ds@576
   258
static cell_t sm_SetEventInt(IPluginContext *pContext, const cell_t *params)
ds@576
   259
{
ds@576
   260
	Handle_t hndl = static_cast<Handle_t>(params[1]);
ds@576
   261
	HandleError err;
ds@576
   262
	EventInfo *pInfo;
ds@576
   263
ds@576
   264
	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
ds@576
   265
		!= HandleError_None)
ds@576
   266
	{
ds@576
   267
		return pContext->ThrowNativeError("Invalid GameEvent Handle %x (error %d)", hndl, err);
ds@576
   268
	}
ds@576
   269
ds@576
   270
	char *key;
ds@576
   271
	pContext->LocalToString(params[2], &key);
ds@576
   272
ds@576
   273
	pInfo->pEvent->SetInt(key, params[3]);
ds@576
   274
ds@576
   275
	return 1;
ds@576
   276
}
ds@576
   277
ds@576
   278
static cell_t sm_SetEventFloat(IPluginContext *pContext, const cell_t *params)
ds@576
   279
{
ds@576
   280
	Handle_t hndl = static_cast<Handle_t>(params[1]);
ds@576
   281
	HandleError err;
ds@576
   282
	EventInfo *pInfo;
ds@576
   283
ds@576
   284
	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
ds@576
   285
		!= HandleError_None)
ds@576
   286
	{
ds@576
   287
		return pContext->ThrowNativeError("Invalid GameEvent Handle %x (error %d)", hndl, err);
ds@576
   288
	}
ds@576
   289
ds@576
   290
	char *key;
ds@576
   291
	pContext->LocalToString(params[2], &key);
ds@576
   292
ds@576
   293
	float value = sp_ctof(params[3]);
ds@576
   294
	pInfo->pEvent->SetFloat(key, value);
ds@576
   295
ds@576
   296
	return 1;
ds@576
   297
}
ds@576
   298
ds@576
   299
static cell_t sm_SetEventString(IPluginContext *pContext, const cell_t *params)
ds@576
   300
{
ds@576
   301
	Handle_t hndl = static_cast<Handle_t>(params[1]);
ds@576
   302
	HandleError err;
ds@576
   303
	EventInfo *pInfo;
ds@576
   304
ds@576
   305
	if ((err=g_HandleSys.ReadHandle(hndl, g_EventManager.GetHandleType(), NULL, (void **)&pInfo))
ds@576
   306
		!= HandleError_None)
ds@576
   307
	{
ds@576
   308
		return pContext->ThrowNativeError("Invalid GameEvent Handle %x (error %d)", hndl, err);
ds@576
   309
	}
ds@576
   310
ds@576
   311
	char *key, *value;
ds@576
   312
	pContext->LocalToString(params[2], &key);
ds@576
   313
	pContext->LocalToString(params[3], &value);
ds@576
   314
ds@576
   315
	pInfo->pEvent->SetString(key, value);
ds@576
   316
ds@576
   317
	return 1;
ds@576
   318
}
ds@576
   319
ds@576
   320
REGISTER_NATIVES(gameEventNatives)
ds@576
   321
{
ds@576
   322
	{"HookEvent",			sm_HookEvent},
ds@576
   323
	{"UnhookEvent",			sm_UnhookEvent},
ds@576
   324
	{"CreateEvent",			sm_CreateEvent},
ds@576
   325
	{"FireEvent",			sm_FireEvent},
ds@576
   326
	{"CancelCreatedEvent",	sm_CancelCreatedEvent},
ds@576
   327
	{"GetEventName",		sm_GetEventName},
ds@576
   328
	{"GetEventBool",		sm_GetEventBool},
ds@576
   329
	{"GetEventInt",			sm_GetEventInt},
ds@576
   330
	{"GetEventFloat",		sm_GetEventFloat},
ds@576
   331
	{"GetEventString",		sm_GetEventString},
ds@576
   332
	{"SetEventBool",		sm_SetEventBool},
ds@576
   333
	{"SetEventInt",			sm_SetEventInt},
ds@576
   334
	{"SetEventFloat",		sm_SetEventFloat},
ds@576
   335
	{"SetEventString",		sm_SetEventString},
ds@576
   336
	{NULL,					NULL}
ds@576
   337
};