[Tutorial] Зомби для вашего сервера без NPC для 0.3z
#1

Вот написал простенький код когда узнал что в 0.3z появится нужные для этого кэлбэки.
За основу был взят давно забытый скрипт где создавали зомбяка и тот летал за указанным ID

Плюсы:
- Не летают
- Не ходят под землей
- Идут к самому ближайшему игроку
- Если он в машине, то бьют машину
- Издают звуки (например удар по машине или звук поедания человека)
- Максимальное количество зомби без стримеров: 167
- Максимальное количество с стримером: 334
- Слотов не жрут

Минусы:
- Нет анимаций т.е. ходят без передвижения ног ( мб исправлю это потом).
- Работает только с 0.3z!

И так если прочли плюсы и минусы и всё же захотели таких кровожадных тварей себе на сервер,то вот и мануал:
Ко всем дефайнам:
PHP Code:
#define MAX_ZOMBIES 40// максимальное кол-во зомби 
Ко всем переменным (new):
PHP Code:
new zhealth[MAX_ZOMBIES];
new 
zombie[MAX_ZOMBIES][7];
new 
Float:Zspeed 5.5;
new 
ZTimerSpeed 500;
enum zombiParts
{
    
partModel,
Float:RelX,
Float:RelY,
Float:RelZ,
Float:RelrX,
Float:RelrY,
Float:RelrZ
}
new 
z11[6][zombiParts]=
{
    {
2905,-0.115479,-0.023924, -1.280131, -90.00000090.000000,0.000000}, // нога
    
{2906, -0.2189950.200928, -0.2531350.000000180.0000000.000000}, // рука
    
{2907, -0.032227, -0.045897, -0.544213270.0000000.0000000.000000}, // туловище
    
{29060.1879870.158448, -0.2657930.0000000.0000000.000000}, // рука
    
{29080.0000000.0000000.000000270.00000090.0000000.000000},//голова
    
{29050.101074, -0.012694, -1.288253270.00000090.0000000.000000// нога
};
new 
z21[6][zombiParts]=
{
    {
29050.005614, -0.110107, -1.280131, -90.00000090.00000090.000000},
    {
2906, -0.148926, -0.180663, -0.2531350.000000180.00000090.000000},
    {
29070.047852, -0.039061, -0.544213270.0000000.00000090.000000},
    {
2906, -0.1523430.171387, -0.2657930.0000000.00000090.000000},
    {
29080.0000000.0000000.000000270.00000090.00000090.000000},
    {
29050.0009770.090332, -1.288253270.00000090.00000090.000000}
};
new 
usedzombi[MAX_ZOMBIES];
new 
TimerAtaca=-1
Ну и форвард впихните куда нибудь в верх.
PHP Code:
forward ZombieAtaca(playerid); 
В OnGameModeInit, тут кстати я использую TSetTimer от Xemyl, это один единый таймер который уменьшает нагрузку на сервер и придает точность таймерам, такая система снизит нагрузку на сервер от этих зомби, подробнее читайте в его теме, она находится вот тут http://pawno-info.ru/threads/153560-a_timer
PHP Code:
if (TimerAtaca!=-1)
    {
        
TKillTimer(TimerAtaca);
    }
    
TimerAtaca=TSetTimer("ZombieAtaca",ZTimerSpeed,1); 
Идем дальше
Где нибудь с низу создаем паблик, это сам движок зомби.
PHP Code:
new Float:X8,Float:Y8,Float:Z8,proveren,rand2,rand3;
new 
Float:X8,Float:Y8,Float:Z8,proveren,rand2,rand3;
public 
ZombieAtaca()
{
    new 
playerid,Float:pX,Float:pY,Float:pZ,Float:angle;
    new 
Float:pX3,Float:pY3,Float:pZ3,Float:PEPE,Float:PIPO;
    for (new 
j=0;jgetmaxzombieid();j++)
    {
    
///    printf("зомби id %d проходит обработку",j);
        
if(usedzombi[j] != 1)continue;
        
playerid GetClosestPlay(zombie[j][4]);
        if(
playerid == INVALID_PLAYER_ID) continue;
        
pX3 X8,pY3 Y8,pZ3Z8;
        
//printf("зомби id %d прошел обработку",j);
           
GetPlayerPos(playerid,pX,pY,pZ);
        
GetObjectPos(zombie[j][4],X8,Y8,Z8);
        
angle 180.0-atan2(X8-pX,Y8-pY);
        
PEPE floatsin((angle*3.14159/180.0));
        
PIPO floatcos((angle*3.14159/180.0));
        
SetObjectRotzombie[j][4], z11[4][RelrX],z11[4][RelrY],angle );
        if ( (
floatabs(pX3-X8) + floatabs(pY3-Y8) + floatabs(pZ3-Z8) )<2.5)
        {
            if( 
!= proveren)
            {
                
rand2 random(4);
                
rand3 random(3);
                switch(
rand2)
                {
                case 
0:pX-=rand3;
                case 
1:pX+=rand3;
                case 
2:pY-=rand3;
                case 
3:pY+=rand3;
                }
            }
        }
        
proveren j;
        if(!
IsPlayerInAnyVehicle(playerid))
        {
            if ( (
floatabs(pX-X8) + floatabs(pY-Y8) + floatabs(pZ-Z8) )>2.8)
            {
                
MoveObject(zombie[j][4],pX+z11[4][RelX]*PIPO+PEPE*z21[4][RelX],pY+z11[4][RelY]*PIPO+PEPE*z21[4][RelY],pZ+z21[4][RelZ]+0.7,Zspeed);
            }
            else 
OnZombieGiveDamage(playerid,7);
            continue;
        }
        else
        {
            if ( (
floatabs(pX-X8) + floatabs(pY-Y8) + floatabs(pZ-Z8) )>5.0)
            {
                
MoveObject(zombie[j][4],pX+z11[4][RelX]*PIPO+PEPE*z21[4][RelX],pY+z11[4][RelY]*PIPO+PEPE*z21[4][RelY],pZ+z21[4][RelZ]+0.7,Zspeed);
            }
            else 
OnZombieGiveDamage(playerid,7);
        }
    }
    return 
1;

Теперь делаем систему попадания по человеку:
PHP Code:
OnZombieGiveDamage(playerid,Float:damage)
{
    new 
Float:pX,Float:pY,Float:pZ;
    
GetPlayerPos(playerid,pX,pY,pZ);
    if ( !
IsPlayerInAnyVehicle(playerid))
    {
           new 
Float:H;
        
GetPlayerHealth(playerid,H);
        if(
<= 0.0) return true;
        
SetPlayerHealthAC(playerid,H-damage);
        
//lasttouch[playerid] = 1;
        
return PlaySoundForPlayersInRange(1960230pX,pY,pZ);
    }
    else
    {
        new 
veh,Float:vehp;
        
veh GetPlayerVehicleID(playerid);
        
GetVehicleHealth(vehvehp);
        
SetVehicleHealth(vehvehp-damage);
        
PlaySoundForPlayersInRange(1940130pX,pY,pZ);
    }
    return 
true;

Теперь необходимые функции для движка:
PHP Code:
getmaxzombies()
{
    new 
x;
    for (new 
j=0;j<getmaxzombieid();j++)
    {
        if(
usedzombi[j] == 1)++;
    }
    return 
x;
}
getmaxzombieid()
{
    new 
= -1;
    for (new 
j=0;j<MAX_ZOMBIES;j++)
    {
        if(
usedzombi[j] == 1)=j;
        continue;
    }
    return 
x+1;

Так а теперь система нахождения ближайшего игрока, вот тут не большая развилка, всё дело в том что я этих зомби делал для своего РП сервера, т.е. вы понимайте что зомби по всюду не всем игрокам понравится и поэтому я у себя сделал ограничение где зомби можно быть.

Для тех кто хочет что-бы зомби были по всюду:
PHP Code:
GetClosestPlay(objectid)
{
    new 
Float:min_dis 99999.99,
Float:player_dis,
    
player INVALID_PLAYER_ID;
    new 
Float:object_xFloat:object_yFloat:object_zFloat:temp_z;
    
GetObjectPos(objectidobject_xobject_yobject_z);
    
MapAndreas_FindAverageZ(object_xobject_ytemp_z);
    if (
object_z temp_z 2.0 || object_z-temp_z)
    {
        
SetObjectPos(objectidobject_xobject_y, (object_z temp_z 2.0));
    }
    foreach (new 
playerid Player)
    {
        if (
GetPlayerState(playerid) == PLAYER_STATE_SPECTATING) continue;
        if (
GetPlayerInterior(playerid)) continue; 
        
player_dis GetPlayerDistanceFromPoint(playeridobject_xobject_yobject_z);
        if (
player_dis min_dis)
        {
            
min_dis player_dis;
            
player playerid;
        }
    }
    return 
player;

Для тех кто хочет что-бы были только в определенных местах:
PHP Code:
GetClosestPlay(objectid)
{
    new 
Float:min_dis 99999.99,
Float:player_dis,
    
player INVALID_PLAYER_ID;
    new 
Float:object_xFloat:object_yFloat:object_zFloat:temp_z;
    
GetObjectPos(objectidobject_xobject_yobject_z);
    
GetPointZPos(object_xobject_ytemp_z);
    if (
object_z temp_z 2.0 || object_z-temp_z)
    {
        
SetObjectPos(objectidobject_xobject_y, (object_z temp_z 2.0));
    }
    foreach (new 
playerid Player)
    {
        if (
GetPlayerState(playerid) == PLAYER_STATE_SPECTATING) continue;
        if (
GetPlayerInterior(playerid) || Isahitman(playerid)) continue; 
        if (!
ISAZOMBIESPAWN(playerid) && !zombiespawn2(playerid)) continue; 
        
player_dis GetPlayerDistanceFromPoint(playeridobject_xobject_yobject_z);
        if (
player_dis min_dis)
        {
            
min_dis player_dis;
            
player playerid;
        }
    }
    return 
player;

Теперь систему попадания по зомби:

PHP Code:
public OnPlayerWeaponShot(playeridweaponidhittypehitidFloat:fXFloat:fYFloat:fZ)
{
    if(
hittype == BULLET_HIT_TYPE_OBJECT)
    {
        new 
zombieid2 IsThisAZombie2(hitid);
        if(
zombieid2 != -1)
        {
            new 
damage;
            if(
weaponid 10) {damage random(50);}// по сути эти строки зря сделал, сам решайте оставлять ли
            
else {damage random(20);}
              if(
Headshot(zombieid2,hitid))
            {
                
damage 70;
                
GameTextForPlayer(playerid"~r~Headshot"10006);
            }
            
zhealth[zombieid2] -= damage;
            if(
zhealth[zombieid2] < 1)
            {
                for (new 
i=0;i<6;i++)
                {
                       
StopObject(zombie[zombieid2][i]);
                       
DestroyObject(zombie[zombieid2][i]);
                       
usedzombi[zombieid2] =0;
                   }
                   
SendClientMessage(playerid,COLOR_WHITE"Вы убили зомби! +500 вирт");
                   
PlayerInfo[playerid][pCash] += 500;// даём ему денег
            
}
        
//    format(string3[playerid],180,"Damage -%d",damage);
        //    GameTextForPlayer(playerid, string3[playerid], 1000, 1);
            
PlayerPlaySound(playerid64010.00.00.0);
        }
    }
    return 
true;

И так что мы имеем?
- Движок зомби
- Нахождение игрока
- Попадание по игроку и его машине
- Урон зомби
Не хватает лишь самого главного создания зомби!
Ну тут тоже не большой вопрос у меня возник: Создавать зомби на определенных спавнах после смерти пред идущего или же после убийства игрока, в таком случае пришлось бы каждый час проверять и если все зомби убиты создавать одного нового.

Пока не решил,но скину код создания зомби:
PHP Code:
createzombie(playerid// ориентация на место положение игрока и его Angle
{
    new 
Float:pX,Float:pY,Float:pZ,Float:Ang;
    
GetPlayerPos(playerid,pX,pY,pZ);
    
GetPlayerFacingAngle(playerid,Ang);
    
pX=pX+3.0*floatsin(-Ang,degrees);
    
pY=pY+3.0*floatcos(-Ang,degrees);
    
pZ=pZ+0.7;
    return 
CrearZombie(pX,pY,pZ,Ang+180.0);
}
CrearZombie(Float:pX,Float:pY,Float:pZ,Float:angle)
{
    if (
getmaxzombies() <MAX_ZOMBIES)
    {
        for (new 
j=0;j<MAX_ZOMBIES;j++)
        {
            if(
usedzombi[j] == 0)
            {
                
zhealth[j] = 100;
                
usedzombi[j] =1;
                new 
Float:PEPE floatsin((angle*3.14159/180.0));
                 new 
Float:PIPO floatcos((angle*3.14159/180.0));
                for (new 
i=0;i<6;i++)
                {
                    
zombie[j][i]=CreateObject(z11[i][partModel],pX+z11[i][RelX]*PIPO+PEPE*z21[i][RelX],pY+z11[i][RelY]*PIPO+PEPE*z21[i][RelY],pZ+z21[i][RelZ],z11[i][RelrX],z11[i][RelrY],angle);
                }
                
AttachObjectToObject(zombie[j][5],zombie[j][4],0.011.30.09000);
                
AttachObjectToObject(zombie[j][3],zombie[j][4],-0.1 ,0.25,0.15027090);
                
AttachObjectToObject(zombie[j][2],zombie[j][4],0.050.55, -0.03202700);
                
AttachObjectToObject(zombie[j][1],zombie[j][4],-0.150.25, -0.1909090);
                
AttachObjectToObject(zombie[j][0],zombie[j][4],01.30, -0.10000);
                break;
            }
        }
    }
    return 
1;

Ах да чуть не забыл, что-бы зомби не летали и не ходили под землей нам потребуется это
https://sampforum.blast.hk/showthread.php?tid=275492
Ну а код корректировки ходьбы зомби уже есть в верху.

Жду предложений и критики.
Кстати напишите как лучше всего создавать зомби.


---------- Post added at 12:29 ---------- Previous post was at 12:15 ----------

Ой забыл добавить
это тоже нужно:
PHP Code:
IsThisAZombie2(object)
{
   for (new 
j=0;jgetmaxzombieid();j++)
   {
           if(
usedzombi[j] != 1)continue;
           for (new 
i=0;i<6;i++)
           {
               if(
object == zombie[j][i]) return j;
        }
   }
   return -
1;
}
IsThisAZombie2(object)
{
   for (new 
j=0;jgetmaxzombieid();j++)
   {
           if(
usedzombi[j] != 1)continue;
           for (new 
i=0;i<6;i++)
           {
               if(
object == zombie[j][i]) return j;
        }
   }
   return -
1;
}
Headshot(zombieid,objectid)
{
 if(
objectid == zombie[zombieid][4]) return true;
 return 
false;

Автор Caypen
Версия: 0.2

Спасибо за корректировку функции GetClosestPlay: Stepashka
Reply


Messages In This Thread
Зомби для вашего сервера без NPC для 0.3z - by Cypen - 24.01.2014, 07:10
Re: Зомби для вашего сервера без NPC для 0.3z - by White_116 - 24.01.2014, 07:57
Re: Зомби для вашего сервера без NPC для 0.3z - by Cypen - 24.01.2014, 08:20
Re: Зомби для вашего сервера без NPC для 0.3z - by KriD - 24.01.2014, 08:24
Re: Зомби для вашего сервера без NPC для 0.3z - by Cypen - 24.01.2014, 08:24
Re: Зомби для вашего сервера без NPC для 0.3z - by XemyL - 24.01.2014, 08:28
Re: Зомби для вашего сервера без NPC для 0.3z - by XemyL - 24.01.2014, 08:32
Re: Зомби для вашего сервера без NPC для 0.3z - by Cypen - 24.01.2014, 08:40
Re: Зомби для вашего сервера без NPC для 0.3z - by Cypen - 24.01.2014, 08:45
Re: Зомби для вашего сервера без NPC для 0.3z - by Cypen - 24.01.2014, 09:10
Re: Зомби для вашего сервера без NPC для 0.3z - by Cypen - 24.01.2014, 09:18
Re: Зомби для вашего сервера без NPC для 0.3z - by Stepashka - 24.01.2014, 09:19
Re: Зомби для вашего сервера без NPC для 0.3z - by Cypen - 24.01.2014, 09:30
Re: Зомби для вашего сервера без NPC для 0.3z - by Stepashka - 24.01.2014, 09:33
Re: Зомби для вашего сервера без NPC для 0.3z - by Cypen - 24.01.2014, 10:20
Re: Зомби для вашего сервера без NPC для 0.3z - by Stepashka - 24.01.2014, 10:46
Re: Зомби для вашего сервера без NPC для 0.3z - by Cypen - 24.01.2014, 11:05
Re: Зомби для вашего сервера без NPC для 0.3z - by Cypen - 24.01.2014, 11:09
Re: Зомби для вашего сервера без NPC для 0.3z - by White_116 - 24.01.2014, 11:11
Re: Зомби для вашего сервера без NPC для 0.3z - by Stepashka - 24.01.2014, 11:13
Re: Зомби для вашего сервера без NPC для 0.3z - by Cypen - 24.01.2014, 11:23
Re: Зомби для вашего сервера без NPC для 0.3z - by Cypen - 24.01.2014, 11:27
Re: Зомби для вашего сервера без NPC для 0.3z - by Cypen - 24.01.2014, 13:38
Re: Зомби для вашего сервера без NPC для 0.3z - by XemyL - 24.01.2014, 13:40
Re: Зомби для вашего сервера без NPC для 0.3z - by Cypen - 24.01.2014, 13:44
Re: Зомби для вашего сервера без NPC для 0.3z - by XemyL - 24.01.2014, 13:46
Re: Зомби для вашего сервера без NPC для 0.3z - by Cypen - 24.01.2014, 13:50
Re: Зомби для вашего сервера без NPC для 0.3z - by Stepashka - 24.01.2014, 13:58
Re: Зомби для вашего сервера без NPC для 0.3z - by XemyL - 24.01.2014, 14:00
Re: Зомби для вашего сервера без NPC для 0.3z - by Cypen - 24.01.2014, 14:10

Forum Jump:


Users browsing this thread: 1 Guest(s)