←  Problemy

AMXX.pl: Support AMX Mod X i SourceMod

»

[ROZWIĄZANE] Problem z crashem gdzieś w ty...


Najlepsza odpowiedź GT Team 08.05.2013 19:15

A JEDNAK :) Działa! Rozłożyłem TakeDamage, bo sądziłem, że wykonuje się za dużo w 1 i oto co zrobiłem:
public TakeDamage(ent, idinflictor, attacker, Float:damage, damagebits)
{
	static classname[32];
	entity_get_string(ent, EV_SZ_classname, classname, 31);
		
	if(equal(classname, "monster")) 
	{	
		new hp = floatround(entity_get_float(ent, EV_FL_health))
		/* Pokazuje zadane obrazenia */
		new id = 0
		if(is_turret(attacker))
		{
			id = SentryOwner(attacker)
			
			if(gPlayerDamage[id])
				damage+=float(gPlayerNewDamage[id])
		}
			
		if(is_turret(attacker))
		{
			new sentryid = SentryId(ent)
			if(damagebits & DMG_SLASH && sentryid == 0)
			{
				set_hudmessage(100, 255, 0, 0.81, 0.27, 0, 6.0, 1.0)
				ShowSyncHudMsg(id, gSync9, "W 1: %d", floatround(damage))
			}
			if(damagebits & DMG_BLAST && sentryid == 1)
			{
				set_hudmessage(100, 255, 0, 0.81, 0.32, 0, 6.0, 1.0)
				ShowSyncHudMsg(id, gSync10, "W 2: %d", floatround(damage))
			}
			if(damagebits & DMG_BURN && sentryid == 2)
			{
				set_hudmessage(100, 255, 0, 0.81, 0.37, 0, 6.0, 1.0)
				ShowSyncHudMsg(id, gSync11, "W 3: %d", floatround(damage))
			}
			if(damagebits & DMG_DROWN && sentryid == 3)
			{
				set_hudmessage(100, 255, 0, 0.81, 0.42, 0, 6.0, 1.0)
				ShowSyncHudMsg(id, gSync12, "W 4: %d", floatround(damage))
			}
			if(MAX_SENTRY > 4 && sentryid >= 4)
			{
				set_hudmessage(100, 0, 255, 0.81, 0.47, 0, 6.0, 1.0)
				ShowSyncHudMsg(id, gSync13, "O: %d", floatround(damage))
			}

		}
		else
		{
			ghave[attacker]++
			if(ghave[attacker] == 1)
			{
				set_hudmessage(0, 255, 0, 0.55, 0.465, 0, 0.0, 1.0, 0.0, 0.2, 1)
				ShowSyncHudMsg(attacker, gSync5, "%d", floatround(damage))
			}
			if(ghave[attacker] == 2)
			{
				set_hudmessage(0, 255, 0, 0.55, 0.5, 0, 0.0, 1.0, 0.0, 0.2, 2)
				ShowSyncHudMsg(attacker, gSync5, "%d", floatround(damage))
			}
			if(ghave[attacker] == 3)
			{
				set_hudmessage(0, 255, 0, 0.55, 0.535, 0, 0.0, 1.0, 0.0, 0.2, 3)
				ShowSyncHudMsg(attacker, gSync5,  "%d", floatround(damage))
			}
			if(ghave[attacker] == 4)
			{
				set_hudmessage(0, 255, 0, 0.55, 0.57, 0, 0.0, 1.0, 0.0, 0.2, 4)
				ShowSyncHudMsg(attacker, gSync5, "%d", floatround(damage))
			}
			if(ghave[attacker] == 5)
			{
				set_hudmessage(0, 255, 0, 0.55, 0.605, 0, 0.0, 1.0, 0.0, 0.2, 1)
				ShowSyncHudMsg(attacker, gSync5, "%d", floatround(damage))
				ghave[attacker] = 0
			}
		}
		/* -- */
		static Float:fOrigin[3]
		static Origin[3]
		pev(ent, pev_origin, fOrigin)
		
		FVecIVec(Origin, fOrigin)
		
		static Color[33][3] ;
		Color[id?id:attacker][0] = gPlayerAttackColorValue[id?id:attacker][0]
		Color[id?id:attacker][1] = gPlayerAttackColorValue[id?id:attacker][1]
		Color[id?id:attacker][2] = gPlayerAttackColorValue[id?id:attacker][2]
		
		msg_dlight(Origin, 10, Color[id?id:attacker], 3, 1)	
		
		if(hp <= floatround(damage))
		{
			new data[1]
			data[0] = id?id:attacker
			set_task(0.1, "TakeDamage2", ent, data, 1)
			if(is_valid_ent(pev(ent, pev_ent_health)))
				remove_entity(pev(ent, pev_ent_health))
		}
		
	}
	if(!is_valid_ent(ent))
	{
		client_print(0, 3, "take damage !pev vaild")
		gMonsterAlive--;
		if(gMonsterAlive < 0)
			gMonsterAlive=0
				
		if(gMonsterAlive <= 0 && gWave && gStart && gGame)
			EndRound()
			
		return HAM_IGNORED
	}
	SetHamParamFloat(4, damage)
	return HAM_IGNORED
}
public TakeDamage2(Params[], ent)
{
	new id = Params[0]
		
	gMonsterAlive--;
	if(gMonsterAlive < 0)
		gMonsterAlive=0
			
	if(gMonsterAlive <= 0 && gWave && gStart && gGame)
		EndRound()
		
	if(is_user_connected(id))
	{
		set_hudmessage(255, 255, 255, -1.0, 0.6, 0, 0.0, 1.0, 0.0, 0.3)
		ShowSyncHudMsg(id, gSync3, "KILL!")
		
		gPlayerPoints[id]+=get_pcvar_num(cvar_points_kill)
			
		cs_set_user_money(id, cs_get_user_money(id)+450)
		
		if(is_user_alive(id))
			GiveAmmo(id, 20)
			
		set_user_frags(id, get_user_frags(id)+1)
		refreshFrags(id)
			
	}
}
Do zamknięcia! Przejdź do postu

