// There is no custom link action - fall back on Link->Action. const int CLA_NONE = 0; // Link is pounding with a hammer. const int CLA_POUND = 1; // Link is stabbing. const int CLA_STAB = 2; // Link is throwing. const int CLA_THROW = 3; // Link is slashing. const int CLA_SLASH = 4; // Link is recovering. const int CLA_RECOVER = 5; //// Pound Constants // Start of 8 tiles for link pounding. The animation is 2 tiles long. const int CLA_POUND_TILE = 38442; // Pound total duration. const int CLA_POUND_DURATION = 16; // Tick on which link switches to the next frame. const int CLA_POUND_LINK_ADV1 = 6; // Tick on which item switches to the next frame. const int CLA_POUND_ITEM_ADV1 = 6; const int CLA_POUND_ITEM_ADV2 = 7; // Tick on which the strike hits. const int CLA_POUND_HIT = 7; //// Stab Constants // Start of 4 tiles for link stabbing. const int CLA_STAB_TILE = 38452; // Stab total duration. const int CLA_STAB_DURATION = 12; //// Throw Constants // Start of 4 tiles for Link throwing. const int CLA_THROW_TILE = 38452; // Throw total duration. const int CLA_THROW_DURATION = 6; //// Slash Constants // Start of 12 tiles for link slashing. const int CLA_SLASH_TILE = 38462; // Tick on which link switches to the next frame. const int CLA_SLASH_ADV1 = 4; const int CLA_SLASH_ADV2 = 8; // Slash total duration. const int CLA_SLASH_DURATION = 12; // The current custom link action. int CLA_Action = CLA_NONE; // The current animation id for link. int CLA_LinkAnimationId = LWEAPON_ID_NULL; // The number of frames the current action has been happening. int CLA_Frames = 0; // Timer for custom durations. int CLA_Timer = 0; //// Info for the item being used to read. // The current item location. int CLA_ItemX = 0; int CLA_ItemY = 0; // The current item frame offset. int CLA_ItemFrame = 0; // If the weapon is striking during this frame. bool CLA_Strike = false; // Test for standard actions that we can override. bool CLA_CanAct() { return CLA_Action == CLA_NONE && (Link->Action == LA_NONE || Link->Action == LA_WALKING || Link->Action == LA_GOTHURTLAND);} // Make the animation base. lweapon CLA_CreateAnimationBase() { lweapon base = Screen->CreateLWeapon(LW_ANIMATION2); base->DeadState = -2; base->CollDetection = false; base->Behind = true; base->Frame = 0; base->NumFrames = 9999; base->ASpeed = 3600; return base;} // Update running custom link action. Just calls the respective update // method for each action. void CLA_Update() { if (CLA_Action == CLA_POUND) {CLA_UpdatePound();} else if (CLA_Action == CLA_STAB) {CLA_UpdateStab();} else if (CLA_Action == CLA_SLASH) {CLA_UpdateSlash();} else if (CLA_Action == CLA_THROW) {CLA_UpdateThrow();} else if (CLA_Action == CLA_RECOVER) {CLA_UpdateRecover();}} // Pound with an item. void CLA_Pound() { // Only works if we're not doing anything else. if (!CLA_CanAct()) {return;} CLA_Action = CLA_POUND; BlockInput(KEY_DIR, CLA_POUND_DURATION); // Setup Link's animation. Link->Invisible = true; lweapon animation = CLA_CreateAnimationBase(); animation->OriginalTile = CLA_POUND_TILE; animation->CSet = 6; CLA_LinkAnimationId = GetId(animation); CLA_Frames = -1; CLA_UpdatePound();} // Stab with an item. void CLA_Stab() { // Only works if we're not doing anything else. if (!CLA_CanAct()) {return;} CLA_Action = CLA_STAB; BlockInput(KEY_DIR, CLA_STAB_DURATION); // Steup Link's animation. Link->Invisible = true; lweapon animation = CLA_CreateAnimationBase(); animation->OriginalTile = CLA_STAB_TILE; animation->CSet = 6; CLA_LinkAnimationId = GetId(animation); CLA_Frames = -1; CLA_UpdateStab();} // Slash with an item. void CLA_Slash() { // Only works if we're not doing anything else. if (!CLA_CanAct()) {return;} CLA_Action = CLA_SLASH; BlockInput(KEY_DIR, CLA_SLASH_DURATION); // Steup Link's animation. Link->Invisible = true; lweapon animation = CLA_CreateAnimationBase(); animation->OriginalTile = CLA_SLASH_TILE; animation->CSet = 6; CLA_LinkAnimationId = GetId(animation); CLA_Frames = -1; CLA_UpdateSlash();} void CLA_Throw() { // Only works if we're not doing anything else. if (!CLA_CanAct()) {return;} CLA_Action = CLA_THROW; BlockInput(KEY_DIR, CLA_THROW_DURATION); // Steup Link's animation. Link->Invisible = true; lweapon animation = CLA_CreateAnimationBase(); animation->OriginalTile = CLA_THROW_TILE; animation->CSet = 6; CLA_LinkAnimationId = GetId(animation); CLA_Frames = -1; CLA_UpdateThrow();} void CLA_Recover(int duration) { // Only works if we're not doing anything else. if (!CLA_CanAct()) {return;} CLA_Action = CLA_RECOVER; BlockInput(KEY_DIR, duration); CLA_Frames = -1; CLA_Timer = duration + 1; CLA_UpdateRecover();} void CLA_UpdatePound() { Link->Action = LA_ATTACKING; CLA_Frames++; // Update link animation. lweapon animation = FindLWeapon(CLA_LinkAnimationId); animation->DrawXOffset = Link->X; animation->DrawYOffset = Link->Y; animation->Frame = Link->Dir * 2 + Cond(CLA_Frames >= CLA_POUND_LINK_ADV1, 1, 0); animation->Tile = animation->OriginalTile + animation->Frame; // Update item info. if (CLA_Frames >= CLA_POUND_ITEM_ADV2) { CLA_ItemX = DirX(Link->Dir) * 16 + Link->X; CLA_ItemY = DirY(Link->Dir) * 16 + Link->Y; CLA_ItemFrame = 2;} else if (CLA_Frames >= CLA_POUND_ITEM_ADV1) { if (Link->Dir >= DIR_LEFT) { CLA_ItemX = DirX(Link->Dir) * 12 + Link->X; CLA_ItemY = Link->Y - 4;} else { CLA_ItemX = Link->X; CLA_ItemY = 16 * (Link->Dir - 1) + Link->Y;} CLA_ItemFrame = 1;} else { CLA_ItemX = Link->X; CLA_ItemY = Link->Y - 14; CLA_ItemFrame = 0;} CLA_Strike = CLA_Frames == CLA_POUND_HIT; // Exit out if we need to. if (CLA_Frames >= CLA_POUND_DURATION) { Remove(animation); Link->Action = LA_NONE; CLA_Action = CLA_NONE; Link->Invisible = false;}} void CLA_UpdateStab() { Link->Action = LA_ATTACKING; CLA_Frames++; lweapon animation = FindLWeapon(CLA_LinkAnimationId); animation->DrawXOffset = Link->X; animation->DrawYOffset = Link->Y; animation->Frame = Link->Dir; animation->Tile = animation->OriginalTile + animation->Frame; // Item Info. int offset = 14; if (CLA_Frames < 2) {offset = 10 + CLA_Frames * 2;} else if (CLA_Frames > CLA_STAB_DURATION - 2) { offset = 10 + (CLA_STAB_DURATION - CLA_Frames) * 2;} CLA_ItemX = offset * DirX(Link->Dir) + Link->X; CLA_ItemY = offset * DirY(Link->Dir) + Link->Y; // Exit if needed. if (CLA_Frames >= CLA_STAB_DURATION) { Remove(animation); Link->Action = LA_NONE; CLA_Action = CLA_NONE; Link->Invisible = false;}} void CLA_UpdateThrow() { Link->Action = LA_ATTACKING; CLA_Frames++; lweapon animation = FindLWeapon(CLA_LinkAnimationId); animation->DrawXOffset = Link->X; animation->DrawYOffset = Link->Y; animation->Frame = Link->Dir; animation->Tile = animation->OriginalTile + animation->Frame; // Item Info. int offset = 8; CLA_ItemX = offset * DirX(Link->Dir) + Link->X; CLA_ItemY = offset * DirY(Link->Dir) + Link->Y; // Exit if needed. if (CLA_Frames >= CLA_THROW_DURATION) { Remove(animation); Link->Action = LA_NONE; CLA_Action = CLA_NONE; Link->Invisible = false;}} void CLA_UpdateSlash() { Link->Action = LA_ATTACKING; CLA_Frames++; // Update link animation. lweapon animation = FindLWeapon(CLA_LinkAnimationId); animation->DrawXOffset = Link->X; animation->DrawYOffset = Link->Y; animation->Frame = Link->Dir * 3 + Cond(CLA_Frames >= CLA_SLASH_ADV1, 1, 0) + Cond(CLA_Frames >= CLA_SLASH_ADV2, 1, 0); animation->Tile = animation->OriginalTile + animation->Frame; // Update item info. if (CLA_Frames >= CLA_SLASH_ADV2) { CLA_ItemFrame = 2; if (Link->Dir == DIR_UP) { CLA_ItemX = Link->X - 8; CLA_ItemY = Link->Y - 8;} else if (Link->Dir == DIR_DOWN) { CLA_ItemX = Link->X + 8; CLA_ItemY = Link->Y + 8;} else if (Link->Dir == DIR_LEFT) { CLA_ItemX = Link->X - 8; CLA_ItemY = Link->Y + 8;} else if (Link->Dir == DIR_RIGHT) { CLA_ItemX = Link->X + 8; CLA_ItemY = Link->Y + 8;}} else if (CLA_Frames >= CLA_SLASH_ADV1) { CLA_ItemX = DirX(Link->Dir) * 14 + Link->X; CLA_ItemY = DirY(Link->Dir) * 14 + Link->Y; CLA_ItemFrame = 1;} else { CLA_ItemFrame = 0; if (Link->Dir == DIR_UP) { CLA_ItemX = Link->X + 8; CLA_ItemY = Link->Y - 8;} else if (Link->Dir == DIR_DOWN) { CLA_ItemX = Link->X - 8; CLA_ItemY = Link->Y + 8;} else if (Link->Dir == DIR_LEFT) { CLA_ItemX = Link->X - 8; CLA_ItemY = Link->Y - 8;} else if (Link->Dir == DIR_RIGHT) { CLA_ItemX = Link->X + 8; CLA_ItemY = Link->Y - 8;}} CLA_Strike = true; // Exit out if we need to. if (CLA_Frames >= CLA_SLASH_DURATION) { Remove(animation); Link->Action = LA_NONE; CLA_Action = CLA_NONE; Link->Invisible = false;}} void CLA_UpdateRecover() { CLA_Timer--; if (CLA_Timer <= 0) { CLA_Action = CLA_NONE;}} // Make sure we don't get permanently stuck somehow. void CLA_Continue() { CLA_Action = CLA_NONE;}