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

[TF2] Sourcemod-Hammer Integration - Keypad Doors


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Phil25
AlliedModders Donor
Join Date: Feb 2015
Old 02-13-2015 , 15:01   [TF2] Sourcemod-Hammer Integration - Keypad Doors
Reply With Quote #1

Hello there!

A brief explanation of what I'm working on:
  • Have a keypad-protected doors on the map,
  • Have a player being able to enter a password,
  • A plugin checks if the password matches the correct one,
  • Opens the doors if it does.

Everything is working quite correctly. I'm just looking for a way to improve this and make it as perfect as it can get with the help from you, guys.
Also, I really wanna share this.

THE TEST MAP
There are quite a few entities which the plugin is accessing:
  • 10 keypad func_buttons:
    - Named "num_0", "num_1", "num_2", ..., "num_9".
    - The OnPressed output is being triggered by damage.
  • 8 symbol func_brushes:
    - Named "symb_0", "symb_1", "symb_2", ..., "symb_7".
    - They play the role of the "●" symbols which are being displayed when typing in a password.
    - They are being displayed on a "screen" next to the keypad made of func_details.
    - They are being enabled/disabled by the plugin so as to show/hide them.
  • 1 "OK" func_button:
    - Named simply "ok".
    - It plays the role of the "Submit" button when finished typing a password, just like Enter.
  • 1 door func_door_rotating:
    - Named simply "doors".
    - The door entity which is being triggered when the password is correct, duh...

THE PLUGIN

CVar: sm_door_pass changes the password. Default is "0000".

PHP Code:
#pragma semicolon 1

#include <sourcemod>
#include <sdktools>

//Holds the 0-8 characters password
new Handle:Keypad_Password INVALID_HANDLE;

//These variables hold the entities
new buttons[10];    //Numpad button
new butt_ok;        //The "OK" button
new doors;        //and the doors


new symbols[8];            //Symbols which are being displayed on the screen (func_brush enabling, disabling)
new bool:symbools[8];
//symbools is there to know whether a symbol is being displayed

//Current password which is being entered
new String:curPass[9];


public 
Plugin:myinfo = {
    
name        "Keypad Password Check",
    
author        "Phil25",
    
description    "Checks if a player has entered the right password on the map's keypad and opens the doors.",
};

public 
OnPluginStart(){
    
    
Keypad_Password CreateConVar(
        
"sm_door_pass",                            //Name of the CVar
        
"0000",                                    //Default Value
        
"The password which protects the doors",    //Description
        
FCVAR_PROTECTED                            //Flag
    
);
    
    
RegConsoleCmd("sm_printdebug"Command_PrintDebug);    //Used for testing purposes

}

