Raised This Month: $51 Target: $400
 12% 

How to save Function in dynamic array?


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Dakex
Junior Member
Join Date: Mar 2019
Old 02-04-2021 , 14:41   How to save Function in dynamic array?
Reply With Quote #1

Hi guys, I am trying to create game mode system for my jailbreak plugin.
The problem is, I want to implement natives which will allow to create custom game modes from different plugins.

I am using two ArrayLists, one for the menu (name of gamemode), second one is used to save the handler.

But the code is not working at all. When I try to open the menu, nothing happens, it just says invalid index 8 at line 57 which makes no sense to me.

Here is the code:
PHP Code:
#define PLUGIN_NAME           "GameModes"
#define PLUGIN_AUTHOR         "Dakex"
#define PLUGIN_DESCRIPTION    ""
#define PLUGIN_VERSION        "1.1 Epom"
#define PLUGIN_URL            ""

#include <sourcemod>
#include <sdktools>

#pragma semicolon 1

ArrayList gameModes;
ArrayList gameModes_Handler;

char defaultGameModes_Handler[] = {"Shooter_Handle""HNS_Handle""Matrix_Handle""CODMW_Handle"};
char defaultGameModes[] = {"Shooter""HNS""Matrix""COD:MW"};

public 
Plugin:myinfo =
{
    
name PLUGIN_NAME,
    
author PLUGIN_AUTHOR,
    
description PLUGIN_DESCRIPTION,
    
version PLUGIN_VERSION,
    
url PLUGIN_URL
};

public 
OnPluginStart()
{
    
gameModes CreateArray(64);
    
gameModes_Handler CreateArray(64);
    
    
LoadDefaultGameModes();
    
    
RegConsoleCmd("gamemod"GameModeMenu"turns the gamemode on");
}
public 
void LoadDefaultGameModes() 
{
    for(
int i 0<= sizeof(defaultGameModes); i++)
    {
        
gameModes.PushString(defaultGameModes[i]);
        
gameModes_Handler.PushString(defaultGameModes_Handler[i]);
    }
}
public 
Action GameModeMenu(int clientint args)
{
    
Menu gameModeMenu = new Menu(GameModeMenu_Handler);
    
char buffer[64];
    
char idBuffer[64];
    
    
gameModeMenu.SetTitle("Game Modes");
    
    for(
int i 0<= gameModes.Lengthi++)
    {
        
IntToString(iidBuffersizeof(idBuffer));
        
        
gameModes.GetString(ibuffersizeof(buffer) );
        
gameModeMenu.AddItem(idBufferbuffer);
    }
    
gameModeMenu.Display(client20);
    
    return 
Plugin_Handled;
}
public 
int GameModeMenu_Handler(Menu menuMenuAction actionint param1int param2)
{
    
char menuIdBuffer[64];
    
char buffer[64];
    
    
GetMenuItem(menuparam2menuIdBuffersizeof(menuIdBuffer));
    
int menuId StringToInt(menuIdBuffer);
    
    
gameModes_Handler.GetString(menuIdbuffersizeof(buffer));
    
    
PrintToServer("%s %d"buffermenuId);
    
    Function 
gameModeFunc GetFunctionByName(INVALID_HANDLEbuffer);
    
Call_StartFunction(INVALID_HANDLEgameModeFunc);
    
Call_Finish();
}
public 
void Shooter_Handle() 
{
    
PrintToChatAll("TURNING ON SHOOTER!");
}
public 
void HNS_Handle()
{
    
PrintToChatAll("TURNING ON HNS!");
}
public 
void Matrix_Handle()
{
    
PrintToChatAll("TURNING ON MATRIX!");
}
public 
void CODMW_Handle()
{
    
PrintToChatAll("Turning the COD:MW MODE ON!");

Dakex is offline
Kailo
Senior Member
Join Date: Sep 2014
Location: Moscow, Russia
Old 02-04-2021 , 18:49   Re: How to save Function in dynamic array?
Reply With Quote #2

I would to suggest next tips:
1) Use ByteCountToCells function to convert byte count to cells for ArrayList contructor
2) Use enum struct to trick ArrayList and be able to set Function type
3) In condition, that menu uses only such type of items. Use param id instead of "info" data

