24.01.2014, 07:10
(
Last edited by Cypen; 25/01/2014 at 06:58 AM.
)
Вот написал простенький код когда узнал что в 0.3z появится нужные для этого кэлбэки.
За основу был взят давно забытый скрипт где создавали зомбяка и тот летал за указанным ID
Плюсы:
- Не летают
- Не ходят под землей
- Идут к самому ближайшему игроку
- Если он в машине, то бьют машину
- Издают звуки (например удар по машине или звук поедания человека)
- Максимальное количество зомби без стримеров: 167
- Максимальное количество с стримером: 334
- Слотов не жрут
Минусы:
- Нет анимаций т.е. ходят без передвижения ног ( мб исправлю это потом).
- Работает только с 0.3z!
И так если прочли плюсы и минусы и всё же захотели таких кровожадных тварей себе на сервер,то вот и мануал:
Ко всем дефайнам:
Ко всем переменным (new):
Ну и форвард впихните куда нибудь в верх.
В OnGameModeInit, тут кстати я использую TSetTimer от Xemyl, это один единый таймер который уменьшает нагрузку на сервер и придает точность таймерам, такая система снизит нагрузку на сервер от этих зомби, подробнее читайте в его теме, она находится вот тут http://pawno-info.ru/threads/153560-a_timer
Идем дальше
Где нибудь с низу создаем паблик, это сам движок зомби.
Теперь делаем систему попадания по человеку:
Теперь необходимые функции для движка:
Так а теперь система нахождения ближайшего игрока, вот тут не большая развилка, всё дело в том что я этих зомби делал для своего РП сервера, т.е. вы понимайте что зомби по всюду не всем игрокам понравится и поэтому я у себя сделал ограничение где зомби можно быть.
Для тех кто хочет что-бы зомби были по всюду:
Для тех кто хочет что-бы были только в определенных местах:
Теперь систему попадания по зомби:
И так что мы имеем?
- Движок зомби
- Нахождение игрока
- Попадание по игроку и его машине
- Урон зомби
Не хватает лишь самого главного создания зомби!
Ну тут тоже не большой вопрос у меня возник: Создавать зомби на определенных спавнах после смерти пред идущего или же после убийства игрока, в таком случае пришлось бы каждый час проверять и если все зомби убиты создавать одного нового.
Пока не решил,но скину код создания зомби:
Ах да чуть не забыл, что-бы зомби не летали и не ходили под землей нам потребуется это
https://sampforum.blast.hk/showthread.php?tid=275492
Ну а код корректировки ходьбы зомби уже есть в верху.
Жду предложений и критики.
Кстати напишите как лучше всего создавать зомби.
---------- Post added at 12:29 ---------- Previous post was at 12:15 ----------
Ой забыл добавить
это тоже нужно:
Автор Caypen
Версия: 0.2
Спасибо за корректировку функции GetClosestPlay: Stepashka
За основу был взят давно забытый скрипт где создавали зомбяка и тот летал за указанным ID
Плюсы:
- Не летают
- Не ходят под землей
- Идут к самому ближайшему игроку
- Если он в машине, то бьют машину
- Издают звуки (например удар по машине или звук поедания человека)
- Максимальное количество зомби без стримеров: 167
- Максимальное количество с стримером: 334
- Слотов не жрут
Минусы:
- Нет анимаций т.е. ходят без передвижения ног ( мб исправлю это потом).
- Работает только с 0.3z!
И так если прочли плюсы и минусы и всё же захотели таких кровожадных тварей себе на сервер,то вот и мануал:
Ко всем дефайнам:
PHP Code:
#define MAX_ZOMBIES 40// максимальное кол-во зомби
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.000000, 90.000000,0.000000}, // нога
{2906, -0.218995, 0.200928, -0.253135, 0.000000, 180.000000, 0.000000}, // рука
{2907, -0.032227, -0.045897, -0.544213, 270.000000, 0.000000, 0.000000}, // туловище
{2906, 0.187987, 0.158448, -0.265793, 0.000000, 0.000000, 0.000000}, // рука
{2908, 0.000000, 0.000000, 0.000000, 270.000000, 90.000000, 0.000000},//голова
{2905, 0.101074, -0.012694, -1.288253, 270.000000, 90.000000, 0.000000} // нога
};
new z21[6][zombiParts]=
{
{2905, 0.005614, -0.110107, -1.280131, -90.000000, 90.000000, 90.000000},
{2906, -0.148926, -0.180663, -0.253135, 0.000000, 180.000000, 90.000000},
{2907, 0.047852, -0.039061, -0.544213, 270.000000, 0.000000, 90.000000},
{2906, -0.152343, 0.171387, -0.265793, 0.000000, 0.000000, 90.000000},
{2908, 0.000000, 0.000000, 0.000000, 270.000000, 90.000000, 90.000000},
{2905, 0.000977, 0.090332, -1.288253, 270.000000, 90.000000, 90.000000}
};
new usedzombi[MAX_ZOMBIES];
new TimerAtaca=-1;
PHP Code:
forward ZombieAtaca(playerid);
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;j< getmaxzombieid();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,pZ3= Z8;
//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));
SetObjectRot( zombie[j][4], z11[4][RelrX],z11[4][RelrY],angle );
if ( (floatabs(pX3-X8) + floatabs(pY3-Y8) + floatabs(pZ3-Z8) )<2.5)
{
if( j != 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(H <= 0.0) return true;
SetPlayerHealthAC(playerid,H-damage);
//lasttouch[playerid] = 1;
return PlaySoundForPlayersInRange(19602, 30, pX,pY,pZ);
}
else
{
new veh,Float:vehp;
veh = GetPlayerVehicleID(playerid);
GetVehicleHealth(veh, vehp);
SetVehicleHealth(veh, vehp-damage);
PlaySoundForPlayersInRange(19401, 30, pX,pY,pZ);
}
return true;
}
PHP Code:
getmaxzombies()
{
new x;
for (new j=0;j<getmaxzombieid();j++)
{
if(usedzombi[j] == 1)x ++;
}
return x;
}
getmaxzombieid()
{
new x = -1;
for (new j=0;j<MAX_ZOMBIES;j++)
{
if(usedzombi[j] == 1)x =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_x, Float:object_y, Float:object_z, Float:temp_z;
GetObjectPos(objectid, object_x, object_y, object_z);
MapAndreas_FindAverageZ(object_x, object_y, temp_z);
if (object_z > temp_z + 2.0 || object_z-1 < temp_z)
{
SetObjectPos(objectid, object_x, object_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(playerid, object_x, object_y, object_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_x, Float:object_y, Float:object_z, Float:temp_z;
GetObjectPos(objectid, object_x, object_y, object_z);
GetPointZPos(object_x, object_y, temp_z);
if (object_z > temp_z + 2.0 || object_z-1 < temp_z)
{
SetObjectPos(objectid, object_x, object_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(playerid, object_x, object_y, object_z);
if (player_dis < min_dis)
{
min_dis = player_dis;
player = playerid;
}
}
return player;
}
PHP Code:
public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float: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", 1000, 6);
}
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(playerid, 6401, 0.0, 0.0, 0.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.01, 1.3, 0.09, 0, 0, 0);
AttachObjectToObject(zombie[j][3],zombie[j][4],-0.1 ,0.25,0.15, 0, 270, 90);
AttachObjectToObject(zombie[j][2],zombie[j][4],0.05, 0.55, -0.032, 0, 270, 0);
AttachObjectToObject(zombie[j][1],zombie[j][4],-0.15, 0.25, -0.19, 0, 90, 90);
AttachObjectToObject(zombie[j][0],zombie[j][4],0, 1.30, -0.10, 0, 0, 0);
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;j< getmaxzombieid();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;j< getmaxzombieid();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;
}
Версия: 0.2
Спасибо за корректировку функции GetClosestPlay: Stepashka