Advertisement
Guest User

Untitled

a guest
Jun 22nd, 2017
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Author: Tab10id
  2.  
  3. #include "_macros.fos"
  4. #define WALK_PERIOD (REAL_SECOND(Random(8,18)))
  5. #define MAXDIST (8) // Максимальное расстояние от HomePos
  6. #define MAXDISTEXT (3) // Максимальное расстояние, на которое может отойти криттер за один раз
  7. #define MAXTRY (10) // Количество попыток найти новую точку назначения
  8. import bool AddWalkPlane(Critter& npc, uint priority, uint16 hexX, uint16 hexY, uint8 dir, bool run, uint cut) from "npc_planes";
  9.  
  10. void _CritInit(Critter& crit, bool firstTime)
  11. {
  12.     uint8 run=0;
  13.     InitWalkRandom(crit, run);
  14.     crit.ModeBase[MODE_NO_HOME]=1; // Отменяем возвращение игрока на HomePos
  15.     crit.SetEvent(CRITTER_EVENT_TALK,"_NpcTalk"); // Обрабатываем попытку игрока заговорить с нпц
  16.     crit.SetEvent(CRITTER_EVENT_PLANE_END,"_PlaneEnd"); // Создаем новое событие для передвижения нпц (нпц дошел до точки назначения)
  17.     crit.SetEvent(CRITTER_EVENT_RESPAWN,"_InitWalk"); // Возобновляем движение после респа
  18.     crit.SetEvent(CRITTER_EVENT_DEAD,"_OnDead"); // Отменяем попытку передвижения, в случае смерти нпц
  19. }
  20.  
  21. void InitWalkRandom(Critter& crit, uint8 run)
  22. {
  23.     if(crit.IsDead())
  24.     {
  25.         return;
  26.     }
  27.     EraseTE(crit);
  28.     crit.AddTimeEvent("cte_WalkRandom",WALK_PERIOD,CTE_WALK_RANDOM,run);
  29. }
  30.  
  31. uint cte_WalkRandom(Critter& crit, int identifier, uint& run)
  32. {
  33.     int incr=0; // Для избегания зацикливания в случае заблокированного пути
  34.     if(!valid(crit))
  35.     {
  36.         return 0;
  37.     }
  38.     if(crit.IsDead())
  39.     {
  40.         return 0;
  41.     }
  42.     Map@ map=crit.GetMap();
  43.     if(!valid(map))
  44.     {
  45.         return 0;
  46.     }
  47.     bool brun = false;
  48.     uint16 x, y, homeX=0, homeY=0, homeM=0, homeD=0;
  49.     uint8 dir;
  50.     crit.GetHomePos(homeM,homeX,homeY,homeD);
  51.     if(run==1)
  52.     {
  53.         brun = true;
  54.     }
  55.     if((int(crit.HexX)<int(homeX)-MAXDIST) or (int(crit.HexX)>int(homeX)+MAXDIST) or (int(crit.HexY)<int(homeY)-MAXDIST) or (int(crit.HexY)>int(homeY)+MAXDIST))
  56.     {
  57.         crit.ModeBase[MODE_NO_HOME]=0; // Заставляем нпц вернуться на HomePos, если он каким-то образом отошел от нее далеко (например, в результате атаки)
  58.     }
  59.     else
  60.     {
  61.         do
  62.         {
  63.             do
  64.             {
  65.                 x=crit.HexX+Random(-MAXDISTEXT,MAXDISTEXT);
  66.             }
  67.             while((x>homeX+MAXDIST) or (x<homeX-MAXDIST));
  68.             do
  69.             {
  70.                 y=crit.HexY+Random(-MAXDISTEXT,MAXDISTEXT);
  71.             }
  72.             while((y>homeY+MAXDIST) or (y<homeY-MAXDIST));
  73.             incr++;
  74.         }
  75.         while(((map.GetPathLength(crit.HexX,crit.HexY,x,y,0)==0) or (map.GetPathLength(crit.HexX,crit.HexY,x,y,0)>MAXDISTEXT)) and (incr<MAXTRY)); // Пытаемся найти новую точку назначения
  76.         if(incr<MAXTRY)
  77.         {
  78.             dir=GetDirection(crit.HexX,crit.HexY,x,y);
  79.             AddWalkPlane(crit, AI_PLANE_WALK_PRIORITY, x, y, dir, brun, 0);
  80.         }
  81.         else
  82.         {
  83.             StartWalkRandom(crit);
  84.         }
  85.     }
  86.     return 0;
  87. }
  88.  
  89. bool _NpcTalk(Critter& crit, Critter& player, bool attach, uint talkCount)
  90. {
  91.     if(attach)
  92.     {
  93.         CancelWalkRandom(crit); // Отменяем все планы на передвижения
  94.         crit.SetDir(GetDirection(crit.HexX,crit.HexY,player.HexX,player.HexY)); // Поворачиваемся лицом к игроку
  95.     }
  96.     else
  97.     {
  98.         StartWalkRandom(crit); // Возобновляем движение
  99.     }
  100.     return true;
  101. }
  102.  
  103. void StartWalkRandom(Critter& crit)
  104. {
  105.     uint8 run=0;
  106. /*  if(crit.ModeBase[MODE_RUN_RANDOM]==1)
  107.     {
  108.         run=1;
  109.     }*/
  110.     if(crit.Mode[MODE_NO_HOME]==0)
  111.     {
  112.         crit.ModeBase[MODE_NO_HOME]=1;
  113.     }
  114.     InitWalkRandom(crit, run);
  115. }
  116.  
  117. void CancelWalkRandom(Critter& crit)
  118. {
  119.     _NpcEraseAllPlanesWalk(crit);
  120.     EraseTE(crit);
  121. }
  122.  
  123. int _PlaneEnd(Critter& crit, NpcPlane& plane, int reason, Critter@ someCr, Item@ someItem)
  124. {
  125.     StartWalkRandom(crit); // Возобновляем движение
  126.     return PLANE_RUN_GLOBAL;
  127. }
  128.  
  129. void _InitWalk(Critter& crit)
  130. {
  131.     uint8 run=0;
  132.     /*if(crit.ModeBase[MODE_RUN_RANDOM]==1)
  133.     {
  134.         run=1;
  135.     }*/
  136.     InitWalkRandom(crit, run); // Возобновляем движение
  137. }
  138.  
  139. void _OnDead(Critter& crit, Critter@ killer)
  140. {
  141.     EraseTE(crit);
  142. }
  143.  
  144. void EraseTE(Critter& crit)
  145. {
  146.     uint[] rates,durations,indexes;
  147.     uint count=crit.GetTimeEvents(CTE_WALK_RANDOM,indexes,durations, rates);
  148.     if(count!=0)
  149.     {
  150.         crit.EraseTimeEvents(CTE_WALK_RANDOM);
  151.     }
  152. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement