16.01.2019, 21:37
So I have a /spec command. However, there are a few issues:
- /spec works if a player is on foot and in the same world as the admin. Any interior. For all players. If the admin is in a different world, they see blueberry and not the player. This needs to be fixed.
- If the world updates whilst someone is spectating, blueberry appears again. Interior updating works fine.
- If a player is in a vehicle when u type /spec, or if they update and enter/exit a vehicle, it works for any player above id 1. ID 0 however, you get to see blueberry.
See all relevant code below, I hope someone can help.
- /spec works if a player is on foot and in the same world as the admin. Any interior. For all players. If the admin is in a different world, they see blueberry and not the player. This needs to be fixed.
- If the world updates whilst someone is spectating, blueberry appears again. Interior updating works fine.
- If a player is in a vehicle when u type /spec, or if they update and enter/exit a vehicle, it works for any player above id 1. ID 0 however, you get to see blueberry.
See all relevant code below, I hope someone can help.
Code:
new Float:SpecX[MAX_PLAYERS], Float:SpecY[MAX_PLAYERS], Float:SpecZ[MAX_PLAYERS], Float:SpecR[MAX_PLAYERS], SpecW[MAX_PLAYERS], SpecI[MAX_PLAYERS], IsSpecing[MAX_PLAYERS], IsBeingSpeced[MAX_PLAYERS],SpecID[MAX_PLAYERS]; public OnPlayerStateChange(playerid, newstate, oldstate) { // spec related start if(newstate == PLAYER_STATE_DRIVER || newstate == PLAYER_STATE_PASSENGER) { if(IsBeingSpeced[playerid] == 1) { foreach(new i:Player) { if(!IsPlayerConnected(i)) continue; if(SpecID[i] == playerid) { PlayerSpectateVehicle(i, GetPlayerVehicleID(playerid)); } } } } if(newstate == PLAYER_STATE_ONFOOT) { if(IsBeingSpeced[playerid] == 1) { foreach(new i:Player) { if(!IsPlayerConnected(i)) continue; if(SpecID[i] == playerid) { PlayerSpectatePlayer(i, playerid); } } } } // spec related end return 1; } public OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid) { if(IsBeingSpeced[playerid] == 1) // admins will re-spec the player if the int is changed. world updates too. { foreach(new i:Player) { if(SpecID[i] == playerid) { SetPlayerInterior(i,GetPlayerInterior(playerid)); SetPlayerVirtualWorld(i,GetPlayerVirtualWorld(playerid)); } } } return 1; } CMD:spec(playerid, params[]) { if(PlayerInfo[playerid][pAdmin] >= 1) { new targetid; if(GetPlayerState(playerid) == PLAYER_STATE_SPECTATING) { TogglePlayerSpectating(playerid, 0); SetPlayerPos(playerid,SpecX[playerid],SpecY[playerid],SpecZ[playerid]); SetPlayerFacingAngle(playerid, SpecR[playerid]); SetPlayerInterior(playerid, SpecI[playerid]); SetPlayerVirtualWorld(playerid, SpecW[playerid]); IsSpecing[playerid] = 0; IsBeingSpeced[SpecID[playerid]] = 0; new str[128]; format(str, sizeof(str), "%s %s(%i) has quit spectating %s(%i).", ReturnAdminLevel(playerid), ReturnICName(playerid), playerid, ReturnICName(SpecID[playerid]), SpecID[playerid]); ABroadCast(COLOR_SADMIN, str, 1); new action[20]; format(action, sizeof(action), "spec end"); new query[250]; mysql_format(g_SQL, query, sizeof(query), "INSERT INTO logs_punishments(acc_dbid, acc_name, ip_address, time, action, reason, by_acc_dbid, by_acc_name) VALUES('%i', '%e', '%e', UTC_TIMESTAMP(), '%e', '-1', '%i', '%e')", PlayerInfo[targetid][pDBID], ReturnName(targetid), ReturnIP(targetid), action, PlayerInfo[playerid][pDBID], ReturnName(playerid)); mysql_tquery(g_SQL, query); } else { if(sscanf(params, "u", targetid)) return SCM(playerid, COLOR_INFO, "/spec [name/id](leave blank to quit spectating)"); if(targetid == playerid) return SCM(playerid, COLOR_ERROR, "You can not use this command on yourself."); if(!IsPlayerConnected(targetid)) return SCM(playerid, COLOR_ERROR, "That account is not connected."); if(!Spawned[targetid]) return SCM(playerid, COLOR_ERROR, "That player has not logged in or spawned yet."); if(GetPlayerState(targetid) == PLAYER_STATE_SPECTATING) return SCMEx(playerid, COLOR_ERROR, "%s(%i) is spectating %s(%i) right now. Try again later.", ReturnICName(targetid), targetid, ReturnICName(SpecID[targetid]), SpecID[targetid]); OnPlayerSave(playerid); // saves the player data so that they don't get their position, health & armour rollbacked for not being spawned (if they quit in spec mode). GetPlayerPos(playerid,SpecX[playerid],SpecY[playerid],SpecZ[playerid]); GetPlayerFacingAngle(playerid, SpecR[playerid]); SpecI[playerid] = GetPlayerInterior(playerid); SpecW[playerid] = GetPlayerVirtualWorld(playerid); if(IsPlayerInAnyVehicle(targetid)) { TogglePlayerSpectating(playerid, 1); SetPlayerInterior(playerid, GetPlayerInterior(targetid)); SetPlayerVirtualWorld(playerid, GetPlayerVirtualWorld(targetid)); PlayerSpectateVehicle(playerid, targetid); } else { TogglePlayerSpectating(playerid, 1); SetPlayerInterior(playerid, GetPlayerInterior(targetid)); SetPlayerVirtualWorld(playerid, GetPlayerVirtualWorld(targetid)); PlayerSpectatePlayer(playerid, targetid); } IsSpecing[playerid] = 1; IsBeingSpeced[targetid] = 1; SpecID[playerid] = targetid; new str[128]; format(str, sizeof(str), "%s %s(%i) is spectating %s(%i).", ReturnAdminLevel(playerid), ReturnICName(playerid), playerid, ReturnICName(targetid), targetid); ABroadCast(COLOR_SADMIN, str, 1); new action[20]; format(action, sizeof(action), "spec start"); new query[250]; mysql_format(g_SQL, query, sizeof(query), "INSERT INTO logs_punishments(acc_dbid, acc_name, ip_address, time, action, reason, by_acc_dbid, by_acc_name) VALUES('%i', '%e', '%e', UTC_TIMESTAMP(), '%e', '-1', '%i', '%e')", PlayerInfo[targetid][pDBID], ReturnName(targetid), ReturnIP(targetid), action, PlayerInfo[playerid][pDBID], ReturnName(playerid)); mysql_tquery(g_SQL, query); } } else return SCM(playerid,COLOR_ERROR,"You do not have the required access to execute this command."); return 1; } public OnPlayerDisconnect(playerid, reason) { if(IsBeingSpeced[playerid] == 1) // admins will stop specing the player if they log out. { foreach(new i:Player) { if(SpecID[i] == playerid) { TogglePlayerSpectating(i, 0); SetPlayerPos(i, SpecX[i],SpecY[i],SpecZ[i]); SetPlayerFacingAngle(i, SpecR[i]); SetPlayerInterior(i, SpecI[i]); SetPlayerVirtualWorld(i, SpecW[i]); IsSpecing[playerid] = 0; IsBeingSpeced[SpecID[playerid]] = 0; new str2[128]; format(str2, sizeof(str2), "%s %s(%i) has quit spectating ID %i.", ReturnAdminLevel(i), ReturnICName(i), i, SpecID[playerid]); ABroadCast(COLOR_SADMIN, str2, 1); new action2[20]; format(action2, sizeof(action2), "spec end (quit)"); new query2[250]; mysql_format(g_SQL, query2, sizeof(query2), "INSERT INTO logs_punishments(acc_dbid, acc_name, ip_address, time, action, reason, by_acc_dbid, by_acc_name) VALUES('%i', '%e', '-1', UTC_TIMESTAMP(), '%e', '-1', '%i', '%e')", PlayerInfo[playerid][pDBID], ReturnName(playerid), action2, PlayerInfo[i][pDBID], ReturnName(i)); mysql_tquery(g_SQL, query2); } } } ResetPlayer(playerid); return 1; } function:ResetPlayer(playerid) { IsSpecing[playerid] = 0; IsBeingSpeced[SpecID[playerid]] = 0; return 1; }