[HL2DM] Определить захват гравипушкой

iamdss

Участник
Сообщения
126
Реакции
12
Как определить, что гравиган захватил и удерживает предмет? Нужно получить доступ к свойствам предмета, но только если он находится в захвате. Также необходимо контролировать момент отпускания предмета.
 

gibs

Фитиль народного волненья
Сообщения
722
Реакции
407
Мошенник
Смотри проп тейблы. Или просмотри функции в серверной библиотеке. В любом случае найдётся функция или метод отлова сего события. Тут с хл2дм очень мало кто работал.
 

iamdss

Участник
Сообщения
126
Реакции
12
Ну, с дм вообще мало кто работает =) Никому не нужен. Но спросить стоило. Посмотрю пропы, спасибо.
 

iamdss

Участник
Сообщения
126
Реакции
12
На будущее тем, кто будет искать что-то похожее. За захваченный предмет отвечает поле:

C-подобный:
CWeaponPhysCannon (type DT_WeaponPhysCannon)
 Table: baseclass (offset 0) (type DT_BaseHL2MPCombatWeapon)
 Member: m_hAttachedObject (offset 1456) (type integer) (bits 21) (Unsigned)

в netprops. Надеюсь, кому-то поможет.

Добавлено через 9 часов 6 минут
Получилось так. Прекрасно работает. Если подскажете что-то по коду, буду очень благодарен.

C-подобный:
#pragma semicolon 1

#include <sourcemod>

enum FX
{
	FxNone = 0,
	FxPulseFast,
	FxPulseSlowWide,
	FxPulseFastWide,
	FxFadeSlow,
	FxFadeFast,
	FxSolidSlow,
	FxSolidFast,
	FxStrobeSlow,
	FxStrobeFast,
	FxStrobeFaster,
	FxFlickerSlow,
	FxFlickerFast,
	FxNoDissipation,
	FxDistort,				// Distort/scale/translate flicker
	FxHologram,				// kRenderFxDistort + Distance fade
	FxExplode,				// Scale up really big!
	FxGlowShell,			// Glowing Shell
	FxClampMinScale,		// Keep this sprite from getting very small (SPRITES only!)
	FxEnvRain,				// for environmental rendermode, make rain
	FxEnvSnow,				//  "        "            "    , make snow
	FxSpotlight,
	FxRagdoll,
	FxPulseFastWider,
};

enum Render
{
	Normal = 0,			// src
	TransColor,			// c*a+dest*(1-a)
	TransTexture,		// src*a+dest*(1-a)
	Glow,				// src*a+dest -- No Z buffer checks -- Fixed size in screen space
	TransAlpha,			// src*srca+dest*(1-srca)
	TransAdd,			// src*a+dest
	Environmental,		// not drawn, used for environmental effects
	TransAddFrameBlend,	// use a fractional frame value to blend between animation frames
	TransAlphaAdd,		// src + dest*(1-a)
	WorldGlow,			// Same as kRenderGlow but not fixed size in screen space
	None,				// Don't render.
};

#define MAX_ENAME_LENGTH 32

new RenderOffs = -1;
new String:TempEName[MAXPLAYERS + 1][MAX_ENAME_LENGTH];
new AttachedEntities[MAXPLAYERS + 1] = { -1, ... };

#define PLUGIN_NAME "Transparent Props In Physcannon"
#define PLUGIN_AUTHOR ""
#define PLUGIN_DESCRIPTION ""
#define PLUGIN_VERSION "1.0"
#define PLUGIN_URL ""

public Plugin:myinfo =
{
	name = PLUGIN_NAME,
	author = PLUGIN_AUTHOR,
	description = PLUGIN_DESCRIPTION,
	version = PLUGIN_VERSION,
	url = PLUGIN_URL
};

public OnPluginStart()
{
	RenderOffs = FindSendPropOffs("CBasePlayer", "m_clrRender");
	HookEvent("player_death", PlayerDeath);
}

public OnClientDisconnect(client)
{
	ShadowEffectOff(client);
}

public Action:OnPlayerRunCmd(client, &buttons, &impulse, Float:velocity[3], Float: angles[3], &weapon)
{
	TempEName[client][0] = '\0';
	GetClientWeapon(client, TempEName[client], MAX_ENAME_LENGTH);
	
	if (!StrEqual(TempEName[client], "weapon_physcannon"))
		return Plugin_Continue;
	
	if (buttons & IN_ATTACK)
	{
		ShadowEffectOff(client);
		return Plugin_Continue;
	}
	
	if (buttons & IN_ATTACK2)
	{
		new AttachedEntity = 
		GetEntPropEnt(
			GetEntPropEnt(client, Prop_Data, "m_hActiveWeapon"),
			Prop_Send,
			"m_hAttachedObject"
		);
		if (AttachedEntity != -1)
		{
			TempEName[client][0] = '\0';
			GetEntityClassname(AttachedEntity, TempEName[client], MAX_ENAME_LENGTH);
			if (StrEqual(TempEName[client], "prop_physics_respawnable")  || 
				StrEqual(TempEName[client], "prop_physics") ||
				StrEqual(TempEName[client], "func_physbox") ||
				StrEqual(TempEName[client], "prop_physics_multiplayer")
			)
			{
				ShadowEffectOn(AttachedEntity, client);
			}
		} else ShadowEffectOff(client);
	}
	return Plugin_Continue;
}

public Action:PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	ShadowEffectOff(client);
	return Plugin_Continue;
}

stock set_rendering(Entity, FX:fx = FxNone, r = 255, g = 255, b = 255, Render:render = Normal, amount = 255)
{
	if (!IsValidEntity(Entity) || 
		GetEntSendPropOffs(Entity, "m_nRenderFX", true) == -1 ||
		GetEntSendPropOffs(Entity, "m_nRenderMode", true) == -1|| 
		RenderOffs == -1) return;
		
	SetEntProp(Entity, Prop_Send, "m_nRenderFX", _:fx, 1);		
	SetEntProp(Entity, Prop_Send, "m_nRenderMode", _:render, 1);
	SetEntData(Entity, RenderOffs, r, 1, true);
	SetEntData(Entity, RenderOffs + 1, g, 1, true);
	SetEntData(Entity, RenderOffs + 2, b, 1, true);
	SetEntData(Entity, RenderOffs + 3, amount, 1, true);
}

stock ShadowEffectOn(const Entity, const client)
{
	if ((Entity > 0) && (Entity != AttachedEntities[client]))
	{
		set_rendering(Entity, FX:FxDistort, 255, 255, 255, Render:RENDER_TRANSADD, 220);
		AttachedEntities[client] = Entity;
	}
}

stock ShadowEffectOff(const client)
{
	if (IsValidClient(client) && IsValidEntity(AttachedEntities[client]) && (AttachedEntities[client] > 0))
	{
		set_rendering(AttachedEntities[client]);
		AttachedEntities[client] = -1;
	}
}

public IsValidClient(const client)
{
	return (IsClientConnected(client) && IsClientInGame(client));
}

А можно на хуках =)
 
Последнее редактирование:

FrozDark

Участник
Сообщения
1,769
Реакции
2,050
лучше бы хукать в OnPluginStart
HookEntityOutput("prop_physics", "OnPhysGunOnlyPickup", OnGravityGunPickup);
HookEntityOutput("prop_physics", "OnPhysGunDrop", OnGravityGunDrop);
 
Сверху Снизу