I optimized the code and added some useful comments inside the script.
PHP Code:
// Checkpoint v1.1
// By Adi '4D1 - thEsp' Behluli
// Started writting as of 8:09 - 6/9/2019
// Ended testing and writting as of 8:37 - 6/9/2019
#include <amxmodx>
#include <engine>
#include <hamsandwich>
#include <amxmisc>
#define has_checkpoint(%1) (HasCP[%1] == true)
#define valid_player(%1) (1 <= %1 && %1 <= 32)
#define reset_cp(%1) HasCP[%1]=false
#define set_cp(%1) HasCP[%1]=true
new Float:SpawnLocations[33][3];
new bool:HasCP[33] = {true,...}; // this is the correct way to set an array with default value;
new bool:Crouching[33];
new Cvar_Damage,Cvar_AutoReset
public plugin_init()
{
register_plugin("Death Checkpoint","1.1","thEsp (4D1)")
register_dictionary("death_cp.txt")
clear_checkpoints()
Cvar_Damage = register_cvar("amx_dcp_damage","1")
Cvar_AutoReset = register_cvar("amx_dcp_autoreset","0")
register_clcmd("say /removecp","cmdRemoveCp")
RegisterHam(Ham_Killed,"player","hamDeath_Post",1,true)
RegisterHam(Ham_Player_Duck,"player","hamDuck_Post",1,true)
RegisterHam(Ham_Spawn,"player","hamSpawn_Post",1,true)
}
clear_checkpoints()
{
for(new i=1, loop = sizeof SpawnLocations;i<loop;i++) // player id start from 1 basically you have 1 useless iteration :D
{
reset_cp(i)
}
}
// Check if player is ducking (removes a bug)
public hamDuck_Post(id)
{
Crouching[id] = (entity_get_int(id,EV_INT_button) & IN_DUCK ? true : false) // I do recommend to check player size before death or even better death animation.
}
// Transports player if died and has checkpoint
public hamSpawn_Post(id)
{
if(!is_user_alive(id)) return; // you need to check if user is alive because this forward is also called on spawning a player entity.(when player putin server or before that I'm not certain).
if(has_checkpoint(id))
{
entity_set_origin(id,SpawnLocations[id])
if(get_pcvar_num(Cvar_Damage) != 1)
drop_to_floor(id)
client_print(id,print_chat,"%L",LANG_PLAYER,"RESPAWN_FROM_CP")
}
if(get_pcvar_num(Cvar_AutoReset) == 1)
{
reset_cp(id)
}
}
// Saves checkpoint
public hamDeath_Post(id,killer)
{
if(valid_player(id)) // here you had useless checks checking if the victim is dead when hamDeath_Post called victim is 100% dead and to be honest you don't really need any check'.
{
if(!has_checkpoint(id)) // you don't need to use switch when you got not much of cases
{
new Origin[3];
get_user_origin(id,Origin)
if(Crouching[id]) Origin[2] += 20;
set_cp(id);
IVecFVec(Origin,SpawnLocations[id])
client_print(id,print_chat,"%L",LANG_PLAYER,"SAVED_CP")
}
}
// also you have no reason to reset the checkpoint on death.
}
// Clears existing checkpoint
public cmdRemoveCp(id)
{
if(!has_checkpoint(id))
{
client_print(id,print_chat,"%L",LANG_PLAYER,"NO_CP")
return PLUGIN_HANDLED;
}
// you don't need else when you have nothing much afterwards...
reset_cp(id);
client_print(id,print_chat,"%L",LANG_PLAYER,"CP_CLEARED")
return PLUGIN_HANDLED;
}
You should also add support for deathrun/kz maps this would be more useful there.
Also you can add check points reset flags for example resetting cp on round end or on spawn or don't allow respawn in water , toxins or lava, etc....
even add an admin command to revive someone from death checkpoint
__________________