Maybe you're right. When i looked to the human's code I realised how complicated would it be to invent. I decided to use it but I wanted to teleport an enemy, not a client. I made some modifications and it works, but not as good as in human race and with no cooldown.
Here is the code after some changes:
/* *************************************** OnUltimateCommand *************************************** */
new bool:inteleportcheck[MAXPLAYERS];
public OnUltimateCommand(client,race,bool:pressed)
{
if(race==thisRaceID && pressed && ValidPlayer(client,true))
{
new skill_ult = War3_GetSkillLevel(client,thisRaceID,ULT_TELEPORT);
if(skill_ult > 0)
{
if(!Silenced(client) && War3_SkillNotInCooldown(client,thisRaceID,ULT_TELEPORT,true ))
{
new enemy = GetRandomPlayer(client);
if( enemy > 0 && !W3HasImmunity(enemy,Immunity_Ultimates))
{
new enemysTeamPlayers;
new enemyTeam = GetClientTeam(enemy);
for(new i = 1; i <= MaxClients; i++)
{
if(i != enemy && ValidPlayer(i,true) && GetClientTeam(i) == enemyTeam)
{
enemysTeamPlayers++;
}
}
if(enemysTeamPlayers > 0)
{
if(!inteleportcheck[enemy]) //not in the 0.2 second delay when we check stuck via moving
{
AttackerID = client; // here I'm saving client's ID
TeleportPlayerView(enemy,TeleportDistance[skill_ult]); // cause I want to teleport another player
}
}
else
{
PrintHintText( client, "Target is last enemy alive, cannot be teleported" );
}
}
else
{
PrintHintText( client, "No Target Found" );
}
}
}
else
{
PrintHintText(client, "Level your Teleport first");
}
}
}
/* *************************************** Teleport Stuff *************************************** */
// Teleport Stuff
// By: stinkyfax
// Much thanks, this would be a nightmare without him.
new ClientTracer;
new Float:emptypos[3];
new Float:oldpos[MAXPLAYERS][3];
new Float:teleportpos[MAXPLAYERS][3];
bool:TeleportPlayerView(client,Float:distance)
{
if(client>0)
{
if(IsPlayerAlive(client))
{
new Float:angle[3];
GetClientEyeAngles(AttackerID,angle); // replaced client to AttackerID
new Float:endpos[3];
new Float:startpos[3];
GetClientEyePosition(AttackerID,startpos); // replaced client to AttackerID
new Float:dir[3];
GetAngleVectors(angle, dir, NULL_VECTOR, NULL_VECTOR);
ScaleVector(dir, distance);
//PrintToChatAll("DIR %f %f %f",dir[0],dir[1],dir[2]);
AddVectors(startpos, dir, endpos);
GetClientAbsOrigin(client,oldpos[client]);
//PrintToChatAll("1");
ClientTracer=client;
TR_TraceRayFilter(startpos,endpos,MASK_ALL,RayType_EndPoint,AimTargetFilter);
TR_GetEndPosition(endpos);
//new Float:normal[3];
//TR_GetPlaneNormal(INVALID_HANDLE,normal);
//ScaleVector(normal, 20.0);
if(enemyImmunityInRange(client,endpos)){
W3MsgEnemyHasImmunity(client);
return false;
}
//PrintToChatAll("1endpos %f %f %f",endpos[0],endpos[1],endpos[2]);
distance=GetVectorDistance(startpos,endpos);
GetAngleVectors(angle, dir, NULL_VECTOR, NULL_VECTOR);///get dir again
ScaleVector(dir, distance-33.0);
AddVectors(startpos,dir,endpos);
//PrintToChatAll("DIR %f %f %f",dir[0],dir[1],dir[2]);
//PrintToChatAll("2endpos %f %f %f",endpos[0],endpos[1],endpos[2]);
//endpos[1]=(startpos[1]+(distance*Sine(DegToRad(angle[1]))));
//endpos[0]=(startpos[0]+(distance*Cosine(DegToRad(angle[1]))));
//if(!CheckPlayerBox(endpos,startpos,client))
// return false;
emptypos[0]=0.0;
emptypos[1]=0.0;
emptypos[2]=0.0;
endpos[2]-=30.0;
getEmptyLocationHull(client,endpos);
//PrintToChatAll("emptypos %f %f %f",emptypos[0],emptypos[1],emptypos[2]);
if(GetVectorLength(emptypos)<1.0){
new String:buffer[100];
Format(buffer, sizeof(buffer), "%T", "NoEmptyLocation", client);
PrintHintText(AttackerID,buffer); // replaced client to AttackerID
return false; //it returned 0 0 0
}
TeleportEntity(client,emptypos,NULL_VECTOR,NULL_VECTOR);
EmitSoundToAll(teleportSound,client);
EmitSoundToAll(teleportSound,AttackerID); // replaced client to AttackerID
teleportpos[client][0]=emptypos[0];
teleportpos[client][1]=emptypos[1];
teleportpos[client][2]=emptypos[2];
inteleportcheck[client]=true;
CreateTimer(0.14,checkTeleport,client);
return true;
}
}
return false;
}
public Action:checkTeleport(Handle:h,any:client){
inteleportcheck[client]=false;
new Float:pos[3];
GetClientAbsOrigin(client,pos);
// new Float:velocity[3];
//GetEntDataVector(client,m_vecVelocity,velocity);
//PrintToChatAll("%f/%f %f/%f %f/%f",teleportpos[client][0],pos[0],teleportpos[client][1],pos[1],teleportpos[client][2],pos[2]);
if(GetVectorDistance(teleportpos[client],pos)<0.001)//he didnt move in this 0.1 second
{
TeleportEntity(client,oldpos[client],NULL_VECTOR,NULL_VECTOR);
PrintHintText(AttackerID,"%T","CantTeleportHere",client);
}
else{
PrintHintText(AttackerID,"%T","Teleported",client); // replaced client to AttackerID
new Float:cooldown=GetConVarFloat(ultCooldownCvar);
War3_CooldownMGR(AttackerID,cooldown,thisRaceID,ULT_TELEPORT,_,_); // replaced client to AttackerID
}
}
public bool:AimTargetFilter(entity,mask)
{
return !(entity==ClientTracer);
}
There is no changes in other parts of this code. I just replaced word "client" to "AttackerID" in some lines. Maybe I overlooked smth or do something wrong.
Sometimes it doesn't work good. Enemy appears behind me when I use it aiming on the floor. I've never done anything with a tracing and I don't know how to fix this bug.
And there is no cooldown for it despite the declarations of averything for that. I called variable for colldown the same as it is in Human Race to not overlook anything but it still doesn't work. Maybe this is due to previous changes, but I'm still checking it.