amaroq7 / spmod Goto Github PK
View Code? Open in Web Editor NEWSourcePawn Scripting Engine for Half-Life 1 based games
License: GNU General Public License v3.0
SourcePawn Scripting Engine for Half-Life 1 based games
License: GNU General Public License v3.0
We need create something similar to this
Uniquie index for all objects instead indexes from 0 to many.
Create Handle base class
We need API for creating menus.
In amxx exists Old style menu and New menus.
I suggest create all in one.
enum Menu
{
INVALID_MENU = -1
};
enum MenuStyle
{
STYLE_ITEMS,
STYLE_TEXT
}
enum MenuProps
{
// def 7 like amxx
MPROP_ITEMS_PER_PAGE,
// def "\r#num#." like "1. item"
// custom "\r[#num#]" like "[1] item"
MPROP_NUMBER_FORMAT,
// show/hide exit item
MPROP_EXIT,
// custom name for exit, back, next
MPROP_EXIT_NAME,
MPROP_NEXT_NAME,
MPROP_BACK_NAME,
// for hl, etc
MPROP_NO_COLORS,
};
enum ItemStatus
{
ITEM_ENABLED,
ITEM_DISABLED
};
enum MenuItem
{
MENU_EXIT = -3,
MENU_NEXT = -2,
MENU_BACK = -1
};
// typedef MenuHandler = function int (Menu menu, MenuAction action, int param1, int param2);
typeset MenuHandler
{
// text style
function void(
Menu menu,
int key,
int player
);
// item style
function void(
Menu menu,
MenuItem item,
int player,
any data
);
};
typedef CallbackHandler = function ItemStatus (Menu menu, MenuItem item, int player);
methodmap Menu
{
// param global if false then destroy after exit
public native Menu(MenuHandler handler, MenuStyle style = STYLE_ITEMS, bool global = false);
// param page only for STYLE_ITEMS
public native void Show(int player, int time = -1, int page = 0);
// only for STYLE_TEXT
public native void AddText(const char text[]);
public native void AddKeys(int keys);
// only for STYLE_ITEMS
public native void SetTitle(const char title[]);
public native void AddItem(const char name[], any data = 0, CallbackHandler callback = 0);
// for blank use AddText(0, "\n") or make "\n" by default instead ""
// TODO: change native name
public native void AddText(int slot = 0, const char text[] = "");
public native void SetProp(MenuProps prop, any ...);
property int Items {
public native get();
}
}
// close any active menu
native void CloseMenu(int player);
Create manager?
Suggestion:
Create folder scripting
for plugins source files, includes and SP compiler
Change current scripts
folder to plugins
for compiled plugins
Depends on #8.
Natives which access cvar by name could be entirely dropped in favor of pcvars.
Possible api:
enum Cvar
{
INVALID_CVAR = -1
};
methodmap Cvar
{
/* this constructor would register cvar */
public native Cvar(const char[] name, const char[] value, CvarFlags = None);
public native float GetFloat();
public native void GetString(char[] value, int size);
public native int GetInt();
public native CvarFlags GetFlags();
public native void SetFloat(float value);
public native void SetString(const char[] value);
public native void SetInt(int value);
public native void SetFlags(CvarFlags flags);
};
native Cvar FindCvar(const char[] name);
n/a
Methodmap API to work with cvar.
n/a
Not really python-like, but inspired by it and by #18 of course.
First of all instead of capsing, like DID_DMG_HITS
, we can use some default translation text (e.g. english text).
Secondly instead of %L
we can use function style: L(player, "He did {damage:d} damage to you with {hits:d} hit(s)\nand still has {health:d}hp and {armor:d}ap.")
This simplifies localization process of plugin that doesn't support it. Look:
Format("He did {damage:d} damage to you with {hits:d} hit(s)\nand still has {health:d}hp and {armor:d}ap."
, FmtArg("damage", damage)
, FmtArg("hits", hits)
, FmtArg("health", player.Health)
, FmtArg("armor", player.Armor)
);
Becomes:
Format(L(player, "He did {damage:d} damage to you with {hits:d} hit(s)\nand still has {health:d}hp and {armor:d}ap.")
, FmtArg("damage", damage)
, FmtArg("hits", hits)
, FmtArg("health", player.Health)
, FmtArg("armor", player.Armor)
);
Just adding L(player,
and )
!
TODO:
SetLanguageContext(player);
to remove repetitive player's index in L
for localized arguments or using last passed player's index if it isn't passedFMTARG
macro that will expand FMTARG(var)
to FmtArg("var", var)
Add info about SPMod version to plugin info struct.
Can help with detection old plugins after breakable changes in API.
Timer manager should responsible for creating, executing, removing tasks.
Timer would be destroyed after finished execution (one time task) or by using Remove()
.
Timer with repeat flag could be destroyed returning PluginStop
in its callback or by executing Remove()
.
Example plugin api:
enum TimerFlag
{
None = 0,
Repeat = (1<<0)
};
typeset TimerCallback
{
function PluginReturn (Task task);
function PluginReturn (Task task, any data);
};
methodmap Task
{
Task(float time, TimerCallback func, any data = 0, TimerFlag flags = None);
Remove();
Trigger();
Change(float interval, bool trigger = true);
};
n/a
SPMod should expose api for plugins and modules to manage timers.
n/a
We should be able to create commands.
There could be natives responsible for creating only console commands (not in say).
typeset CmdCallback
{
// For client cmd
function PluginReturn (int client);
// for srv cmd
function PluginReturn ();
}
// Client console
RegisterClCmd(const char[] cmd, CmdCallback func, int flags = 0, const char[] info = "")
// Server console
RegisterSrvCmd(const char[] cmd, CmdCallback func, const char[] info = "")
For say we would have forward which is executed on "say" and "say_team" commands.
//1st variant
forward PluginReturn OnSayCommand(int client, bool say_team)
//2nd variant (argv would store first argument of say command, f.e. for "say /test" argv param would store "/test")
forward PluginReturn OnSayCommand(int client, const char[] argv, bool say_team)
Example of registering say command
//1st variant
public PluginReturn OnSayCommand(int client, bool say_team)
{
char argv[32];
CmdGetArgv(1, argv, sizeof(argv)); //Not existent native for now
if (!StrCmp(argv, "/test"))
{
SomeCmdCallback(client);
return PluginStop;
}
return PluginContinue;
}
//2nd variant
public PluginReturn OnSayCommand(int client, const char[] argv, bool say_team)
{
if (!StrCmp(argv, "/test"))
{
SomeCmdCallback(client);
return PluginStop;
}
return PluginContinue;
}
In amxx we have to check permissions manually by executing cmd_access
in command callback. I think it would be better to check them in SPMod and execute command callback whenever client has right permissions.
n/a
We should be able to register commands.
Any thoughts on this?
We should be able to do arithmetic operations on float values.
For reference:
https://github.com/alliedmodders/sourcemod/blob/master/core/logic/smn_float.cpp
https://github.com/alliedmodders/sourcemod/blob/master/plugins/include/float.inc
n/a
Float operations should work.
n/a
Create hook for handling of pressing buttons
Code style starts getting a little bit inconsistent across the codebase.
clang-format could unify the code style in SPMod.
n/a
The main idea is to control loading procces of plugins. For example this might be useful to enable some plugins at day and other at night. Or some plugins can depend by map name or other factors. But it is so hard to create configuration system that can take all possible options. Thats why i propose to create sm plugin where users can do it manually. Inside this should be only one hook thats can return enable or disable plugin. And of course some natives for getting date/time or map name. For example
forward PluginReturn OnPLuginLoading(PluginInfo pluginInfo);
My suggestion is move binds for other languages to extentions, in core create only interfaces for another modules.
With this we can easier create binds for more languages(if someone will want add support for other language).
Question for discussion:
Maybe better develop metamod instead metaplugin for interfaces?
I'm want to use this in 2021. Help with updated binaries (.so).
Examples:
Format("Hello, {:s}!", "world"); // "Hello, world"
Format("{0:s}{1:s}{0:s}", "abra", "cad"); // "abracadabra"
Format("The answer is {:d}.", 42); // "42"
Format("Hello, {name:s}! The answer is {number:d}. Goodbye, {name:s}.", FmtArg("name", "World"), FmtArg("number", 42)); // "Hello, World! The answer is 42. Goodbye, World."
There is tagof
operator in SP, can we use it for type auto-examination? Can we use it at least for FmtArg
? If not, should we add argument in FmtArg
to pass the type?
Also we can choose default type for {}
, but there are several frequently used types, so I don't prefer it.
Could you add curl module support?
Create get_players
analog with own conditions.
// return players in array
native int GetPlayers(int players[32], int flags = 0, ConditionHandler func);
enum PlayerReturn {
PlayerAllowed,
PlayerDenied
}
public PlayerReturn PlayerCondition(int player)
{
if(myFunc(player))
return PlayerAllowed;
return PlayerDenied;
}
Create menu with players and own conditions.
Something like native Menu CreatePlayersMenu(MenuHandler handler, int flags, ConditionHandler condition);
An awesome methodmap for strings to get rid of char arrays and simplify tones of code. Not sure it all possible, but would be great
String str = "Hello world." // Overloading `=` operator.
str.Format("Foo. %s Bar.", str) // Self formatting, => `Foo. Hello world. Bar.`
int len = str.Length // `Length` property. => characters count of `Foo. Hello world. Bar.`
str = "Foo. " + str + " Bar." // Overloading `+` operator => `Foo. Hello world. Bar.`
str == "Foo. Hello world. Bar." // Overloading `==` operator => strings equal or not
str.Equals("Foo. Hello world. Bar.", false) // Same as above, but with case sensitivity parameter
Example usage in player class.
String name = player.GetName() // GetName should return String instead of char[]
//Just instead of
new name[33]
player.GetName(name, charsmax(name))
Suggestions?
Create iterators for player loops. Do this for SPMod and for SPMod plugins.
PlayersItterReset();
Player player;
while (PlayersItterNext(PL_ITTER_EXCLUDE_HLTV | PL_ITTER_EXCLUDE_BOTS)) {
player = PlayersItterGetPlayer();
// Do some stuf
}
or
for(Player p = GetFirstPlayer(SOME_SEARCH_FLAGS); p; p.NextPlayer(/* flags? */))
{
// code
}
First natives use camelCase styling, but recently added ones #3 use CamelCase. I think we should decide which one we should go with. Personally I don't mind any of them, but I prefer to keep naming unified.
n/a
We should go with camelCase or CamelCase styling for natives, not both.
What are your thoughts?
Need system for hooks. For message manager I create own manager but this needs for more systems.
https://github.com/libsigcplusplus/libsigcplusplus
I think this lib can be useful
Check if file exists before precache, so server wont crash if user forgot to put resource in folder. But we need to stop plugin if resource not precached(SetFailState)
At some point I changed the header and haven't updated it in all files.
Old: https://github.com/Amaroq7/SPMod/blob/master/src/coreNatives.cpp#L1-L16
New: https://github.com/Amaroq7/SPMod/blob/master/src/CvarsNatives.cpp#L1-L18
n/a
New license header instead of old one.
n/a
In amxx we have register_message
and register_event
where event is message_post but have filters(alive, dead, global, etc.)
Maybe we need create something unified?
Missing docs for https://github.com/Amaroq7/SPMod/blob/master/scripts/include/messages.inc#L39-L67.
n/a
Described natives.
n/a
Meson has built-in VS project generator but its completely fucked up and needs a lot of fixes after generation. Why dont just create project once and add it to repository?
Is your feature request related to a problem? Please describe.
Each module/adapter adds headers to include/public so in the course of time there will be too many headers there. One idea is to separate include/public into each module/adapter.
Additional context
├── public
│ ├── core
│ ├── module 1
│ ├── module 2
│ └── adapter 1
└
Create manager for cvar.
We should know what plugin create a cvar.
Cvar access from plugin should be faster than now, we don't have any cache system.
Issue for projects list
I think we can fully port FileSystem natives from SourceMod. But it depends by localization, so we need to extend format
to support localization(maybe port translations from sourcemod too?)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.