GT Team - zdjęcie GT Team 05.05.2013

Gdzieś w tym thinku jest jakiś malutki drobiazg który powoduje, że serwer się crashuje
new ghave[33];
public TakeDamage(ent, idinflictor, attacker, Float:damage, damagebits)
{	
	if(!pev_valid(ent))
	{
		gMonsterAlive--;
		if(gMonsterAlive < 0)
			gMonsterAlive=0
				
		if(gMonsterAlive <= 0 && gWave && gStart && gGame)
			EndRound()
		remove_entity(pev(ent, pev_ent_health));
		remove_entity(ent)
		return PLUGIN_CONTINUE
	}
	new classname[32];
	entity_get_string(ent, EV_SZ_classname, classname, 31);
		
	if(equal(classname, "monster")) 
	{	
		new hp = floatround(entity_get_float(ent, EV_FL_health))
		/* Pokazuje zadane obrazenia */
		new id = 0
		if(is_turret(attacker))
		{
			id = get_sentry_owner_by_ent_id(attacker)
			if(gPlayerDamage[id])
				damage+=float(gPlayerNewDamage[id])
		}
			
		if(is_turret(attacker))
		{
			new sentryid = get_sentry_id_by_ent(id, attacker)
			if(damagebits & DMG_SLASH && sentryid == 0)
			{
				set_hudmessage(100, 255, 0, 0.81, 0.27, 0, 6.0, 1.0)
				ShowSyncHudMsg(id, gSync9, "W 1: %d", floatround(damage))
			}
			if(damagebits & DMG_BLAST && sentryid == 1)
			{
				set_hudmessage(100, 255, 0, 0.81, 0.32, 0, 6.0, 1.0)
				ShowSyncHudMsg(id, gSync10, "W 2: %d", floatround(damage))
			}
			if(damagebits & DMG_BURN && sentryid == 2)
			{
				set_hudmessage(100, 255, 0, 0.81, 0.37, 0, 6.0, 1.0)
				ShowSyncHudMsg(id, gSync11, "W 3: %d", floatround(damage))
			}
			if(damagebits & DMG_DROWN && sentryid == 3)
			{
				set_hudmessage(100, 255, 0, 0.81, 0.42, 0, 6.0, 1.0)
				ShowSyncHudMsg(id, gSync12, "W 4: %d", floatround(damage))
			}
			if(MAX_SENTRY > 4 && sentryid >= 4)
			{
				set_hudmessage(100, 0, 255, 0.81, 0.47, 0, 6.0, 1.0)
				ShowSyncHudMsg(id, gSync13, "O: %d", floatround(damage))
			}
		}
		else
		{
			ghave[attacker]++
			if(ghave[attacker] == 1)
			{
				set_hudmessage(0, 255, 0, 0.55, 0.465, 0, 0.0, 1.0, 0.0, 0.2, 1)
				ShowSyncHudMsg(attacker, gSync5, "%d", floatround(damage))
			}
			if(ghave[attacker] == 2)
			{
				set_hudmessage(0, 255, 0, 0.55, 0.5, 0, 0.0, 1.0, 0.0, 0.2, 2)
				ShowSyncHudMsg(attacker, gSync5, "%d", floatround(damage))
			}
			if(ghave[attacker] == 3)
			{
				set_hudmessage(0, 255, 0, 0.55, 0.535, 0, 0.0, 1.0, 0.0, 0.2, 3)
				ShowSyncHudMsg(attacker, gSync5,  "%d", floatround(damage))
			}
			if(ghave[attacker] == 4)
			{
				set_hudmessage(0, 255, 0, 0.55, 0.57, 0, 0.0, 1.0, 0.0, 0.2, 4)
				ShowSyncHudMsg(attacker, gSync5, "%d", floatround(damage))
			}
			if(ghave[attacker] == 5)
			{
				set_hudmessage(0, 255, 0, 0.55, 0.605, 0, 0.0, 1.0, 0.0, 0.2, 1)
				ShowSyncHudMsg(attacker, gSync5, "%d", floatround(damage))
				ghave[attacker] = 0
			}
		}
		/* -- */
		static Float:fOrigin[3]
		static Origin[3]
		pev(ent, pev_origin, fOrigin)
				
		Origin[0] = floatround(fOrigin[0])
		Origin[1] = floatround(fOrigin[1])
		Origin[2] = floatround(fOrigin[2])
		
		static Color[33][3] ;
		Color[id?id:attacker][0] = gPlayerAttackColorValue[id?id:attacker][0]
		Color[id?id:attacker][1] = gPlayerAttackColorValue[id?id:attacker][1]
		Color[id?id:attacker][2] = gPlayerAttackColorValue[id?id:attacker][2]
		
		msg_dlight(Origin, 10, Color[id?id:attacker], 3, 1)
		if(hp <= floatround(damage) && pev_valid(ent))
		{
			gMonsterAlive--;
			if(gMonsterAlive < 0)
				gMonsterAlive=0
				
			if(gMonsterAlive <= 0 && gWave && gStart && gGame)
				EndRound()
				
			if(pev_valid(ent))
				remove_entity(pev(ent, pev_ent_health));
				
			if(is_user_alive(id?id:attacker))
			{
				gPlayerPoints[id?id:attacker]+=get_pcvar_num(cvar_points_kill)
				cs_set_user_money(id?id:attacker, cs_get_user_money(id?id:attacker)+450)
				GiveAmmo(id?id:attacker, 20)
				set_user_frags(id?id:attacker, get_user_frags(id?id:attacker)+1)
				refreshFrags(id?id:attacker)
			}
		}
		
	}
	SetHamParamFloat(4, damage)
	return PLUGIN_CONTINUE
}
Proszę o pomoc w znalezieniu jego i o optymalizacje kodu. Jak jest to zły dział to przepraszam, lecz nie widzę innego. Jeśli chcecie, mogę dać inne funkcje.
Odpowiedz

  • +
  • -
Klakier - zdjęcie Klakier 05.05.2013

O co chodzi w tym, że tak powiem?

id?id:attacker

 

Sprawdzasz czy id jest większe, równe od 1 i jeżeli tak to nadajesz id=1, a jeżeli warunek jest niespełniony (id=0 - id serwera) to ?

Odpowiedz

GT Team - zdjęcie GT Team 05.05.2013

Niee. Jeżeli ID jest true ( większe od 0 ) to ID, a jak nie to Attacker
new id = 0
		if(is_turret(attacker))
		{
			id = get_sentry_owner_by_ent_id(attacker)


Id jest wtedy, gdy jest to właściciel wieżyczki ( gracz ), attacker jest wtedy kiedy jest to atakujący ( gracz ). Bo przecież nie mogę dać fragów wieżyczce :D
Odpowiedz

  • +
  • -
Klakier - zdjęcie Klakier 05.05.2013

Sory, nie zauważyłem :facepalm2:  ;)

Odpowiedz

GT Team - zdjęcie GT Team 05.05.2013

Ok ok ;P
Odpowiedz

  • +
  • -
GwynBleidD - zdjęcie GwynBleidD 05.05.2013

Polecam debug "na diodę" :) albo jak kto woli: na dziel i rządź.

 

Dodajesz po kolei console print, albo log z różnymi wartościami co każdy znaczący fragment kodu. Przy crashu patrzysz który z printów, czy tam logów zdążył się wypisać, a który nie. Pomiędzy masz swój błąd, szatkujesz więc ten kawałek na drobniejsze kawałki logami i jeszcze raz operacja taka ;)


Użytkownik GwynBleidD edytował ten post 05.05.2013 23:39
Odpowiedz

GT Team - zdjęcie GT Team 06.05.2013

