This commit is contained in:
Jackzie 2024-09-22 14:27:39 -05:00
parent 1a1663ba37
commit ed383ecc91
14 changed files with 553 additions and 46 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -5,10 +5,11 @@
#define PLUGIN_VERSION "1.0"
#define PRECACHE_SOUNDS_COUNT 4
#define PRECACHE_SOUNDS_COUNT 5
char PRECACHE_SOUNDS[PRECACHE_SOUNDS_COUNT][] = {
"custom/xen_teleport.mp3",
"custom/mariokartmusic.mp3",
"custom/airhorn.mp3",
"custom/spookyscaryskeletons.mp3",
"custom/wearenumberone2.mp3",
};

View file

@ -248,6 +248,14 @@ public void Event_L4D2_Death(Event event, const char[] name, bool dontBroadcast)
if(IsFakeClient(attacker)) GetClientName(attacker, attackerName, sizeof(attackerName));
else GetClientAuthId(attacker, AuthId_Steam2, attackerName, sizeof(attackerName));
if(GetClientTeam(attacker) == 2) {
char weaponName[32];
event.GetString("weapon", weaponName, sizeof(weaponName));
if(weaponName[0] != '\0') {
AddLogCustom("STATE", attackerName, victimName, "\"%L\" killed \"%L\" with \"%s\"", attacker, victim, weaponName);
return;
}
}
AddLogCustom("STATE", attackerName, victimName, "\"%L\" killed \"%L\"", attacker, victim);
} else {
AddLogCustom("STATE", "", victimName, "\"%L\" died", victim);
@ -268,6 +276,14 @@ public void Event_L4D2_Incapped(Event event, const char[] name, bool dontBroadca
if(IsFakeClient(attacker)) GetClientName(attacker, attackerName, sizeof(attackerName));
else GetClientAuthId(attacker, AuthId_Steam2, attackerName, sizeof(attackerName));
if(GetClientTeam(attacker) == 2) {
char weaponName[32];
event.GetString("weapon", weaponName, sizeof(weaponName));
if(weaponName[0] != '\0') {
AddLogCustom("STATE", attackerName, victimName, "\"%L\" incapped \"%L\" with \"%s\"", attacker, victim, weaponName);
return;
}
}
AddLogCustom("STATE", attackerName, victimName, "\"%L\" incapped \"%L\"", attacker, victim);
} else {
AddLogCustom("STATE", "", victimName, "\"%L\" was incapped", victim);

View file

@ -203,6 +203,7 @@ void LoadFolder(ArrayList parent, const char[] rootPath) {
DirectoryListing listing = OpenDirectory(rootPath);
if(listing == null) {
LogError("Cannot open \"%s\"", rootPath);
return;
}
while(listing.GetNext(buffer, sizeof(buffer), fileType)) {
if(fileType == FileType_Directory) {

View file

@ -135,7 +135,7 @@ Action Command_DoAHat(int client, int args) {
char sizeStr[4];
GetCmdArg(2, sizeStr, sizeof(sizeStr));
float size = StringToFloat(sizeStr);
if(size == 0.0) {
if(size <= 0.0) {
ReplyToCommand(client, "[Hats] Invalid size");
return Plugin_Handled;
}
@ -335,7 +335,12 @@ Action Command_DoAHat(int client, int args) {
} else {
// Find a new hatable entity
int flags = 0;
if(args > 0 && isForced) {
char arg[16];
entity = GetCmdArgInt(1);
} else {
entity = GetLookingEntity(client, Filter_ValidHats);
}
if(entity <= 0) {
PrintCenterText(client, "[Hats] No entity found");
return Plugin_Handled;

View file

@ -0,0 +1,427 @@
int SpawnCar(VariantEntityData entity) {
if(entity.model[0] == '\0') {
LogError("Missing model for entity with type \"%s\"", entity.type);
return -1;
}
PrecacheModel(entity.model);
int vehicle;
if(StrEqual(entity.type, "_car_alarm")) {
vehicle = SpawnAlarmCar(entity.model, entity.origin, entity.angles, entity.color);
return vehicle;
}
char glassModel[64];
strcopy(glassModel, sizeof(glassModel), entity.type);
ReplaceString(glassModel, sizeof(glassModel), ".mdl", "_glass.mdl");
if(StrEqual(entity.type, "_car_physics")) {
vehicle = CreateProp("prop_physics", entity.model, entity.origin, entity.angles);
} else {
vehicle = CreateProp("prop_dynamic", entity.model, entity.origin, entity.angles);
}
if(PrecacheModel(glassModel)) {
int glass = CreateProp(glassModel, entity.model, entity.origin, entity.angles);
SetVariantString("!activator");
AcceptEntityInput(glass, "SetParent", vehicle);
}
SetEntityRenderColor(vehicle, GetRandomInt(0, 255), GetRandomInt(0, 255), GetRandomInt(0, 255));
return vehicle;
}
/**
// ====================================================================================================
:::BEGIN::: -> Source Code (with changes) from:
* DieTeetasse - [L4D1&2] Spawn Alarmcars plugin https://forums.alliedmods.net/showthread.php?t=139352
* Marttt - [L4D1 & L4D2] Replace Cars Into Car Alarms plugin https://forums.alliedmods.net/showthread.php?p=2731868
// ====================================================================================================
*/
/****************************************************************************************************/
#define DISTANCE_FRONT 101.0
#define DISTANCE_SIDETURN 34.0
#define DISTANCE_UPFRONT 29.0
#define DISTANCE_BACK 103.0
#define DISTANCE_SIDE 27.0
#define DISTANCE_UPBACK 31.0
#define SOUND_CAR_ALARM "vehicles/car_alarm/car_alarm.wav"
#define SOUND_CAR_ALARM_CHIRP2 "vehicles/car_alarm/car_alarm_chirp2.wav"
#define COLOR_YELLOWLIGHT "224 162 44"
#define COLOR_REDLIGHT "255 13 19"
#define COLOR_WHITELIGHT "252 243 226"
#define ALARMCAR_GLOW_SPRITE "sprites/glow.vmt"
int SpawnAlarmCar(const char[] model, float vPos[3], float vAng[3], int color[4] = { 255, 255, 255, 255})
{
PrecacheModel(model);
PrecacheModel(ALARMCAR_GLOW_SPRITE, true);
PrecacheSound(SOUND_CAR_ALARM, true);
PrecacheSound(SOUND_CAR_ALARM_CHIRP2, true);
char carName[64];
char glassOnName[64];
char glassOffName[64];
char timerName[64];
char alarmSoundName[64];
char chirpSoundName[64];
char lightsName[64];
char headlightsName[64];
char remarkName[64];
char gameEventName[64];
// create car
int carEntity = CreateEntityByName("prop_car_alarm");
FormatEx(carName, sizeof(carName), "randomizer_car_%d", carEntity);
FormatEx(glassOnName, sizeof(glassOnName), "randomizer_car_glasson_%d", carEntity);
FormatEx(glassOffName, sizeof(glassOffName), "randomizer_car_glassoff_%d", carEntity);
FormatEx(timerName, sizeof(timerName), "randomizer_car_alarmtimer_%d", carEntity);
FormatEx(alarmSoundName, sizeof(alarmSoundName), "randomizer_car_alarmsound_%d", carEntity);
FormatEx(chirpSoundName, sizeof(chirpSoundName), "randomizer_car_chirpsound_%d", carEntity);
FormatEx(lightsName, sizeof(lightsName), "randomizer_car_lights_%d", carEntity);
FormatEx(headlightsName, sizeof(headlightsName), "randomizer_car_headlights_%d", carEntity);
FormatEx(remarkName, sizeof(remarkName), "randomizer_car_remark_%d", carEntity);
FormatEx(gameEventName, sizeof(gameEventName), "randomizer_car_gameevent_%d", carEntity);
char tempString[128];
DispatchKeyValue(carEntity, "targetname", carName);
DispatchKeyValue(carEntity, "model", model);
Format(tempString, sizeof(tempString), "%d %d %d %d", color[0], color[1], color[2], color[3]);
DispatchKeyValue(carEntity, "rendercolor", tempString);
Debug("spawning alarm car ent%d \"%s\" (m=%s) at %.0f %.0f %.0f", carEntity, carName, model, vPos[0], vPos[1], vPos[2]);
Format(tempString, sizeof(tempString), "%s,PlaySound,,0.2,-1", chirpSoundName);
DispatchKeyValue(carEntity, "OnCarAlarmChirpStart", tempString);
Format(tempString, sizeof(tempString), "%s,ShowSprite,,0.2,-1", lightsName);
DispatchKeyValue(carEntity, "OnCarAlarmChirpStart", tempString);
Format(tempString, sizeof(tempString), "%s,HideSprite,,0.7,-1", lightsName);
DispatchKeyValue(carEntity, "OnCarAlarmChirpEnd", tempString);
Format(tempString, sizeof(tempString), "%s,Enable,,0,-1", timerName);
DispatchKeyValue(carEntity, "OnCarAlarmStart", tempString);
Format(tempString, sizeof(tempString), "%s,PlaySound,,0,-1", alarmSoundName);
DispatchKeyValue(carEntity, "OnCarAlarmStart", tempString);
Format(tempString, sizeof(tempString), "%s,Enable,,0,-1", glassOffName);
DispatchKeyValue(carEntity, "OnCarAlarmStart", tempString);
DispatchKeyValue(carEntity, "OnHitByTank", tempString);
Format(tempString, sizeof(tempString), "%s,Kill,,0,-1", glassOnName);
DispatchKeyValue(carEntity, "OnCarAlarmStart", tempString);
DispatchKeyValue(carEntity, "OnHitByTank", tempString);
Format(tempString, sizeof(tempString), "%s,Kill,,0,-1", timerName);
DispatchKeyValue(carEntity, "OnCarAlarmEnd", tempString);
DispatchKeyValue(carEntity, "OnHitByTank", tempString);
Format(tempString, sizeof(tempString), "%s,Kill,,0,-1", alarmSoundName);
DispatchKeyValue(carEntity, "OnCarAlarmEnd", tempString);
DispatchKeyValue(carEntity, "OnHitByTank", tempString);
Format(tempString, sizeof(tempString), "%s,Kill,,0,-1", chirpSoundName);
DispatchKeyValue(carEntity, "OnCarAlarmEnd", tempString);
DispatchKeyValue(carEntity, "OnHitByTank", tempString);
Format(tempString, sizeof(tempString), "%s,Kill,,0,-1", lightsName);
DispatchKeyValue(carEntity, "OnCarAlarmEnd", tempString);
DispatchKeyValue(carEntity, "OnHitByTank", tempString);
Format(tempString, sizeof(tempString), "%s,Kill,,0,-1", headlightsName);
DispatchKeyValue(carEntity, "OnCarAlarmEnd", tempString);
DispatchKeyValue(carEntity, "OnHitByTank", tempString);
Format(tempString, sizeof(tempString), "%s,Kill,,0,-1", remarkName);
DispatchKeyValue(carEntity, "OnCarAlarmEnd", tempString);
DispatchKeyValue(carEntity, "OnHitByTank", tempString);
Format(tempString, sizeof(tempString), "%s,Kill,,0,-1", gameEventName);
DispatchKeyValue(carEntity, "OnCarAlarmEnd", tempString);
DispatchKeyValue(carEntity, "OnHitByTank", tempString);
DispatchKeyValueVector(carEntity, "origin", vPos);
DispatchKeyValueVector(carEntity, "angles", vAng);
DispatchSpawn(carEntity);
// create glasses
strcopy(tempString, sizeof(tempString), model);
ReplaceString(tempString, sizeof(tempString), ".mdl", "_glass.mdl");
if(PrecacheModel(tempString))
CreateGlass(tempString, glassOnName, false, vPos, vAng, carName);
// CreateGlass(glassOffName, true, vPos, vAng, carName);
CreateSound(alarmSoundName, "16", "Car.Alarm", vPos, carName);
CreateSound(chirpSoundName, "48", "Car.Alarm.Chirp2", vPos, carName);
CreateLights(lightsName, vPos, vAng, carName);
CreateHeadlights(headlightsName, vPos, vAng, carName);
CreateLogicTimer(timerName, lightsName, headlightsName, vPos, carName);
CreateRemark(remarkName, vPos, vAng, carName);
CreateGameEvent(gameEventName, vPos, vAng, carName);
return carEntity;
}
/****************************************************************************************************/
void CreateGlass(const char[] model, char[] targetName, bool startDisabled, float vPos[3], float vAng[3], char[] carName)
{
int entity = CreateEntityByName("prop_car_glass");
DispatchKeyValue(entity, "targetname", targetName);
DispatchKeyValue(entity, "model", model);
DispatchKeyValue(entity, "StartDisabled", startDisabled ? "1" : "0");
DispatchKeyValueVector(entity, "origin", vPos);
DispatchKeyValueVector(entity, "angles", vAng);
DispatchSpawn(entity);
SetVariantString(carName);
AcceptEntityInput(entity, "SetParent", entity, entity, 0);
}
/****************************************************************************************************/
void CreateSound(char[] targetName, char[] spawnFlags, char[] messageName, float vPos[3], char[] carName)
{
int entity = CreateEntityByName("ambient_generic");
float newPos[3];
newPos = vPos;
newPos[2] += 80.0;
DispatchKeyValue(entity, "targetname", targetName);
DispatchKeyValue(entity, "spawnflags", spawnFlags);
DispatchKeyValue(entity, "message", messageName);
DispatchKeyValue(entity, "SourceEntityName", carName);
DispatchKeyValue(entity, "radius", "4000");
DispatchKeyValueVector(entity, "origin", newPos);
DispatchSpawn(entity);
ActivateEntity(entity); // Don't work without it
SetVariantString(carName);
AcceptEntityInput(entity, "SetParent", entity, entity, 0);
}
/****************************************************************************************************/
void CreateLights(char[] lightsName, float vPos[3], float vAng[3], char[] carName)
{
float distance[6] = {DISTANCE_FRONT, DISTANCE_SIDETURN, DISTANCE_UPFRONT, DISTANCE_BACK, DISTANCE_SIDE, DISTANCE_UPBACK};
float newPos[3];
float lightDistance[3];
newPos = vPos;
lightDistance[0] = distance[0];
lightDistance[1] = distance[1]*-1.0;
lightDistance[2] = distance[2];
MoveVectorvPos3D(newPos, vAng, lightDistance); // front left
CreateLight(lightsName, COLOR_YELLOWLIGHT, newPos, carName);
newPos = vPos;
lightDistance[1] = distance[1];
MoveVectorvPos3D(newPos, vAng, lightDistance); // front right
CreateLight(lightsName, COLOR_YELLOWLIGHT, newPos, carName);
newPos = vPos;
lightDistance[0] = distance[3]*-1.0;
lightDistance[1] = distance[4]*-1.0;
lightDistance[2] = distance[5];
MoveVectorvPos3D(newPos, vAng, lightDistance); // back left
CreateLight(lightsName, COLOR_REDLIGHT, newPos, carName);
newPos = vPos;
lightDistance[1] = distance[4];
MoveVectorvPos3D(newPos, vAng, lightDistance); // back right
CreateLight(lightsName, COLOR_REDLIGHT, newPos, carName);
}
/****************************************************************************************************/
void CreateLight(char[] targetName, char[] renderColor, float vPos[3], char[] carName)
{
int entity = CreateEntityByName("env_sprite");
DispatchKeyValue(entity, "targetname", targetName);
DispatchKeyValue(entity, "rendercolor", renderColor);
DispatchKeyValue(entity, "model", ALARMCAR_GLOW_SPRITE);
DispatchKeyValue(entity, "scale", "0.5");
DispatchKeyValue(entity, "rendermode", "9");
DispatchKeyValue(entity, "renderamt", "255");
DispatchKeyValue(entity, "HDRColorScale", "0.7");
DispatchKeyValue(entity, "GlowProxySize", "5");
DispatchKeyValueVector(entity, "origin", vPos);
DispatchSpawn(entity);
SetVariantString(carName);
AcceptEntityInput(entity, "SetParent", entity, entity, 0);
}
/****************************************************************************************************/
void CreateHeadlights(char[] headlightsName, float vPos[3], float vAng[3], char[] carName)
{
float distance[3] = {DISTANCE_FRONT, DISTANCE_SIDE, DISTANCE_UPFRONT};
float newPos[3];
float headlightDistance[3];
newPos = vPos;
headlightDistance[0] = distance[0];
headlightDistance[1] = distance[1]*-1.0;
headlightDistance[2] = distance[2];
MoveVectorvPos3D(newPos, vAng, headlightDistance); // front left
CreateHeadlight(headlightsName, newPos, vAng, carName);
newPos = vPos;
headlightDistance[1] = distance[1];
MoveVectorvPos3D(newPos, vAng, headlightDistance); // front right
CreateHeadlight(headlightsName, newPos, vAng, carName);
}
/****************************************************************************************************/
void CreateHeadlight(char[] targetName, float vPos[3], float vAng[3], char[] carName)
{
int entity = CreateEntityByName("beam_spotlight");
DispatchKeyValue(entity, "targetname", targetName);
DispatchKeyValue(entity, "rendercolor", COLOR_WHITELIGHT);
DispatchKeyValue(entity, "spotlightwidth", "32");
DispatchKeyValue(entity, "spotlightlength", "256");
DispatchKeyValue(entity, "spawnflags", "2");
DispatchKeyValue(entity, "rendermode", "5");
DispatchKeyValue(entity, "renderamt", "150");
DispatchKeyValue(entity, "maxspeed", "100");
DispatchKeyValue(entity, "HDRColorScale", "0.5");
DispatchKeyValueVector(entity, "origin", vPos);
DispatchKeyValueVector(entity, "angles", vAng);
DispatchSpawn(entity);
SetVariantString(carName);
AcceptEntityInput(entity, "SetParent", entity, entity, 0);
}
/****************************************************************************************************/
void CreateLogicTimer(char[] targetName, char[] lightsName, char[] headlightsName, float vPos[3], char[] carName)
{
int entity = CreateEntityByName("logic_timer");
DispatchKeyValue(entity, "targetname", targetName);
DispatchKeyValue(entity, "StartDisabled", "1");
DispatchKeyValue(entity, "RefireTime", "0.75");
char tempString[128];
Format(tempString, sizeof(tempString), "%s,ShowSprite,,0,-1", lightsName);
DispatchKeyValue(entity, "OnTimer", tempString);
Format(tempString, sizeof(tempString), "%s,ShowSprite,,0,-1", lightsName);
DispatchKeyValue(entity, "OnTimer", tempString);
Format(tempString, sizeof(tempString), "%s,LightOn,,0,-1", headlightsName);
DispatchKeyValue(entity, "OnTimer", tempString);
Format(tempString, sizeof(tempString), "%s,HideSprite,,0.5,-1", lightsName);
DispatchKeyValue(entity, "OnTimer", tempString);
Format(tempString, sizeof(tempString), "%s,HideSprite,,0.5,-1", lightsName);
DispatchKeyValue(entity, "OnTimer", tempString);
Format(tempString, sizeof(tempString), "%s,LightOff,,0.5,-1", headlightsName);
DispatchKeyValue(entity, "OnTimer", tempString);
DispatchKeyValueVector(entity, "origin", vPos);
DispatchSpawn(entity);
SetVariantString(carName);
AcceptEntityInput(entity, "SetParent", entity, entity, 0);
}
/****************************************************************************************************/
void CreateRemark(char[] targetName, float vPos[3], float vAng[3], char[] carName)
{
int entity = CreateEntityByName("info_remarkable");
DispatchKeyValue(entity, "targetname", targetName);
DispatchKeyValue(entity, "contextsubject", "remark_caralarm");
DispatchKeyValueVector(entity, "origin", vPos);
DispatchKeyValueVector(entity, "angles", vAng);
DispatchSpawn(entity);
SetVariantString(carName);
AcceptEntityInput(entity, "SetParent", entity, entity, 0);
}
/****************************************************************************************************/
void CreateGameEvent(char[] targetName, float vPos[3], float vAng[3], char[] carName)
{
int entity = CreateEntityByName("info_game_event_proxy");
DispatchKeyValue(entity, "targetname", targetName);
DispatchKeyValue(entity, "spawnflags", "1");
DispatchKeyValue(entity, "range", "100");
DispatchKeyValue(entity, "event_name", "explain_disturbance");
DispatchKeyValueVector(entity, "origin", vPos);
DispatchKeyValueVector(entity, "angles", vAng);
DispatchSpawn(entity);
SetVariantString(carName);
AcceptEntityInput(entity, "SetParent", entity, entity, 0);
}
/****************************************************************************************************/
void MoveVectorvPos3D(float vPos[3], float constvAng[3], float constDistance[3])
{
float vAng[3], dirFw[3], dirRi[3], dirUp[3], distance[3];
distance = constDistance;
vAng[0] = DegToRad(constvAng[0]);
vAng[1] = DegToRad(constvAng[1]);
vAng[2] = DegToRad(constvAng[2]);
// roll (rotation over x)
dirFw[0] = 1.0;
dirFw[1] = 0.0;
dirFw[2] = 0.0;
dirRi[0] = 0.0;
dirRi[1] = Cosine(vAng[2]);
dirRi[2] = Sine(vAng[2])*-1;
dirUp[0] = 0.0;
dirUp[1] = Sine(vAng[2]);
dirUp[2] = Cosine(vAng[2]);
MatrixMulti(dirFw, dirRi, dirUp, distance);
// pitch (rotation over y)
dirFw[0] = Cosine(vAng[0]);
dirFw[1] = 0.0;
dirFw[2] = Sine(vAng[0]);
dirRi[0] = 0.0;
dirRi[1] = 1.0;
dirRi[2] = 0.0;
dirUp[0] = Sine(vAng[0])*-1;
dirUp[1] = 0.0;
dirUp[2] = Cosine(vAng[0]);
MatrixMulti(dirFw, dirRi, dirUp, distance);
// yaw (rotation over z)
dirFw[0] = Cosine(vAng[1]);
dirFw[1] = Sine(vAng[1])*-1;
dirFw[2] = 0.0;
dirRi[0] = Sine(vAng[1]);
dirRi[1] = Cosine(vAng[1]);
dirRi[2] = 0.0;
dirUp[0] = 0.0;
dirUp[1] = 0.0;
dirUp[2] = 1.0;
MatrixMulti(dirFw, dirRi, dirUp, distance);
// addition
for (int i = 0; i < 3; i++) vPos[i] += distance[i];
}
/****************************************************************************************************/
void MatrixMulti(float matA[3], float matB[3], float matC[3], float vec[3])
{
float res[3];
for (int i = 0; i < 3; i++) res[0] += matA[i]*vec[i];
for (int i = 0; i < 3; i++) res[1] += matB[i]*vec[i];
for (int i = 0; i < 3; i++) res[2] += matC[i]*vec[i];
vec = res;
}
/**
// ====================================================================================================
:::END::: -> Source Code from DieTeetasse - [L4D1&2] Spawn Alarmcars plugin https://forums.alliedmods.net/showthread.php?t=139352
// ====================================================================================================
*/

View file

@ -35,8 +35,8 @@ void OpenVariantsMenu(int client) {
Menu menu = new Menu(BuilderHandler_VariantsMenu);
menu.SetTitle("%s > Variants", g_builder.selectedSceneId);
char id[8], display[32];
menu.AddItem("new", "New");
menu.AddItem("-1", "None (Shared Scene)");
menu.AddItem("new", "New Variant");
menu.AddItem("-1", "Global Scene Variant");
JSONArray variants = view_as<JSONArray>(g_builder.selectedSceneData.Get("variants"));
JSONObject varObj;
@ -45,9 +45,9 @@ void OpenVariantsMenu(int client) {
varObj = view_as<JSONObject>(variants.Get(i));
entities = view_as<JSONArray>(varObj.Get("entities"));
if(i == g_builder.selectedVariantIndex) {
Format(display, sizeof(display), "%d entities (selected)", entities.Length);
Format(display, sizeof(display), "#%d - %d entities (✔)", i, entities.Length);
} else {
Format(display, sizeof(display), "%d entities", entities.Length);
Format(display, sizeof(display), "#%d - %d entities", i, entities.Length);
}
IntToString(i, id, sizeof(id));
menu.AddItem(id, display);

View file

@ -24,6 +24,8 @@ TopMenu g_topMenu;
char g_currentMap[64];
ConVar enabledBlacklist;
//int g_markedMode
#include <editor/editor.sp>
@ -80,6 +82,8 @@ public void OnPluginStart() {
LoadTranslations("common.phrases");
HookEvent("player_spawn", Event_PlayerSpawn);
enabledBlacklist = CreateConVar("editor_denylist", "7", "The lists to check, add bits together.\n1 = classnames\n2 = models\n4 = targetnames", FCVAR_NONE, true, 0.0);
RegAdminCmd("sm_mkwall", Command_MakeWall, ADMFLAG_CUSTOM2);
RegAdminCmd("sm_edit", Command_Editor, ADMFLAG_CUSTOM2);
RegAdminCmd("sm_wall", Command_Editor, ADMFLAG_CUSTOM2);
@ -489,13 +493,15 @@ char FORBIDDEN_MODELS[MAX_FORBIDDEN_MODELS][] = {
bool CheckBlacklist(int entity) {
if(entity == 0) return false;
static char buffer[64];
if(enabledBlacklist.IntValue & 1) {
GetEntityClassname(entity, buffer, sizeof(buffer));
for(int i = 0; i < MAX_FORBIDDEN_CLASSNAMES; i++) {
if(StrEqual(FORBIDDEN_CLASSNAMES[i], buffer)) {
return false;
}
}
if(StrContains(buffer, "prop_") > -1) {
}
if(enabledBlacklist.IntValue & 2) {
GetEntPropString(entity, Prop_Data, "m_ModelName", buffer, sizeof(buffer));
for(int i = 0; i < MAX_FORBIDDEN_MODELS; i++) {
if(StrEqual(FORBIDDEN_MODELS[i], buffer)) {
@ -503,10 +509,12 @@ bool CheckBlacklist(int entity) {
}
}
}
if(enabledBlacklist.IntValue & 4) {
GetEntPropString(entity, Prop_Data, "m_iName", buffer, sizeof(buffer));
if(StrEqual(buffer, "l4d2_randomizer")) {
if(StrContains(buffer, "randomizer") > -1) {
return false;
}
}
return true;
}

View file

@ -22,9 +22,9 @@ int g_iLaserIndex;
#if defined DEBUG_BLOCKERS
#include <smlib/effects>
#endif
#define ENT_PROP_NAME "l4d2_randomizer"
#define ENT_ENV_NAME "l4d2_randomizer"
#define ENT_BLOCKER_NAME "l4d2_randomizer"
#define ENT_PROP_NAME "randomizer"
#define ENT_ENV_NAME "randomizer"
#define ENT_BLOCKER_NAME "randomizer"
#include <gamemodes/ents>
#define MAX_SCENE_NAME_LENGTH 32
@ -100,6 +100,7 @@ enum struct BuilderData {
}
#include <randomizer/rbuild.sp>
#include <randomizer/caralarm.sp>
public Plugin myinfo =
{
@ -116,24 +117,40 @@ public void OnPluginStart() {
SetFailState("This plugin is for L4D/L4D2 only.");
}
HookEvent("round_start_post_nav", Event_RoundStartPosNav);
RegAdminCmd("sm_rcycle", Command_CycleRandom, ADMFLAG_CHEATS);
RegAdminCmd("sm_expent", Command_ExportEnt, ADMFLAG_GENERIC);
RegAdminCmd("sm_rbuild", Command_RandomizerBuild, ADMFLAG_CHEATS);
cvarEnabled = CreateConVar("sm_randomizer_enabled", "0");
HookEvent("player_first_spawn", Event_PlayerFirstSpawn);
g_MapData.activeScenes = new ArrayList(sizeof(ActiveSceneData));
}
void Event_PlayerFirstSpawn(Event event, const char[] name ,bool dontBroadcast) {
int client = GetClientOfUserId(event.GetInt("userid"));
if(GetUserFlagBits(client) & ADMFLAG_CHAT) {
// If enabled but no map loaded:
if(cvarEnabled.BoolValue && g_MapData.scenes == null)
PrintToChat(client, "Randomizer Note: This map has no randomizer support at the moment.");
}
}
void Event_RoundStartPosNav(Event event, const char[] name ,bool dontBroadcast) {
if(cvarEnabled.BoolValue)
CreateTimer(5.0, Timer_Run);
}
// TODO: on round start
public void OnMapStart() {
g_iLaserIndex = PrecacheModel("materials/sprites/laserbeam.vmt", true);
GetCurrentMap(currentMap, sizeof(currentMap));
if(cvarEnabled.BoolValue)
CreateTimer(5.0, Timer_Run);
}
public void OnMapEnd() {
g_builder.Cleanup();
Cleanup();
@ -196,7 +213,7 @@ public Action Command_CycleRandom(int client, int args) {
if(client > 0)
PrintCenterText(client, "Cycled flags=%d", flags);
} else {
ReplyToCommand(client, "Active Scenes:");
ReplyToCommand(client, "Active Scenes (%d/%d):", g_MapData.activeScenes.Length, g_MapData.scenes.Length);
ActiveSceneData scene;
for(int i = 0; i < g_MapData.activeScenes.Length; i++) {
g_MapData.activeScenes.GetArray(i, scene);
@ -284,7 +301,7 @@ Action Command_RandomizerBuild(int client, int args) {
} else if(StrEqual(arg, "menu")) {
OpenMainMenu(client);
} else if(g_builder.mapData == null) {
ReplyToCommand(client, "No map data for %s, either load with /rbuild load, or start new /rbuild new", currentMap);
ReplyToCommand(client, "No map data loaded for %s, either load with /rbuild load, or start new /rbuild new", currentMap);
return Plugin_Handled;
} else if(StrEqual(arg, "save")) {
SaveMapJson(currentMap, g_builder.mapData);
@ -358,10 +375,10 @@ JSONObject ExportEntity(int entity, ExportType exportType = Export_Model) {
GetEntPropVector(entity, Prop_Send, "m_angRotation", angles);
GetEntPropVector(entity, Prop_Send, "m_vecMaxs", size);
char model[128];
char classname[128], model[128];
JSONObject entityData = new JSONObject();
GetEntityClassname(entity, model, sizeof(model));
if(StrContains(model, "prop_") == -1) {
GetEntityClassname(entity, classname, sizeof(classname));
if(StrContains(classname, "prop_") == -1) {
entityData.Set("scale", VecToArray(size));
}
if(exportType == Export_HammerId) {
@ -376,6 +393,7 @@ JSONObject ExportEntity(int entity, ExportType exportType = Export_Model) {
entityData.SetString("model", model);
} else {
GetEntPropString(entity, Prop_Data, "m_ModelName", model, sizeof(model));
entityData.SetString("type", classname);
entityData.SetString("model", model);
}
entityData.Set("origin", VecToArray(origin));
@ -567,17 +585,18 @@ enum InputType {
enum struct VariantInputData {
char name[MAX_INPUTS_CLASSNAME_LENGTH];
InputType type;
char input[32];
char input[64];
void Trigger() {
int entity = -1;
switch(this.type) {
case Input_Classname: {
entity = FindEntityByClassname(entity, this.name);
while((entity = FindEntityByClassname(entity, this.name)) != INVALID_ENT_REFERENCE) {
this._trigger(entity);
}
}
case Input_Targetname: {
char targetname[32];
char targetname[64];
while((entity = FindEntityByClassname(entity, "*")) != INVALID_ENT_REFERENCE) {
GetEntPropString(entity, Prop_Data, "m_iName", targetname, sizeof(targetname));
if(StrEqual(targetname, this.name)) {
@ -617,11 +636,16 @@ enum struct VariantInputData {
char cmd[32];
// Split input "a b" to a with variant "b"
int len = SplitString(this.input, " ", cmd, sizeof(cmd));
if(len > -1) SetVariantString(this.input[len]);
Debug("_trigger(%d): %s (v=%s)", entity, this.input, cmd);
if(len > -1) {
SetVariantString(this.input[len]);
AcceptEntityInput(entity, cmd);
Debug("_trigger(%d): %s (v=%s)", entity, cmd, this.input[len]);
} else {
Debug("_trigger(%d): %s", entity, this.input);
AcceptEntityInput(entity, this.input);
}
}
}
}
}
@ -858,7 +882,7 @@ void loadChoice(SceneData scene, JSONObject choiceData, JSONArray extraEntities)
// Parses entities and loads to choice.entities
loadChoiceEntity(choice.entities, view_as<JSONObject>(extraEntities.Get(i)));
}
delete extraEntities;
// delete extraEntities;
}
// Load all inputs
if(choiceData.HasKey("inputs")) {
@ -874,6 +898,7 @@ void loadChoice(SceneData scene, JSONObject choiceData, JSONArray extraEntities)
for(int i = 0; i < scenes.Length; i++) {
scenes.GetString(i, sceneId, sizeof(sceneId));
choice.forcedScenes.PushString(sceneId);
Debug("scene %s: require %s", scene.name, sceneId);
}
delete scenes;
}
@ -882,6 +907,7 @@ void loadChoice(SceneData scene, JSONObject choiceData, JSONArray extraEntities)
void loadChoiceInput(ArrayList list, JSONObject inputData) {
VariantInputData input;
input.type = Input_Classname;
// Check classname -> targetname -> hammerid
if(!inputData.GetString("classname", input.name, sizeof(input.name))) {
if(inputData.GetString("targetname", input.name, sizeof(input.name))) {
@ -936,10 +962,10 @@ void loadChoiceEntity(ArrayList list, JSONObject entityData) {
entityData.GetString("model", entity.model, sizeof(entity.model));
if(!entityData.GetString("type", entity.type, sizeof(entity.type))) {
entity.type = "prop_dynamic";
} else if(entity.type[0] == '_') {
} /*else if(entity.type[0] == '_') {
LogError("Invalid custom entity type \"%s\"", entity.type);
return;
}
}*/
GetVector(entityData, "origin", entity.origin);
GetVector(entityData, "angles", entity.angles);
GetVector(entityData, "scale", entity.scale);
@ -1013,10 +1039,17 @@ void selectScenes(int flags = 0) {
// Traverse active scenes, loading any other scene it requires (via .force_scenes)
ActiveSceneData aScene;
SceneVariantData choice;
char sceneId[64];
// list of scenes that will need to be forced if not already:
ArrayList forcedScenes = new ArrayList(ByteCountToCells(MAX_SCENE_NAME_LENGTH));
for(int i = 0; i < g_MapData.activeScenes.Length; i++) {
g_MapData.activeScenes.GetArray(i, aScene);
g_MapData.scenes.GetArray(i, scene);
// Load scene from active scene entry
if(!g_MapData.scenesKv.GetArray(aScene.name, scene, sizeof(scene))) {
// can't find scene, ignore
continue;
}
if(aScene.variantIndex < scene.variants.Length) {
scene.variants.GetArray(aScene.variantIndex, choice);
if(choice.forcedScenes != null) {
for(int j = 0; j < choice.forcedScenes.Length; j++) {
@ -1025,12 +1058,16 @@ void selectScenes(int flags = 0) {
}
}
}
}
if(forcedScenes.Length > 0) {
Debug("Loading %d forced scenes", forcedScenes.Length);
}
// Iterate and activate any forced scenes
for(int i = 0; i < forcedScenes.Length; i++) {
forcedScenes.GetString(i, key, sizeof(key));
// Check if scene was already loaded
bool isSceneAlreadyLoaded = false;
for(int j = 0; j < g_MapData.activeScenes.Length; i++) {
for(int j = 0; j < g_MapData.activeScenes.Length; j++) {
g_MapData.activeScenes.GetArray(j, aScene);
if(StrEqual(aScene.name, key)) {
isSceneAlreadyLoaded = true;
@ -1077,7 +1114,6 @@ void selectScene(SceneData scene, int flags) {
}
}
}
Debug("Total choices: %d", choices.Length);
if(flags & view_as<int>(FLAG_ALL_VARIANTS)) {
delete choices;
} else if(choices.Length > 0) {
@ -1118,7 +1154,7 @@ void spawnEntity(VariantEntityData entity) {
CreateEnvBlockerScaled(entity.type, entity.origin, entity.scale);
} else if(StrEqual(entity.type, "infodecal")) {
CreateDecal(entity.model, entity.origin);
} else if(StrContains(entity.type, "prop_") == 0) {
} else if(StrContains(entity.type, "prop_") == 0 || StrEqual(entity.type, "prop_fuel_barrel")) {
if(entity.model[0] == '\0') {
LogError("Missing model for entity with type \"%s\"", entity.type);
return;
@ -1165,6 +1201,8 @@ void spawnEntity(VariantEntityData entity) {
}
if(!found)
Debug("Warn: Could not find entity (classname=%s)", entity.model);
} else if(StrContains(entity.type, "_car") != -1) {
SpawnCar(entity);
} else {
LogError("Unknown entity type \"%s\"", entity.type);
}
@ -1201,6 +1239,17 @@ void Cleanup() {
}
delete g_MapData.lumpEdits;
// Cleanup all alarm car entities:
int entity = -1;
char targetname[128];
while((entity = FindEntityByClassname(entity, "*")) != INVALID_ENT_REFERENCE) {
GetEntPropString(entity, Prop_Data, "m_iName", targetname, sizeof(targetname));
if(StrContains(targetname, "randomizer_car") != -1) {
RemoveEntity(entity);
}
}
// TODO: delete car alarms
DeleteCustomEnts();
g_MapData.activeScenes.Clear();
}