Advertisement
ZoriaRPG

Daira (AutoGhost, Classic.zh)

Mar 7th, 2019
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.64 KB | None | 0 0
  1. //Used by Daira and Lizalfos "Mace only"
  2. //Type: Other
  3. //Animation: 4-Frame 4 Direction
  4. //Attr 1: And the numbers below for abilities
  5. //1 throws weapon
  6. //2 reduced knockback "I gave my Lizalfos this, it is optional"
  7. //4 shielded "Lizalfos have shields, it is optional. See SPINATTACK_SHIELD_OVERRIDE constant below for info"
  8. //Attr 11: GH_INVISIBLE_COMBO "-1 by default"
  9. //Attr 12: Script slot number with daira
  10. //Step speed, random rate, homing factor, & hunger are used.
  11.  
  12. //Melee weapons arranged in the right 4 columns in up down left right for each respective row of animation.
  13. //Thrown weapons are on the last row beneath the enemy sprites and use 4 frames and need a custom sprite made.
  14. //Scripted weapons are used for melee and beams are used for ranged.
  15.  
  16. //PROTIP: COPY THE SPRITES FROM THE ZELDA AWAKENING ENEMY SHEET AND USE THOSE AS A BASE FOR YOUR EDITS!
  17. //This is shared by Lizalfos, Ironknuckels, Fokkas, and DairaLizalfos
  18. const int SPINATTACK_SHIELD_OVERRIDE = 0; //if this on the spin attack will ignore the enemies shields.
  19.  
  20. ffc script Daira
  21. {
  22.     void run(int enemyID)
  23.     {
  24.         //Init
  25.         npc ghost;
  26.         ghost = Ghost_InitAutoGhost(this, enemyID);
  27.  
  28.         //Flags
  29.         Ghost_SetFlag(GHF_NORMAL);
  30.         if(ghost->Attributes[0]&2)
  31.             Ghost_SetFlag(GHF_REDUCED_KNOCKBACK);
  32.  
  33.         //Original Tile
  34.         int OTile = ghost->OriginalTile;
  35.  
  36.         //Movement Variables
  37.         float counter = -1;
  38.         int step = ghost->Step;
  39.         int rate = ghost->Rate;
  40.         int homing = ghost->Homing;
  41.         int hunger = ghost->Hunger;
  42.        
  43.         //Weapon Variables
  44.         eweapon wpn;
  45.         int damage = ghost->WeaponDamage;
  46.         int attackTimer;
  47.         int attackWait; //Time between swings.
  48.         bool throw = (ghost->Attributes[0]&1);
  49.         bool shielded = ghost->Attributes[0]&4;
  50.         int wSprite = Ghost_GetAttribute(ghost,1,-1);
  51.  
  52.         //Behavior
  53.         while(true)
  54.         {
  55.             //Movement
  56.             counter = Ghost_ConstantWalk4(counter, step, rate, homing, hunger);
  57.  
  58.             //Attacking
  59.             if(Distance(Link->X, Link->Y, Ghost_X, Ghost_Y) < 80 && attackTimer==0) //Attacks when close to Link.
  60.             {
  61.                 attackWait--;
  62.                 if(attackWait<=0)
  63.                 {
  64.                     attackTimer = 21;
  65.                     attackWait = 60;
  66.                 }
  67.             }
  68.  
  69.             if(attackTimer>0) //Attacking?
  70.             {
  71.                 if(ghost->OriginalTile == OTile)
  72.                 {
  73.                     wpn = FireNonAngularEWeapon(EW_SCRIPT1, Ghost_X, Ghost_Y, -1, 0, damage, 0, 0, NULL);
  74.                     SetEWeaponLifespan(wpn, EWL_TIMER, 21);
  75.                     SetEWeaponDeathEffect(wpn, EWD_VANISH, 0);
  76.                     wpn->CSet = Ghost_CSet;
  77.                 }
  78.                 else if(!wpn->isValid())
  79.                 {
  80.                     ghost->OriginalTile = OTile;
  81.                     DairaLizalfos_Waitframe(this,ghost,shielded);
  82.                     attackTimer = 0;
  83.                     continue;
  84.                 }
  85.                 ghost->OriginalTile = OTile + 20*Div(28-attackTimer, 7);
  86.                 wpn->Tile = ghost->OriginalTile+Ghost_Dir+16;
  87.                 wpn->X = Ghost_X;
  88.                 wpn->Y = Ghost_Y;
  89.                 wpn->DeadState = WDS_ALIVE;
  90.                 if(attackTimer>14)
  91.                 {
  92.                     if((Ghost_Dir == DIR_UP || Ghost_Dir == DIR_DOWN))
  93.                         wpn->Y -= 16;
  94.                     else wpn->X -= InFrontX(Ghost_Dir, 0);
  95.                 }
  96.                 else if(attackTimer>7)
  97.                 {
  98.                     if(Ghost_Dir == DIR_UP || Ghost_Dir == DIR_DOWN)
  99.                     {
  100.                         if(Ghost_Dir == DIR_UP || Ghost_FlagIsSet(GHF_REDUCED_KNOCKBACK))
  101.                         wpn->Y -= 16;
  102.                     }
  103.                     else
  104.                     {
  105.                         wpn->X += InFrontX(Ghost_Dir, 0);
  106.                     }
  107.                 }
  108.                 else
  109.                 {
  110.                     wpn->X += InFrontX(Ghost_Dir,0);
  111.                     wpn->Y += InFrontY(Ghost_Dir,0);
  112.                 }
  113.                 //the weapon hit boxes are small.
  114.                 SetWpnHitOffsets(wpn, Ghost_FlagIsSet(GHF_REDUCED_KNOCKBACK), Div(28-attackTimer, 7), Ghost_Dir);
  115.                 attackTimer--;
  116.             }
  117.             else if(wpn->isValid())
  118.             {
  119.                 ghost->OriginalTile = OTile;
  120.                 if(throw)
  121.                 {
  122.                     eweapon e = FireNonAngularEWeapon(EW_BEAM, wpn->X, wpn->Y, Ghost_Dir, 200, damage, wSprite, -1, NULL);
  123.                     e->OriginalTile = ghost->OriginalTile + 80 + (Ghost_Dir*4);
  124.                     e->CSet = Ghost_CSet;
  125.                 }
  126.             }
  127.             if(!DairaLizalfos_Waitframe(this,ghost,shielded))
  128.             {
  129.                 if(wpn->isValid())
  130.                     wpn->DeadState = WDS_DEAD;
  131.                     Quit();
  132.             }
  133.         }
  134.     }
  135.     void SetWpnHitOffsets(eweapon wpn, bool lizalfos, int frame, int dir)
  136.     {
  137.         //Set Default Collision Properties
  138.         wpn->CollDetection = true;
  139.         wpn->HitXOffset = 0;
  140.         wpn->HitYOffset = 0;
  141.         wpn->HitWidth = 16;
  142.         wpn->HitHeight = 16;
  143.  
  144.         //Modify it based off attack frame.
  145.         if(frame == 1)
  146.         {
  147.             if(dir == DIR_UP || dir == DIR_DOWN)
  148.             {
  149.                 wpn->CollDetection = false;
  150.                 return;
  151.             }
  152.             else
  153.                 wpn->HitWidth = 8;
  154.             if(dir == DIR_RIGHT)
  155.                 wpn->HitXOffset = 8;
  156.         }
  157.         else if(frame == 2)
  158.         {
  159.             if(dir == DIR_UP || dir==DIR_DOWN)
  160.             {
  161.                 if(lizalfos) wpn->HitYOffset = 8;
  162.                 wpn->HitHeight = 8;
  163.                 return;
  164.             }
  165.             else
  166.                 wpn->HitWidth = 8;
  167.             if(dir == DIR_LEFT)
  168.             wpn->HitXOffset = 8;
  169.         }
  170.         else if(frame == 3)
  171.         {
  172.             wpn->HitXOffset = Cond(dir==DIR_LEFT, 8, 0);
  173.             wpn->HitYOffset = Cond(dir==DIR_UP, 8, 0);
  174.             wpn->HitWidth = Cond(dir==DIR_LEFT||dir==DIR_RIGHT, 8, 16);
  175.             wpn->HitHeight = Cond(dir==DIR_UP||dir==DIR_DOWN, 8, 16);
  176.         }
  177.         else //Out of range.
  178.         {
  179.             wpn->DeadState = WDS_DEAD;
  180.             return;
  181.         }
  182.     }
  183.     bool DairaLizalfos_Waitframe(ffc this, npc ghost, bool shielded)
  184.     {
  185.         if(shielded) return Shielded_Waitframe(this,ghost,true,true);
  186.         else return Ghost_Waitframe(this,ghost,true,false);
  187.     }
  188.     bool Shielded_Waitframe(ffc this, npc ghost, bool clearondeath, bool quitondeath)
  189.     {
  190.         if(Link->Action==LA_SPINNING && SPINATTACK_SHIELD_OVERRIDE)
  191.         {
  192.             ghost->Defense[NPCD_SWORD]=NPCDT_IGNORE;
  193.             lweapon sword = LoadLWeaponOf(LW_SWORD);
  194.             if(sword->isValid() && Collision(ghost,sword))
  195.             {
  196.                 Ghost_HP-=sword->Damage;
  197.                 Ghost_StartFlashing();
  198.                 Game->PlaySound(SFX_EHIT);
  199.             }
  200.         }
  201.         else
  202.             ghost->Defense[NPCD_SWORD]=NPCDT_NONE;
  203.         return Ghost_Waitframe(this,ghost,clearondeath,quitondeath);
  204.     }
  205. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement