portals diff

Created Diff never expires
82 removals
329 lines
108 additions
355 lines
#include <sourcemod>
#include <sourcemod>
#include <sdktools>
#include <sdktools>
#include <sdkhooks>
#include <sdkhooks>


#pragma semicolon 1

new Float:bluepos[3];
new Float:bluepos[3];
new Float:redpos[3];
new Float:redpos[3];


new BluePortal = 0;
new BluePortal = 0;
new RedPortal = 0;
new RedPortal = 0;


new bool:PortalUseDelay = false;
new bool:PortalUseDelay = false;
new bool:PortalSeperated = false;
new bool:PortalSeperated = false;
new bool:PortalsActive = false;
//new bool:PortalsActive = false;


#define PORTAL_MDL "models/props_mall/mall_shopliftscanner.mdl"
#define PORTAL_MDL "models/props_mall/mall_shopliftscanner.mdl"
#define PORTAL_SND "weapons/defibrillator/defibrillator_use.wav"
#define PORTAL_SND "weapons/defibrillator/defibrillator_use.wav"


public OnPluginStart()
public OnPluginStart()
{
{
RegConsoleCmd("sm_startportals", Start_Portal, "allow use of portals");
RegConsoleCmd("sm_startportals", Start_Portal, "allow use of portals");
RegConsoleCmd("sm_blue", Blue_Move, "move blue portal");
RegConsoleCmd("sm_blue", Blue_Move, "move blue portal");
RegConsoleCmd("sm_red", Red_Move, "move red portal");
RegConsoleCmd("sm_red", Red_Move, "move red portal");
RegConsoleCmd("sm_killportals",Kill_Portal, "remove portals");
RegConsoleCmd("sm_killportals",Kill_Portal, "remove portals");
HookEvent("round_end", Event_RoundChange)
HookEvent("round_start", Event_RoundChange);
}
}


public OnMapStart()
public OnMapStart()
{
{
PortalUseDelay = false;
PortalUseDelay = false;
PortalSeperated = false;
PortalSeperated = false;
PortalsActive = false;
//PortalsActive = false;
PrecacheSound(PORTAL_SND);
PrecacheSound(PORTAL_SND);
}
}


public Event_RoundChange(Handle:event, String:name[], bool:dontBroadcast)
public Event_RoundChange(Handle:event, String:name[], bool:dontBroadcast)
{
{
PortalUseDelay = false;
PortalUseDelay = false;
PortalSeperated = false;
PortalSeperated = false;
PortalsActive = false;
//PortalsActive = false;
}
}