public 
OnMapStart(){
    
/*
        ASSIGNING ALL THE ENTITIES TO THEIR RESPECTIVE VARIABLES
    */
    
    //Assuming there's more than one doors on the map:
    
new ent_doors = -1;
    while((
ent_doors FindEntityByClassname(ent_doors"func_door_rotating")) != INVALID_ENT_REFERENCE){
        
        
decl String:ent_doors_name[32];
        
GetEntPropString(ent_doorsProp_Data"m_iName"ent_doors_namesizeof(ent_doors_name));
        
        if(
StrEqual(ent_doors_name"doors"))
            
doors ent_doors;
        
    }
    
    
//Searching for numpad buttons: (They are named: "num_0", "num_1", "num_2" and so on...)
    
new ent_butt = -1;
    while((
ent_butt FindEntityByClassname(ent_butt"func_button")) != INVALID_ENT_REFERENCE){ //Looping through every valid func_button
        
        
decl String:butt_name[32];
        
GetEntPropString(ent_buttProp_Data"m_iName"butt_namesizeof(butt_name));            //Getting the name of current one
        
        
if(StrEqual(butt_name"ok"))        //Check if the entity's name equals the "ok" button
            
butt_ok ent_butt;    
        else{                                
//If not then look for numpad buttons
        
            
decl String:exp_butt_name[2][16];
            
//Checking, if exploding the name using "_" will return more strings:
            
if(ExplodeString(butt_name"_"exp_butt_namesizeof(exp_butt_name), sizeof(exp_butt_name[])) > 0)
                if(
StrEqual(exp_butt_name[0], "num"))                                                //If yes, check if the first part equals "num"
                    
buttons[StringToInt(exp_butt_name[1])] = ent_butt;                                //If also yes, assign the ent_butt to its corresponding array id in buttons[] using the second part
            
        
}
        
    }
    
    
//Checking for symbols to display on the keypad's screen: (Named: "symb_0", "symb_1", "symb_2" and so on...)
    //(Those are kinda optional, they're just there to give the person who's putting the code in some feedback) 
    
new ent_symb = -1;
    while((
ent_symb FindEntityByClassname(ent_symb"func_brush")) != INVALID_ENT_REFERENCE){
        
        
decl String:symb_name[32];                                                        //Everything here follows the same rule as above
        
GetEntPropString(ent_symbProp_Data"m_iName"symb_namesizeof(symb_name));
        
        
decl String:exp_symb_name[2][16];
        if(
ExplodeString(symb_name"_"exp_symb_namesizeof(exp_symb_name), sizeof(exp_symb_name[])) > 0)
            if(
StrEqual(exp_symb_name[0], "symb"))
                
symbols[StringToInt(exp_symb_name[1])] = ent_symb;
        
    }
    
    
    
/*
        HOOKING "OnPressed" OUTPUTS OF THE BUTTONS
    */
    
    
for(new 0sizeof(buttons); i++){
        
        
HookSingleEntityOutput(buttons[i], "OnPressed"ButtonPressedNum);
        
    }
    
    
HookSingleEntityOutput(butt_ok"OnPressed"ButtonPressedOk);
    
}

public 
ButtonPressedNum(const String:output[], calleractivatorFloat:delay){
    
    
/*AcceptEntityInput(doors, "Open", activator, -1);
    
    decl String:temp_name[32];
    GetEntPropString(caller, Prop_Data, "m_iName", temp_name, sizeof(temp_name));    //Used to test, figured I'll
    decl String:acti_name[32];                                                        //leave the code for now.
    GetClientName(activator, acti_name, sizeof(acti_name));                            //(Tests successful ofc :p)
    
    PrintToChatAll(
        "Output Name: %s, Ent Name: %s, Activator: %s (client: %d), Delay: %0.2f",
        output, temp_name, acti_name, activator, delay
    );*/
    
    
decl String:caller_name[32];
    
GetEntPropString(callerProp_Data"m_iName"caller_namesizeof(caller_name));    //Get the button's name
    
    
decl String:add_str[2][16];
    
ExplodeString(caller_name"_"add_strsizeof(add_str), sizeof(add_str[]));        //Get the button number
    
    
Format(curPasssizeof(curPass), "%s%s"curPassadd_str[1]);                        //Add the strings together
    
    //Loop through the symbols and enable the next one which hasn't been enabled yet
    
for(new 0sizeof(symbools); i++){
        
        if(!
symbools[i]){
            
AcceptEntityInput(symbols[i], "Enable"activator, -1);
            
symbools[i] = true;
            break;    
//If found a one which hasn't been enabled, enable it and break the loop
        
}else continue;    //If not, keep searching
        
    
}
    
}

