Jump to content
  • Chmurka
  • Boróweczka
  • Jabłuszko
  • Limonka
  • Czekoladka
  • Węgielek
Yamakashi

[Rozwiązane] Problem z hookiem OnWeaponEquip

Recommended Posts

Witam, mam problem z hookiem OnWeaponEquip. Kilka dni temu zostałem poproszony przez Właściciela Sieci o przerobienie modyfikacji GoMod pod serwer typowo pod FFA.

Aktualnie jeżeli wejdzie się  na broń to blokujesz się w niej. Hooka wykorzystuję, aby ustawić skina dla danej broni. Dodam, że w konsoli serwera cały czas spami "Weapon spawning in solid"

 

Kod:

Spoiler

public void OnClientPostAdminCheck(int client)
{
	if(IsValidClient(client))
	{
		char steam32[20];
		char temp[20];
		GetClientAuthId(client, AuthId_Steam3, steam32, sizeof(steam32));
		strcopy(temp, sizeof(temp), steam32[5]);
		int index;
		if((index = StrContains(temp, "]")) > -1)
			temp[index] = '\0';
			
		g_iSteam32[client] = StringToInt(temp);
	}
}

public Action OnWeaponEquip(int client, int weapon)
{
	char sWeapon[64];
	GetEntityClassname(weapon, sWeapon, sizeof(sWeapon));
	if(IsValidEdict(weapon))
	{
		if(weapon != g_iEarlierEntity[client])
		{
			int weaponindex = GetEntProp(weapon, Prop_Send, "m_iItemDefinitionIndex");
			int clip = GetEntProp(weapon, Prop_Send, "m_iClip1");
			int reserve = GetEntProp(weapon, Prop_Send, "m_iPrimaryReserveAmmoCount");
			RemovePlayerItem(client, weapon);
			AcceptEntityInput(weapon, "Kill");
			weapon = CreateEntityByName(sWeapon);
			SetEntProp(weapon, Prop_Send, "m_iItemDefinitionIndex", weaponindex);
			SetEntProp(weapon, Prop_Send, "m_bInitialized", 1);
			SetEntProp(weapon, Prop_Send, "m_iClip1", clip);
			SetEntProp(weapon, Prop_Send, "m_iPrimaryReserveAmmoCount", reserve);
			g_iEarlierEntity[client] = weapon;
			EquipPlayerWeapon(client, weapon);
			if(IsValidEdict(weapon))
			{
				static int IDHigh = 16384;
				SetEntProp(weapon, Prop_Send, "m_iItemIDLow", -1);
				SetEntProp(weapon, Prop_Send, "m_iItemIDHigh", IDHigh++);
					
				if(StrContains(sWeapon, "weapon_knife") != -1 || StrContains(sWeapon, "bayonet") != -1)
					SetEntProp(weapon, Prop_Send, "m_nFallbackPaintKit", g_iClientKnife[client]);
				else if(StrEqual(sWeapon, "weapon_ak47"))
					SetEntProp(weapon, Prop_Send, "m_nFallbackPaintKit", g_iClientAk47[client]);
				else if(StrEqual(sWeapon, "weapon_m4a1"))
					SetEntProp(weapon, Prop_Send, "m_nFallbackPaintKit", g_iClientM4a4[client]);
				else if(StrEqual(sWeapon, "weapon_m4a1_silencer"))
					SetEntProp(weapon, Prop_Send, "m_nFallbackPaintKit", g_iClientM4a1[client]);
				else if(StrEqual(sWeapon, "weapon_awp"))
					SetEntProp(weapon, Prop_Send, "m_nFallbackPaintKit", g_iClientAwp[client]);
				else if(StrEqual(sWeapon, "weapon_ssg08"))
					SetEntProp(weapon, Prop_Send, "m_nFallbackPaintKit", g_iClientScout[client]);
				else if(StrEqual(sWeapon, "weapon_glock"))
					SetEntProp(weapon, Prop_Send, "m_nFallbackPaintKit", g_iClientGlock[client]);
				else if(StrEqual(sWeapon, "weapon_usp_silencer"))
					SetEntProp(weapon, Prop_Send, "m_nFallbackPaintKit", g_iClientUsp[client]);
				else if(StrEqual(sWeapon, "weapon_deagle"))
					SetEntProp(weapon, Prop_Send, "m_nFallbackPaintKit", g_iClientDeagle[client]);
		
				SetEntPropFloat(weapon, Prop_Send, "m_flFallbackWear", 0.000001);
				SetEntProp(weapon, Prop_Send, "m_nFallbackSeed", GetRandomInt(0, 8192));

				SetEntProp(weapon, Prop_Send, "m_iAccountID", g_iSteam32[client]);
				SetEntPropEnt(weapon, Prop_Send, "m_hOwnerEntity", client);
				SetEntPropEnt(weapon, Prop_Send, "m_hPrevOwner", -1);
			}
			return Plugin_Handled;
		}
	}
	return Plugin_Continue;
}

 

 

Share this post


Link to post
Share on other sites

Kilka pomysłów/porad:

 

- Sprawdź najpierw, czy samo usunięcie broni Ci działa, możliwe że błąd w konsoli (który oznacza że byt broni tworzymy w innym bycie który jest stały, SOLID) właśnie tego dotyczy

 

- Dlaczego tworzysz broń jak byt? Nie prościej jest po prostu... dać graczowi tę broń którą kasujesz i nadać jej odpowiednie właściwości? Przecież te właściwości i tak nadajesz po stworzeniu bytu, więc nie powinno to mieć zbytniej różnicy, a zmniejszy ilość operacji

 

- Jeśli nadajemy bytowi broni jakieś właściwości, to dlaczego dopiero w połowie ich nadawania sprawdzamy czy IsValidEdict? To samo pytanie dotyczy się dania klientowi broni, dlaczego dzieje się to w połowie funkcji a nie na jej końcu?

 

- Jeśli zamiast g_iClientKnife/g_iClientAK47 użyłbyś g_iClientWeapon[id_broni][client] (dwu wymiarowej tablicy zawierającej ID skinu dla każdego klienta oraz każdej broni zamiast dla każdej broni używać nowej zmiennej), mógłbyś wtedy użyć CS_AliasToWeaponID
Hej! Skorzystałeś z linku lub pobrałeś załącznik? Uhonoruj naszą pracę poprzez rejestrację na forum i rośnij razem z nami! i zamiast masy else if'ów kod na nadanie skina nowej broni wyglądałby mniej więcej tak:

SetEntProp(weapon, Prop_Send, "m_nFallbackPaintKit", g_iClientWeapons[CS_AliasToWeaponID(sWeapon)][client]);

I ta jedna linia obsługiwałaby wszystkie bronie. Minus jest taki, że nadal tablica g_iClientWeapons jest tworzona dla wszystkich broni więc zajmuje na pewno więcej pamięci, bo zajmuje miejsce nawet dla broni dla których skinów nie używasz. Ale jeśli nawet byś jej użył to możesz ją lekko "zoptymalizować" i skrócić tablicę bo według listy broni CSWeaponID
Hej! Skorzystałeś z linku lub pobrałeś załącznik? Uhonoruj naszą pracę poprzez rejestrację na forum i rośnij razem z nami! nie trzeba przecież nadawać skinów dla granatów które akurat znajdują się na samym końcu. Wtedy tablica skraca się z 55 miejsc na 51

 

- Możesz ukrócić sobie pracę w elseifach i zamiast podwójnie sprawdzać M4A1, użyj StrContains na string "weapon_m4a1"

  • Kocham to! 2

Share this post


Link to post
Share on other sites

@Update do pomysłu z tablicami:
W sumie to nie trzeba robić dwuwymiarowej tablicy która będzie zawierała każdą broń. Zoptymalizowane rozwiązanie w pseudokodzie:

//1
int weaponHasSkin[MAX_WEAPONS] = {1, -1, -1, 3, 0 ... 2};

//2
int clientWeaponSkins[MAX_AVALIBLE_SKINS][MaxClients+1];

//3
if (weaponHasSkin[CS_AliasToWeaponID(sWeapon)] != -1)
	SetEntProp(weapon, Prop_Send, "m_nFallbackPaintKit", clientWeaponSkins[weaponHasSkin[CS_AliasToWeaponID(sWeapon)]][client]);
  1. W pierwszej linii znajduje się tablica jednowymiarowa, dla każdego indeksu broni jest wartość int określająca indeks z clientWeaponSkins w jakim znajduje się skin dla danej broni
  2. W drugiej linii jest już omawiana wcześniej zmienna przechowująca wszystkie wybrane przez klienta skiny, jednakże tym razem nie zawiera ona miejsca tylko dla tych broni, które skina posiadają
  3. W trzeciej linii jest już sposób użycia

 

W poprzednim rozwiązaniu zajmujemy zawsze 50*65(MAX_WEAPONS*MaxClients) miejsc

W tym rozwiązaniu zajmujemy zależnie od ilości skinów na serwerze w najgorszym przypadku 50*65(MAX_AVALIBLE_SKINS*MaxClients) + 50(MAX_WEAPONS), więc o 50 więcej niż w pierwszym rozwiązaniu, ale jak się domyślam nie każda broń będzie miała skin. Dlatego spokojnie można założyć, że jest to 20*65+50, co daje nam ponad dwukrotnie mniejszą zajętą pamięć

Share this post


Link to post
Share on other sites

Wiadomość wygenerowana automatycznie

 

Temat został zamknięty. Powodem jest całkowite rozwiązanie problemu zawartego w temacie.

 

Jeśli się z tym nie zgadzasz, zaraportuj ten post z prośbą o ponowne otwarcie i kontynuację dyskusji.

Share this post


Link to post
Share on other sites
Guest
This topic is now closed to further replies.

  • Recently Browsing   0 members

    No registered users viewing this page.

Nasza historia

Na początku byliśmy małą grupą internetowych znajomych, którzy stwierdzili, że potrzebne jest solidne forum, na którym znajdą się ludzie z dużą wiedzą programistyczną ukierunkowaną na CS:GO. Pomysł powstał na początku 2018 roku, a parę miesięcy później, 19 kwietnia, powstała ta strona internetowa. Jako alternatywna odpowiedź na inne tego typu miejsca, poważnie podeszliśmy do tematu, najpierw tłumacząc angielską dokumentację SourceMod'a na język polski, a potem pisząc rozległe poradniki i wypełniając forum najpotrzebniejszymi rzeczami dla właścicieli serwerów i programistów. Cała nasza Ekipa jest dumna z pracy jaką w to włożyliśmy i cieszymy się że zbierają się wokół nas zarówno ludzie znający tematy sourcepawn'a i konfiguracji, jak i również nowe twarze w tym "biznesie", którym z chęcią niesiemy wiedzę oraz pomoc w rozwiązywaniu problemów.

Największe modyfikacje serwerowe

×
×
  • Create New...