public Action:Start_Portal(client, args)
public Action:Start_Portal(client, args)
{
{
//PrintToChat(client,"portals started");
//PrintToChat(client,"portals started");

if (!PortalsActive)
//good idea to kill them when starting again or you will have an entity leak and other touch hooked portal entities will interfere that were not killed.
if(IsValidEntRef(BluePortal))
{
{
decl Float:pos[3];
AcceptEntityInput(BluePortal , "Kill" );
decl Float:ang[3];
}
GetClientAbsOrigin(client, pos);
if(IsValidEntRef(RedPortal))
GetClientEyeAngles(client, ang);
{
AcceptEntityInput(RedPortal , "Kill" );
ang[0] = NULL_VECTOR[0];
}
ang[2] = NULL_VECTOR[2];
new Blue;
decl Float:pos[3];
new Red;
decl Float:ang[3];
GetClientAbsOrigin(client, pos);
Blue = CreateEntityByName("prop_physics_override");
GetClientEyeAngles(client, ang);
DispatchKeyValue(Blue, "model", PORTAL_MDL);
DispatchKeyValue( Blue, "Solid", "6");
ang[0] = NULL_VECTOR[0];
DispatchKeyValueVector( Blue, "Origin", pos );
ang[2] = NULL_VECTOR[2];
DispatchKeyValueVector( Blue, "Angles", ang );
DispatchSpawn(Blue);
new Blue;
new Red;
Blue = CreateEntityByName("prop_physics_override");
DispatchKeyValue(Blue, "model", PORTAL_MDL);
DispatchKeyValue( Blue, "Solid", "6");
DispatchKeyValueVector( Blue, "Origin", pos );
DispatchKeyValueVector( Blue, "Angles", ang );
DispatchSpawn(Blue);
//AcceptEntityInput(BluePortal, "EnableCollision");
//AcceptEntityInput(BluePortal, "EnableCollision");
SetEntityMoveType(Blue, MOVETYPE_NONE);
SetEntityMoveType(Blue, MOVETYPE_NONE);
SetEntityRenderColor(Blue, 0, 0, 255, 200);
SetEntityRenderColor(Blue, 0, 0, 255, 200);
SetGlowBlue(Blue)
SetGlowBlue(Blue);
BluePortal = EntIndexToEntRef(Blue)
BluePortal = EntIndexToEntRef(Blue);
SDKHook(Blue, SDKHook_Touch, TouchBlue);
SDKHook(Blue, SDKHook_Touch, TouchBlue);
SDKHook(Blue, SDKHook_OnTakeDamage, BlockDMG);//block damage to the portal entity
Red = CreateEntityByName("prop_physics_override");
DispatchKeyValue( Red, "model", PORTAL_MDL);
Red = CreateEntityByName("prop_physics_override");
DispatchKeyValue( Red, "Solid", "6");
DispatchKeyValue( Red, "model", PORTAL_MDL);
DispatchKeyValueVector( Red, "Origin", pos );
DispatchKeyValue( Red, "Solid", "6");
DispatchKeyValueVector( Red, "Angles", ang );
DispatchKeyValueVector( Red, "Origin", pos );
DispatchSpawn(Red);
DispatchKeyValueVector( Red, "Angles", ang );
DispatchSpawn(Red);
//AcceptEntityInput(RedPortal, "EnableCollision");
//AcceptEntityInput(RedPortal, "EnableCollision");
SetEntityMoveType(Red, MOVETYPE_NONE);
SetEntityMoveType(Red, MOVETYPE_NONE);
SetEntityRenderColor(Red, 255, 0, 0, 200);
SetEntityRenderColor(Red, 255, 0, 0, 200);
SetGlowRed(Red)
SetGlowRed(Red);
SDKHook(Red, SDKHook_OnTakeDamage, BlockDMG);
SDKHook(Red, SDKHook_Touch, TouchRed);
RedPortal = EntIndexToEntRef(Red)
SDKHook(Red, SDKHook_Touch, TouchRed);
RedPortal = EntIndexToEntRef(Red);
PortalsActive = true;
//PortalsActive = true;
if(IsValidEntRef(RedPortal) && IsValidEntRef(BluePortal))
{
if(IsValidEntRef(RedPortal) && IsValidEntRef(BluePortal))
PrintToChat(client,"portals entref sucsess");
{
}
PrintToChat(client,"portals entref sucsess");
}
}
}
}


public Action BlockDMG(int victim, int &attacker, int &inflictor, float &damage, int &damagetype, int &weapon, float damageForce[3], float damagePosition[3])
{
//i'm not sure if prop damage is what is killing your entity just incase the tank punches it ect, we just block all damage.
return Plugin_Handled;
}

public Action:TouchBlue(entity, other)
public Action:TouchBlue(entity, other)
{
{
// if portals arent indelay and have been seperated and are active
// if portals arent indelay and have been seperated and are active
if(!PortalUseDelay && PortalSeperated && PortalsActive && IsValidClient(other))
if(!PortalUseDelay && IsValidEntRef(RedPortal) && PortalSeperated && IsValidClient(other))//check if the red portal is valid don't assume
{
{
//PrintToChatAll("%i touch blue %N",entity,other);
//PrintToChatAll("%i touch blue %N",entity,other);
decl Float:BlueClientOrigin[3];
decl Float:BlueClientOrigin[3];
decl Float:BlueClientAngle[3];
decl Float:BlueClientAngle[3];
decl Float:PlayerVec[3];
decl Float:PlayerVec[3];
decl Float:PlayerAng[3];
decl Float:PlayerAng[3];
GetEntPropVector(EntRefToEntIndex(RedPortal), Prop_Data, "m_vecOrigin", PlayerVec);
GetEntPropVector(RedPortal, Prop_Data, "m_vecOrigin", PlayerVec);
GetEntPropVector(EntRefToEntIndex(RedPortal), Prop_Data, "m_angRotation", PlayerAng);
GetEntPropVector(RedPortal, Prop_Data, "m_angRotation", PlayerAng);
BlueClientOrigin[0] = (PlayerVec[0] + 50 * Cosine(DegToRad(PlayerAng[1])));
BlueClientOrigin[0] = (PlayerVec[0] + 50 * Cosine(DegToRad(PlayerAng[1])));
BlueClientOrigin[1] = (PlayerVec[1] + 50 * Sine(DegToRad(PlayerAng[1])));
BlueClientOrigin[1] = (PlayerVec[1] + 50 * Sine(DegToRad(PlayerAng[1])));
BlueClientOrigin[2] = (PlayerVec[2] + 10);
BlueClientOrigin[2] = (PlayerVec[2] + 10);


BlueClientAngle[0] = PlayerAng[0];
BlueClientAngle[0] = PlayerAng[0];
BlueClientAngle[1] = PlayerAng[1];
BlueClientAngle[1] = PlayerAng[1];
BlueClientAngle[2] = PlayerAng[2];
BlueClientAngle[2] = PlayerAng[2];
TeleportEntity(other, BlueClientOrigin, BlueClientAngle, BlueClientOrigin);
TeleportEntity(other, BlueClientOrigin, BlueClientAngle, BlueClientOrigin);
EmitSoundToAll(PORTAL_SND);
EmitSoundToAll(PORTAL_SND);
CreateTimer(1.0, resetportal, 0, 0);
CreateTimer(1.0, resetportal, 0, 0);
PortalUseDelay = true;
PortalUseDelay = true;
}
}
}
}


public Action:TouchRed(entity, other)
public Action:TouchRed(entity, other)
{
{
// if portals arent indelay and have been seperated and are active
// if portals arent indelay and have been seperated and are active
if(!PortalUseDelay && PortalSeperated && PortalsActive && IsValidClient(other))
if(!PortalUseDelay && IsValidEntRef(BluePortal) && PortalSeperated && IsValidClient(other))//check if the blue portal is valid don't assume
{
{
decl Float:BlueClientOrigin[3];
decl Float:BlueClientOrigin[3];
decl Float:BlueClientAngle[3];
decl Float:BlueClientAngle[3];
decl Float:PlayerVec[3];
decl Float:PlayerVec[3];
decl Float:PlayerAng[3];
decl Float:PlayerAng[3];
GetEntPropVector(EntRefToEntIndex(BluePortal), Prop_Data, "m_vecOrigin", PlayerVec);
GetEntPropVector(EntRefToEntIndex(BluePortal), Prop_Data, "m_angRotation", PlayerAng);
GetEntPropVector(BluePortal, Prop_Data, "m_vecOrigin", PlayerVec);
GetEntPropVector(BluePortal, Prop_Data, "m_angRotation", PlayerAng);
BlueClientOrigin[0] = (PlayerVec[0] + 50 * Cosine(DegToRad(PlayerAng[1])));
BlueClientOrigin[0] = (PlayerVec[0] + 50 * Cosine(DegToRad(PlayerAng[1])));
BlueClientOrigin[1] = (PlayerVec[1] + 50 * Sine(DegToRad(PlayerAng[1])));
BlueClientOrigin[1] = (PlayerVec[1] + 50 * Sine(DegToRad(PlayerAng[1])));
BlueClientOrigin[2] = (PlayerVec[2] + 10);
BlueClientOrigin[2] = (PlayerVec[2] + 10);


BlueClientAngle[0] = PlayerAng[0];
BlueClientAngle[0] = PlayerAng[0];
BlueClientAngle[1] = PlayerAng[1];
BlueClientAngle[1] = PlayerAng[1];
BlueClientAngle[2] = PlayerAng[2];
BlueClientAngle[2] = PlayerAng[2];
TeleportEntity(other, BlueClientOrigin, BlueClientAngle, BlueClientOrigin);
TeleportEntity(other, BlueClientOrigin, BlueClientAngle, BlueClientOrigin);
EmitSoundToAll(PORTAL_SND);
EmitSoundToAll(PORTAL_SND);
CreateTimer(1.0, resetportal, 0, 0);
CreateTimer(1.0, resetportal, 0, 0);
PortalUseDelay = true;
PortalUseDelay = true;
}
}
}
}


public Action:resetportal(Handle:hTimer, any:client)
public Action:resetportal(Handle:hTimer, any:client)
{
{
PortalUseDelay = false;
PortalUseDelay = false;
}
}


public Action:Blue_Move(client, args)
public Action:Blue_Move(client, args)
{
{
decl Float:Ang[3];
decl Float:Ang[3];
new Blue;
new Blue;
if(IsValidEntRef(BluePortal))
if(IsValidEntRef(BluePortal))
{
{
Blue = EntRefToEntIndex(BluePortal)
Blue = EntRefToEntIndex(BluePortal);
}
}
else
else
{
{
PrintToChat(client,"!!!Blue portal broke, tell an admin!!!")
PrintToChat(client,"!!!Blue portal broke, tell an admin!!!"); //this could be removed unless you need it, i suggest using ReplyToCommand() and saying portals need to be created.
return;
return;
}
}
if (GetNewPos(client,bluepos))
if (GetNewPos(client,bluepos))
{
{
GetClientEyeAngles(client, Ang);
GetClientEyeAngles(client, Ang);
Ang[0] = NULL_VECTOR[0];
Ang[0] = NULL_VECTOR[0];
Ang[1] += 180;
Ang[1] += 180;
Ang[2] = NULL_VECTOR[2];
Ang[2] = NULL_VECTOR[2];
//TeleportEntity(Blue , bluepos, Ang, NULL_VECTOR);
//TeleportEntity(Blue , bluepos, Ang, NULL_VECTOR);
DispatchKeyValueVector( Blue, "Origin", bluepos );
DispatchKeyValueVector( Blue, "Origin", bluepos );
DispatchKeyValueVector( Blue, "Angles", Ang );
DispatchKeyValueVector( Blue, "Angles", Ang );
PortalSeperated = true;
PortalSeperated = true;
}
}
}
}


public Action:Red_Move(client, args)
public Action:Red_Move(client, args)
{
{
decl Float:Ang[3];
decl Float:Ang[3];
new Red;
new Red;
if(IsValidEntRef(RedPortal))
if(IsValidEntRef(RedPortal))
{
{
Red = EntRefToEntIndex(RedPortal)
Red = EntRefToEntIndex(RedPortal);
}
}
else
else
{
{
PrintToChat(client,"!!!Red portal broke, tell an admin!!!")
PrintToChat(client,"!!!Red portal broke, tell an admin!!!");
return;
return;
}
}
if (GetNewPos(client,redpos))
if (GetNewPos(client,redpos))
{
{
GetClientEyeAngles(client,Ang);
GetClientEyeAngles(client,Ang);
Ang[0] = NULL_VECTOR[0];
Ang[0] = NULL_VECTOR[0];
Ang[1] += 180;
Ang[1] += 180;
Ang[2] = NULL_VECTOR[2];
Ang[2] = NULL_VECTOR[2];
//TeleportEntity( Red,redpos, Ang, NULL_VECTOR);
//TeleportEntity( Red,redpos, Ang, NULL_VECTOR);
DispatchKeyValueVector( Red, "Origin", redpos );
DispatchKeyValueVector( Red, "Origin", redpos );
DispatchKeyValueVector( Red, "Angles", Ang );
DispatchKeyValueVector( Red, "Angles", Ang );
PortalSeperated = true;
PortalSeperated = true;
}
}
}
}


bool GetNewPos(client, Float:vecBuffer[3])
bool GetNewPos(client, Float:vecBuffer[3])
{
{
decl Float:vPos[3];
decl Float:vPos[3];
decl Float:vAng[3];
decl Float:vAng[3];
decl Float:nPos[3];
decl Float:nPos[3];
GetClientEyePosition(client,vPos);
GetClientEyePosition(client,vPos);
GetClientEyeAngles(client,vAng);
GetClientEyeAngles(client,vAng);
new Handle:trace = TR_TraceRayFilterEx(vPos, vAng, MASK_PLAYERSOLID, RayType_Infinite, TraceFilter, client);
new Handle:trace = TR_TraceRayFilterEx(vPos, vAng, MASK_PLAYERSOLID, RayType_Infinite, TraceFilter, client);


if (TR_DidHit(trace))
if (TR_DidHit(trace))// close the ray even if it hit or not else you are leaking handles or make it static instead of new
{
{
//TR_GetEndPosition(vecBuffer, trace);
//TR_GetEndPosition(vecBuffer, trace);
TR_GetEndPosition(nPos, trace);
TR_GetEndPosition(nPos, trace);
if (GetVectorDistance(vPos, nPos) > 220)
if (GetVectorDistance(vPos, nPos) > 220)
{
{
CloseHandle(trace);
PrintCenterText(client,"out of range");
PrintCenterText(client,"out of range");
return false;
return false;
}
}
vecBuffer[0]=nPos[0]
vecBuffer[0]=nPos[0];
vecBuffer[1]=nPos[1]
vecBuffer[1]=nPos[1];
vecBuffer[2]=nPos[2]
vecBuffer[2]=nPos[2];


CloseHandle(trace);
CloseHandle(trace);
return true;
return true;
}
}
CloseHandle(trace);
return false;
return false;
}
}
bool IsValidEntRef(int iEntRef)
bool IsValidEntRef(int iEntRef)
{
{
return (iEntRef != 0 && EntRefToEntIndex(iEntRef) != INVALID_ENT_REFERENCE);
return (iEntRef != 0 && EntRefToEntIndex(iEntRef) != INVALID_ENT_REFERENCE);
}
}
public bool:TraceFilter(entity, contentsMask, any:client)
public bool:TraceFilter(entity, contentsMask, any:client)
{
{
if( entity == client )return false;
if( entity == client )return false;
return true;
return true;
}
}