public 
ButtonPressedOk(const String:output[], calleractivatorFloat:delay){
    
    
decl String:correctPass[9];        //Get the correct pass from the ConVar
    
GetConVarString(Keypad_PasswordcorrectPasssizeof(correctPass));
    
    if(
StrEqual(curPasscorrectPass)){    //Check if the strings match
        
decl String:activ_name[64];
        
GetClientName(activatoractiv_namesizeof(activ_name));
        
        
PrintToChat(activator"\x01Password \x077ee12dCorrect\x01! Welcome, \x04%s\x01!"activ_name);
        
        
AcceptEntityInput(doors"Open"activator, -1);    //Open the door entity if yep
    
}else
        
PrintToChat(activator"\x01Password \x07d72833Incorrect\x01!");    //Yell at the guy if nah
    
    
Format(curPasssizeof(curPass), "");    //Set the current password which is being entered to nothing
    
    
for(new 0sizeof(symbools); i++){
        
        
AcceptEntityInput(symbols[i], "Disable"activator, -1);    //Disable every symbol
        
symbools[i] = false;        //Set every symbool to false
        
    
}
    
}

public 
Action:Command_PrintDebug(clientargs){
    
    
PrintToConsole(client"");
    
PrintToConsole(client"------------------");
    
PrintToConsole(client"    - SYMBOLS:");
    
    for(new 
0sizeof(symbols); i++){
        
        
decl String:ent_name[32];
        
GetEntPropString(symbols[i], Prop_Data"m_iName"ent_namesizeof(ent_name));
        
PrintToConsole(client"%d. %s"ient_name);
        
    }
    
    
PrintToConsole(client"");
    
PrintToConsole(client"    - BUTTONS:");
    
    for(new 
0sizeof(buttons); i++){
        
        
decl String:ent_name[32];
        
GetEntPropString(buttons[i], Prop_Data"m_iName"ent_namesizeof(ent_name));
        
PrintToConsole(client"%d. %s"ient_name);
        
    }
    
    
decl String:butt_name[32];
    
GetEntPropString(butt_okProp_Data"m_iName"butt_namesizeof(butt_name));
    
    
PrintToConsole(client"10. %s"butt_name);
    
    
PrintToConsole(client"");
    
PrintToConsole(client"    - REST:");
    
    
decl String:door_name[32];
    
GetEntPropString(doorsProp_Data"m_iName"door_namesizeof(door_name));
    
    
PrintToConsole(client"Doors: %s"door_name);
    
    
PrintToConsole(client"------------------");
    
PrintToConsole(client"");
    
PrintToChat(client"Check the console for output.");
    

STUFF WORTH NOTICING
  • The plugin needs to be reloaded for it to work for some reason.
  • The symbols in Hammer are round although they appear as squares in the game.
  • The OnPressed in buttons is activated via damage. When you use explosives in order to do that symbols display in an incorrect matter.
  • To push the buttons you should get a pistol or something small and shoot them from a small distance because the melee registering system in TF2 is weird at some angles...

QUESTIONS
  • About the plugin not working from start, what is up with that??
  • I'm fetching a lot of entities, is there any better way of doing that other than what I'm using?
  • Are the plugin's while loops supposed to break when finding the right entity?
  • Treating buttons with explosives. What can be done so they won't break the symbols?
  • For Hammer folks: Is there a way of making the symbols appear after one another using some logic system in the editor? They just need to be turned on/off and the "OK" button can simply clear them all out.
  • Is there a better way of doing what I'm trying to achieve? What is your opinion?
I'm looking forward to discuss any additional comments on the topic. Thank you all very much in advance and take care.

ATTACHMENTS
Map BSP File (Game-Ready)
Map VMF File (Hammer Source)
Attached Files
File Type: smx KeypadPass.smx (5.8 KB, 98 views)
File Type: txt KeypadPass.txt (7.1 KB, 253 views)

Last edited by Phil25; 02-14-2015 at 03:11.
Phil25 is offline
Pala4
Senior Member
Join Date: Dec 2007
Old 04-28-2018 , 10:21   Re: [TF2] Sourcemod-Hammer Integration - Keypad Doors
Reply With Quote #2

Thank you for a good plugin, but recently there were errors
Spoiler

Can you fix them?
Pala4 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 04:25.


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