#include #include #include #include #include #pragma newdecls required #define PLUGIN_VERSION "1.0" public Plugin myinfo = { name = "[CS:GO] Crossbow like Backwards", author = "Eyal282", description = "Crossbow gun like in the TTT server of backwards'", version = PLUGIN_VERSION, url = "N/A" } #define EF_NODRAW 32 bool bHoldingCrossbow[MAXPLAYERS + 1]; public void OnMapStart() { LoadDirOfModels("materials/models/weapons/eminem/advanced_crossbow"); LoadDirOfModels("models/weapons/eminem/advanced_crossbow"); LoadDirOfModels("sound/weapons/eminem/advanced_crossbow"); PrecacheModel("models/weapons/w_eq_fraggrenade_dropped.mdl", true); PrecacheModel("models/weapons/eminem/advanced_crossbow/w_crossbow_bolt_dropped.mdl", true) PrecacheGeneric("particles/backwards_ttt_blood.pcf", true) PrecacheParticleSystem("backwards_ttt_blood"); } public void OnPluginStart() { HookEvent("player_spawn", Event_PlayerSpawn, EventHookMode_Post); for (int i = 1; i <= MaxClients;i++) { if(!IsClientInGame(i)) continue; Func_OnClientPutInServer(i); } } public void OnClientPutInServer(int client) { Func_OnClientPutInServer(client); } public void Func_OnClientPutInServer(int client) { SDKHook(client, SDKHook_WeaponCanUse, OnWeaponCanUse); SDKHook(client, SDKHook_WeaponSwitchPost, OnWeaponSwitchPost); SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage); } public Action OnWeaponCanUse(int client, int weapon) { if(weapon == -1) return Plugin_Continue; else if(!IsEntityAxe(weapon)) return Plugin_Continue; GivePlayerAxe(client); AcceptEntityInput(weapon, "Kill"); return Plugin_Handled; } public void OnWeaponSwitchPost(int client, int weapon) { bHoldingCrossbow[client] = false; if(weapon == -1) return; else if(!IsEntityAxe(weapon)) return; bHoldingCrossbow[client] = true; } public Action OnTakeDamage(int victim, int& attacker, int& inflictor, float& damage, int& damagetype) { if(bHoldingCrossbow[attacker]) { damage = 0.0; return Plugin_Stop; } return Plugin_Continue; } public Action OnPlayerRunCmd(int client, int& buttons, int& impulse, float vel[3], float angles[3], int& weapon, int& subtype, int& cmdnum, int& tickcount, int& seed, int mouse[2]) { if(bHoldingCrossbow[client]) { buttons &= ~IN_ATTACK2; if(!(buttons & IN_ATTACK)) return Plugin_Continue; else if(GetEntPropFloat(client, Prop_Send, "m_flNextAttack") > GetGameTime()) return Plugin_Continue; int bullet = CreateEntityByName("smokegrenade_projectile"); //SetEntProp(bullet, Prop_Send, "m_usSolidFlags", 12); //FSOLID_NOT_SOLID|FSOLID_TRIGGER SetEntProp(bullet, Prop_Data, "m_nSolidType", 6); // SOLID_VPHYSICS //SetEntProp(bullet, Prop_Send, "m_CollisionGroup", 1); //COLLISION_GROUP_DEBRIS //SetEntityMoveType(bullet, MOVETYPE_FLY); // A random model to create a physics object. //SetEntityModel(bullet, "models/weapons/w_eq_fraggrenade_dropped.mdl"); float speed = 1024.0; float fOrigin[3], fAngles[3], fFwd[3]; GetClientEyePosition(client, fOrigin); GetClientEyeAngles(client, fAngles); GetAngleVectors(fAngles, fFwd, NULL_VECTOR, NULL_VECTOR); //fAngles = fFwd; NormalizeVector(fFwd, fFwd); ScaleVector(fFwd, speed); // While the bullet is a smokegrenade model, make it invisible. SetEntProp(bullet, Prop_Send, "m_fEffects", GetEntProp(bullet, Prop_Send, "m_fEffects") | EF_NODRAW); DispatchSpawn(bullet); ActivateEntity(bullet); AcceptEntityInput(bullet, "EnableMotion"); TeleportEntity(bullet, fOrigin, fAngles, fFwd); //SetEntityMoveType(bullet, MOVETYPE_VPHYSICS); DataPack DP = new DataPack(); DP.WriteCell(bullet); DP.WriteFloat(fFwd[2]); RequestFrame(Frame_NoGravity, DP); SetEntPropFloat(client, Prop_Send, "m_flNextAttack", GetGameTime() + 1.0); // After the entity is created, give the real model. SetEntPropEnt(bullet, Prop_Send, "m_hOwnerEntity", client); SDKHook(bullet, SDKHook_StartTouchPost, OnStartTouch); RequestFrame(Frame_GiveModel, bullet); buttons &= ~IN_ATTACK; return Plugin_Changed; } return Plugin_Continue; } public void OnStartTouch(int bullet, int toucher) { int owner = GetEntPropEnt(bullet, Prop_Send, "m_hOwnerEntity"); if(owner == -1) return; else if(IsPlayer(toucher)) { if(toucher == owner) return; OnPlayerHitByCrossbow(toucher, owner); } else { // If you hit glass or a JailBreak vent, break it! SDKHooks_TakeDamage(toucher, bullet, owner, 128.0, DMG_BULLET); } AcceptEntityInput(bullet, "Kill"); } public void OnPlayerHitByCrossbow(int victim, int attacker) { CreateParticle(victim, "backwards_ttt_blood"); //TE_SetupBloodSprite(fOrigin, { 90.0, 0.0, 0.0 }, { 255, 0, 0, 255 }, 25, bloodModel, bloodPuddleModel); //TE_SendToAll(); PrintToChatAll("B"); } void CreateParticle(int victim, char[] szName) { int iEntity; iEntity = CreateEntityByName("info_particle_system"); if (IsValidEdict(iEntity) && (victim > 0)) { if (IsPlayerAlive(victim)) { // Get players current position float vPosition[3]; GetEntPropVector(victim, Prop_Send, "m_vecOrigin", vPosition); // Move particle to player TeleportEntity(iEntity, vPosition, NULL_VECTOR, NULL_VECTOR); // Set entity name DispatchKeyValue(iEntity, "targetname", "particle"); // Get player entity name char szParentName[64]; GetEntPropString(victim, Prop_Data, "m_iName", szParentName, sizeof(szParentName)); // Set the effect name DispatchKeyValue(iEntity, "effect_name", szName); // Spawn the particle DispatchSpawn(iEntity); // Target the particle SetVariantString("!activator"); // Set particle parent name DispatchKeyValue(iEntity, "parentname", szParentName); // Set client to parent of particle AcceptEntityInput(iEntity, "SetParent", victim, iEntity, 0); // Activate the entity (starts animation) ActivateEntity(iEntity); AcceptEntityInput(iEntity, "Start"); // Attach to parent model SetEntPropEnt(iEntity, Prop_Send, "m_hOwnerEntity", victim); SetFlags(iEntity); SDKHook(iEntity, SDKHook_SetTransmit, OnSetTransmit); //g_unClientAura[iClient] = EntIndexToEntRef(iEntity); } } } public void SetFlags(int iEdict) { if (GetEdictFlags(iEdict) & FL_EDICT_ALWAYS) { SetEdictFlags(iEdict, (GetEdictFlags(iEdict) ^ FL_EDICT_ALWAYS)); } } public Action OnSetTransmit(int iEnt, int iClient) { int iOwner = GetEntPropEnt(iEnt, Prop_Send, "m_hOwnerEntity"); SetFlags(iEnt); if(iOwner && IsClientInGame(iOwner)) { return Plugin_Continue; } return Plugin_Continue; } public void Frame_NoGravity(DataPack DP) { ResetPack(DP); int bullet = DP.ReadCell(); if(!IsValidEntity(bullet)) { delete DP; return; } float Velocity[3]; GetEntPropVector(bullet, Prop_Data, "m_vecVelocity", Velocity); Velocity[2] = DP.ReadFloat(); TeleportEntity(bullet, NULL_VECTOR, NULL_VECTOR, Velocity); RequestFrame(Frame_NoGravity, DP); } public void Frame_GiveModel(int bullet) { SetEntityModel(bullet, "models/weapons/eminem/advanced_crossbow/w_crossbow_bolt_dropped.mdl"); SetEntProp(bullet, Prop_Send, "m_fEffects", GetEntProp(bullet, Prop_Send, "m_fEffects") & ~EF_NODRAW); //new Float:Origin[3]; } public Action Event_PlayerSpawn(Handle hEvent, const char[] Name, bool dontBroadcast) { int client = GetClientOfUserId(GetEventInt(hEvent, "userid")); GivePlayerAxe(client); int weapon = GetEntPropEnt(client, Prop_Send, "m_hActiveWeapon"); bHoldingCrossbow[client] = false; if(weapon == -1) return; else if(!IsEntityAxe(weapon)) return; bHoldingCrossbow[client] = true; } stock void LoadDirOfModels(char[] dirofmodels) { char path[256]; FileType type; char FileAfter[256]; Handle dir = OpenDirectory(dirofmodels, false, "GAME"); if (!dir) { return; } while (ReadDirEntry(dir, path, 256, type)) { if (type == FileType_File) { FormatEx(FileAfter, 256, "%s/%s", dirofmodels, path); AddFileToDownloadsTable(FileAfter); } } CloseHandle(dir); dir = INVALID_HANDLE; return; } stock void GivePlayerAxe(int client) { int entity = CreateEntityByName("weapon_axe"); EquipPlayerWeapon(client, entity); } stock bool IsPlayer(int entity) { if(entity < 1) return false; else if(entity > MaxClients) return false; return true; } stock bool IsEntityAxe(int entity) { return GetEntProp(entity, Prop_Send, "m_iItemDefinitionIndex") == CS_WeaponIDToItemDefIndex(CSWeapon_AXE); }