Compare commits

...

4 Commits

Author SHA1 Message Date
luxury fabka
1b1f1d04dd minor menu changes (#373)
Co-authored-by: Michael Wilson <roflmuffin@users.noreply.github.com>
Co-authored-by: Roflmuffin <shortguy014@gmail.com>
2024-03-18 05:00:31 +00:00
Ian Lucas
dbc348c1bf Add RemoveAll method to NetworkedVector class (#380) 2024-03-18 14:56:29 +10:00
Michael Wilson
d295589c44 fix: update collision groups (#376) 2024-03-13 16:10:42 +10:00
Michael Wilson
16767fd494 feat: add Server.RunOnTick method which allows tick scheduling (#374) 2024-03-11 23:08:54 +10:00
19 changed files with 289 additions and 59 deletions

View File

@@ -49,6 +49,8 @@ SET(SOURCE_FILES
src/core/managers/event_manager.cpp
src/core/timer_system.h
src/core/timer_system.cpp
src/core/tick_scheduler.h
src/core/tick_scheduler.cpp
src/scripting/autonative.h
src/scripting/natives/natives_engine.cpp
src/core/engine_trace.h

View File

@@ -439,6 +439,12 @@
<Left>.\ApiCompat\v151.dll</Left>
<Right>obj\Debug\net7.0\CounterStrikeSharp.API.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:CounterStrikeSharp.API.Core.NativeAPI.GetGameFrameTime</Target>
<Left>.\ApiCompat\v151.dll</Left>
<Right>obj\Debug\net7.0\CounterStrikeSharp.API.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:CounterStrikeSharp.API.Core.NativeAPI.QueueTaskForNextFrame(System.IntPtr)</Target>
@@ -469,6 +475,18 @@
<Left>.\ApiCompat\v151.dll</Left>
<Right>obj\Debug\net7.0\CounterStrikeSharp.API.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:CounterStrikeSharp.API.Modules.Memory.DynamicFunctions.DynamicHook.GetReturn``1(System.Int32)</Target>
<Left>.\ApiCompat\v151.dll</Left>
<Right>obj\Debug\net7.0\CounterStrikeSharp.API.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:CounterStrikeSharp.API.Server.get_GameFrameTime</Target>
<Left>.\ApiCompat\v151.dll</Left>
<Right>obj\Debug\net7.0\CounterStrikeSharp.API.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:CounterStrikeSharp.API.Core.IPlugin.OnAllPluginsLoaded(System.Boolean)</Target>
@@ -487,6 +505,12 @@
<Left>.\ApiCompat\v151.dll</Left>
<Right>obj\Debug\net7.0\CounterStrikeSharp.API.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>P:CounterStrikeSharp.API.Modules.Menu.IMenu.ExitButton</Target>
<Left>.\ApiCompat\v151.dll</Left>
<Right>obj\Debug\net7.0\CounterStrikeSharp.API.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0010</DiagnosticId>
<Target>T:CounterStrikeSharp.API.Core.RenderMultisampleType_t</Target>

View File

@@ -315,16 +315,6 @@ namespace CounterStrikeSharp.API.Core
}
}
public static float GetGameFrameTime(){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.SetIdentifier(0x97E331CA);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
return (float)ScriptContext.GlobalScriptContext.GetResult(typeof(float));
}
}
public static double GetEngineTime(){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
@@ -512,6 +502,17 @@ namespace CounterStrikeSharp.API.Core
}
}
public static void QueueTaskForFrame(int tick, InputArgument callback){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(tick);
ScriptContext.GlobalScriptContext.Push((InputArgument)callback);
ScriptContext.GlobalScriptContext.SetIdentifier(0x2F92C340);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
}
}
public static void QueueTaskForNextWorldUpdate(InputArgument callback){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
@@ -1095,6 +1096,16 @@ namespace CounterStrikeSharp.API.Core
}
}
public static void RemoveAllNetworkVectorElements(IntPtr vec){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();
ScriptContext.GlobalScriptContext.Push(vec);
ScriptContext.GlobalScriptContext.SetIdentifier(0x67206C08);
ScriptContext.GlobalScriptContext.Invoke();
ScriptContext.GlobalScriptContext.CheckErrors();
}
}
public static short GetSchemaOffset(string classname, string propname){
lock (ScriptContext.GlobalScriptContext.Lock) {
ScriptContext.GlobalScriptContext.Reset();

View File

@@ -33,6 +33,11 @@ public partial class NetworkedVector<T> : NativeObject, IReadOnlyCollection<T>
}
}
public void RemoveAll()
{
NativeAPI.RemoveAllNetworkVectorElements(Handle);
}
public IEnumerator<T> GetEnumerator()
{
for (int i = 0; i < Count; i++)

View File

@@ -18,34 +18,37 @@ namespace CounterStrikeSharp.API.Modules.Entities.Constants
{
public enum CollisionGroup
{
COLLISION_GROUP_NONE = 0,
COLLISION_GROUP_DEBRIS, // Collides with nothing but world and static stuff
COLLISION_GROUP_DEBRIS_TRIGGER, // Same as debris, but hits triggers
COLLISION_GROUP_INTERACTIVE_DEBRIS, // Collides with everything except other interactive debris or debris
COLLISION_GROUP_INTERACTIVE, // Collides with everything except interactive debris or debris
COLLISION_GROUP_NONE = 0,
COLLISION_GROUP_NEVER,
COLLISION_GROUP_TRIGGER,
COLLISION_GROUP_CONDITIONALLY_SOLID,
COLLISION_GROUP_DEFAULT,
COLLISION_GROUP_DEBRIS, // Collides with nothing but world and static stuff
COLLISION_GROUP_INTERACTIVE_DEBRIS, // Collides with everything except other interactive debris or debris
COLLISION_GROUP_INTERACTIVE, // Collides with everything except interactive debris or debris
COLLISION_GROUP_PLAYER,
COLLISION_GROUP_BREAKABLE_GLASS,
COLLISION_GROUP_VEHICLE,
COLLISION_GROUP_PLAYER_MOVEMENT, // For HL2, same as Collision_Group_Player, for
// TF2, this filters out other players and CBaseObjects
COLLISION_GROUP_NPC, // Generic NPC group
COLLISION_GROUP_IN_VEHICLE, // for any entity inside a vehicle
COLLISION_GROUP_WEAPON, // for any weapons that need collision detection
COLLISION_GROUP_VEHICLE_CLIP, // vehicle clip brush to restrict vehicle movement
COLLISION_GROUP_PROJECTILE, // Projectiles!
COLLISION_GROUP_DOOR_BLOCKER, // Blocks entities not permitted to get near moving doors
COLLISION_GROUP_PASSABLE_DOOR, // Doors that the player shouldn't collide with
COLLISION_GROUP_DISSOLVING, // Things that are dissolving are in this group
COLLISION_GROUP_PUSHAWAY, // Nonsolid on client and server, pushaway in player code
COLLISION_GROUP_PLAYER_MOVEMENT, // For HL2, same as Collision_Group_Player, for
COLLISION_GROUP_NPC_ACTOR, // Used so NPCs in scripts ignore the player.
COLLISION_GROUP_NPC_SCRIPTED, // USed for NPCs in scripts that should not collide with each other
// TF2, this filters out other players and CBaseObjects
COLLISION_GROUP_NPC, // Generic NPC group
COLLISION_GROUP_IN_VEHICLE, // for any entity inside a vehicle
COLLISION_GROUP_WEAPON, // for any weapons that need collision detection
COLLISION_GROUP_VEHICLE_CLIP, // vehicle clip brush to restrict vehicle movement
COLLISION_GROUP_PROJECTILE, // Projectiles!
COLLISION_GROUP_DOOR_BLOCKER, // Blocks entities not permitted to get near moving doors
COLLISION_GROUP_PASSABLE_DOOR, // Doors that the player shouldn't collide with
COLLISION_GROUP_DISSOLVING, // Things that are dissolving are in this group
COLLISION_GROUP_PUSHAWAY, // Nonsolid on client and server, pushaway in player code
COLLISION_GROUP_NPC_ACTOR, // Used so NPCs in scripts ignore the player.
COLLISION_GROUP_NPC_SCRIPTED, // USed for NPCs in scripts that should not collide with each other
COLLISION_GROUP_PZ_CLIP,
COLLISION_GROUP_DEBRIS_BLOCK_PROJECTILE, // Only collides with bullets
COLLISION_GROUP_PROPS,
LAST_SHARED_COLLISION_GROUP
}
}
}