PS
1) Your code is looking right, can't see why it not work
2) I also don't know, why ArrayList::*Function natives not exists. weird.
__________________

Last edited by Kailo; 02-04-2021 at 18:52.
Kailo is offline
Dakex
Junior Member
Join Date: Mar 2019
Old 02-05-2021 , 02:39   Re: How to save Function in dynamic array?
Reply With Quote #3

Hi, Thank you for your help, but I'm not sure how to go about it.
I tried, but my code throws a lot of errors.
PHP Code:
#include <sourcemod>
#include <sdktools>

#pragma semicolon 1

ArrayList gameModes;

typedef gameModeFunc = function Action ();

enum struct GameMode 
{
    
char name[48];
    
gameModeFunc gameMode_Handler;
}

gameModeFunc defaultGameModes_Handler[] = {Shooter_HandleHNS_HandleMatrix_HandleCODMW_Handle};
char defaultGameModes[] = {"Shooter""HNS""Matrix""COD:MW"};

public 
Plugin:myinfo =
{
    
name PLUGIN_NAME,
    
author PLUGIN_AUTHOR,
    
description PLUGIN_DESCRIPTION,
    
version PLUGIN_VERSION,
    
url PLUGIN_URL
};

public 
OnPluginStart()
{
    
gameModes CreateArray(ByteCountToCells(64));
    
    
LoadDefaultGameModes();
    
    
RegConsoleCmd("gamemod"GameModeMenu"turns on any gamemode!");
}
public 
void LoadDefaultGameModes() 
{
    for(
int i 0<= sizeof(defaultGameModes); i++)
    {
        
GameMode gameMod;
        
strcopy(gameMod.nameByteCountToCells(48), defaultGameModes[i]);
        
        
gameMod.gameMode_Handler defaultGameModes_Handler[i];
        
        
gameModes.PushArray(gameModsizeof(gameMod));
    }
}
public 
Action GameModeMenu(int clientint args)
{
    
Menu gameModeMenu = new Menu(GameModeMenu_Handler);
    
GameMode buffer[64];
    
char idBuffer[64];
    
    
gameModeMenu.SetTitle("Game Modes");
    
    for(
int i 0<= gameModes.Lengthi++)
    {
        
IntToString(iidBuffersizeof(idBuffer));
        
        
gameModes.GetArray(ibuffer);
        
gameModeMenu.AddItem(idBufferbuffer.name);
    }
    
gameModeMenu.Display(client20);
    
    return 
Plugin_Handled;
}
public 
int GameModeMenu_Handler(Menu menuMenuAction actionint param1int param2)
{
    if(
action == MenuAction_End || action == MenuAction_Cancel)
    {
        
CloseHandle(menu);
    }
    
    if(
action == MenuAction_Select)
    {
        
GameMode buffer[64];
        
gameModes.GetArray(param2buffer);
        
        
buffer.gameMode_Handler();
        
    }
}
public 
Action Shooter_Handle() 
{
    
PrintToChatAll("shooter!");
}
public 
Action HNS_Handle()
{
    
PrintToChatAll("hns!");
}
public 
Action Matrix_Handle()
{
    
PrintToChatAll("matrix!");
}
public 
Action CODMW_Handle()
{
    
PrintToChatAll("codmw!");

Errors:
PHP Code:
    F:\workspace\sourcepawn\jailbreak\testmod.sp(24) : error 008must be a constant expressionassumed zero
    F
:\workspace\sourcepawn\jailbreak\testmod.sp(69) : error 048: array (do not match
    F
:\workspace\sourcepawn\jailbreak\testmod.sp(70) : error 106cannot call methods on an array
    
F:\workspace\sourcepawn\jailbreak\testmod.sp(86) : error 048: array (do not match
    F
:\workspace\sourcepawn\jailbreak\testmod.sp(88) : error 106cannot call methods on an array
    
F:\workspace\sourcepawn\jailbreak\testmod.sp(88) : error 029invalid expressionassumed zero
    F
:\workspace\sourcepawn\jailbreak\testmod.sp(88) : warning 215expression has no effect
    F
:\workspace\sourcepawn\jailbreak\testmod.sp(39) : warning 204symbol is assigned a value that is never used"gameModes_Handler" 
Dakex is offline
Kailo
Senior Member
Join Date: Sep 2014
Location: Moscow, Russia
Old 02-05-2021 , 09:48   Re: How to save Function in dynamic array?
Reply With Quote #4

I see you found main problem of first example, incorrect menu handler function

1) You must use Call_* natives to call function by function id. You can't use () operator for this
2) Adding typedef is optional here
3) ByteCountToCells needed if you store strings insde ArrayList like in your first example. Because ArrayList constructor take size param in cell - 64 cells equal 256 bytes, but you use char[64] (64 bytes)
4) Not use array brackets for enum strcut variables if this not array, like you did: "GameMode buffer[64];"
5) Use sizeof to take enum struct size, with structure name or varialbe name, ex.: sizeof(GameMode)
6) Don't close menu handle on Cancel action, only on End action
7) Array have indexes from 0 to size - 1. You must use < comparison agains <= in loops, overwise you will got error with try to [size] access
Use null instead INVALID_HANDLE

