// Jumping Stalfos // originally by Colossal // Attributes // 1: How close a sword needs to be, in pixels, for the enemy to jump away. Set to 0 to disable jumping and firing. (24) // 2: The jump value when the enemy jumps away multiplied by 100. (280) // 3: How fast the enemy moves while jumping. (140) // 4: Type of eweapon to fire. See std.zh for values (EW_* constants). Set to 0 to disable firing back. (132 (Sword beam)) // 5: Eweapon speed. (200) // 6: Eweapon sprite. // 7: Sfx when the enemy jumps. // 8: Sfx when the enemy fires back. // 9: Type of Stalfos: 0->stump on Link, 1->jump away // 10: Tile offset for jumping graphics // 11: Set to GH_INVISIBLE_COMBO (1 by default). // 12: Set to the script's slot number. const int STALFOS_ATTACK_WAIT = 8; const int STALFOS_WAITFRAMES = 20; // npc->Attributes[] variables const int STALFOS_SWORD_DISTANCE = 0; const int STALFOS_JUMP = 1; const int STALFOS_JUMP_STEP = 2; const int STALFOS_EW_ID = 3; const int STALFOS_EW_STEP = 4; const int STALFOS_EW_SPRITE = 5; const int STALFOS_JUMPING_SFX = 6; const int STALFOS_FIRING_SFX = 7; const int STALFOS_TYPE = 8; const int STALFOS_JUMPING_TILE_OFFSET = 9; // ffc->Misc[] variables const int STALFOS_ATTACKED = 0; const int STALFOS_JUMP_ANGLE = 1; const int STALFOS_WAIT_TIME = 2; const int STALFOS_ASPEED = 3; const int STALFOS_ORIG_TILE = 4; ffc script LttPStalfos { void run(int enemyID) { npc ghost; bool walking; int step; int haltrate; int homing; // Initialization ghost = Ghost_InitAutoGhost(this, enemyID, GHF_NORMAL | GHF_SET_OVERLAY); haltrate = ghost->Haltrate; homing = ghost->Homing; step = ghost->Step / 100; ghost->Dir = Rand(4); this->Misc[STALFOS_ASPEED] = ghost->ASpeed; this->Misc[STALFOS_ORIG_TILE] = ghost->OriginalTile; while(true) { // Direction and animation if((ghost->Dir <= 1 && (Ghost_Y & 0xF) == 0) || (ghost->Dir >= 2 && (Ghost_X & 0xF) == 0) || !Ghost_CanMove(ghost->Dir, step, 0)) { if(!Ghost_CanMove(ghost->Dir, step, 0) || Rand(16) < haltrate) { ghost->ASpeed = 0; Stalfos_Move(this, ghost, 0, STALFOS_WAITFRAMES); if(Rand(256) < homing) ghost->Dir = AngleDir4(Angle(Ghost_X, Ghost_Y, Link->X, Link->Y)); else ghost->Dir = Rand(4); int newdir = ghost->Dir; while(!Ghost_CanMove(newdir, step, 0)) { newdir = (newdir + 1) & 11b; if(newdir == ghost->Dir) break; } ghost->Dir = newdir; ghost->ASpeed = this->Misc[STALFOS_ASPEED]; Stalfos_Move(this, ghost, step, 1); } } Stalfos_Move(this, ghost, step, 1); } } void Stalfos_Move(ffc this, npc ghost, int step, int frames) { // Movement, jumping, firing, and waitframe for(int i = 0; i < frames; i++) { if(ghost->Attributes[STALFOS_SWORD_DISTANCE] > 0) { // Check for a nearby sword lweapon l = LoadLWeaponOf(LW_SWORD); if(l->isValid()) { if(Distance(l->X + l->HitXOffset, l->Y + l->HitYOffset, Ghost_X, Ghost_Y) <= ghost->Attributes[STALFOS_SWORD_DISTANCE] && Ghost_Z == 0) { this->Misc[STALFOS_ATTACKED] = 1; ghost->ASpeed = 0; Ghost_Jump = ghost->Attributes[STALFOS_JUMP] / 100; Game->PlaySound(ghost->Attributes[STALFOS_JUMPING_SFX]); if(ghost->Attributes[STALFOS_TYPE]==0){ this->Misc[STALFOS_JUMP_ANGLE] = Angle(Link->X, Link->Y, Ghost_X, Ghost_Y); } else if(ghost->Attributes[STALFOS_TYPE]==1){ this->Misc[STALFOS_JUMP_ANGLE] = Angle(Ghost_X, Ghost_Y, Link->X, Link->Y); } this->Misc[STALFOS_WAIT_TIME] = STALFOS_ATTACK_WAIT; ghost->OriginalTile = this->Misc[STALFOS_ORIG_TILE] + ghost->Attributes[STALFOS_JUMPING_TILE_OFFSET]; } } if(Ghost_Z > 0 || Ghost_Jump > 0) { Ghost_ForceDir(AngleDir4(this->Misc[STALFOS_JUMP_ANGLE]) ^ 1b); Ghost_MoveAtAngle(this->Misc[STALFOS_JUMP_ANGLE], ghost->Attributes[STALFOS_JUMP_STEP] / 100, 0); } if(this->Misc[STALFOS_ATTACKED] == 1 && ghost->Z == 0) { if(this->Misc[STALFOS_WAIT_TIME] > 0){ this->Misc[STALFOS_WAIT_TIME]--; } else{ if(ghost->Attributes[STALFOS_EW_ID] > 0) { FireAimedEWeapon(ghost->Attributes[STALFOS_EW_ID], ghost->X, ghost->Y, 0, ghost->Attributes[STALFOS_EW_STEP], ghost->WeaponDamage, ghost->Attributes[STALFOS_EW_SPRITE], ghost->Attributes[STALFOS_FIRING_SFX], EWF_UNBLOCKABLE); } this->Misc[STALFOS_ATTACKED] = 0; ghost->OriginalTile = this->Misc[STALFOS_ORIG_TILE]; } } } if(this->Misc[STALFOS_ATTACKED] == 0 && step > 0) { Ghost_Move(ghost->Dir, step, 0); } // Waitframe if(ghost->Stun == 0) Ghost_Waitframe(this, ghost, true, true); else Ghost_Waitframe2(this, ghost, true, true); } } }
I found this old script in the database from around 2013 it seems, but it has some quirks that I don't know how to fix:
1.- The enemy is not spawned by the "Puff" animation.
2.- After jumping, the enemy "skates" in the direction it's facing until it hits a solid combo, then it starts to walk again.
3.- Attribute 9 detects whether the enemy will stomp or jump away from Link. If set to 0, it will jump away (which works pretty well so far), but if set to 1 (which I think is the stomping part), the enemy does kind of jump towards Link, but it either lands next to him, or lands a bit farther.
However, can the following be added to the script? Instead of the stalfoes jumping when Link uses the sword, I would like for the enemy to react to any kind of weaponry; that way, any kind of equipment Link uses against the stalfos, it should jump or stomp on Link (depending on the setup of course).
Finally, for the stomping part, can it please be edited to act in the following pattern? When Link attacks and the stalfoes jumps towards his direction, the stalfos should last about 30 frames in the air above Link and then stomp him; I remember seeing this behavior in one of the GB Zeldas but I can't recall which was it.
I'll appreciate any given help.