View File

@@ -30,7 +30,8 @@ public abstract class BaseMenu : IMenu
public string Title { get; set; }
public List<ChatMenuOption> MenuOptions { get; } = new();
public PostSelectAction PostSelectAction { get; set; } = PostSelectAction.Reset;
public bool ExitButton { get; set; } = true;
protected BaseMenu(string title)
{
Title = title;
@@ -76,8 +77,8 @@ public abstract class BaseMenuInstance : IMenuInstance
}
protected bool HasPrevButton => Page > 0;
protected bool HasNextButton => CurrentOffset + NumPerPage < Menu.MenuOptions.Count;
protected int MenuItemsPerPage => NumPerPage + 2 - (HasNextButton ? 1 : 0) - (HasPrevButton ? 1 : 0);
protected bool HasNextButton => Menu.MenuOptions.Count > NumPerPage && CurrentOffset + NumPerPage < Menu.MenuOptions.Count;
protected virtual int MenuItemsPerPage => NumPerPage;
public virtual void Display()
{
@@ -142,7 +143,7 @@ public abstract class BaseMenuInstance : IMenuInstance
PrevPageOffsets.Clear();
}
public void Close()
public virtual void Close()
{
MenuManager.CloseActiveMenu(Player);
}

View File

@@ -24,14 +24,15 @@ public class CenterHtmlMenu : BaseMenu
public CenterHtmlMenu(string title) : base(ModifyTitle(title))
{
}
public override ChatMenuOption AddMenuOption(string display, Action<CCSPlayerController, ChatMenuOption> onSelect, bool disabled = false)
public override ChatMenuOption AddMenuOption(string display, Action<CCSPlayerController, ChatMenuOption> onSelect,
bool disabled = false)
{
var option = new ChatMenuOption(ModifyOptionDisplay(display), disabled, onSelect);
MenuOptions.Add(option);
return option;
}
private static string ModifyTitle(string title)
{
if (title.Length > 32)
@@ -59,14 +60,15 @@ public class CenterHtmlMenuInstance : BaseMenuInstance
{
private readonly BasePlugin _plugin;
public override int NumPerPage => 5; // one less than the actual number of items per page to avoid truncated options
protected override int MenuItemsPerPage => (Menu.ExitButton ? 0 : 1) + ((HasPrevButton && HasNextButton) ? NumPerPage - 1 : NumPerPage);
public CenterHtmlMenuInstance(BasePlugin plugin, CCSPlayerController player, IMenu menu) : base(player, menu)
{
_plugin = plugin;
RemoveOnTickListener();
plugin.RegisterListener<Core.Listeners.OnTick>(Display);
}
public override void Display()
{
if (MenuManager.GetActiveMenu(Player) != this)
@@ -74,7 +76,7 @@ public class CenterHtmlMenuInstance : BaseMenuInstance
Reset();
return;
}
var builder = new StringBuilder();
builder.Append($"<b><font color='yellow'>{Menu.Title}</font></b>");
builder.AppendLine("<br>");
@@ -88,7 +90,7 @@ public class CenterHtmlMenuInstance : BaseMenuInstance
builder.Append($"<font color='{color}'>!{keyOffset++}</font> {option.Text}");
builder.AppendLine("<br>");
}
if (HasPrevButton)
{
builder.AppendFormat("<font color='yellow'>!7</font> &#60;- Prev");
@@ -101,18 +103,21 @@ public class CenterHtmlMenuInstance : BaseMenuInstance
builder.AppendLine("<br>");
}
builder.AppendFormat("<font color='red'>!9</font> -> Close");
builder.AppendLine("<br>");
if (Menu.ExitButton)
{
builder.AppendFormat("<font color='red'>!9</font> -> Close");
builder.AppendLine("<br>");
}
var currentPageText = builder.ToString();
Player.PrintToCenterHtml(currentPageText);
}
public override void Reset()
public override void Close()
{
base.Reset();
base.Close();
RemoveOnTickListener();
// Send a blank message to clear the menu
Player.PrintToCenterHtml(" ");
}