You want to make native for addtions of new gamemodes with modules in feature? Or why you use ArrayList? If you already know final count of modes, you can use only common arrays.

I would do like this, ask all things that you don't understand "how it works" in this code:
PHP Code:
#define PLUGIN_NAME           "GameModes"
#define PLUGIN_AUTHOR         "Dakex"
#define PLUGIN_DESCRIPTION    ""
#define PLUGIN_VERSION        "1.1 Epom"
#define PLUGIN_URL            ""

#include <sourcemod>
#include <sdktools>

#pragma semicolon 1

ArrayList gameModes;
ArrayList gameModes_Handler;

enum struct Wrapper 
{
    Function 
id;
}

char defaultGameModes[] = {"Shooter""HNS""Matrix""COD:MW"};
char defaultGameModes_Handler[] = {"Shooter_Handle""HNS_Handle""Matrix_Handle""CODMW_Handle"};

public 
Plugin:myinfo =
{
    
name PLUGIN_NAME,
    
author PLUGIN_AUTHOR,
    
description PLUGIN_DESCRIPTION,
    
version PLUGIN_VERSION,
    
url PLUGIN_URL
};

public 
OnPluginStart()
{
    
gameModes = new ArrayList(ByteCountToCells(64));
    
gameModes_Handler = new ArrayList(sizeof(Wrapper));

    
LoadDefaultGameModes();

    
RegConsoleCmd("gamemod"GameModeMenu"turns on any gamemode!");
}
public 
void LoadDefaultGameModes() 
{
    
Wrapper func;

    for(
int i 0sizeof(defaultGameModes); i++)
    {
        
gameModes.PushString(defaultGameModes[i]);
        
func.id GetFunctionByName(nulldefaultGameModes_Handler[i]);
        
gameModes_Handler.PushArray(func);
    }
}
public 
Action GameModeMenu(int clientint args)
{
    
Menu gameModeMenu = new Menu(GameModeMenu_Handler);
    
char buffer[64];

    
gameModeMenu.SetTitle("Game Modes");

    for(
int i 0size gameModes.Lengthsizei++)
    {
        
gameModes.GetString(ibuffersizeof(buffer));
        
gameModeMenu.AddItem(""buffer);
    }
    
gameModeMenu.Display(client20);

    return 
Plugin_Handled;
}
public 
int GameModeMenu_Handler(Menu menuMenuAction actionint param1int param2)
{
    if(
action == MenuAction_Select)
    {
        
Wrapper func;
        
gameModes_Handler.GetArray(param2func);

        
Call_StartFunction(nullfunc.id);
        
Call_Finish();
    }
    else if(
action == MenuAction_End)
    {
        
menu.Close();
    }
}
public 
Action Shooter_Handle() 
{
    
PrintToChatAll("shooter!");
}
public 
Action HNS_Handle()
{
    
PrintToChatAll("hns!");
}
public 
Action Matrix_Handle()
{
    
PrintToChatAll("matrix!");
}
public 
Action CODMW_Handle()
{
    
PrintToChatAll("codmw!");

__________________
Kailo is offline
Dakex
Junior Member
Join Date: Mar 2019
Old 02-05-2021 , 15:04   Re: How to save Function in dynamic array?
Reply With Quote #5

Thank you!

Quote:
You want to make native for addtions of new gamemodes with modules in feature? Or why you use ArrayList? If you already know final count of modes, you can use only common arrays.
Yes, that's right.
Dakex is offline
Dakex
Junior Member
Join Date: Mar 2019
Old 02-05-2021 , 17:43   Re: How to save Function in dynamic array?
Reply With Quote #6

Bump, it's not working.
The menu says: Shooter
hooter
ooter
and only the first one works.
Dakex is offline
Bacardi
Veteran Member
Join Date: Jan 2010
Location: mom's basement
Old 02-05-2021 , 19:33   Re: How to save Function in dynamic array?
Reply With Quote #7

Aaa.... string array?
Code:
char*defaultGameModes_Handler[][]*=*{"Shooter_Handle",*"HNS_Handle",*"Matrix_Handle",*"CODMW_Handle"};
char*defaultGameModes[][]*=*{"Shooter",*"HNS",*"Matrix",*"COD:MW"};
*edit
Okey, my copy/paste code got broken. But you get a idea.
__________________
Do not Private Message @me

Last edited by Bacardi; 02-05-2021 at 19:35.
Bacardi is offline
StrikeR14
AlliedModders Donor
Join Date: Apr 2016
Location: Behind my PC
Old 02-05-2021 , 19:35   Re: How to save Function in dynamic array?
Reply With Quote #8

PHP Code:
char defaultGameModes[] = {"Shooter""HNS""Matrix""COD:MW"};
char defaultGameModes_Handler[] = {"Shooter_Handle""HNS_Handle""Matrix_Handle""CODMW_Handle"}; 
To

PHP Code:
char defaultGameModes[][] = {"Shooter""HNS""Matrix""COD:MW"};
char defaultGameModes_Handler[][] = {"Shooter_Handle""HNS_Handle""Matrix_Handle""CODMW_Handle"}; 
An array of chars is a string, and an array of an array of chars simply means an array of strings.
__________________
Currently taking TF2/CSGO paid private requests!

My Plugins | My Discord Account
StrikeR14 is offline
Dakex
Junior Member
Join Date: Mar 2019
Old 02-06-2021 , 07:00   Re: How to save Function in dynamic array?
Reply With Quote #9

Thank you both! Now it is working as expected.

But I still have lot to go trough unfortunately. I need to find a way, how to save Plugin handle, which is required to call the function.
Dakex is offline
Kailo
Senior Member
Join Date: Sep 2014
Location: Moscow, Russia
Old 02-06-2021 , 07:13   Re: How to save Function in dynamic array?
Reply With Quote #10

Quote:
Originally Posted by Dakex View Post
Thank you both! Now it is working as expected.

But I still have lot to go trough unfortunately. I need to find a way, how to save Plugin handle, which is required to call the function.
PHP Code:
enum struct GameMode
{
    
Handle plugin;
    Function 
id;

__________________
Kailo is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 18:07.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode