Sideview Castlevania-styled staircases
#31
Posted 31 July 2013 - 01:31 AM
Alucard also has issues with whistle wraps, where using the whistle whirlwind warps directly back to the screen on which it was used. Could that be due to the screen movement and side-warp portions of this script?
#32
Posted 31 July 2013 - 07:34 AM
Also Link is able to move after being trapped by LikeLikes which causes many bugs.
#33
Posted 01 August 2013 - 12:51 AM
For the record, I don't know what is causing that. Whatever it is, this is the exact effect:
1> Link is captured by the LikeLike.
2> Link flashes, and can move outside the Likelike. Link remains in a flickering state, as if a clock item was in effect.
3> Attacking from anywhere on the screen causes the current weapon to hit the LikeLike, both visually, and actually. Link can be six tiles away, facing in the wrong direction, then swing his sword, and the sword's Misc. Gfx tile appears inside the LikeLike, and hits it.
4> The LikeLike dies, else Link Leave the screen and the glitch ends.
That is, if the LikeLike dies, the flickering and weapon glitch ends at that second. It does not persist on the screen without leaving if Link kills the LikeLike.
Further, the LikeLike is invisible in screenshots!
I would actually love to know what is causing this, and be able to replicate it (when desired) or LWeapons.
It may be due to some kind of script conflict, as it did not exist until after I reordered the scripts, and added Ghost, and other active global functions. I would think that it must be in the active global script, as it is a persistent effect.
In addition, I would like to know why Input_Update2(); is disabled in the global active script, as this would seem to fix one of my issues with movement on stairs. Did it cause problems?
Edited by ZoriaRPG, 01 August 2013 - 08:51 AM.
#34
Posted 03 August 2013 - 12:06 AM
The current link is now updated to fix that bug and adds the AdjustLinkJump item script. Just set it as the item's pickup script. The first argument is the normal jump speed (-4 to start with), the second is your jump speed when holding down (normally -1).
If you want to adjust how far you have to move before you're 'off' the stairs, just adjust lines 661 and 662 as needed. They set the x position interval for which you're still considered 'on' the stairs.
With the LikeLikes, it's simply that the custom movement script doesn't know you've been hit by a LikeLike and lets you keep moving. I don't know of any way in code to tell if you've been hit by a LikeLike, so I'm kind of stuck on what to do. I could probably script a full ghosted LikeLike, but that sounds really painful. We really need onHitLink scripts for normal enemies.
Yeah, I think I remember Input_Update2() breaking things. You're welcome to try it, though. It might work fine now.
#35
Posted 03 August 2013 - 03:47 AM
I'm posting this in the thread for the sake of thread and script preservation. (I'm not sure why people post these off-site in the first place.)
import "std.zh" //////////////////////////////////////////////////////////////// //// Engine Constants. // Combo Flag for soft platforms. const int CF_SOFT = 98; //// Block Types. // An empty block. const int BLOCK_EMPTY = 0; // A fallthrough block. const int BLOCK_SOFT = 1; // A standard block. const int BLOCK_HARD = 2; //// Stair combo types. const int CT_NEG = 142; const int CT_CROSS = 143; const int CT_POS = 144; //// Custom Engine Constants. // Link's walk speed. const float LINK_WALK = 1.5; // Link's gravitic acceleration. const float LINK_GRAV = 0.16; // Link's terminal velocity. const float LINK_TERM = 3.2; //////////////////////////////////////////////////////////////// //// Global Variables //////////////// //// Link's State //// How to handle Link's movement. // We're letting the ZC engine handle movement. const int LINK_MODE_ENGINE = 0; // We're dealing with Link's movement ourselves. const int LINK_MODE_CUSTOM = 1; // We're moving link accourding to the stair system. const int LINK_MODE_STAIR = 2; // Link's current movement mode. int LinkMode = LINK_MODE_ENGINE; // Link's Location. This is so we can have fractional movement. float LinkX = 0; float LinkY = 0; // Link's Vertical Velocity. float LinkVy = 0; // What Link is standing on. int LinkBlock = BLOCK_HARD; // Link's jump speed. float LinkJump = -4; // Link's hop speed. float LinkHop = -1; //// Fake input since we're cancelling it. bool InputJump = false; bool PressJump = false; //// Various parts of Link's state from last frame. // Link's Position. float OldLinkX = 0; float OldLinkY = 0; int OldLinkAction = LA_NONE; //// Stair State. // On a down-left up-right stair. const int STAIR_NEG = -1; // Not on any stairs. const int STAIR_NONE = 0; // On an up-left down-right stair. const int STAIR_POS = 1; //// Stair Positioning - where we are on a stair. // We're in the middle of the stair. const int STAIR_MIDDLE = 0; // We're anchored to the side of a stair. const int STAIR_BOTTOM = 1; // We're anchored to a stair diagonally. const int STAIR_TOP = 2; // The current kind of stair that Link is standing on. int StairMode = STAIR_NONE; // If the stairs were mounted this frame. bool StairMount = false; // The combo position fo the stair that Link is anchored to. int StairLoc = -1; // Where we are on the stair. int StairPos = STAIR_MIDDLE; // The x position of the edge of the stairs. int StairEdgeX = -1; // The left edge of the stairs that Link is on. int StairLeft = 0; // The right edge of the stairs that Link is on. int StairRight = 0; // If the anchored stair has another above it. bool StairAbove = false; // If the anchored stair has another below it. bool StairBelow = false; // The y offset of the current stair. int StairY = 0; //////////////// //// Screen Change //// Screen State on the previous frame. // DMap from last frame. int OldDMap = -1; // DMap Screen from last frame. int OldDScreen = -1; // If the dmap has changed from the last frame. bool DMapChanged = false; // If the screen has changed from the last frame. bool ScreenChanged = false; // Used so that ScreenChanged is only set on the first frame // of a scrolling screen change. bool _ScreenChanged_ScrollFlag = false; // The ScreenChange FFC sets this so that maze screens can be used. bool _ScreenChanged_ForceFlag = false; // If the screen change has been handled by custom code. bool ScreenChangeHandled = true; // We're pretty sure that the screen change was caused by a warp of // some sort. const int SCREEN_CHANGE_WARP = -1; // Best guess for which direction we changed screens in // based on Link's current position. int ScreenChangeDir = SCREEN_CHANGE_WARP; global script Active { void run() { LinkX = Link->X; LinkY = Link->Y; while (true) { OldLink_Update1(); ScreenChange_Update1(); Stair_Update1(); Input_Update1(); //Input_Update2(); // Performs Game Logic. Waitdraw(); ScreenChange_Update2(); DetermineLinkMode(); // If we're not using custom movement, update Link's positioning // variables to match whatever the engine says. if (LinkMode == LINK_MODE_ENGINE) { LinkX = Link->X; LinkY = Link->Y;} // Perform custom movement. if (LinkMode == LINK_MODE_CUSTOM) { StairMode = STAIR_NONE; LinkCustomOnScreenChange(); LinkCustomUpdatePosition(); LinkCustomJump(); LinkCustomMountStair();} // We could possibly switch to stair movement at this point. if (LinkMode == LINK_MODE_STAIR) { Link->Jump = 0; LinkStairOnScreenChange(); LinkStairFindStair(); LinkStairFallOff();} // And away from it at this point. if (LinkMode == LINK_MODE_STAIR) { LinkStairUpdatePosition(); LinkStairJump();} LinkAdjust(); // Wait for the screen to draw. // (You wouldn't think it from the name, right?) Waitframe();}}} // If the combo location (in units of tiles) is valid, it is returned. // otherwise, -1 is returned. int FindLoc(int tx, int ty) { if (tx < 0 || tx > 15 || ty < 0 || ty > 10) { return -1;} return tx + (ty << 4);} // Determine whether we'll be relying on the ZC engine for movement // or on this custom code. // Place after Waitdraw, and before anything that needs to know Link's mode. void DetermineLinkMode() { // Check for various situations in which we want to fallback on // the built-in ZC engine. if (// If we're not a sideview screen, we definitely want // to use the ZC engine. !IsSideview() || // If Link is Frozen, he's probably using the hookshot. Link->Action == LA_FROZEN || // If the screen is scrolling, we can't do anything anyway. Link->Action == LA_SCROLLING || // If he's hurt, we want to rely on the built-in knockback. Link->Action == LA_GOTHURTLAND || Link->Action == LA_GOTHURTWATER) { // Rely on the engine. LinkMode = LINK_MODE_ENGINE;} // There's on reason not to, so use our custom engine or stairs.. else if (StairMode != STAIR_NONE) { LinkMode = LINK_MODE_STAIR;} else { LinkMode = LINK_MODE_CUSTOM;}} // Return true if the combo at the given position is a stair. bool IsStair(int x, int y) { if (x < 0 || x >= 256 || y < 0 || y >= 176) {return false;} else {return IsStair((y & 240) + (x >> 4));}} bool IsStair(int loc) { if (loc == -1) {return false;} int ct = Screen->ComboT[loc]; return CT_NEG <= ct && ct <= CT_POS;} bool IsValidStair(int loc) { if (StairMode == STAIR_NEG) {return IsNegStair(loc);} else if (StairMode == STAIR_POS) {return IsPosStair(loc);}} bool IsValidStair(int x, int y) { if (StairMode == STAIR_NEG) {return IsNegStair(x, y);} else if (StairMode == STAIR_POS) {return IsPosStair(x, y);}} bool IsPosStair(int x, int y) { if (x < 0 || x > 255 || y < 0 || y > 175) {return false;} else {return IsPosStair((y & 240) + (x >> 4));}} bool IsPosStair(int loc) { if (loc == -1) {return false;} int ct = Screen->ComboT[loc]; return ct == CT_CROSS || ct == CT_POS;} bool IsNegStair(int x, int y) { if (x < 0 || x > 255 || y < 0 || y > 175) {return false;} else {return IsNegStair((y & 240) + (x >> 4));}} bool IsNegStair(int loc) { if (loc == -1) {return false;} int ct = Screen->ComboT[loc]; return ct == CT_CROSS || ct == CT_NEG;} // Gets the block type at the given position on screen. int GetBlockType(int x, int y) { // Outside the screen is always considered open. if (x < 0 || x >= 256 || y < 0 || y >= 176) {return BLOCK_EMPTY;} // Non-solid blocks are always empty. else if (!Screen->isSolid(x, y)) {return BLOCK_EMPTY;} // Otherwise, if has the soft flag or is a stair, // it is a soft block. else if (ComboFI(x, y, CF_SOFT) || IsStair(x, y)) {return BLOCK_SOFT;} // Otherwise it is hard. else {return BLOCK_HARD;}} // Updates Old Link position when the screen changes. void LinkUpdateOldOnScreenChange() { // Set old link position to the edge of the screen we came in from. if (ScreenChangeDir == DIR_UP) { OldLinkY = 160;} else if (ScreenChangeDir == DIR_DOWN) { OldLinkY = 0;} else if (ScreenChangeDir == DIR_LEFT) { OldLinkX = 240;} else if (ScreenChangeDir == DIR_RIGHT) { OldLinkX = 0;}} // Various actions to perform if the screen changed on us. void LinkCustomOnScreenChange() { if (ScreenChangeHandled) {return;} // Respect any warps or such. LinkX = Link->X; LinkY = Link->Y; LinkUpdateOldOnScreenChange(); // Mark as being handled. ScreenChangeHandled = true;} // Perform the actual movement of Link. void LinkCustomUpdatePosition() { // First, move according to player input. if (// We can only move if we're standing still or walking. Link->Action == LA_NONE || Link->Action == LA_WALKING || // Or we're in the air and attacking. (Link->Action == LA_ATTACKING && LinkBlock == BLOCK_EMPTY)) { // Then move left or right, but not both. if (Link->InputLeft) {LinkX -= LINK_WALK;} else if (Link->InputRight) {LinkX += LINK_WALK;}} // Check against running into a wall to the left. if (// First check that we moved left. LinkX < OldLinkX && (// Then check for hard blocks at Link's top, middle, and bottom. GetBlockType(LinkX, LinkY) == BLOCK_HARD || GetBlockType(LinkX, LinkY + 8) == BLOCK_HARD || GetBlockType(LinkX, LinkY + 15) == BLOCK_HARD)) { // If he hit, move Link right to the next multiple of 8. LinkX += 8 - (LinkX % 8);} // Check against running into a wall to the right. if (// First check that we moved right. LinkX > OldLinkX && (// Then check for hard blocks at Link's top, middle, and bottom. GetBlockType(LinkX + 15, LinkY) == BLOCK_HARD || GetBlockType(LinkX + 15, LinkY + 8) == BLOCK_HARD || GetBlockType(LinkX + 15, LinkY + 15) == BLOCK_HARD)) { // If he hit, move Link left to the previous multiple of 8. LinkX &= 0x1FFF8;} // Then move Link according to his vertical velocity. LinkY += LinkVy; // Check against running into a hard block above. if (// First check that we're moving up. LinkY < OldLinkY && (// Then check against Link's middle-left and middle-right. GetBlockType(LinkX + 5, LinkY) == BLOCK_HARD || GetBlockType(LinkX + 11, LinkY) == BLOCK_HARD)) { // If he hit, move Link down to the next multiple of 8. LinkY += 8 - (LinkY % 8); // and get rid of his vertical velocity. LinkVy = 0;} // Check against running into a block below, and assign the block type // below Link to LinkBlock for this round. // First check to make sure we're moving down. if (LinkY > OldLinkY) { // Get the hardest type of platform below Link. // Check against his middle-left and middle-right. LinkBlock = Max(GetBlockType(LinkX + 5, LinkY + 16), GetBlockType(LinkX + 11, LinkY + 16)); // See if we ran into a block. if (// A hard block always counts. LinkBlock == BLOCK_HARD || // A soft block counts as long as we're not holding the jump // button down, or we started out past it. (LinkBlock == BLOCK_SOFT && !InputJump && !(OldLinkY > (LinkY & 0x1FFF8)))) { // If he hit, move Link up to the previous multiple of 8. LinkY &= 0x1FFF8; // and get rid of his vertical velocity. LinkVy = 0;}} // Otherwise, we're in the air. else { LinkBlock = BLOCK_EMPTY;} Link->Jump = 0; Link->Z = 0; // Gravity. LinkVy = Min(LinkVy + LINK_GRAV, LINK_TERM);} // Perform a sideview jump. void SideviewJump() { Game->PlaySound(SFX_JUMP); // We're holding down, so only hop. if (Link->InputDown) {LinkVy = LinkHop;} // Otherwise do the full jump. else {LinkVy = LinkJump;}} // Jump according to custom mode rules. void LinkCustomJump() { if (// The Jump button is pressed. PressJump && // Can't jump in the air. LinkBlock != BLOCK_EMPTY && // Must have positive y velocity. LinkVy >= 0 && // Can't be doing anything but walking. (Link->Action == LA_NONE || Link->Action == LA_WALKING)) { // Jump! SideviewJump();}} // Check if we need to get onto stairs from custom mode. void LinkCustomMountStair() { // We never get on a stair unless we're standing on something. if (LinkBlock == BLOCK_EMPTY) {return;} // We must have a positive or 0 y velocity. if (LinkVy < 0) {return;} // We're moving up-left, so check an up-left going stair on the same // tile as Link. if (Link->InputLeft && Link->InputUp && IsPosStair(LinkX, LinkY + 15)) { MountStair(LinkX, LinkY + 15, STAIR_POS); StairPos = STAIR_BOTTOM;} // We're moving up-right, so check an up-right going stair on the same // tile as Link. else if (Link->InputRight && Link->InputUp && IsNegStair(LinkX + 15, LinkY + 15)) { MountStair(LinkX + 15, LinkY + 15, STAIR_NEG); StairPos = STAIR_BOTTOM;} // We're moving down-left, so check a down-left going stair on the // tile below Link. if (Link->InputLeft && Link->InputDown && IsNegStair(LinkX + 2, LinkY + 18)) { MountStair(LinkX + 2, LinkY + 18, STAIR_NEG); StairPos = STAIR_TOP;} // We're moving down-right, so check a down-right going stair on the // tile below Link. if (Link->InputRight && Link->InputDown && IsPosStair(LinkX + 13, LinkY + 18)) { MountStair(LinkX + 13, LinkY + 18, STAIR_POS); StairPos = STAIR_TOP;}} // Causes Link to mount the stair at the given position. // Returns true if the stair was mounted. bool MountStair(int x, int y, int mode) { // First, make sure there's actually a stair there. int start = (y & 240) + (x >> 4); if (x < 0 || x >= 256 || y < 0 || y >= 176 || !IsStair(start)) { LinkMode = LINK_MODE_CUSTOM; StairMode = STAIR_NONE; return false;} // Change to stair movement mode. LinkMode = LINK_MODE_STAIR; StairMode = mode; StairLoc = ComboAt(x, y); // Mark the stairs being mounted this frame. StairMount = true; // Set the Y offset. x = ComboX(start); y = ComboY(start); StairY = // Start with the y position of the stair combo. y // Move to 1 cell above it. - 16 // Adjust for the x position of the stair combo in the stair direction. - x * StairMode; return true;} void Stair_Update1() { StairMount = false;} // Adjust Link's position if the screen changed. void LinkStairOnScreenChange() { if (ScreenChangeHandled) {return;} int stairTX = StairLoc % 16; int stairTY = StairLoc >> 4; LinkUpdateOldOnScreenChange(); // If we walked off the top of the screen. if (ScreenChangeDir == DIR_UP) { int adjust = (StairLoc >> 4) + 1; stairTX -= adjust * StairMode; stairTY = 10; StairLoc = FindLoc(stairTX, stairTY); LinkX = (stairTX + StairMode) * 16; LinkY = 160;} // We walked off the bottom of the screen. else if (ScreenChangeDir == DIR_DOWN) { int adjust = 11 - stairTY; // First check if there is actually a stair on the top of the new screen. int loc = FindLoc(stairTX + StairMode * adjust, 0); if (!IsValidStair(loc)) { // If there isn't then just set Link's X to where that stair would be. LinkX = ComboX(loc); StairLoc = -1;} // If there is, proceed as normal. else { stairTX += 2 * StairMode; stairTY = 1; StairLoc = FindLoc(stairTX, stairTY); LinkX = stairTX * 16;} LinkY = 0;} // We walked off the left edge of the screen. Make sure that the // stairs actually reached all the way to the left as well. else if (ScreenChangeDir == DIR_LEFT && (// If we were on the edge stair, then we know it existed. stairTX == 0 || // Check above or below based on stair direction Cond(StairMode == STAIR_POS, StairAbove, StairBelow))) { stairTX = 15; // How far away the stair we're anchored to is from the wall. int adjust = (StairLoc % 16) + 1; stairTY -= adjust * StairMode; StairLoc = FindLoc(stairTX, stairTY); LinkX = 240; LinkY = (stairTY - 1) * 16; // If there isn't a valid stair there, and we were moving up, then // move Link down a tile, because he never climbed it while the // screen was scrolling. if (StairMode == STAIR_POS && !IsValidStair(StairLoc)) { LinkY += 16;}} // We walked off the right edge of the screen. Make sure that the // stairs actually reached all the way to the right as well. else if (ScreenChangeDir == DIR_RIGHT && (// If we were on the edge stair, then we know it existed. stairTX == 15 || // Check above or below based on stair direction Cond(StairMode == STAIR_POS, StairBelow, StairAbove))) { stairTX = 0; // How far away the stair we're anchored to is from the wall. int adjust = 16 - (StairLoc % 16); stairTY += adjust * StairMode; StairLoc = FindLoc(stairTX, stairTY); LinkX = 0; LinkY = (stairTY - 1) * 16; // If there isn't a valid stair there, and we were moving up, then // move Link down a tile, because he never climbed it while the // screen was scrolling. if (StairMode == STAIR_NEG && !IsValidStair(StairLoc)) { LinkY += 16;}} // Otherwise, cancel stairs. else { LinkX = Link->X; LinkY = Link->Y; StairMode = STAIR_NONE; LinkMode = LINK_MODE_CUSTOM;} if (StairMode != STAIR_NONE) { MountStair(stairTX << 4, stairTY << 4, StairMode);} ScreenChangeHandled = true;} // Update Link's position based on the stair he's on. void LinkStairUpdatePosition() { // First, move according to player input. if (// We can only move if we're standing still or walking. Link->Action == LA_NONE || Link->Action == LA_WALKING) { // Then move left or right, but not both. if (Link->InputLeft) {LinkX -= LINK_WALK;} else if (Link->InputRight) {LinkX += LINK_WALK;}} // If we're at the top or bottom of the stair, check against running // into walls. if (StairPos != STAIR_MIDDLE) { // Check against running into a wall to the left. if (// First check that we moved left. LinkX < OldLinkX && // Then check that we're not at the top of a negative stair. (StairPos != STAIR_TOP || StairMode != STAIR_NEG) && (// Then check for hard blocks at Link's top, middle, and bottom. GetBlockType(LinkX, LinkY) == BLOCK_HARD || GetBlockType(LinkX, LinkY + 8) == BLOCK_HARD || GetBlockType(LinkX, LinkY + 15) == BLOCK_HARD)) { // If he hit, move Link right to the next multiple of 8. LinkX += 8 - (LinkX % 8);} // Check against running into a wall to the right. if (// First check that we moved right. LinkX > OldLinkX && // Then check that we're not at the top of a positive stair. (StairPos != STAIR_TOP || StairMode != STAIR_POS) && (// Then check for hard blocks at Link's top, middle, and bottom. GetBlockType(LinkX + 15, LinkY) == BLOCK_HARD || GetBlockType(LinkX + 15, LinkY + 8) == BLOCK_HARD || GetBlockType(LinkX + 15, LinkY + 15) == BLOCK_HARD)) { // If he hit, move Link left to the previous multiple of 8. LinkX &= 0x1FFF8;}} //// Then adjust y positioning. // If we're at the middle of the stair, use the standard formula. LinkY = LinkX * StairMode + StairY; // If we're at the bottom, align Link with the anchored stair. if (StairPos == STAIR_BOTTOM && ((StairMode == STAIR_NEG && LinkX <= ComboX(StairLoc) - 16) || (StairMode == STAIR_POS && LinkX >= ComboX(StairLoc) + 16))) { LinkY = ComboY(StairLoc);} // If we're at the top, align Link with the cell above the anchored stair. else if (StairPos == STAIR_TOP && ((StairMode == STAIR_NEG && LinkX >= ComboX(StairLoc) - 1) || (StairMode == STAIR_POS && LinkX <= ComboX(StairLoc) + 1))) { LinkY = ComboY(StairLoc) - 16;}} // Find the stair that Link is currently standing on. void LinkStairFindStair() { if (StairLoc == -1) {return;} //// First, check if we've moved off of the stair we're currently anchored to. // Get the edge closest to the stair. int x = LinkX + Cond(StairMode == STAIR_POS, 0, 15); int stairX = ComboX(StairLoc); int stairTX = StairLoc % 16; int stairTY = StairLoc >> 4; // Direction we've shifted. int shiftDir = 0; // We've moved off the left side of the stair, so move the StairLoc // 1 to the left, plus up or down as appropriate. if (x < stairX) { stairTX--; stairTY -= StairMode; shiftDir = -1;} // We've moved off the right side of the stair, so move the StairLoc // 1 to the right, plus up or down as appropriate. else if (x >= stairX + 16) { stairTX++; stairTY += StairMode; shiftDir = 1;} StairLoc = FindLoc(stairTX, stairTY); StairPos = STAIR_MIDDLE; // If we found the stairs, but we're on the top edge of a stair (and // not on the edge of a screen), set to the top edge anyway. if (IsValidStair(StairLoc) && ((StairMode == STAIR_POS && stairTX != 0) || (StairMode == STAIR_NEG && stairTX != 15))) { int aboveLoc = FindLoc(stairTX - StairMode, stairTY - 1); if (!IsValidStair(aboveLoc)) { StairPos = STAIR_TOP;}} // Check for a stair to the side. if (// First, make sure that we didn't already find a stair. !IsValidStair(StairLoc) && // And then also make sure that we didn't shift up the stair, // because we're shifting up again and a double shift doesn't // make sense. shiftDir * StairMode != -1) { StairLoc = FindLoc(stairTX - StairMode, stairTY - 1); // If we're on the bottom of the screen, assume there's more // stairs on the next screen. if (stairTY - 1 < 10) { StairPos = STAIR_BOTTOM;}} // Then check for a stair diagonally downward. if (!IsValidStair(StairLoc)) { StairLoc = FindLoc(stairTX + StairMode, stairTY + 1); StairPos = STAIR_TOP;} // Check if we failed. if (!IsValidStair(StairLoc)) { StairLoc = -1; return;} // Set StairLeft and StairRight to the proper values for Link's position. if (StairPos == STAIR_MIDDLE) { StairLeft = 0; StairRight = 255;} else { stairTX = StairLoc % 16; StairLeft = (stairTX - 1) * 16 - 2; StairRight = (stairTX + 1) * 16 + 2;} // Find if there's a stair above and below. StairAbove = IsValidStair(FindLoc(stairTX - StairMode, stairTY - 1)); StairBelow = IsValidStair(FindLoc(stairTX + StairMode, stairTY + 1));} // See if Link is leaving the stairs. void LinkStairFallOff() { if (// Getting hurt knocks you off of stairs. Link->Action == LA_GOTHURTLAND || Link->Action == LA_GOTHURTWATER || // If we couldn't locate a stair earlier, that means we fall off, too. StairLoc == -1 || // Or if we've moved too far off of the top or bottom of a stair. LinkX < StairLeft || LinkX > StairRight) { StairMode = STAIR_NONE; LinkMode = LINK_MODE_CUSTOM;}} // Jump according to stair mode rules. void LinkStairJump() { if (// The Jump button is pressed. PressJump && // Can't be doing anything but walking. (Link->Action == LA_NONE || Link->Action == LA_WALKING)) { StairMode = STAIR_NONE; LinkMode = LINK_MODE_CUSTOM; // Jump! SideviewJump();}} // Assigns all the OldLink variables for the upcoming frame. // Place before Waitdraw(). void OldLink_Update1() { OldLinkX = Link->X; OldLinkY = Link->Y; OldLinkAction = Link->Action;} // Record the current dmap and dscreen right before they are changed. // Place before Waitdraw(). void ScreenChange_Update1() { OldDMap = Game->GetCurDMap(); OldDScreen = Game->GetCurDMapScreen();} // Updates information dealing with changing screens. // Place after Waitdraw(), when the screen changes happen. void ScreenChange_Update2() { // Grab current values. int dMap = Game->GetCurDMap(); int dScreen = Game->GetCurDMapScreen(); // Compare with old values. DMapChanged = dMap != OldDMap; ScreenChanged = DMapChanged || dScreen != OldDScreen; // Check for scrolling change to the same screen. if (Link->Action == LA_SCROLLING) { if (!ScreenChanged && !_ScreenChanged_ScrollFlag) { ScreenChanged = true; _ScreenChanged_ScrollFlag = true;}} // We're no longer scrolling, so reset scroll flag. else { _ScreenChanged_ScrollFlag = false;} // Check for a forced screen change flag. if (_ScreenChanged_ForceFlag) { ScreenChanged = true; _ScreenChanged_ForceFlag = false;} // Find the screen change direction. if (ScreenChanged) { // Mark the screen change as needing to be handled. ScreenChangeHandled = false; // Try to guess the direction. if (Link->Y >= 160) {ScreenChangeDir = DIR_UP;} else if (Link->Y <= 0) {ScreenChangeDir = DIR_DOWN;} else if (Link->X >= 240) {ScreenChangeDir = DIR_LEFT;} else if (Link->X <= 0) {ScreenChangeDir = DIR_RIGHT;} else {ScreenChangeDir = SCREEN_CHANGE_WARP;}}} // Adjust some of Link's variables after all the mechanical // manipulation is done. void LinkAdjust() { // Don't do anything in engine mode. if (LinkMode == LINK_MODE_ENGINE) {return;} // Update Link's actual position. Link->X = Round(LinkX); Link->Y = Round(LinkY); // Force the walking animation if we moved and have no other action. if (Link->Action == LA_NONE && (LinkX != OldLinkX || LinkY != OldLinkY)) { Link->Action = LA_WALKING;} // Set the direction according to input. if (Link->InputUp) {Link->Dir = DIR_UP;} else if (Link->InputDown) {Link->Dir = DIR_DOWN;} else if (Link->InputLeft) {Link->Dir = DIR_LEFT;} else if (Link->InputRight) {Link->Dir = DIR_RIGHT;}} // Don't scroll through items on sideview screens with L. void Input_Update1() { // Ignore L if this is a sideview screen. if (IsSideview()) { InputJump = Link->InputL; PressJump = Link->PressL; Link->InputL = false; Link->PressL = false;}} // Change the inputs so the engine doesn't set Link facing a weird // direction or something else we don't want. void Input_Update2() { // If we're not in engine mode, up and down take preference for // direction. if (LinkMode != LINK_MODE_ENGINE && (Link->InputUp || Link->InputDown)) { Link->InputLeft = false; Link->InputRight = false; Link->PressLeft = false; Link->PressRight = false;}} ffc script ScreenChange { void run() { _ScreenChanged_ForceFlag = true;}} // Don't carry over velocity or stair state. global script OnContinue { void run() { StairMode = STAIR_NONE; LinkVy = 0;}} // Set first argument to Link's full jump speed. // Set second argument to Link's jump speed while holding down. item script AdjustLinkJump { void run (int jumpSpeed, int hopSpeed) { LinkJump = jumpSpeed; LinkHop = hopSpeed;}}
#36
Posted 03 August 2013 - 08:16 AM
Pardon the double-post, but I don;t want this lost in the length of that script:
I thought it might have been my fault (i.e; something I changed), but it does not appear so. There may be a conflict with the stairs script and ghost.zh, or other scripts, or the way I have things arranged, but I don't see it if it exists. I did check LikeLike enemies in my game, and they work perfectly, so I know that it isn't merely the code that I added, but some combination of that and the stairs scripts, if not the stairs scripts alone.
It may be that Alucard will have to sacrifice that enemy type for this game at present. I certainly am not well-versed enough at this point to code a LikeLike ghosted enemy. I am just learning how to make a simple ghosted enemy, and without sample scripts of normal enemies as ghosted enemies (e.g. a ghosted moblin or octorock), I' shooting in the dark.
I will insert the new scripts, and try to adjust things on Sunday.
#37
Posted 03 August 2013 - 11:27 AM
I thought it might have been my fault (i.e; something I changed), but it does not appear so. There may be a conflict with the stairs script and ghost.zh, or other scripts, or the way I have things arranged, but I don't see it if it exists. I did check LikeLike enemies in my game, and they work perfectly, so I know that it isn't merely the code that I added, but some combination of that and the stairs scripts, if not the stairs scripts alone.
It may be that Alucard will have to sacrifice that enemy type for this game at present. I certainly am not well-versed enough at this point to code a LikeLike ghosted enemy. I am just learning how to make a simple ghosted enemy, and without sample scripts of normal enemies as ghosted enemies (e.g. a ghosted moblin or octorock), I' shooting in the dark.
This is why I have sent an invitation into this project to MoscowModder as he/she knows better about scripting.
#38
Posted 16 August 2013 - 12:45 PM
Sorry for double-posting but I have finally got the stairs script update installed in my quest project. And I have found more bugs:
1. Hookshoot while on stairs causes Link`s sprite to fall off stairs. But as soon as hookshot finishes retracting Link magically teleports onto staircase.
2. If stairs are placed too close to a corner of a screen it can cause Link to fall off stairs or even cause warping madness similar to the one which can be encountered in earlier versions of the script.
Link to beta: http://zoriarpg.com/zc/CV/CV1_3B.qst
#39
Posted 13 April 2014 - 07:18 AM
Eureka!
Also tagged with one or more of these keywords: sideview, castlevania, stairs
ghost.zh
Zelda Classic →
Scripting Discussion →
Detecting if the given FFC ghosts given enemyStarted by Alucard648 , 11 Nov 2021 ghost.zh, sideview |
|
|
||
Zelda Classic →
Scripting Discussion →
GraySwanDir sideview engineStarted by Alucard648 , 24 Oct 2021 sideview |
|
|
||
Zelda Classic →
Quest Design Help →
Poll Semi-solid FFCs. To crush or not to crush.Started by Alucard648 , 16 Sep 2021 sideview |
|
|
||
Sideview
Zelda Classic →
Developers' Exchange →
Looking for sideview Classic/Cambria Link swimming tilesStarted by Alucard648 , 29 Aug 2021 Sideview |
|
|
||
Zelda Classic →
ZQuest Editor Help →
SFX issue with stairsStarted by Cynicalove , 14 May 2015 sound, effects, sfx, stairs |
|
|
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users