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

Replay entity


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Point
Junior Member
Join Date: Oct 2014
Old 05-06-2019 , 05:54   Replay entity
Reply With Quote #1

PHP Code:
/**
 *    Ghost Recorder by TeddyDesTodes
 *  
 *  No CVars / Only Defines
 * 
 *  Thx to Empī for helping with casting
 * 
 *     How to:
 *      copy recorder.amxx to addons/amxmodx/plugins/
 *         insert recorder.amxx into plugins.ini
 *         create a folder called "kzrecord/" in your mod folder
 * 
 *  Ingame Commands:
 *         say /demomenu        opens the menu
 * 
 *  Defines:
 *         MAXSLOTS = Maximum saveslots per player and map
 *         SAVEPATH = Folder for storing ghosts (dont forget to create it)
 *         RECLIMITER = Limits the amount of data written to file higher means less size but less accurate results should be something between 0.05 and 0.01
 * 
 **/


#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <fakemeta_util>

#define PLUGIN    "Ghost Recorder"
#define AUTHOR    "TeddyDesTodes"
#define VERSION    "0.21"

#define MAXPLAYERS 33
#define RECLIMITER 0.03
#define MAXSLOTS 6
#define SAVEPATH "kzrecord/"

#define RECORDKEYS MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_0
#define SLOTKEYS MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_5|MENU_KEY_6|MENU_KEY_7|MENU_KEY_8|MENU_KEY_9|MENU_KEY_0
new g_FileHandler[MAXPLAYERS]
new 
Float:g_LastThink[MAXPLAYERS]
new 
Float:g_LastAngle[MAXPLAYERS][3]
new 
Float:g_LastOrigin[MAXPLAYERS][3]
new 
Float:g_LastVelocity[MAXPLAYERS][3]
new 
g_isRecording[MAXPLAYERS],g_isPause[MAXPLAYERS],g_SaveSlot[MAXPLAYERS],g_MenuOpen[MAXPLAYERS]

public 
plugin_init()
{
    
register_plugin(PLUGINVERSIONAUTHOR)
    
register_forward(FM_Think,"fm_ghost_think",0)
    
register_forward(FM_PlayerPreThink,"fm_plr_prethink",0)
    
register_clcmd("say /demomenu","menu_show")
    
register_clcmd("say /test","choose_slot")
    
register_menucmd(register_menuid("Demo Recorder"), RECORDKEYS"menuhandler")
    
register_menucmd(register_menuid("Slot Chooser"), SLOTKEYS"slothandler")
    
register_cvar("ghost_recorder"VERSIONFCVAR_SERVER);
    
//create dir if needed
    
if(!dir_exists(SAVEPATH)){
        
log_amx("Save dir doe not exsit, creating for you =)")
        if(
mkdir(SAVEPATH) != 0){
            
log_amx("Couldn't create dir do it yourself")
        }
    }
    
}
public 
plugin_precache(){
    
precache_model"models/player/vip/vip.mdl" );
}
public 
client_putinserver(id){
    
g_FileHandler[id] = 0
    g_isRecording
[id] = 0
    g_isPause
[id] = 0
    g_LastThink
[id] = get_gametime()
    
g_SaveSlot[id] = 0
}
public 
plugin_end(){
    for(new 
0MAXPLAYERSi++){
        if(
g_FileHandler[i] != 0){
            
fclose(g_FileHandler[i])
        }
    }
}
public 
client_disconnect(id){
    
    if(
g_FileHandler[id] != 0){
        
fclose(g_FileHandler[id]);
    }

}
public 
menu_show(id){
    
g_MenuOpen[id] = 1;
    new 
menu[128],filename[128]
    new 
size[10]
    new 
playpause[3],stop[3],record[19],choose[3];
    
get_filename(id,g_SaveSlot[id],filename)
    if(
file_exists(filename)){
        
formatex(size,9,"%dKb",file_size(filename)/1024)
        
formatex(playpause,2,"\y")
    }else{
        
formatex(size,9,"FREE")
        
formatex(playpause,2,"\d")
    }
    if(
g_isRecording[id]){
        
formatex(playpause,2,"\d")
        
formatex(record,18,"\y Stop Recording")
    }else{
        
formatex(record,18,"\y Start Recording")
    }
    if(
g_isRecording[id] == && g_FileHandler[id] != 0){
        
formatex(stop,2,"\y")
        
formatex(record,18,"\d Start Recording")
    }else{
        
formatex(stop,2,"\d")
    }
    if(
g_FileHandler[id] != 0){
        
formatex(choose,2,"\d")
    }else{
        
formatex(choose,2,"\y")
    }
    
format(menu,127,"Active Slot: \r%d \d(%s)^n\r1.%s Choose Slot^n\r2.%s^n\r3.%s Play/Pause^n\r4.%s Stop^n\r^n^n0. \wEXIT",g_SaveSlot[id],size,choose,record,playpause,stop)
    
show_menu(id,RECORDKEYS,menu, -1"Demo Recorder")
}
public 
choose_slot(id){
    new 
menu[256]
    
format(menu,255,"\yChoose Slot");
    for( new 
MAXSLOTS i++){
        static 
filename[128]
        
get_filename(id,i,filename)
        if(
file_exists(filename)){
            
format(menu,255,"%s^n\r%d. \w SLOT %d (%dKb)",menu,i+1,i,file_size(filename)/1024)
        }else{
            
format(menu,255,"%s^n\r%d. \w SLOT %d (FREE)",menu,i+1,i)
        }
    }
    
show_menu(id,SLOTKEYS,menu, -1"Slot Chooser")
}
public 
slothandler(id,key){
    if(
key MAXSLOTS){
        
g_SaveSlot[id] = key
        menu_show
(id)
    }else{
        
choose_slot(id)
    }
}
public 
menuhandler(id,key){
    switch (
key) {
        case 
9: {
            
g_MenuOpen[id] = 0
            
return PLUGIN_CONTINUE
        
}
        case 
0: {
            if(
g_FileHandler[id] == 0){
                
choose_slot(id);
            }else{
                
menu_show(id)
            }
            return 
PLUGIN_CONTINUE;
        }
        case 
1: { 
            if(
g_isRecording[id] == 1){
                
stop_record(id);
            }else if(
g_FileHandler[id] == 0){
                
start_record(id);
            }
            
menu_show(id)
        }
        case 
2: { 
            if(
g_isRecording[id] == && g_FileHandler[id] == 0){
                
start_replay(id);
            }else if(
g_isRecording[id] == 0){
                if(
g_isPause[id]){
                    
g_isPause[id] = 0
                    client_print
(id,print_chat,"[Recorder] Playback resumed")
                }else{
                    
g_isPause[id] = 1
                    client_print
(id,print_chat,"[Recorder] Playback paused")
                }
            }
            
menu_show(id)
        }
        case 
3: { 
            if(
g_isRecording[id] == && g_FileHandler[id] != 0){
                
client_print(id,print_chat,"[Recorder] Stopping playback")
                
g_isPause[id] = 0;
                
g_FileHandler[id] = 0;
            }
            
menu_show(id)
        }
    }
    return 
PLUGIN_HANDLED
}
public 
fm_ghost_think(id){
    static 
szClassname[13]
    
pev(id,pev_classnameszClassname,12)
    if( !
equal(szClassname"ghost_player") )
        return 
FMRES_IGNORED;
    static 
Float:ago,Float:origin[3],Float:angles[3],Float:veloc[3];
    static 
owner,data,sequence,gaitsequence
    owner 
pev(id,pev_owner);
    if(!
is_user_connected(owner)) return FMRES_IGNORED;
    if(
g_isPause[owner] == 1){
        
set_pev(id,pev_nextthink,get_gametime()+0.5)
        return 
FMRES_IGNORED
    
}
    
fread(g_FileHandler[owner],_:angles[0],BLOCK_INT)
    
fread(g_FileHandler[owner],_:angles[1],BLOCK_INT)
    
fread(g_FileHandler[owner],_:angles[2],BLOCK_INT)
    
fread(g_FileHandler[owner],_:origin[0],BLOCK_INT)
    
fread(g_FileHandler[owner],_:origin[1],BLOCK_INT)
    
fread(g_FileHandler[owner],_:origin[2],BLOCK_INT)
    
fread(g_FileHandler[owner],_:veloc[0],BLOCK_INT)
    
fread(g_FileHandler[owner],_:veloc[1],BLOCK_INT)
    
fread(g_FileHandler[owner],_:veloc[2],BLOCK_INT)
    
fread(g_FileHandler[owner],sequence,BLOCK_INT)
    
fread(g_FileHandler[owner],gaitsequence,BLOCK_INT)
    
data fread(g_FileHandler[owner],_:ago,BLOCK_INT)
    if(
data != 1){
        
client_print(owner,print_chat,"[Recorder] Playback Finished")
        if(
g_FileHandler[owner] != 0)fclose(g_FileHandler[owner])
        
g_FileHandler[owner] = 0
        
if(g_MenuOpen[owner]){
            
menu_show(owner)
        }
        
fm_remove_entity(id);
        return 
FMRES_IGNORED;
    }
    
set_pev(id,pev_nextthink,get_gametime()+ago)
    
set_pev(id,pev_origin,origin)
    
set_pev(id,pev_angles,angles)
    
set_pev(id,pev_velocity,veloc)
    
set_pev(id,pev_gaitsequence,sequence)
    
set_pev(id,pev_sequence,gaitsequence)
    return 
FMRES_HANDLED;

}
public 
start_replay(id){
    
log_amx("starting replay")
    if(
g_FileHandler[id] != 0){
        
client_print(id,print_chat,"[Recorder] Can't open File, maybe you are still recording")
        return 
PLUGIN_CONTINUE;
    }
    new 
fileName[128]
    
get_filename(id,g_SaveSlot[id],fileName)
    
log_amx(fileName);
    
g_FileHandler[id] = fopen(fileName,"rb");
    if(
g_FileHandler[id] == 0){
        
client_print(id,print_chat,"[Recorder] Couldn't open file mybe none existent")
    }else{
        
client_print(id,print_chat,"[Recorder] Playback started")
        
fnCreateGhost(id)
        new 
dummy
        fread
(g_FileHandler[id],dummy,BLOCK_INT)
    }
    return 
PLUGIN_HANDLED
}
public 
fm_plr_prethink(id){
    if(
is_user_alive(id) && g_isRecording[id] != 0){
        static 
Float:ago,Float:origin[3],Float:angles[3],Float:veloc[3];
        static 
sequence,gaitsequence
        ago 
get_gametime()-g_LastThink[id]
        if(
ago RECLIMITER) return FMRES_IGNORED
        pev
(id,pev_origin,origin)
        
pev(id,pev_velocity,veloc)
        
pev(id,pev_angles,angles)
        
sequence pev(id,pev_sequence)
        
gaitsequence pev(id,pev_gaitsequence)
        if((
g_LastAngle[id][0] == angles[0] && g_LastAngle[id][1] == angles[1] && g_LastAngle[id][2] == angles[2] ) && (g_LastOrigin[id][0] == origin[0] && g_LastOrigin[id][1] == origin[1] && g_LastOrigin[id][2] == origin[2] ) && (g_LastVelocity[id][0] == veloc[0] &&    g_LastVelocity[id][1] == veloc[1] && g_LastVelocity[id][2] == veloc[2])) return FMRES_IGNORED
        g_LastAngle
[id][0] = angles[0]
        
g_LastAngle[id][1] = angles[1]
        
g_LastAngle[id][2] = angles[2]
        
g_LastOrigin[id][0] = origin[0]
        
g_LastOrigin[id][1] = origin[1]
        
g_LastOrigin[id][2] = origin[2]
        
g_LastVelocity[id][0] = veloc[0]
        
g_LastVelocity[id][1] = veloc[1]
        
g_LastVelocity[id][2] = veloc[2]
        
g_LastThink[id] = get_gametime()
        
fwrite(g_FileHandler[id],_:ago,BLOCK_INT)
        
fwrite(g_FileHandler[id],_:angles[0],BLOCK_INT)
        
fwrite(g_FileHandler[id],_:angles[1],BLOCK_INT)
        
fwrite(g_FileHandler[id],_:angles[2],BLOCK_INT)
        
fwrite(g_FileHandler[id],_:origin[0],BLOCK_INT)
        
fwrite(g_FileHandler[id],_:origin[1],BLOCK_INT)
        
fwrite(g_FileHandler[id],_:origin[2],BLOCK_INT)
        
fwrite(g_FileHandler[id],_:veloc[0],BLOCK_INT)
        
fwrite(g_FileHandler[id],_:veloc[1],BLOCK_INT)
        
fwrite(g_FileHandler[id],_:veloc[2],BLOCK_INT)
        
fwrite(g_FileHandler[id],sequence,BLOCK_INT)
        
fwrite(g_FileHandler[id],gaitsequence,BLOCK_INT)
        return 
FMRES_HANDLED
    
}
    return 
FMRES_IGNORED
}
public 
start_record(id){
    new 
fileName[128]
    
get_filename(id,g_SaveSlot[id],fileName)
    
log_amx(fileName)
    
g_FileHandler[id] = fopen(fileName,"wb");
    
g_isRecording[id] = 1;
    
client_print(id,print_chat,"[Recorder] Recording started")
}
public 
stop_record(id){
    
g_isRecording[id] = 0
    fclose
(g_FileHandler[id])
    
g_FileHandler[id] = 0
    client_print
(id,print_chat,"[Recorder] Recording stoped")
}
public 
get_filename(id,slot,fileName[]){
    new 
mapname[33],steamid[35]
    
get_mapname(mapname,32)
    
get_user_authid(id,steamid,34)
    
replace_all(steamid,34,":","_")
    
format(fileName,127,"%s%s_%d_%s",SAVEPATH,steamid,slot,mapname)
}
public 
fnCreateGhostiOwner ) {
    new 
ent engfunc(EngFunc_CreateNamedEntityengfunc(EngFunc_AllocString"info_target"))
        
//make sure entity was created successfully
    
if (pev_valid(ent)) {
        
dllfunc(DLLFunc_Spawn,ent)
        
engfunc(EngFunc_SetModel,ent,"models/player/vip/vip.mdl")
        
set_pev(entpev_classname"ghost_player")
        
set_pev(entpev_solidSOLID_NOT)
        
set_pev(ent,pev_movetype,MOVETYPE_PUSHSTEP)
        
set_pev(entpev_owneriOwner)
        
set_pev(ent,pev_animtime2.0)
        
set_pev(ent,pev_framerate1.0)
        
set_pev(ent,pev_flagsFL_MONSTER)
        
set_pev(ent,pev_controller_0125)
        
set_pev(ent,pev_controller_1125)
        
set_pev(ent,pev_controller_2125)
        
set_pev(ent,pev_controller_3125)
        
fm_set_rendering(entkRenderFxGlowShell255255255kRenderTransAlpha150)
        
set_pev(entpev_nextthinkget_gametime() + 0.1)
    }else{
        
client_print(iOwner,print_chat,"[Recorder] Ghost couldn't be created")
        
fclose(g_FileHandler[iOwner])
    }

I'd appreciate some ideas / examples

Last edited by Point; 05-24-2019 at 20:41.
Point 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 17:24.


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