Zrobiłem to, zatrzymało się na "kill" a kill było w :
if(is_user_alive(id?id:attacker))
			{
				gPlayerPoints[id?id:attacker]+=get_pcvar_num(cvar_points_kill)
				cs_set_user_money(id?id:attacker, cs_get_user_money(id?id:attacker)+450)
				GiveAmmo(id?id:attacker, 20)
				set_user_frags(id?id:attacker, get_user_frags(id?id:attacker)+1)
				refreshFrags(id?id:attacker)
			}
client_print(0, 3,"kill")
}
Nie wiem czy lepiej dać częśc kodu w post bo ten aktualny jest w pre
Odpowiedz

  • +
  • -
GwynBleidD - zdjęcie GwynBleidD 06.05.2013

wklej printa przed i po refreshFrags.

Odpowiedz

GT Team - zdjęcie GT Team 06.05.2013

Tzn. źle napisałem. pokazało się kill i potem crash. Nagle zaczął występować błąd INVALID ENTITY
if(pev_valid(ent))
				remove_entity(pev(ent, pev_ent_health)); - TUTAJ
Odpowiedz

  • +
  • -
GwynBleidD - zdjęcie GwynBleidD 06.05.2013

To pokaż co po tym kill się wykonuje.

 

Co do invalid entity, sprawdź czy ent zwracany przez pev(ent, pev_ent_health) jest prawidłowy.

Odpowiedz

GT Team - zdjęcie GT Team 06.05.2013

1.
if(hp <= floatround(damage) && pev_valid(ent))
		{
			gMonsterAlive--;
			if(gMonsterAlive < 0)
				gMonsterAlive=0
				
			if(gMonsterAlive <= 0 && gWave && gStart && gGame)
				EndRound()
				
			if(pev_valid(ent))
				remove_entity(pev(ent, pev_ent_health));
				
			if(is_user_alive(id?id:attacker))
			{
				gPlayerPoints[id?id:attacker]+=get_pcvar_num(cvar_points_kill)
				cs_set_user_money(id?id:attacker, cs_get_user_money(id?id:attacker)+450)
				GiveAmmo(id?id:attacker, 20)
				set_user_frags(id?id:attacker, get_user_frags(id?id:attacker)+1)
				refreshFrags(id?id:attacker)
			}
                        client_print(0, 3,"kill")
		}
		
	}
	SetHamParamFloat(4, damage)
	return PLUGIN_CONTINUE
}
2. Dawałem i invalid entity pokazywało w tym ifie
Odpowiedz

  • +
  • -
sebul - zdjęcie sebul 06.05.2013

1. ent != pev(ent, pev_ent_health), a przynajmniej nie musi, co najwyżej może być równe.
Odpowiedz

GT Team - zdjęcie GT Team 06.05.2013

sebul nie rozumiem Twojej wypowiedzi. Może trochę jaśniej ?
Odpowiedz

  • +
  • -
sebul - zdjęcie sebul 06.05.2013

if(pev_valid(ent))
remove_entity(pev(ent, pev_ent_health));

Sprawdzasz, czy istnieje "ent", a potem usuwasz coś co znajduje się pod "pev(ent, pev_ent_health)".
Odpowiedz

GT Team - zdjęcie GT Team 06.05.2013

Używam pre-procesora, lecz w tym Pre TakeDamage ent raczej istnieje bo jest Pre
Odpowiedz

  • +
  • -
GwynBleidD - zdjęcie GwynBleidD 06.05.2013

Ale to, co zwraca pev(ent, pev_ent_health) niekoniecznie musi istnieć...

Odpowiedz

GT Team - zdjęcie GT Team 06.05.2013

pev(ent, pev_ent_health)
Jest to id Ent'a healthbara tego potwora
sebul (06.05.2013 19:23):
Ale co to ma do rzeczy? Przeczytaj jeszcze raz dokładnie to co zostało tutaj napisane, bo chyba dalej nie wiesz o co chodzi.
Odpowiedz

  • +
  • -
DarkGL - zdjęcie DarkGL 07.05.2013

Ente health bara to całkowicie niezależny obiekt więc musisz się upewnić że napewno istnieje, ty go sobie przypisales wirtualnie do innego enta ale dla gry już tak nie jest, prościej się już nie da
Odpowiedz

GT Team - zdjęcie GT Team 07.05.2013

if(pev_valid(pev(ent, pev_ent_health)))
      remove_entity(pev(ent, pev_ent_health))


Wywala błąd na ifie, Invalid entity
Odpowiedz

  • +
  • -
GwynBleidD - zdjęcie GwynBleidD 07.05.2013

if(pev_valid(ent))
    if(pev_valid(pev(ent, pev_ent_health)))
        remove_entity(pev(ent, pev_ent_health))

 

Musisz wszak sprawdzać, czy oba enty są prawidłowe :)

 

Odpowiedz