SetGlowRed(gun)
SetGlowRed(gun)
{
{
//since you not passing a reference here anyway no point is passing a reference either way if index is invalid or different entity will still be wrong.
SetEntProp(EntRefToEntIndex(gun), Prop_Send, "m_iGlowType", 3);
SetEntProp(gun, Prop_Send, "m_iGlowType", 3);//SetEntProp can accept entity references and indexs
SetEntProp(EntRefToEntIndex(gun), Prop_Send, "m_nGlowRange", 0);
SetEntProp(gun, Prop_Send, "m_nGlowRange", 0);
SetEntProp(EntRefToEntIndex(gun), Prop_Send, "m_nGlowRangeMin", 1);
SetEntProp(gun, Prop_Send, "m_nGlowRangeMin", 1);
new red=0;
new red=0;
new gree=0;
new gree=0;
new blue=0;
new blue=0;
red=200;
red=200;
gree=0;
gree=0;
blue=0;
blue=0;
SetEntProp(EntRefToEntIndex(gun), Prop_Send, "m_glowColorOverride", red + (gree * 256) + (blue* 65536));
SetEntProp(gun, Prop_Send, "m_glowColorOverride", red + (gree * 256) + (blue* 65536));
}
}


SetGlowBlue(gun)
SetGlowBlue(gun)
{
{
SetEntProp(EntRefToEntIndex(gun), Prop_Send, "m_iGlowType", 3);
SetEntProp(gun, Prop_Send, "m_iGlowType", 3);
SetEntProp(EntRefToEntIndex(gun), Prop_Send, "m_nGlowRange", 0);
SetEntProp(gun, Prop_Send, "m_nGlowRange", 0);
SetEntProp(EntRefToEntIndex(gun), Prop_Send, "m_nGlowRangeMin", 1);
SetEntProp(gun, Prop_Send, "m_nGlowRangeMin", 1);
new red=0;
new red=0;
new gree=0;
new gree=0;
new blue=0;
new blue=0;
red=0;
red=0;
gree=0;
gree=0;
blue=200;
blue=200;
SetEntProp(EntRefToEntIndex(gun), Prop_Send, "m_glowColorOverride", red + (gree * 256) + (blue* 65536));
SetEntProp(gun, Prop_Send, "m_glowColorOverride", red + (gree * 256) + (blue* 65536));
}
}


public IsValidClient(client)
public IsValidClient(client)
{
{
if (client == 0)
if (client == 0)
return false;
return false;
if (!IsClientConnected(client))
if (!IsClientConnected(client))
return false;
return false;
//if (IsFakeClient(client))
//if (IsFakeClient(client))
//return false;
//return false;
if (!IsClientInGame(client))
if (!IsClientInGame(client))
return false;
return false;
if (!IsPlayerAlive(client))
if (!IsPlayerAlive(client))
return false;
return false;
return true;
return true;
}
}
public Action:Kill_Portal(client, args)
public Action:Kill_Portal(client, args)
{
{
if(PortalsActive)
// PortalsActive is bad idea since you need to kill them regardless if active or not.
if(IsValidEntRef(BluePortal))
{
AcceptEntityInput(BluePortal , "Kill" );//AcceptEntityInput can accept entity references
}
if(IsValidEntRef(RedPortal))
{
{
AcceptEntityInput( EntRefToEntIndex(BluePortal) , "Kill" );
AcceptEntityInput(RedPortal , "Kill" );
AcceptEntityInput( EntRefToEntIndex(RedPortal) , "Kill" );
}
PortalUseDelay = false;
PortalUseDelay = false;
PortalSeperated = false;
PortalSeperated = false;
PortalsActive = false;
//PortalsActive = false;
}
}
}
public Plugin:myinfo =
public Plugin:myinfo =
{
{
name = "Portals V2",
name = "Portals V2",
author = "Spirit",
author = "Spirit",
description = "create improved portals",
description = "create improved portals",
version = "1.0",
version = "1.0",
url = "NONE"
url = "NONE"
}
}