
W tym poradniku pokaze w jaki sposob dodac rakietki do klasy/itemu. Na poczatek musimy standardowo utworzyc jakas klase lub item a nastepnie gdzies na gorze dodajemy:
new ilosc_rakiet_gracza[MAX_PLAYERS+1]
Nastepnie szukamy:
new String:modele_serwera[][] =
{
i tworzymy nowy wpis, jako nowa pozycje (w tym wypadku 11) dodajemy:
"models/props/de_vertigo/construction_safetyribbon_01.mdl" // 11
Teraz szukamy:
public OnMapStart()
{
i dodajemy do srodka:
PrecacheSound("weapons/hegrenade/explode5.wav");
Schodzimy troche nizej i widzimy:
public OnClientPutInServer(client)
{
i do srodka dodajemy:
ilosc_rakiet_gracza[client] = 0;
nastepnie szukamy:
public Action:Prethink(client)
{
if(!IsValidClient(client) || IsFakeClient(client) || freeze_time)
return Plugin_Continue;
if(IsPlayerAlive(client))
{
new buttons = GetClientButtons(client);
new ile = poziom_gracza[client]-1 >= 0? doswiadczenie_poziomu[poziom_gracza[client]-1]: 0;
new Float:procent_gracza = 0.0;
procent_gracza = (float(doswiadczenie_gracza[client]-ile)/float(doswiadczenie_poziomu[poziom_gracza[client]]-ile))*100.0;
PrintHintText(client, "[Klasa: <b>%s</b>]\n[Xp: <b>%0.1f</b>/<b>100.0%%</b> | Lv: <b>%i</b>]\n[Item: <b>%s</b> [<b>%i%%</b>]]", nazwy_klas[klasa_gracza[client]], procent_gracza, poziom_gracza[client], nazwy_itemow[informacje_itemu_gracza[client][0]], moc_itemu[client]);
new String:weapon[32];
GetClientWeapon(client, weapon, sizeof(weapon));
i teraz dodajemy do switcha klasy lub itemu sprawdzanie czy gracz naciska klawisz, jesli tak to wykonujemy public StworzRakiete. Nizej przyklad dla klasy Wsparcie Ogniowe:
Do
switch(klasa_gracza[client])
{
dodaje
case WsparcieOgniowe:
{
if(!oldbuttons1[client] && buttons & IN_USE)
{
StworzRakiete(client);
oldbuttons1[client] = 1;
}
else if(oldbuttons1[client] && !(buttons & IN_USE))
oldbuttons1[client] = 0;
}
Po nacisnieciu a nastepnie puszczeniu klawisza E, bedzie wykonywany kod rakiety.
Nastepnie gdzies na silnika dole dodajemy:
public Action:StworzRakiete(client)
{
if(ilosc_rakiet_gracza[client])
{
new ent = CreateEntityByName("hegrenade_projectile");
if(ent == -1)
return;
new Float:OwnerAng[3];
new Float:OwnerPos[3];
new Float:InitialPos[3];
new Float:InitialVec[3];
new Float:InitialAng[3];
SetEntPropEnt(ent, Prop_Send, "m_hOwnerEntity", client);
GetClientEyeAngles(client, OwnerAng);
GetClientEyePosition(client, OwnerPos);
TR_TraceRayFilter(OwnerPos, OwnerAng, MASK_SOLID, RayType_Infinite, WybuchEnta, ent);
TR_GetEndPosition(InitialPos);
MakeVectorFromPoints(OwnerPos, InitialPos, InitialVec);
NormalizeVector(InitialVec, InitialVec);
ScaleVector(InitialVec, 1000.0);
GetVectorAngles(InitialVec, InitialAng);
DispatchSpawn(ent);
ActivateEntity(ent);
SetEntityModel(ent, modele_serwera[11]);
SetEntityMoveType(ent, MOVETYPE_FLY);
TeleportEntity(ent, OwnerPos, InitialAng, InitialVec);
SDKHook(ent, SDKHook_StartTouchPost, DotykRakiety);
ilosc_rakiet_gracza[client]--;
}
else
PrintToChat(client, "[COD:MW] Wykorzystales juz moc swojej klasy w tej rundzie!");
}
public Action:DotykRakiety(ent, other)
{
if(GetEntProp(other, Prop_Data, "m_nSolidType") && !(GetEntProp(other, Prop_Data, "m_usSolidFlags") & 0x0004))
{
new MissileOwner = GetEntPropEnt(ent, Prop_Send, "m_hOwnerEntity");
if(IsValidClient(MissileOwner))
{
new Float:MissilePos[3];
new MissileOwnerTeam = GetEntProp(MissileOwner, Prop_Send, "m_iTeamNum");
new ExplosionIndex = CreateEntityByName("env_explosion");
GetEntPropVector(ent, Prop_Send, "m_vecOrigin", MissilePos);
SetEntProp(ent, Prop_Send, "m_iTeamNum", MissileOwnerTeam);
DispatchKeyValue(ExplosionIndex,"classname","hegrenade_projectile");
SetEntProp(ExplosionIndex, Prop_Data, "m_spawnflags", 6146);
SetEntProp(ExplosionIndex, Prop_Data, "m_iMagnitude", 40+(inteligencja_gracza[MissileOwner]+bonusowa_inteligencja_gracza[MissileOwner])/6);
SetEntProp(ExplosionIndex, Prop_Data, "m_iRadiusOverride", 200);
DispatchSpawn(ExplosionIndex);
ActivateEntity(ExplosionIndex);
TeleportEntity(ExplosionIndex, MissilePos, NULL_VECTOR, NULL_VECTOR);
SetEntPropEnt(ExplosionIndex, Prop_Send, "m_hOwnerEntity", MissileOwner);
SetEntProp(ExplosionIndex, Prop_Send, "m_iTeamNum", MissileOwnerTeam);
EmitSoundToAll("weapons/hegrenade/explode5.wav", ExplosionIndex, 1, 90);
AcceptEntityInput(ExplosionIndex, "Explode");
DispatchKeyValue(ExplosionIndex,"classname","env_explosion");
AcceptEntityInput(ExplosionIndex, "Kill");
AcceptEntityInput(ent, "Kill");
}
else
AcceptEntityInput(ent, "Kill");
}
}
public bool:WybuchEnta(ent, contentsMask, any:data)
{
return false;
}
Musimy jeszcze przypisac odpowiednia ilosc rakiet dla warunku jaki przypisalismy. Tak wiec jezeli ma to byc dla klasy to przechodzimy do odrodzenia, a jezeli dla itemu to do dajitem. Ja pokaze na tej samej klasie na ktorej dodalem wykonywanie kodu rakiety, a wiec szukam:
public Action:Odrodzenie(client)
{
if(!IsValidClient(client) || !IsPlayerAlive(client))
return;
if(!klasa_gracza[client])
WybierzKlase(client);
else
{
if(nowa_klasa_gracza[client])
{
klasa_gracza[client] = nowa_klasa_gracza[client];
nowa_klasa_gracza[client] = 0;
ilosc_apteczek_gracza[client] = 0;
CS_UpdateClientModel(client);
WczytajDane(client, klasa_gracza[client]);
}
switch(klasa_gracza[client])
{
i dodaje:
Do switch(klasa_gracza[client})
case WsparcieOgniowe: ilosc_rakiet_gracza[client] = 2;
To na tyle, obrazenia z rakiety zmienia sie w public DotykRakiety. Co do modelu, odradzam ustawianie innych niz tych standardowych, poniewaz moga wystapic bledy. Jezeli gracz bedzie miec jakis problem z pobraniem modelu lub jej tekstury to zamiast modelu wyswietli sie mu napis "ERROR".
Opcjonalnie, jezeli nie chcemy by w momencie zmiany klasy rakiety nie przechodzily na inna klase to do if(nowa_klasa_gracza[client]), dodajemy resetowanie rakiet czyl:
ilosc_rakiet_gracza[client] = 0;


Dodatki SourceMod