View File

@@ -18,10 +18,11 @@ using CounterStrikeSharp.API.Modules.Utils;
namespace CounterStrikeSharp.API.Modules.Menu;
public class ChatMenu: BaseMenu
public class ChatMenu : BaseMenu
{
public ChatMenu(string title) : base(title)
{
ExitButton = false;
}
}
@@ -37,15 +38,11 @@ public class ChatMenuInstance : BaseMenuInstance
Player.PrintToChat("---");
var keyOffset = 1;
for (var i = CurrentOffset;
i < Math.Min(CurrentOffset + MenuItemsPerPage, Menu.MenuOptions.Count);
i++)
for (var i = CurrentOffset; i < Math.Min(CurrentOffset + MenuItemsPerPage, Menu.MenuOptions.Count); i++)
{
var option = Menu.MenuOptions[i];
Player.PrintToChat(
$" {(option.Disabled ? ChatColors.Grey : ChatColors.Green)} !{keyOffset++} {ChatColors.Default}{option.Text}");
Player.PrintToChat($" {(option.Disabled ? ChatColors.Grey : ChatColors.Green)} !{keyOffset++} {ChatColors.Default}{option.Text}");
}
if (HasPrevButton)
@@ -57,6 +54,11 @@ public class ChatMenuInstance : BaseMenuInstance
{
Player.PrintToChat($" {ChatColors.Yellow}!8 {ChatColors.Default}-> Next");
}
if (Menu.ExitButton)
{
Player.PrintToChat($" {ChatColors.Red}!9 {ChatColors.Default}-> Close");
}
}
}

View File

@@ -42,7 +42,7 @@ public class ConsoleMenuInstance : BaseMenuInstance
{
var option = Menu.MenuOptions[i];
Player.PrintToConsole($"{(option.Disabled ? "[Enabled]" : "[Disabled] - ")} css_{keyOffset++} {option.Text}");
Player.PrintToConsole($"{(option.Disabled ? "[Disabled] - " : "[Enabled]")} css_{keyOffset++} {option.Text}");
}
if (HasPrevButton)
@@ -54,5 +54,10 @@ public class ConsoleMenuInstance : BaseMenuInstance
{
Player.PrintToConsole("css_8 -> Next");
}
if (Menu.ExitButton)
{
Player.PrintToConsole("css_9 -> Close");
}
}
}

View File

@@ -27,6 +27,7 @@ public interface IMenu
get { throw new NotImplementedException(); }
set { throw new NotImplementedException(); }
}
public bool ExitButton { get; set; }
public ChatMenuOption AddMenuOption(string display, Action<CCSPlayerController, ChatMenuOption> onSelect, bool disabled = false);
}

View File

@@ -28,19 +28,66 @@ namespace CounterStrikeSharp.API
{
public class Server
{
public static float TickInterval => NativeAPI.GetTickInterval();
/// <summary>
/// Duration of a single game tick in seconds, based on a 64 tick server (hard coded in CS2).
/// </summary>
public static float TickInterval => 0.015625f;
/// <summary>
/// Executes a command on the server, as if it was entered from the console.
/// </summary>
/// <param name="command"></param>
public static void ExecuteCommand(string command) => NativeAPI.IssueServerCommand(command);
public static string MapName => NativeAPI.GetMapName();
// public static void PrintToConsole(string message) => NativeAPI.PrintToConsole(message);
/// <summary>
/// Returns the total time the server has been running in seconds.
/// </summary>
/// <remarks>Does not increment when server is hibernating</remarks>
public static double TickedTime => NativeAPI.GetTickedTime();
/// <summary>
/// Returns the current map time in seconds, as an interval of the server's tick interval.
/// e.g. 70.046875 would represent 70 seconds of map time and the 4483rd tick of the server (70.046875 / 0.015625).
/// </summary>
/// <remarks>Increments even when server is hibernating</remarks>
public static float CurrentTime => NativeAPI.GetCurrentTime();
/// <summary>
/// Returns the current map tick count.
/// CS2 is a 64 tick server, so the value will increment by 64 every second.
/// </summary>
public static int TickCount => NativeAPI.GetTickCount();
public static float GameFrameTime => NativeAPI.GetGameFrameTime();
/// <summary>
/// Returns the total time the server has been running in seconds.
/// </summary>
/// <remarks>Increments even when server is hibernating</remarks>
public static double EngineTime => NativeAPI.GetEngineTime();
public static void PrecacheModel(string name) => NativeAPI.PrecacheModel(name);
/// <summary>
/// <inheritdoc cref="RunOnTick"/>
/// Returns Task that completes once the synchronous task has been completed.
/// </summary>
public static Task RunOnTickAsync(int tick, Action task)
{
var functionReference = FunctionReference.Create(task, FunctionLifetime.SingleUse);
NativeAPI.QueueTaskForFrame(tick, functionReference);
return functionReference.CompletionTask;
}
/// <summary>
/// Queue a task to be executed on the specified tick.
/// See <see cref="TickCount"/> to retrieve the current tick.
/// <remarks>Does not execute if the server is hibernating.</remarks>
/// </summary>
public static void RunOnTick(int tick, Action task)
{
RunOnTickAsync(tick, task);
}
/// <summary>
/// <inheritdoc cref="NextFrame"/>

View File

@@ -1,6 +1,7 @@
#include "mm_plugin.h"
#include "core/globals.h"
#include "core/managers/player_manager.h"
#include "core/tick_scheduler.h"
#include "iserver.h"
#include "managers/event_manager.h"
#include "scripting/callback_manager.h"
@@ -79,6 +80,7 @@ EntityManager entityManager;
ChatManager chatManager;
ServerManager serverManager;
VoiceManager voiceManager;
TickScheduler tickScheduler;
bool gameLoopInitialized = false;
GetLegacyGameEventListener_t* GetLegacyGameEventListener = nullptr;

View File

@@ -47,6 +47,7 @@ class CallbackManager;
class ConVarManager;
class PlayerManager;
class MenuManager;
class TickScheduler;
class TimerSystem;
class ChatCommands;
class HookManager;
@@ -100,6 +101,7 @@ extern ChatCommands chatCommands;
extern ChatManager chatManager;
extern ServerManager serverManager;
extern VoiceManager voiceManager;
extern TickScheduler tickScheduler;
extern HookManager hookManager;
extern SourceHook::ISourceHook *source_hook;

View File

@@ -0,0 +1,45 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
#include "tick_scheduler.h"
namespace counterstrikesharp {
void TickScheduler::schedule(int tick, std::function<void()> callback)
{
std::lock_guard<std::mutex> lock(taskMutex);
scheduledTasks.push(std::make_pair(tick, callback));
}
std::vector<std::function<void()>> TickScheduler::getCallbacks(int currentTick)
{
std::vector<std::function<void()>> callbacksToRun;
std::lock_guard<std::mutex> lock(taskMutex);
if (scheduledTasks.empty()) {
return callbacksToRun;
}
// Process tasks due for the current tick
while (!scheduledTasks.empty() && scheduledTasks.top().first <= currentTick) {
callbacksToRun.push_back(scheduledTasks.top().second);
scheduledTasks.pop();
}
return callbacksToRun;
}
} // namespace counterstrikesharp

44
src/core/tick_scheduler.h Normal file
View File

@@ -0,0 +1,44 @@
/*
* This file is part of CounterStrikeSharp.
* CounterStrikeSharp is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CounterStrikeSharp is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CounterStrikeSharp. If not, see <https://www.gnu.org/licenses/>. *
*/
#include <functional>
#include <queue>
#include <mutex>
#include <condition_variable>
namespace counterstrikesharp {
class TickScheduler
{
public:
struct TaskComparator
{
bool operator()(const std::pair<int, std::function<void()>>& a,
const std::pair<int, std::function<void()>>& b) const
{
return a.first > b.first;
}
};
void schedule(int tick, std::function<void()> callback);
std::vector<std::function<void()>> getCallbacks(int currentTick);
private:
std::priority_queue<std::pair<int, std::function<void()>>,
std::vector<std::pair<int, std::function<void()>>>,
TaskComparator>
scheduledTasks;
std::mutex taskMutex;
};
} // namespace counterstrikesharp

View File

@@ -22,6 +22,7 @@
#include "core/gameconfig.h"
#include "core/game_system.h"
#include "core/timer_system.h"
#include "core/tick_scheduler.h"
#include "core/utils.h"
#include "core/managers/entity_manager.h"
#include "igameeventsystem.h"
@@ -48,6 +49,7 @@ DLL_EXPORT void InvokeNative(counterstrikesharp::fxNativeContext& context)
if (context.nativeIdentifier != counterstrikesharp::hash_string_const("QUEUE_TASK_FOR_NEXT_FRAME") &&
context.nativeIdentifier != counterstrikesharp::hash_string_const("QUEUE_TASK_FOR_NEXT_WORLD_UPDATE") &&
context.nativeIdentifier != counterstrikesharp::hash_string_const("QUEUE_TASK_FOR_FRAME") &&
counterstrikesharp::globals::gameThreadId != std::this_thread::get_id())
{
counterstrikesharp::ScriptContextRaw scriptContext(context);
@@ -218,6 +220,16 @@ void CounterStrikeSharpMMPlugin::Hook_GameFrame(bool simulating, bool bFirstTick
out_list[i]();
}
}
auto callbacks = globals::tickScheduler.getCallbacks(globals::getGlobalVars()->tickcount);
if (callbacks.size() > 0) {
CSSHARP_CORE_TRACE("Executing frame specific tasks of size: {0} on tick number {1}", callbacks.size(),
globals::getGlobalVars()->tickcount);
for (auto& callback : callbacks) {
callback();
}
}
}
// Potentially might not work

View File

@@ -32,6 +32,7 @@
#include "core/function.h"
#include "core/managers/player_manager.h"
#include "core/managers/server_manager.h"
#include "core/tick_scheduler.h"
// clang-format on
#if _WIN32
@@ -238,6 +239,15 @@ void QueueTaskForNextWorldUpdate(ScriptContext& script_context)
globals::serverManager.AddTaskForNextWorldUpdate([func]() { reinterpret_cast<voidfunc*>(func)(); });
}
void QueueTaskForFrame(ScriptContext& script_context)
{
auto tick = script_context.GetArgument<int>(0);
auto func = script_context.GetArgument<void*>(1);
typedef void(voidfunc)(void);
globals::tickScheduler.schedule(tick, reinterpret_cast<voidfunc*>(func));
}
enum InterfaceType
{
Engine,
@@ -331,6 +341,7 @@ REGISTER_NATIVES(engine, {
ScriptEngine::RegisterNativeHandler("GET_TICKED_TIME", GetTickedTime);
ScriptEngine::RegisterNativeHandler("QUEUE_TASK_FOR_NEXT_FRAME", QueueTaskForNextFrame);
ScriptEngine::RegisterNativeHandler("QUEUE_TASK_FOR_NEXT_WORLD_UPDATE", QueueTaskForNextWorldUpdate);
ScriptEngine::RegisterNativeHandler("QUEUE_TASK_FOR_FRAME", QueueTaskForFrame);
ScriptEngine::RegisterNativeHandler("GET_VALVE_INTERFACE", GetValveInterface);
ScriptEngine::RegisterNativeHandler("GET_COMMAND_PARAM_VALUE", GetCommandParamValue);
ScriptEngine::RegisterNativeHandler("PRINT_TO_SERVER_CONSOLE", PrintToServerConsole);

View File

@@ -4,7 +4,6 @@ IS_MAP_VALID: mapname:string -> bool
GET_TICK_INTERVAL: -> float
GET_CURRENT_TIME: -> float
GET_TICK_COUNT: -> int
GET_GAME_FRAME_TIME: -> float
GET_ENGINE_TIME: -> double
GET_MAX_CLIENTS: -> int
ISSUE_SERVER_COMMAND: command:string -> void
@@ -22,6 +21,7 @@ TRACE_FILTER_PROXY_SET_SHOULD_HIT_ENTITY_CALLBACK: trace_filter:pointer, callbac
NEW_TRACE_RESULT: -> pointer
GET_TICKED_TIME: -> double
QUEUE_TASK_FOR_NEXT_FRAME: callback:func -> void
QUEUE_TASK_FOR_FRAME: tick:int, callback:func -> void
QUEUE_TASK_FOR_NEXT_WORLD_UPDATE: callback:func -> void
GET_VALVE_INTERFACE: interfaceType:int, interfaceName:string -> pointer
GET_COMMAND_PARAM_VALUE: param:string, dataType:DataType_t, defaultValue:any -> any

View File

@@ -159,6 +159,13 @@ void* GetNetworkVectorElementAt(ScriptContext& script_context)
return &vec->Element(index);
}
void RemoveAllNetworkVectorElements(ScriptContext& script_context)
{
auto vec = script_context.GetArgument<CUtlVector<CEntityHandle>*>(0);
vec->RemoveAll();
}
REGISTER_NATIVES(memory, {
ScriptEngine::RegisterNativeHandler("CREATE_VIRTUAL_FUNCTION", CreateVirtualFunction);
ScriptEngine::RegisterNativeHandler("CREATE_VIRTUAL_FUNCTION_BY_SIGNATURE",
@@ -169,5 +176,6 @@ REGISTER_NATIVES(memory, {
ScriptEngine::RegisterNativeHandler("FIND_SIGNATURE", FindSignatureNative);
ScriptEngine::RegisterNativeHandler("GET_NETWORK_VECTOR_SIZE", GetNetworkVectorSize);
ScriptEngine::RegisterNativeHandler("GET_NETWORK_VECTOR_ELEMENT_AT", GetNetworkVectorElementAt);
ScriptEngine::RegisterNativeHandler("REMOVE_ALL_NETWORK_VECTOR_ELEMENTS", RemoveAllNetworkVectorElements);
})
} // namespace counterstrikesharp