Advertisement
ZoriaRPG

NPC.zh v0.2

Dec 7th, 2018
307
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.82 KB | None | 0 0
  1. //NPC.ZH
  2. //An attempt to port guys.cpp functions to ZScript
  3. //for use by npc scripts
  4.  
  5. //Special Walk Styles //values are arbitrary. -Z
  6. define spw_wizzrobe = 1000;
  7. define spw_floater = 1001;
  8. define spw_door = 1002; //can walk in a doorway
  9. define spw_clipbottomright = 1003; //clip options
  10. define spw_clipright = 1004; //clip options
  11. define spw_halfstep = 1005;
  12. define spw_water = 1006;
  13.  
  14. bool isjumper(npc n)
  15. {
  16.     switch(n->family)
  17.     {
  18.         case NPCT_ROCK:
  19.         case NPCT_TEKTITE:
  20.             return true;
  21.        
  22.         case NPCT_WALK:
  23.             if(n->Attributes[8] == NPCA_WALK_WS_VIRE ) return true;
  24.             else if(n->Attributes[8] == NPCA_WALK_WS_POLSVOICE ) return true;
  25.             return false;
  26.  
  27.         default: return false;
  28.     }
  29. }
  30.  
  31.  
  32. bool isfixedtogrid(npc n)
  33. {
  34.     switch(n->family)
  35.     {
  36.         case NPCT_WALK:
  37.         case NPCT_LEEVER:
  38.         case NPCT_ZORA:
  39.         case NPCT_DODONGO:
  40.         case NPCT_GANON:
  41.         case NPCT_ROCK:
  42.         case NPCT_GLEEOK:
  43.         case NPCT_AQUAMENTUS:
  44.         case NPCT_LANMOLA:
  45.         return true;
  46.    
  47.         default: return false;
  48.     }
  49. }
  50.  
  51. // Can't fall, can have Z value.
  52. bool isflier(npc n)
  53. {
  54.     switch(n->family) //id&0x0FFF)
  55.     {
  56.         case NPCT_PEAHAT:
  57.         case eeKEESE:
  58.         case eePATRA:
  59.         case eeFAIRY:
  60.         case eeGHINI:
  61.    
  62.         // Could theoretically have their Z set by a script
  63.         //case eeFIRE: //this is 'NPCT_OTHER'
  64.             return true;
  65.         default: return false;
  66.  
  67.     }
  68. }
  69.  
  70. bool never_in_air(npc n)
  71. {
  72.     switch(n->family)
  73.     {
  74.         case NPCT_MANHANDLA:
  75.         case NPCT_MOLDORM:
  76.         case NPCT_LANMOLA:
  77.         case NPCT_GLEEOK:
  78.         case NPCT_ZORA:
  79.         case NPCT_LEEVER:
  80.         case NPCT_AQUAMENTUS:
  81.         case NPCT_ROCK:
  82.         case NPCT_GANON:
  83.         case NPCT_TRAP:
  84.         case NPCT_PROJECTILE:
  85.         case NPCT_SPINTILE:
  86.         return true;
  87.        
  88.         default: return false;
  89.     }
  90. }
  91.  
  92. bool canfall(npc n)
  93. {
  94.     /*
  95.     switch(n->amily)
  96.     {
  97.         case eeGUY:
  98.         {
  99.             if(id < eOCTO1S)
  100.             return false;
  101.            
  102.             switch(guysbuf[id&0xFFF].misc10)
  103.             {
  104.                 case 1:
  105.                 case 2:
  106.                 return true;
  107.            
  108.                 case 0:
  109.                 case 3:
  110.                 default:
  111.                 return false;
  112.             }
  113.        
  114.         case eeGHOMA:
  115.         case eeDIG:
  116.             return false;
  117.         }
  118.     }
  119.     */
  120.     if ( never_in_air(n) ) return false;
  121.     if ( isflier(n) ) return false;
  122.     if ( isjumper(n) ) return false;
  123.     return true;
  124. }
  125.  
  126. int COMBOTYPE(int x, int y)
  127. {
  128.     return ( Screen->ComboT[ComboAt(x,y)] );   
  129. }
  130. // Returns true iff a combo type or flag precludes enemy movement.
  131. bool groundblocked(int dx, int dy)
  132. {
  133.     if ( COMBOTYPE(dx,dy)==CT_PIT )
  134.     COMBOTYPE(dx,dy)==CT_PITB
  135.     COMBOTYPE(dx,dy)==CT_PITC
  136.     COMBOTYPE(dx,dy)==CT_PITD
  137.     COMBOTYPE(dx,dy)==CT_PITR
  138.    
  139.     combodata cd = Game->LoadComboData(Screen->ComboT[ComboAt(x,y));
  140.     if ( (cd->BlockNPC&1) ) return true;
  141.    
  142.            // Block enemies type and block enemies flags
  143.            //combo_class_buf[COMBOTYPE(dx,dy)].block_enemies&1 ||
  144.        
  145.     if ( Screen->ComboF[ComboAt(x,y)] == mfNOENEMY ) return true;
  146.     if ( Screen->ComboI[ComboAt(x,y)] == mfNOENEMY ) return true;
  147.     if ( Screen->ComboF[ComboAt(x,y)] == mfNOGROUNDENEMY ) return true;
  148.     if ( Screen->ComboI[ComboAt(x,y)] == mfNOGROUNDENEMY ) return true;
  149.     if ( (cd->Ladder&1) && (cd->Water != 0) ) return true;
  150.     //ADD THIS When we can read QRs by script.
  151.     //if ( GetFFRule(qr_DROWN) && !isSideView() && (cd->Water != 0)  ) return true;
  152.    
  153.            // Check for ladder-only combos which aren't dried water
  154.            //(combo_class_buf[COMBOTYPE(dx,dy)].ladder_pass&1 && !iswater_type(COMBOTYPE(dx,dy))) ||
  155.            // Check for drownable water
  156.            //(get_bit(quest_rules,qr_DROWN) && !(tmpscr->flags7&fSIDEVIEW) && (iswater(MAPCOMBO(dx,dy))));
  157. }
  158.  
  159.  
  160. bool m_walkflag(int dx,int dy,int special, int x, int y) //int x=-1000, int y=-1000)
  161. {
  162.     int yg = 0;
  163.     if ( special==spw_floater ) yg = 8
  164.  
  165.     //When we can read quest rules by script.
  166.     int nb = 16;
  167.     //int nb = get_bit(quest_rules, qr_NOBORDER) ? 16 : 0;
  168.    
  169.     if( dx < 16-nb ) return true;
  170.     if ( dy < Max(16-yg-nb,0) ) return true;
  171.     if ( dx >= 240 + nb ) return true;
  172.     if ( dy >= 160 + nb ) return true;
  173.        
  174.     if(IsDungeon() || special==spw_wizzrobe)
  175.     {
  176.         if((x>=32 && dy<32-yg) || (y>-1000 && y<=144 && dy>=144))
  177.             return true;
  178.            
  179.         if((x>=32 && dx<32) || (x>-1000 && x<224 && dx>=224))
  180.             if(special!=spw_door) // walk in door way
  181.                 return true;
  182.     }
  183.    
  184.     switch(special)
  185.     {
  186.         case spw_clipbottomright:
  187.             if(dy>=128 || dx>=208) return true;
  188.        
  189.         case spw_clipright:
  190.             break; //if(x>=208) return true; break;
  191.        
  192.         case spw_wizzrobe: // fall through
  193.         case spw_floater: // Special case for fliers and wizzrobes - hack!
  194.         {
  195.             if(IsDungeon())
  196.             {
  197.                 if(dy < 32-yg || dy >= 144) return true;
  198.                 if(dx < 32 || dx >= 224) return true;
  199.             }
  200.             return false;
  201.         }
  202.         default: break;
  203.     }
  204.    
  205.     if ( special==spw_halfstep ) dx &= ~7;
  206.     else dx &= ~15;
  207.     //dx&=(special==spw_halfstep)?(~7):(~15);
  208.     if ( special==spw_halfstep || isSideView() ) dy &= ~7;
  209.     else dy &= ~15;
  210.     //dy&=(special==spw_halfstep || tmpscr->flags7&fSIDEVIEW)?(~7):(~15);
  211.    
  212.    
  213.     //water-WALKFLAG IS TOO COMPLEX for me to implement right now, so I'm skipping this.
  214.     //if(special==spw_water)
  215.     //    return (water_walkflag(dx,dy+8,1) || water_walkflag(dx+8,dy+8,1));
  216.     if ( Screen->ComboS[ComboAt(dx,dy+8)] ) return true;
  217.     if ( Screen->ComboS[ComboAt(dx+8,dy+8)] ) return true;
  218.     //return _walkflag(dx,dy+8,1) || _walkflag(dx+8,dy+8,1) ||
  219.     if ( groundblocked(dx,dy+8) ) return true;
  220.     if ( groundblocked(dx+8,dy+8) ) return true;
  221.     return false;
  222.    
  223. }
  224.  
  225. // Returns true iff enemy is floating and blocked by a combo type or flag.
  226. bool flyerblocked(int dx, int dy, int special)
  227. {
  228.     combodata cd = Game->LoadComboData(Screen->ComboD[ComboAt(dx,dy)]);
  229.     if (special==spw_floater)
  230.     {
  231.         if ( COMBOTYPE(dx,dy)==cNOFLYZONE ) return true;
  232.         if ( (cd->BlockNPC&4) ) return true;
  233.         if ( Screen->ComboF[ComboAt(dx,dy)] == mfNOENEMY ) return true;
  234.         if ( Screen->ComboI[ComboAt(dx,dy)] == mfNOENEMY ) return true;
  235.        
  236.     }
  237.     return false;
  238. }
  239.  
  240. bool tooclose(int x,int y,int max_dist)
  241. {
  242.     if (abs(Link->X-x)< max_dist )
  243.     {
  244.         if ( abs(Link->Y-y) < max_dist ) return true;
  245.     }
  246.     return false;
  247. }
  248.  
  249.  
  250. ///////////////
  251.  
  252.  
  253.  
  254. // returns true if next step is ok, false if there is something there
  255. bool canmove(npc n, int ndir, float step,int special,int dx1,int dy1,int dx2,int dy2)
  256. {
  257.     bool ok;
  258.     int dx = 0, dy = 0;
  259.     int sv = 8;
  260.    
  261.     step += 0.5; // Make the ints round; doesn't seem to cause any problems.
  262.    
  263.     switch(ndir)
  264.     {
  265.     case 8:
  266.     case DIR_UP:
  267.         if(canfall(id) && tmpscr->flags7&fSIDEVIEW)
  268.             return false;
  269.            
  270.         dy = dy1-step;
  271.         special = (special==spw_clipbottomright)?spw_none:special;
  272.         ok = !m_walkflag(n->X,n->Y+dy,special, n->X, n->Y) && !flyerblocked(n->X,n->Y+dy, special);
  273.         break;
  274.        
  275.     case 12:
  276.     case DIR_DOWN:
  277.         if(canfall(id) && tmpscr->flags7&fSIDEVIEW)
  278.             return false;
  279.            
  280.         dy = dy2+step;
  281.         ok = !m_walkflag(n->X,n->Y+dy,special, n->X, n->Y) && !flyerblocked(n->X,n->Y+dy, special);
  282.         break;
  283.        
  284.     case 14:
  285.     case DIR_LEFT:
  286.         dx = dx1-step;
  287.         sv = ((tmpscr->flags7&fSIDEVIEW)?7:8);
  288.         special = (special==spw_clipbottomright||special==spw_clipright)?spw_none:special;
  289.         ok = !m_walkflag(n->X+dx,n->Y+sv,special, n->X, n->Y) && !flyerblocked(n->X+dx,n->Y+8, special);
  290.         break;
  291.        
  292.     case 10:
  293.     case DIR_RIGHT:
  294.         dx = dx2+step;
  295.         sv = ((tmpscr->flags7&fSIDEVIEW)?7:8);
  296.         ok = !m_walkflag(n->X+dx,n->Y+sv,special, n->X, n->Y) && !flyerblocked(n->X+dx,n->Y+8, special);
  297.         break;
  298.        
  299.     case 9:
  300.     case DIR_RIGHTUP:
  301.         dx = dx2+step;
  302.         dy = dy1-step;
  303.         ok = !m_walkflag(n->X,n->Y+dy,special, n->X, n->Y) && !m_walkflag(n->X+dx,n->Y+sv,special, n->X, n->Y) &&
  304.              !flyerblocked(n->X,n->Y+dy, special) && !flyerblocked(n->X+dx,n->Y+8, special);
  305.         break;
  306.        
  307.     case 11:
  308.     case r_down:
  309.         dx = dx2+step;
  310.         dx = dy2+step;
  311.         ok = !m_walkflag(n->X,n->Y+dy,special, n->X, n->Y) && !m_walkflag(n->X+dx,n->Y+sv,special, n->X, n->Y) &&
  312.              !flyerblocked(n->X,n->Y+dy, special) && !flyerblocked(n->X+dx,n->Y+8, special);
  313.         break;
  314.        
  315.     case 13:
  316.     case DIR_LEFTDOWN:
  317.         dx = dx1-step;
  318.         dy = dy2+step;
  319.         ok = !m_walkflag(n->X,n->Y+dy,special, n->X, n->Y) && !m_walkflag(n->X+dx,n->Y+sv,special, n->X, n->Y) &&
  320.              !flyerblocked(n->X,n->Y+dy, special) && !flyerblocked(n->X+dx,n->Y+8, special);
  321.         break;
  322.        
  323.     case 15:
  324.     case DIR_LEFTUP:
  325.         dx = dx1-step;
  326.         dy = dy1-step;
  327.         ok = !m_walkflag(n->X,n->Y+dy,special, n->X, n->Y) && !m_walkflag(n->X+dx,n->Y+sv,special, n->X, n->Y) &&
  328.              !flyerblocked(n->X,n->Y+dy, special) && !flyerblocked(n->X+dx,n->Y+8, special);
  329.         break;
  330.        
  331.     default:
  332.         db=99;
  333.         return true;
  334.     }
  335.    
  336.     return ok;
  337. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement