Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import "std.zh"
- import "ffcscript.zh"
- import "ghost.zh"
- //Global Scripts
- //%MGSO% DECLARATION ScrollingBackgrounds
- //%MGSO% DECLARATION MovingPlatforms
- //%MGSO% DECLARATION MooshPit
- //%MGSO% DECLARATION Confusion
- //%MGSO% DECLARATION SolidFFC
- //%MGSO% DECLARATION BombArrow
- //%MGSO% HEADER_START ScrollingBackgrounds
- const int SCROLLINGLAYER_LINKSTEP = 1.5; //Link's step speed
- const int SCROLLINGLAYER_FASTSCROLLING = 1; //Set to 1 if Very Fast Scrolling is enabled
- const int SCROLLINGLAYER_DEBUG = 0; //Set to 1 to show positions of onscreen layers
- int ScrollingBG[112]; //Size should be at least _SBG_START + 6 * _SBG_BLOCK
- //Global array indices
- const int _SBG_LINKX = 0;
- const int _SBG_LINKY = 1;
- const int _SBG_SCROLLDIR = 2;
- const int _SBG_SCROLLCOUNTER = 3;
- //Start index of the 2D part of the global array and block size
- const int _SBG_START = 16;
- const int _SBG_BLOCK = 16;
- //Indices for scrolling layer properties
- const int _SBG_X = 0;
- const int _SBG_Y = 1;
- const int _SBG_XSTEP = 2;
- const int _SBG_YSTEP = 3;
- const int _SBG_MAP = 4;
- const int _SBG_SCREEN = 5;
- const int _SBG_LAYER = 6;
- const int _SBG_WIDTH = 7;
- const int _SBG_HEIGHT = 8;
- const int _SBG_OPACITY = 9;
- const int _SBG_FLAGS = 10;
- const int _SBG_DMAP = 11;
- //Flag constants
- const int _SBGF_NORESET = 00000001b;
- const int _SBGF_NOPOSITION = 00000010b;
- const int _SBGF_TRACKX = 00000100b;
- const int _SBGF_TRACKY = 00001000b;
- const int _SBGF_TRACKXSCROLL = 00010000b;
- const int _SBGF_TRACKYSCROLL = 00100000b;
- const int _SBGF_FORCEDRAWSCREEN = 01000000b;
- void ScrollingBG_Init(){
- int i; int j; int k;
- for(i=0; i<6; ++i){
- j = _SBG_START+i*_SBG_BLOCK;
- //If the layer hasn't been assigned by an FFC this frame, clear it on F6
- if(!(ScrollingBG[j+_SBG_FLAGS]&_SBGF_NORESET)){
- for(k=0; k<_SBG_BLOCK; ++k){
- ScrollingBG[j+k] = 0;
- }
- }
- }
- ScrollingBG[_SBG_LINKX] = Link->X;
- ScrollingBG[_SBG_LINKY] = Link->Y;
- ScrollingBG[_SBG_SCROLLDIR] = -1;
- ScrollingBG[_SBG_SCROLLCOUNTER] = 0;
- }
- void ScrollingBG_Update(){
- int i; int j; int k;
- int x; int y; int w; int h;
- bool trackLinkX; bool trackScrollX;
- bool trackLinkY; bool trackScrollY;
- int dX = (Link->X-ScrollingBG[_SBG_LINKX])/SCROLLINGLAYER_LINKSTEP;
- int dY = (Link->Y-ScrollingBG[_SBG_LINKY])/SCROLLINGLAYER_LINKSTEP;
- ScrollingBG[_SBG_LINKX] = Link->X;
- ScrollingBG[_SBG_LINKY] = Link->Y;
- if(Link->Action==LA_SCROLLING){
- if(ScrollingBG[_SBG_SCROLLDIR]==-1){
- if(Link->Y>160)
- ScrollingBG[_SBG_SCROLLDIR] = DIR_UP;
- else if(Link->Y<0)
- ScrollingBG[_SBG_SCROLLDIR] = DIR_DOWN;
- else if(Link->X>240)
- ScrollingBG[_SBG_SCROLLDIR] = DIR_LEFT;
- else
- ScrollingBG[_SBG_SCROLLDIR] = DIR_RIGHT;
- ScrollingBG[_SBG_SCROLLCOUNTER] = 0;
- }
- else
- ++ScrollingBG[_SBG_SCROLLCOUNTER];
- }
- else
- ScrollingBG[_SBG_SCROLLDIR] = -1;
- for(i=0; i<6; ++i){
- j = _SBG_START+i*_SBG_BLOCK;
- if(ScrollingBG[j+_SBG_OPACITY]&&ScrollingBG[j+_SBG_DMAP]==Game->GetCurDMap()&&Game->GetCurScreen()<0x7F){
- if(ScrollingBG[j+_SBG_FLAGS]&_SBGF_TRACKX)
- trackLinkX = true;
- if(ScrollingBG[j+_SBG_FLAGS]&_SBGF_TRACKY)
- trackLinkY = true;
- if(ScrollingBG[j+_SBG_FLAGS]&_SBGF_TRACKXSCROLL)
- trackScrollX = true;
- if(ScrollingBG[j+_SBG_FLAGS]&_SBGF_TRACKYSCROLL)
- trackScrollY = true;
- w = 256*ScrollingBG[j+_SBG_WIDTH];
- h = 176*ScrollingBG[j+_SBG_HEIGHT];
- //Process scrolling animation
- //X-axis
- if(ScrollingBG_IsScrolling()){
- //During the scroll animation, move the background if set to track scrolling
- if(trackScrollX){
- if(ScrollingBG[_SBG_SCROLLDIR]==DIR_LEFT)
- ScrollingBG[j+_SBG_X] -= ScrollingBG[j+_SBG_XSTEP];
- else if(ScrollingBG[_SBG_SCROLLDIR]==DIR_RIGHT)
- ScrollingBG[j+_SBG_X] += ScrollingBG[j+_SBG_XSTEP];
- }
- //Scroll automatically if neither Link nor scrolling are being tracked
- else if(!trackLinkX){
- ScrollingBG[j+_SBG_X] += ScrollingBG[j+_SBG_XSTEP];
- }
- }
- else{
- //Only move when Link does if tracking him
- if(trackLinkX){
- ScrollingBG[j+_SBG_X] += ScrollingBG[j+_SBG_XSTEP]*dX;
- }
- else if(!trackScrollX)
- ScrollingBG[j+_SBG_X] += ScrollingBG[j+_SBG_XSTEP];
- }
- //Y-axis
- if(ScrollingBG_IsScrolling()){
- //During the scroll animation, move the background if set to track scrolling
- if(trackScrollY){
- if(ScrollingBG[_SBG_SCROLLDIR]==DIR_UP)
- ScrollingBG[j+_SBG_Y] -= ScrollingBG[j+_SBG_YSTEP];
- else if(ScrollingBG[_SBG_SCROLLDIR]==DIR_DOWN)
- ScrollingBG[j+_SBG_Y] += ScrollingBG[j+_SBG_YSTEP];
- }
- //Scroll automatically if neither Link nor scrolling are being tracked
- else if(!trackLinkY){
- ScrollingBG[j+_SBG_Y] += ScrollingBG[j+_SBG_YSTEP];
- }
- }
- else{
- //Only move when Link does if tracking him
- if(trackLinkY){
- ScrollingBG[j+_SBG_Y] += ScrollingBG[j+_SBG_YSTEP]*dY;
- }
- else if(!trackScrollX)
- ScrollingBG[j+_SBG_Y] += ScrollingBG[j+_SBG_YSTEP];
- }
- //Keep the X and Y positions of the background wrapped based on size
- if(ScrollingBG[j+_SBG_X]<0)
- ScrollingBG[j+_SBG_X] += w;
- if(ScrollingBG[j+_SBG_X]>=w)
- ScrollingBG[j+_SBG_X] -= w;
- if(ScrollingBG[j+_SBG_Y]<0)
- ScrollingBG[j+_SBG_Y] += h;
- if(ScrollingBG[j+_SBG_Y]>=h)
- ScrollingBG[j+_SBG_Y] -= h;
- x = Floor(ScrollingBG[j+_SBG_X]);
- y = Floor(ScrollingBG[j+_SBG_Y]);
- ScrollingBG_DrawLayer(ScrollingBG[j+_SBG_LAYER], ScrollingBG[j+_SBG_MAP], ScrollingBG[j+_SBG_SCREEN], x, y, ScrollingBG[j+_SBG_WIDTH], ScrollingBG[j+_SBG_HEIGHT], ScrollingBG[j+_SBG_OPACITY], ScrollingBG[j+_SBG_FLAGS]&_SBGF_FORCEDRAWSCREEN);
- if(SCROLLINGLAYER_DEBUG){
- Screen->DrawInteger(6, 24*i, 0, FONT_Z3SMALL, 0x01, 0x0F, -1, -1, x, 0, 128);
- Screen->DrawInteger(6, 24*i, 8, FONT_Z3SMALL, 0x01, 0x0F, -1, -1, y, 0, 128);
- }
- }
- //Unmark flags telling the global not to reset it and the FFC not to reposition it
- if(ScrollingBG[j+_SBG_FLAGS]&_SBGF_NORESET)
- ScrollingBG[j+_SBG_FLAGS] &= ~_SBGF_NORESET;
- if(ScrollingBG[j+_SBG_FLAGS]&_SBGF_NOPOSITION)
- ScrollingBG[j+_SBG_FLAGS] &= ~_SBGF_NOPOSITION;
- }
- }
- bool ScrollingBG_IsScrolling(){
- int xFrames = 64;
- int yFrames = 44;
- if(SCROLLINGLAYER_FASTSCROLLING){
- xFrames = 16;
- yFrames = 11;
- }
- if(ScrollingBG[_SBG_SCROLLDIR]>-1&&ScrollingBG[_SBG_SCROLLCOUNTER]>0){
- if(ScrollingBG[_SBG_SCROLLDIR]<2&&ScrollingBG[_SBG_SCROLLCOUNTER]<yFrames+1)
- return true;
- if(ScrollingBG[_SBG_SCROLLDIR]>=2&&ScrollingBG[_SBG_SCROLLCOUNTER]<xFrames+1)
- return true;
- }
- return false;
- }
- void ScrollingBG_DrawLayer(int layer, int srcMap, int srcScreen, int x, int y, int w, int h, int op, bool forceDrawScreen){
- int i;
- bool useDrawScreen;
- if(forceDrawScreen)
- useDrawScreen = true;
- //While scrolling, avoid using DrawLayer on negative layers. ZC does not like this.
- if(op==128&&Link->Action==LA_SCROLLING){
- if(layer==2&&ScreenFlag(SF_VIEW, 4))
- useDrawScreen = true;
- if(layer==3&&ScreenFlag(SF_VIEW, 5))
- useDrawScreen = true;
- }
- int tmpScreen;
- int scrnX;
- int scrnY;
- for(i=0; i<4; ++i){
- scrnX = Floor(x/256)+(i%2);
- scrnY = Floor(y/176)+Floor(i/2);
- if(scrnX<0)
- scrnX += w;
- if(scrnX>w-1)
- scrnX -= w;
- if(scrnY<0)
- scrnY += h;
- if(scrnY>h-1)
- scrnY -= h;
- tmpScreen = srcScreen+scrnX+scrnY*16;
- if(useDrawScreen)
- Screen->DrawScreen(layer, srcMap, tmpScreen, -(x%256)+256*(i%2), -(y%176)+176*Floor(i/2), 0);
- else
- Screen->DrawLayer(layer, srcMap, tmpScreen, 0, -(x%256)+256*(i%2), -(y%176)+176*Floor(i/2), 0, op);
- }
- }
- //This FFC script is placed on the screen to assign or unassign a scrolling layer for the current DMap
- //D0: Which of the simultaneous scrolling layers to assign (0-5)
- //D1: Layer to draw to
- //D2: Source Map for the layer
- //D3: Source Screen for the layer (in decimal)
- //D4: X speed for the layer
- //D5: Y speed for the layer
- //D6: Opacity for the layer (0 to clear, 64 for transparent, 128 for opaque)
- //D7: Sum of all of these flags you want to use
- // 1 - Track Link when walking on the X axis
- // 2 - Track Link when walking on the Y axis
- // 4 - Track Link when scrolling on the X axis
- // 8 - Track Link when scrolling on the Y axis
- // 16 - Use 2x2 screen block
- // 32 - Use 3x3 screen block
- // 64 - Use 4x4 screen block
- // 128 - Always use drawscreen (slow)
- ffc script ScrollingLayer_Assign{
- void run(int whichScrollingLayer, int drawLayer, int srcMap, int srcScreen, int xStep, int yStep, int opacity, int flags){
- whichScrollingLayer = Clamp(whichScrollingLayer, 0, 5);
- int width = 1;
- if(flags&16)
- width = 2;
- if(flags&32)
- width = 3;
- if(flags&64)
- width = 4;
- //Get the starting array index for the scrolling layer block
- int i = _SBG_START+whichScrollingLayer*_SBG_BLOCK;
- int j;
- //This runs twice because of script order shenanigans. Hooraaaay! Script order!
- for(j=0; j<2; ++j){
- if(opacity!=0&&(ScrollingBG[i+_SBG_OPACITY]&&ScrollingBG[i+_SBG_DMAP]==Game->GetCurDMap())){
- Waitframe();
- continue;
- }
- //Assign that stuff
- if(!(ScrollingBG[i+_SBG_FLAGS]&_SBGF_NOPOSITION)){
- ScrollingBG[i+_SBG_X] = 0;
- ScrollingBG[i+_SBG_Y] = 0;
- ScrollingBG[i+_SBG_WIDTH] = width;
- ScrollingBG[i+_SBG_HEIGHT] = width;
- }
- ScrollingBG[i+_SBG_XSTEP] = xStep;
- ScrollingBG[i+_SBG_YSTEP] = yStep;
- ScrollingBG[i+_SBG_MAP] = srcMap;
- ScrollingBG[i+_SBG_SCREEN] = srcScreen;
- ScrollingBG[i+_SBG_LAYER] = drawLayer;
- ScrollingBG[i+_SBG_OPACITY] = opacity;
- //Assign the flag that tells the global not to reset this index, as well as any others specified
- ScrollingBG[i+_SBG_FLAGS] = _SBGF_NORESET;
- if(flags&1)
- ScrollingBG[i+_SBG_FLAGS] |= _SBGF_TRACKX;
- if(flags&2)
- ScrollingBG[i+_SBG_FLAGS] |= _SBGF_TRACKY;
- if(flags&4)
- ScrollingBG[i+_SBG_FLAGS] |= _SBGF_TRACKXSCROLL;
- if(flags&8)
- ScrollingBG[i+_SBG_FLAGS] |= _SBGF_TRACKYSCROLL;
- if(flags&128)
- ScrollingBG[i+_SBG_FLAGS] |= _SBGF_FORCEDRAWSCREEN;
- ScrollingBG[i+_SBG_DMAP] = Game->GetCurDMap();
- Quit();
- }
- }
- }
- //This FFC script is placed on the screen to change the position of an assigned layer (because the last script ran out of arguments)
- //D0: Which of the simultaneous scrolling layers to assign (0-5)
- //D1: X position to set the layer to
- //D2: Y position to set the layer to
- //D3: Width to set the layer to (overrides flags used by the previous script)
- //D4: Height to set the layer to (overrides flags used by the previous script)
- ffc script ScrollingLayer_Reposition{
- void run(int whichScrollingLayer, int x, int y, int newW, int newH){
- whichScrollingLayer = Clamp(whichScrollingLayer, 0, 5);
- newW = Clamp(newW, 0, 16);
- newH = Clamp(newH, 0, 8);
- //Get the starting array index for the scrolling layer block
- int i = _SBG_START+whichScrollingLayer*_SBG_BLOCK;
- int j;
- int w = ScrollingBG[i+_SBG_WIDTH]*256;
- int h = ScrollingBG[i+_SBG_HEIGHT]*176;
- //This runs twice because of script order shenanigans. Hooraaaay! Script order!
- for(j=0; j<2; ++j){
- if(!ScrollingBG[i+_SBG_OPACITY]||ScrollingBG[i+_SBG_FLAGS]&_SBGF_NORESET){
- if(newW&&newH){
- ScrollingBG[i+_SBG_WIDTH] = newW;
- ScrollingBG[i+_SBG_HEIGHT] = newH;
- w = ScrollingBG[i+_SBG_WIDTH]*256;
- h = ScrollingBG[i+_SBG_HEIGHT]*176;
- }
- while(x<0)
- x += w;
- while(x>=w)
- x -= w;
- while(y<0)
- y += h;
- while(y>=h)
- y -= h;
- ScrollingBG[i+_SBG_X] = x;
- ScrollingBG[i+_SBG_Y] = y;
- //Flag that the ScrollingLayer_Assign script shouldn't reset the layer's position, if this one comes first
- ScrollingBG[i+_SBG_FLAGS] |= _SBGF_NOPOSITION;
- Quit();
- }
- Waitframe();
- }
- }
- }
- //%MGSO% HEADER_END ScrollingBackgrounds
- //%MGSO% HEADER_START MovingPlatforms
- ///Constants and Variables used by platform script;
- const int DIAGONAL_MOVEMENT = 0; //Enable the option and change this to 0 for nes movement.
- int onplatform; //Global variable use this to check if Link is on a platform for other scripts.
- void NesMovementFix()
- {
- if(DIAGONAL_MOVEMENT==0 && (Link->InputUp || Link->InputDown))
- {
- Link->InputLeft = false;
- Link->InputRight = false;
- }
- }
- void MovingPlatforms()
- {
- onplatform = 0;
- if(Link->Z == 0)
- {
- int buffer[] = "movingplatform";
- for(int i = 1; i <= 32; i++)
- {
- ffc f = Screen->LoadFFC(i);
- if(f->Script != Game->GetFFCScript(buffer)) continue;
- if(Abs(Link->X + 8 - CenterX(f)) >= f->TileWidth*8) continue;
- if(Abs(Link->Y + 12 - CenterY(f)) >= f->TileHeight*8) continue;
- onplatform = FFCNum(f);
- break;
- }
- }
- }
- ffc script MovingPlatform
- {
- void run()
- {
- float oldx = this->X;
- float oldy = this->Y;
- float linkx;
- float linky;
- while(true)
- {
- if(onplatform == FFCNum(this))
- {
- linkx += this->X - oldx;
- linky += this->Y - oldy;
- if(linkx << 0 != 0)
- {
- Link->X += linkx << 0;
- linkx -= linkx << 0;
- }
- if(linky << 0 != 0)
- {
- Link->Y += linky << 0;
- linky -= linky << 0;
- }
- }
- else
- {
- linkx = 0;
- linky = 0;
- }
- oldx = this->X;
- oldy = this->Y;
- Waitframe();
- }
- }
- }
- //%MGSO% HEADER_END MovingPlatforms
- //%MGSO% HEADER_START MooshPit
- int MooshPit[16];
- const int _MP_LASTX = 0;
- const int _MP_LASTY = 1;
- const int _MP_LASTDMAP = 2;
- const int _MP_LASTSCREEN = 3;
- const int _MP_ENTRYX = 4;
- const int _MP_ENTRYY = 5;
- const int _MP_ENTRYDMAP = 6;
- const int _MP_ENTRYSCREEN = 7;
- const int _MP_FALLX = 8;
- const int _MP_FALLY = 9;
- const int _MP_FALLTIMER = 10;
- const int _MP_FALLSTATE = 11;
- const int _MP_DAMAGETYPE = 12;
- const int _MP_SLIDETIMER = 13;
- const int MOOSHPIT_NO_GRID_SNAP = 0; //Set to 1 to prevent Link's falling sprite from snapping to the combo grid.
- const int MOOSHPIT_ENABLE_SLIDEYPITS = 0; //Set to 1 if Link should slide into pits he's partially on
- const int MOOSHPIT_NO_MOVE_WHILE_FALLING = 1; //Set to 1 if you don't want Link able to move while falling
- const int MOOSHPIT_NO_REENTER_STAIRS = 1; //Set to 1 to prevent Link reentering stairs when respawning from a pit. This uses an FFC slot to run the script
- const int MOOSHPIT_STUN_ENEMIES_WHILE_FALLING = 1; //Set to 1 to stun stunnable enemies while falling in a pit
- const int CT_HOLELAVA = 128; //Combo type for pits (No Ground Enemies by default)
- const int CF_LAVA = 98; //Combo flag marking pits as lava (Script 1 by default)
- const int SPR_FALLHOLE = 100; //Sprite for Link falling in a hole
- const int SPR_FALLLAVA = 89; //Sprite for Link falling in lava
- const int SFX_FALLHOLE = 38; //Sound for falling in a hole
- const int SFX_FALLLAVA = 13; //Sound for falling in lava
- const int DAMAGE_FALLHOLE = 8; //How much damage pits deal (1/2 heart default)
- const int DAMAGE_FALLLAVA = 16; //How much damage lava deals (1 heart default)
- const int FFC_MOOSHPIT_AUTOWARPA = 32; //FFC that turns into an auto side warp combo when you fall in a pit
- const int CMB_MOOSHPIT_AUTOWARPA = 875; //Combo number of an invisible Auto Side Warp A combo
- const int SF_MISC_MOOSHPITWARP = 2; //Number of the screen flag under the Misc. section that makes pits warp (Script 1 by default)
- //All pit warps use Side Warp A
- const int MOOSHPIT_MIN_FALL_TIME = 60; //Minimum time for the pit's fall animation, to prevent repeated falling in pits
- const int MOOSHPIT_EXTRA_FALL_TIME = 0; //Extra frames at the end of the falling animation before Link respawns
- //Width and height of Link's hitbox for colliding with pits
- const int MOOSHPIT_LINKHITBOXWIDTH = 2;
- const int MOOSHPIT_LINKHITBOXHEIGHT = 2;
- //Width and height of Link's hitbox for colliding with pits/lava in sideview
- const int MOOSHPIT_SIDEVIEW_LINKHITBOXWIDTH = 2;
- const int MOOSHPIT_SIDEVIEW_LINKHITBOXHEIGHT = 2;
- const int MOOSHPIT_SLIDEYPIT_FREQ = 3; //Link will be pushed into slideypits every 1/n frames
- const int MOOSHPIT_SLIDEYPIT_MAXTIME = 20; //Link will be pushed into slideypits more intensely after n frames
- const int MOOSHPIT_SLIDEYPIT_ACCELFREQ = 8; //How often Link accelerates when falling in the pit
- int MooshPit_OnPit(int LinkX, int LinkY, bool countFFCs){
- if(Link->Action==LA_FROZEN||Link->Action==LA_RAFTING||Link->Action==LA_INWIND)
- return -1;
- if(countFFCs){
- if(MooshPit_OnFFC(LinkX, LinkY))
- return -1;
- }
- bool sideview;
- if(Screen->Flags[SF_ROOMTYPE]&100b)
- sideview = true;
- //wew lad
- int width = MOOSHPIT_LINKHITBOXWIDTH;
- int height = MOOSHPIT_LINKHITBOXHEIGHT;
- int total;
- int solidTotal;
- for(int x=0; x<=1; x++){
- for(int y=0; y<=1; y++){
- int X; int Y;
- if(sideview){ //Hitbox functions differently in sideview
- width = MOOSHPIT_SIDEVIEW_LINKHITBOXWIDTH;
- height = MOOSHPIT_SIDEVIEW_LINKHITBOXHEIGHT;
- X = Floor(LinkX+7-width/2+(width-1)*x)+1;
- Y = Floor(LinkY+7-height/2+(height-1)*y)+1;
- }
- else{
- X = Floor(LinkX+7-width/2+(width-1)*x)+1;
- Y = Floor(LinkY+11-height/2+(height-1)*y)+1;
- }
- //If one corner of Link's hitbox is on a pit, flag that corner as covered
- if(Screen->ComboT[ComboAt(X, Y)]==CT_HOLELAVA){
- total |= 1<<(1+(x+y*2));
- }
- //If Link is on a solid combo, count that corner as a pit
- if(Screen->isSolid(X, Y)){
- solidTotal |= 1<<(x+y*2);
- }
- }
- }
- if(total>0) //Assuming Link is on at least one actual pit, add up the solid and nonsolid pits
- return (total>>1)|(solidTotal<<4);
- return -1;
- }
- bool MooshPit_OnFFC(int LinkX, int LinkY){
- for(int i=1; i<=32; i++){ //Cycle through every FFC
- ffc f = Screen->LoadFFC(i);
- //Check if the FFC is solid
- if(f->Data>0&&!f->Flags[FFCF_CHANGER]&&!f->Flags[FFCF_ETHEREAL]){
- //Check if Link collides with the FFC
- if(RectCollision(LinkX+4, LinkY+9, LinkX+11, LinkY+14, f->X, f->Y, f->X+f->EffectWidth-1, f->Y+f->EffectHeight-1)){
- return true;
- }
- }
- }
- //If Link doesn't collide with any FFC, return false
- return false;
- }
- void MooshPit_StunEnemies(){
- for(int i=Screen->NumNPCs(); i>=1; i--){ //Cycle through every enemy
- npc n = Screen->LoadNPC(i);
- //Make it so the enemy's stun never falls below 1
- n->Stun = Max(n->Stun, 1);
- }
- }
- void MooshPit_Init(){
- MooshPit[_MP_LASTX] = Link->X;
- MooshPit[_MP_LASTY] = Link->Y;
- MooshPit[_MP_LASTDMAP] = Game->GetCurDMap();
- MooshPit[_MP_LASTSCREEN] = Game->GetCurDMapScreen();
- MooshPit[_MP_ENTRYX] = Link->X;
- MooshPit[_MP_ENTRYY] = Link->Y;
- MooshPit[_MP_ENTRYDMAP] = Game->GetCurDMap();
- MooshPit[_MP_ENTRYSCREEN] = Game->GetCurDMapScreen();
- MooshPit[_MP_FALLSTATE] = 0;
- MooshPit[_MP_FALLTIMER] = 0;
- Link->CollDetection = true;
- Link->Invisible = false;
- }
- void MooshPit_Update(){
- int i;
- bool isWarp;
- if(Screen->Flags[SF_MISC]&(1<<SF_MISC_MOOSHPITWARP))
- isWarp = true;
- bool sideview;
- if(Screen->Flags[SF_ROOMTYPE]&100b)
- sideview = true;
- if(Link->Action!=LA_SCROLLING){
- //Update the entry point whenever the screen changes
- if(MooshPit[_MP_ENTRYDMAP]!=Game->GetCurDMap()||MooshPit[_MP_ENTRYSCREEN]!=Game->GetCurDMapScreen()){
- MooshPit[_MP_ENTRYX] = Link->X;
- MooshPit[_MP_ENTRYY] = Link->Y;
- MooshPit[_MP_ENTRYDMAP] = Game->GetCurDMap();
- MooshPit[_MP_ENTRYSCREEN] = Game->GetCurDMapScreen();
- }
- if(MooshPit[_MP_FALLSTATE]==0){ //Not falling in pit
- int onPit = MooshPit_OnPit(Link->X, Link->Y, true);
- //Check if slidey pits are enabled and it's not sideview
- if(MOOSHPIT_ENABLE_SLIDEYPITS&&!IsSideview()){
- if(Link->Z<=0&&onPit>-1){ //If Link is partially on a pit
- int slideVx; int slideVy;
- int reps = 1;
- //Check if it's a frame Link should be moved
- if(MooshPit[_MP_SLIDETIMER]%MOOSHPIT_SLIDEYPIT_FREQ==0||MooshPit[_MP_SLIDETIMER]>=MOOSHPIT_SLIDEYPIT_MAXTIME){
- if((onPit&0111b)==0111b){ //Going up-left
- slideVx = -1;
- slideVy = -1;
- }
- else if((onPit&1011b)==1011b){ //Going up-right
- slideVx = 1;
- slideVy = -1;
- }
- else if((onPit&1101b)==1101b){ //Going down-left
- slideVx = -1;
- slideVy = 1;
- }
- else if((onPit&1110b)==1110b){ //Going down-right
- slideVx = 1;
- slideVy = 1;
- }
- else if((onPit&0011b)==0011b){ //Going up
- slideVy = -1;
- }
- else if((onPit&1100b)==1100b){ //Going down
- slideVy = 1;
- }
- else if((onPit&0101b)==0101b){ //Going left
- slideVx = -1;
- }
- else if((onPit&1010b)==1010b){ //Going right
- slideVx = 1;
- }
- else if((onPit&0001b)==0001b){ //Going up-left
- slideVx = -1;
- slideVy = -1;
- }
- else if((onPit&0010b)==0010b){ //Going up-right
- slideVx = 1;
- slideVy = -1;
- }
- else if((onPit&0100b)==0100b){ //Going down-left
- slideVx = -1;
- slideVy = 1;
- }
- else if((onPit&1000b)==1000b){ //Going down-right
- slideVx = 1;
- slideVy = 1;
- }
- //DEBUG DRAWS
- //VX
- // Screen->DrawInteger(6, 0, 0, FONT_Z1, 0x01, 0x0F, -1, -1, slideVx, 0, 128);
- //VY
- // Screen->DrawInteger(6, 0, 8, FONT_Z1, 0x01, 0x0F, -1, -1, slideVy, 0, 128);
- //ONPIT BITS
- // Screen->DrawInteger(6, 0, 16, FONT_Z1, 0x01, 0x0F, -1, -1, (onPit&1000b)>>3, 0, 128);
- // Screen->DrawInteger(6, 8, 16, FONT_Z1, 0x01, 0x0F, -1, -1, (onPit&0100b)>>2, 0, 128);
- // Screen->DrawInteger(6, 16, 16, FONT_Z1, 0x01, 0x0F, -1, -1, (onPit&0010b)>>1, 0, 128);
- // Screen->DrawInteger(6, 24, 16, FONT_Z1, 0x01, 0x0F, -1, -1, (onPit&0001b), 0, 128);
- //If Link is over the max slide time, increase the speed every 4 frames
- if(MooshPit[_MP_SLIDETIMER]>=MOOSHPIT_SLIDEYPIT_MAXTIME)
- reps += Floor((MooshPit[_MP_SLIDETIMER]-MOOSHPIT_SLIDEYPIT_MAXTIME)/MOOSHPIT_SLIDEYPIT_ACCELFREQ);
- }
- for(i=0; i<reps; i++){
- if(slideVx<0&&CanWalk(Link->X, Link->Y, DIR_LEFT, 1, false)){
- Link->X--;
- }
- else if(slideVx>0&&CanWalk(Link->X, Link->Y, DIR_RIGHT, 1, false)){
- Link->X++;
- }
- if(slideVy<0&&CanWalk(Link->X, Link->Y, DIR_UP, 1, false)){
- Link->Y--;
- }
- else if(slideVy>0&&CanWalk(Link->X, Link->Y, DIR_DOWN, 1, false)){
- Link->Y++;
- }
- }
- MooshPit[_MP_SLIDETIMER]++;
- }
- else{
- MooshPit[_MP_SLIDETIMER] = 0;
- }
- }
- if(onPit>-1){
- //Combine solid combo bits with pit bits
- onPit |= (onPit>>4);
- //Remove non pit bits
- onPit &= 1111b;
- }
- if(Link->Z<=0&&onPit==15){ //If Link steps on a pit
- int underLink;
- if(!sideview){
- underLink = ComboAt(Link->X+8, Link->Y+12);
- if(Screen->ComboT[underLink]!=CT_HOLELAVA){
- for(i=0; i<4; i++){
- underLink = ComboAt(Link->X+15*(i%2), Link->Y+8+7*Floor(i/2));
- if(Screen->ComboT[underLink]==CT_HOLELAVA)
- break;
- }
- }
- }
- else{
- underLink = ComboAt(Link->X+8, Link->Y+8);
- if(Screen->ComboT[underLink]!=CT_HOLELAVA){
- for(i=0; i<4; i++){
- underLink = ComboAt(Link->X+15*(i%2), Link->Y+15*Floor(i/2));
- if(Screen->ComboT[underLink]==CT_HOLELAVA)
- break;
- }
- }
- }
- lweapon fall;
- //Check if the combo is lava
- if(ComboFI(underLink, CF_LAVA)){
- //Play sound and display animation
- Game->PlaySound(SFX_FALLLAVA);
- fall = CreateLWeaponAt(LW_SCRIPT10, Link->X, Link->Y);
- if(!MOOSHPIT_NO_GRID_SNAP){
- fall->X = ComboX(underLink);
- fall->Y = ComboY(underLink);
- }
- fall->UseSprite(SPR_FALLLAVA);
- fall->CollDetection = false;
- fall->DeadState = fall->ASpeed*fall->NumFrames;
- //Mark as lava damage
- MooshPit[_MP_DAMAGETYPE] = 1;
- }
- //Otherwise it's a pit
- else{
- //Play sound and display animation
- Game->PlaySound(SFX_FALLHOLE);
- fall = CreateLWeaponAt(LW_SCRIPT10, Link->X, Link->Y);
- if(!MOOSHPIT_NO_GRID_SNAP){
- fall->X = ComboX(underLink);
- fall->Y = ComboY(underLink);
- if(isWarp){
- Link->X = ComboX(underLink);
- Link->Y = ComboY(underLink);
- }
- }
- fall->UseSprite(SPR_FALLHOLE);
- fall->CollDetection = false;
- fall->DeadState = fall->ASpeed*fall->NumFrames;
- //Mark as hole damage
- MooshPit[_MP_DAMAGETYPE] = 0;
- }
- MooshPit[_MP_FALLX] = Link->X;
- MooshPit[_MP_FALLY] = Link->Y;
- //Cooldown should last as long as the fall animation
- MooshPit[_MP_FALLSTATE] = 1;
- MooshPit[_MP_FALLTIMER] = Max(MOOSHPIT_MIN_FALL_TIME, fall->DeadState+MOOSHPIT_EXTRA_FALL_TIME);
- //Render Link invisible and intangible
- Link->Invisible = true;
- Link->CollDetection = false;
- NoAction();
- }
- else if(MooshPit_OnPit(Link->X, Link->Y, false)==-1&&Link->Action!=LA_FROZEN){ //All other times, while Link is on solid ground, record Link's last position
- if(sideview){
- //Link has no Z value in sideview, so we check if he's on a platform instead
- if(OnSidePlatform(Link->X, Link->Y)){
- MooshPit[_MP_LASTDMAP] = Game->GetCurDMap();
- MooshPit[_MP_LASTSCREEN] = Game->GetCurDMapScreen();
- MooshPit[_MP_LASTX] = Link->X;
- MooshPit[_MP_LASTY] = Link->Y;
- }
- }
- else{
- if(Link->Z<=0){
- MooshPit[_MP_LASTDMAP] = Game->GetCurDMap();
- MooshPit[_MP_LASTSCREEN] = Game->GetCurDMapScreen();
- MooshPit[_MP_LASTX] = Link->X;
- MooshPit[_MP_LASTY] = Link->Y;
- }
- }
- }
- }
- else if(MooshPit[_MP_FALLSTATE]==1){ //Falling animation
- if(MooshPit[_MP_FALLTIMER]>0)
- MooshPit[_MP_FALLTIMER]--;
- if(MOOSHPIT_STUN_ENEMIES_WHILE_FALLING)
- MooshPit_StunEnemies();
- Link->Jump = 0;
- Link->Z = 0;
- //Keep Link invisible just in case
- Link->Invisible = true;
- Link->CollDetection = false;
- NoAction();
- if(MooshPit[_MP_FALLTIMER]==0){
- MooshPit[_MP_SLIDETIMER] = 0;
- if(!isWarp||MooshPit[_MP_DAMAGETYPE]==1){ //If the pit isn't a warp, deal damage and move Link back to the return point
- //If the entry would dump Link back in the pit, dump him out at the failsafe position
- if(MooshPit_OnPit(MooshPit[_MP_ENTRYX], MooshPit[_MP_ENTRYY], false)==15){
- if(MOOSHPIT_NO_REENTER_STAIRS){
- //Call a script to place an FFC under Link to prevent reentering stairs
- int scriptName[] = "MooshPit_StairsFix";
- int ffcNum = RunFFCScript(Game->GetFFCScript(scriptName), 0);
- if(ffcNum>0){
- ffc f = Screen->LoadFFC(ffcNum);
- f->Flags[FFCF_ETHEREAL] = false;
- f->X = MooshPit[_MP_LASTX];
- f->Y = MooshPit[_MP_LASTY];
- }
- }
- Link->X = MooshPit[_MP_LASTX];
- Link->Y = MooshPit[_MP_LASTY];
- //If the failsafe position was on a different screen, warp there
- if(Game->GetCurDMap()!=MooshPit[_MP_LASTDMAP]||Game->GetCurDMapScreen()!=MooshPit[_MP_LASTSCREEN]){
- Link->PitWarp(MooshPit[_MP_LASTDMAP], MooshPit[_MP_LASTSCREEN]);
- }
- Link->Invisible = false;
- Link->CollDetection = true;
- }
- else{
- if(MOOSHPIT_NO_REENTER_STAIRS){
- //Call a script to place an FFC under Link to prevent reentering stairs
- int scriptName[] = "MooshPit_StairsFix";
- int ffcNum = RunFFCScript(Game->GetFFCScript(scriptName), 0);
- if(ffcNum>0){
- ffc f = Screen->LoadFFC(ffcNum);
- f->Flags[FFCF_ETHEREAL] = false;
- f->X = MooshPit[_MP_ENTRYX];
- f->Y = MooshPit[_MP_ENTRYY];
- }
- }
- //Move Link to the entry and make him visible
- Link->X = MooshPit[_MP_ENTRYX];
- Link->Y = MooshPit[_MP_ENTRYY];
- Link->Invisible = false;
- Link->CollDetection = true;
- }
- //Subtract HP based on damage type
- if(MooshPit[_MP_DAMAGETYPE]==1)
- Link->HP -= DAMAGE_FALLLAVA;
- else
- Link->HP -= DAMAGE_FALLHOLE;
- //Play hurt sound and animation
- Link->Action = LA_GOTHURTLAND;
- Link->HitDir = -1;
- Game->PlaySound(SFX_OUCH);
- MooshPit[_MP_FALLSTATE] = 0;
- }
- else{
- MooshPit[_MP_FALLSTATE] = 2;
- MooshPit[_MP_FALLTIMER] = 1;
- ffc warp = Screen->LoadFFC(FFC_MOOSHPIT_AUTOWARPA);
- warp->Data = CMB_MOOSHPIT_AUTOWARPA;
- warp->Flags[FFCF_CARRYOVER] = false;
- }
- }
- }
- else if(MooshPit[_MP_FALLSTATE]==2){ //Just warped
- if(sideview){
- Link->X = MooshPit[_MP_FALLX];
- Link->Y = 0;
- }
- else{
- Link->X = MooshPit[_MP_FALLX];
- Link->Y = MooshPit[_MP_FALLY];
- Link->Z = 176;
- }
- Link->Invisible = false;
- Link->CollDetection = true;
- if(MOOSHPIT_NO_MOVE_WHILE_FALLING){
- MooshPit[_MP_FALLSTATE] = 3;
- NoAction();
- }
- else
- MooshPit[_MP_FALLSTATE] = 0;
- MooshPit[_MP_FALLTIMER] = 0;
- }
- else if(MooshPit[_MP_FALLSTATE]==3){ //Falling into a new room (no action)
- if(MOOSHPIT_STUN_ENEMIES_WHILE_FALLING)
- MooshPit_StunEnemies();
- NoAction();
- if(IsSideview()){
- if(OnSidePlatform(Link->X, Link->Y))
- MooshPit[_MP_FALLSTATE] = 0;
- }
- else{
- if(Link->Z<=0)
- MooshPit[_MP_FALLSTATE] = 0;
- }
- }
- }
- }
- void MooshPit_ResetEntry(){
- MooshPit[_MP_ENTRYX] = Link->X;
- MooshPit[_MP_ENTRYY] = Link->Y;
- MooshPit[_MP_ENTRYDMAP] = Game->GetCurDMap();
- MooshPit[_MP_ENTRYSCREEN] = Game->GetCurDMapScreen();
- }
- ffc script MooshPit_StairsFix{
- void run(){
- this->Flags[FFCF_ETHEREAL] = false;
- while(LinkCollision(this)){
- Waitframe();
- }
- this->X = 0;
- this->Y = 0;
- this->Data = 0;
- }
- }
- //%MGSO% HEADER_END MooshPit
- //%MGSO% HEADER_START Confusion
- const int CR_CONFUSION = 7; //The counter to use for confusion. CR_SCRIPT# values are 7-31.
- global script Init
- {
- void run()
- {
- Game->MCounter[CR_CONFUSION]=65535; //Max
- }
- }
- void UpdateConfusion()
- {
- if(Link->Drunk > 0)
- {
- Game->Counter[CR_CONFUSION]=Link->Drunk;
- Link->Drunk=0;
- }
- if(Game->Counter[CR_CONFUSION]>0)
- {
- Game->Counter[CR_CONFUSION]--;
- if(Link->InputUp != Link->InputDown)
- {
- Link->InputUp = !Link->InputUp;
- Link->InputDown = !Link->InputDown;
- }
- if(Link->InputLeft != Link->InputRight)
- {
- Link->InputLeft = !Link->InputLeft;
- Link->InputRight = !Link->InputRight;
- }
- }
- }
- item script RemoveConfusion
- {
- void run()
- {
- Game->Counter[CR_CONFUSION]=NULL;
- }
- }
- //%MGSO% HEADER_END Confusion
- //%MGSO% HEADER_START SolidFFC
- //Global Constants
- const int MISC_SOLIDFFC = 14; //A misc value between 0 and 15 to denote a ffc as solid.
- const int MISC_SFFC_X = 0; //This can be used by other ffcs as long as they're not solid.
- const int SFFC_SIDEVIEWTHRESHOLD = 12; //Sideview X Overlap: used for hitdetection.
- const int CRUSH_DAMAGE = 16; //Damage in 16ths of a heart dealt to link when he is crushed.
- const int SF_SIDEWARP = 2; //The flag to denote that Left/Right sidewarps are used on a screen.
- const int BIG_LINK = 0;
- const int CT_LADDER = 0; //If not using CT_RIGHTSTATUE
- //Don't touch me, don't even think about setting these variables. HEY!
- float SFFC_LinkX;
- float SFFC_LinkY;
- // this utility routine by Saffith checks for walkability of combos
- bool isSolid(int x, int y){
- if(x<0 || x>255 || y<0 || y>175) return false;
- int mask=1111b;
- if(x%16< 8) mask&=0011b;
- else mask&=1100b;
- if(y%16< 8) mask&=0101b;
- else mask&=1010b;
- return (!(Screen->ComboS[ComboAt(x, y)]&mask)==0);
- }
- // this utility is used by the ffcs to check if the platform can move link.
- bool CanMoveLink(int x){
- if(x > 0) x+=Link->X+16;
- else if(x < 0) x+=Link->X-1;
- if(x<0) return (Game->GetCurScreen()%16==0 && ScreenFlag(SF_MISC, SF_SIDEWARP));
- if(x>240) return (Game->GetCurScreen()%16==15 && ScreenFlag(SF_MISC,SF_SIDEWARP));
- int mask;
- if(x < Link->X) mask = 1100b;
- else mask = 11b;
- if(Cond(BIG_LINK || IsSideview(),false,true)){
- if(Link->Y % 16 < 8) mask &= ~101b;
- }
- return (Screen->ComboS[ComboAt(x, Link->Y)]&mask)==0 && !OnLadder();
- }
- // You can customize these functions to suit your needs.
- // this utility is used to check if link is doing something that would interfer with him using an item.
- bool LinkBusy()
- {
- return (Link->Action==LA_ATTACKING||Link->Action == LA_CHARGING||Link->Action==LA_FROZEN);
- }
- // this utility is used to check if link using the feather.
- bool UseFeather()
- {
- return !LinkBusy() && ((GetEquipmentA()==I_ROCSFEATHER && Link->PressA) || (GetEquipmentB()==I_ROCSFEATHER && Link->PressB));
- }
- // this utility is used to check if link is on a sideview ladder.
- bool OnLadder()
- {
- int ct = Screen->ComboT[ComboAt(CenterLinkX(),CenterLinkY())];
- return (ct == Cond(CT_LADDER==0,CT_RIGHTSTATUE,CT_LADDER));
- }
- //Editing anything beneath this point may cause sickness, coma, brain anuerysm, or death.
- //Do so at your own risk and don't hold me responsible. Have a good day! ^_^
- void SolidFFCs(int startx, int starty, int linkxpos, int linkypos, bool dragged)
- {
- int reservedx = Link->X;
- int reservedy = Link->Y;
- bool linkmoved[4]; //Up Down Left Right
- int edge[2];
- bool crushed;
- for(int i = 1; i <= 32 && !crushed; i++)
- {
- ffc f = Screen->LoadFFC(i);
- if(!f->Misc[MISC_SOLIDFFC]) continue;
- if(!SFFC_LinkCollision(f, edge)) continue;
- if(!SFFC_SetDirection(f, linkmoved, edge, linkxpos, linkypos))
- {
- crushed = SFFC_CrushLink(f, linkmoved, edge, startx, starty, dragged);
- continue;
- }
- crushed = SFFC_CrushLink(f, linkmoved, edge, startx, starty, dragged);
- if(!crushed)
- {
- if(edge[0]==DIR_UP || edge[0]==DIR_DOWN)
- {
- if(!IsSideview())
- {
- SFFC_LinkY += edge[1];
- if(Abs(SFFC_LinkY) >= 1) Link->Y += Floor(SFFC_LinkY);
- SFFC_LinkY -= Floor(SFFC_LinkY);
- }
- else if(edge[0]==DIR_UP)
- {
- if(!(OnLadder() && UseFeather()))
- Link->Jump=0; //Negate dat dang gravity
- }
- if(Link->InputLeft || Link->InputRight) Link->X = reservedx;
- }
- else if(edge[0]==DIR_LEFT ||edge[0]==DIR_RIGHT)
- {
- SFFC_LinkX += edge[1];
- if(Abs(SFFC_LinkX) >= 1) Link->X += Floor(SFFC_LinkX);
- SFFC_LinkX -= Floor(SFFC_LinkX);
- if(Link->InputUp || Link->InputDown || IsSideview()) Link->Y=reservedy;
- }
- reservedx=Link->X;
- reservedy=Link->Y;
- }
- }
- }
- //As usual Sideview gravity breaks everything even solid ffcs. XD
- int SFFC_SideviewShenanigans(int linkxpos, int linkypos)
- {
- bool linkmoved[4]; //Up Down Left Right
- int edge[2];
- float dragged;
- for(int i = 1; i <= 32; i++)
- {
- ffc f = Screen->LoadFFC(i);
- if(!f->Misc[MISC_SOLIDFFC]) continue;
- if(!SFFC_LinkCollision(f, edge) || !SFFC_SetDirection(f, linkmoved, edge, linkxpos, linkypos))
- {
- f->Misc[MISC_SFFC_X] = f->X;
- continue;
- }
- if(edge[0]==DIR_UP)
- {
- if(!OnLadder())
- {
- if(UseFeather())
- {
- itemdata feather = Game->LoadItemData(I_ROCSFEATHER);
- Link->Jump = feather->InitD[0];
- Game->PlaySound(feather->UseSound);
- f->Misc[MISC_SFFC_X] = f->X;
- break; //Cause it should only happen once per frame.
- }
- else
- {
- if(Link->Jump<=0) Link->Jump=0;
- Link->Y = f->Y-16;
- }
- linkypos = Link->Y;
- }
- if(CanMoveLink(f->X-f->Misc[MISC_SFFC_X]))
- {
- SFFC_LinkX += f->X-f->Misc[MISC_SFFC_X];
- if(Abs(SFFC_LinkX) >= 1)
- {
- Link->X += Floor(SFFC_LinkX);
- SFFC_LinkX -= Floor(SFFC_LinkX);
- }
- linkxpos = Link->X;
- dragged=0.9999;
- }
- else
- {
- linkxpos = Link->X;
- Link->Jump=0;
- dragged=0;
- }
- }
- else if(edge[0]==DIR_DOWN && Link->Jump>0)
- {
- Link->Jump=0;
- }
- f->Misc[MISC_SFFC_X] = f->X;
- }
- return (linkxpos|(linkypos<<8))+dragged;
- }
- //Link Collision
- bool SFFC_LinkCollision(ffc f, int edge)
- {
- int linktop = Link->Y+Cond(BIG_LINK || IsSideview(), 0, 8)>>0;
- int linkbottom = Link->Y+15>>0;
- int linkleft = Link->X>>0;
- int linkright = Link->X+15>>0;
- int top = HitboxTop(f)>>0;
- int bottom = HitboxBottom(f)>>0;
- int left = HitboxLeft(f)>>0;
- int right = HitboxRight(f)>>0;
- int mod=0;
- if(IsSideview()) mod = SFFC_SIDEVIEWTHRESHOLD;
- // horizontal
- if(linktop < bottom && linkbottom > top)
- {
- if(IsSideview()) mod = 16-mod; //Less math.
- if(CenterLinkX() < CenterX(f)) // Left Side
- {
- edge[0]=DIR_LEFT;
- return (linkright >= left+mod);
- }
- else //Right Side
- {
- edge[0]=DIR_RIGHT;
- return (linkleft <= right-mod);
- }
- }
- // vertical
- else if(linkleft < right && linkright > left)
- {
- if(CenterLinkY() < CenterY(f)) // Top Side
- {
- edge[0]=DIR_UP;
- if(IsSideview()) return linkbottom+1 >= top && (linkleft > left-mod && linkleft < left+mod+(f->TileWidth-1)*16);
- else return (linkbottom >= top);
- }
- else //Bottom Side
- {
- edge[0]=DIR_DOWN;
- return (linktop <= bottom);
- }
- }
- else return false;
- }
- bool SFFC_SetDirection(ffc f, bool linkmoved, int edge, int linkxpos, int linkypos)
- {
- //Move link to his old position.
- int x = Link->X;
- int y = Link->Y;
- Link->X = linkxpos;
- Link->Y = linkypos;
- //Then check for collisions again.
- bool ret = SFFC_LinkCollision(f, edge);
- //If we get here we know he didn't walk on the ffc and we got stuff to do.
- if(edge[0]==DIR_UP) edge[1] = -Abs(HitboxTop(f)-(Link->Y+15));
- else if(edge[0]==DIR_DOWN) edge[1] = Abs(HitboxBottom(f)-(Link->Y+Cond(BIG_LINK || IsSideview(),0,8)));
- else if(edge[0]==DIR_LEFT) edge[1] = -Abs(HitboxLeft(f)-(Link->X+15));
- else if(edge[0]==DIR_RIGHT) edge[1] = Abs(HitboxRight(f)-Link->X);
- linkmoved[edge[0]] = true;
- if(!ret)
- {
- if(Link->X >= HitboxLeft(f)-15 && Link->X <= HitboxRight(f) &&
- (Link->InputLeft||Link->InputRight)) Link->X=x;
- else if(Link->Y >= HitboxTop(f)-15 && Link->Y+Cond(BIG_LINK || IsSideview(),0,8) <= HitboxBottom(f) &&
- (Link->InputUp||Link->InputDown) || IsSideview()) Link->Y=y;
- }
- return ret;
- }
- bool SFFC_CrushLink(ffc f, bool linkmoved, int edge, int linkx, int linky, bool dragged)
- {
- // Solid Combos
- bool crush; //Canwalk sucks, do it yourself guys. :)
- if(!IsSideview()) dragged = false;
- if(edge[0]==DIR_UP)
- {
- crush = isSolid(Floor(CenterLinkX()), Floor(Link->Y+Cond(BIG_LINK || IsSideview(), 0,8)+edge[1])) && !dragged;
- if(IsSideview() && crush) crush = (Floor(Link->Y)+16+edge[1]>=HitboxTop(f)); //Squash Bug Fix.
- }
- else if(edge[0]==DIR_DOWN)
- crush = isSolid(Floor(CenterLinkX()), Floor(Link->Y+15+edge[1]));
- else if(edge[0]==DIR_LEFT)
- crush = isSolid(Floor(Link->X+edge[1]), Floor(Link->Y+Cond(BIG_LINK || IsSideview(), 0,8)));
- else if(edge[0]==DIR_RIGHT)
- crush = isSolid(Floor(Link->X+15+edge[1]), Floor(Link->Y+Cond(BIG_LINK || IsSideview(), 0,8)));
- // Solid FFCs
- if(!crush)
- {
- for(int i; i < 4; i++)
- {
- if(linkmoved[i] && i==OppositeDir(edge[0]))
- {
- crush=true;
- break;
- }
- }
- }
- // Crushing Behavior
- if(crush)
- {
- Link->X = Clamp(linkx,0,240);
- Link->Y = Clamp(linky,0,160);
- Link->HP -= CRUSH_DAMAGE;
- Link->Action = LA_GOTHURTLAND;
- Link->HitDir = -1;
- Game->PlaySound(SFX_OUCH);
- }
- return crush;
- }
- ffc script SolidFFC
- {
- void run()
- {
- this->Misc[MISC_SOLIDFFC] = 1;
- this->Misc[MISC_SFFC_X] = this->X;
- }
- }
- //%MGSO% HEADER_END SolidFFC
- //%MGSO% HEADER_START BombArrow
- //Input constants
- const int ArrowDamage = 2; //Damage for Arrow to deal. Wooden sword deals 2 damage
- const int BombDamage = 8; //Damage for explosion to deal
- const int ArrowSpeed = 300; //Speed arrow moves at, in hundredths of pixels per frame
- const int T_BOMBARROW = 28169; //Arrange tiles in the order 'Up,Down,Left,Right' on the tilesheet. Set up-facing bomb arrow tile here
- //Variables
- int UseBombArrow;
- int ArrowX; int ArrowY;
- //Functions
- //Check inherent and regular flags at the same time
- item script BombArrow{
- void run(){
- if(Game->Counter[CR_SBOMBS] > 0 && UseBombArrow == 0){
- UseBombArrow++;
- Game->Counter[CR_SBOMBS]--;
- }
- }
- }
- //%MGSO% HEADER_END BombArrow
- global script MGSO_Combined
- {
- void run()
- {
- //%MGSO% INIT_START ScrollingBackgrounds
- ScrollingBG_Init();
- //%MGSO% INIT_END ScrollingBackgrounds
- //%MGSO% INIT_START MovingPlatforms
- //%MGSO% INIT_END MovingPlatforms
- //%MGSO% INIT_START MooshPit
- MooshPit_Init();
- //%MGSO% INIT_END MooshPit
- //%MGSO% INIT_START Confusion
- //%MGSO% INIT_END Confusion
- //%MGSO% INIT_START SolidFFC
- int olddmap = Game->GetCurDMap();
- int oldscreen = Game->GetCurScreen();
- int startx = Link->X;
- int starty = Link->Y;
- int linkxpos = startx;
- int linkypos = starty;
- bool dragged;
- //%MGSO% INIT_END SolidFFC
- //%MGSO% INIT_START BombArrow
- //%MGSO% INIT_END BombArrow
- while(true)
- {
- //%MGSO% UPDATE1_START ScrollingBackgrounds
- ScrollingBG_Update();
- //%MGSO% UPDATE1_END ScrollingBackgrounds
- //%MGSO% UPDATE1_START MovingPlatforms
- NesMovementFix();
- //%MGSO% UPDATE1_END MovingPlatforms
- //%MGSO% UPDATE1_START MooshPit
- MooshPit_Update();
- //%MGSO% UPDATE1_END MooshPit
- //%MGSO% UPDATE1_START Confusion
- //Waitdraw();
- UpdateConfusion();
- //%MGSO% UPDATE1_END Confusion
- //%MGSO% UPDATE1_START SolidFFC
- if((Link->Action!=LA_SCROLLING) && (olddmap != Game->GetCurDMap() || oldscreen != Game->GetCurScreen()))
- {
- olddmap = Game->GetCurDMap();
- oldscreen = Game->GetCurScreen();
- startx = Link->X;
- starty = Link->Y;
- }
- if(IsSideview())
- {
- //A fix for something I should of done different D:
- float linkposition = SFFC_SideviewShenanigans(linkxpos, linkypos);
- linkxpos = linkposition&0xFF;
- linkypos = (linkposition>>8)&0xFF;
- if((linkposition%1)*10000) dragged=true;
- else dragged=false;
- }
- //%MGSO% UPDATE1_END SolidFFC
- //%MGSO% UPDATE1_START BombArrow
- //Call bomb arrow functions
- if(UseBombArrow > 0) BombArrow();
- //%MGSO% UPDATE1_END BombArrow
- Waitdraw();
- //%MGSO% UPDATE2_START ScrollingBackgrounds
- //%MGSO% UPDATE2_END ScrollingBackgrounds
- //%MGSO% UPDATE2_START MovingPlatforms
- MovingPlatforms();
- //%MGSO% UPDATE2_END MovingPlatforms
- //%MGSO% UPDATE2_START MooshPit
- //%MGSO% UPDATE2_END MooshPit
- //%MGSO% UPDATE2_START Confusion
- //%MGSO% UPDATE2_END Confusion
- //%MGSO% UPDATE2_START SolidFFC
- SolidFFCs(startx, starty, linkxpos, linkypos, dragged);
- linkxpos = Link->X;
- linkypos = Link->Y;
- //%MGSO% UPDATE2_END SolidFFC
- //%MGSO% UPDATE2_START BombArrow
- //%MGSO% UPDATE2_END BombArrow
- Waitframe();
- }
- }
- //%MGSO% FUNCTIONS_START ScrollingBackgrounds
- //%MGSO% FUNCTIONS_END ScrollingBackgrounds
- //%MGSO% FUNCTIONS_START MovingPlatforms
- //%MGSO% FUNCTIONS_END MovingPlatforms
- //%MGSO% FUNCTIONS_START MooshPit
- //%MGSO% FUNCTIONS_END MooshPit
- //%MGSO% FUNCTIONS_START Confusion
- //%MGSO% FUNCTIONS_END Confusion
- //%MGSO% FUNCTIONS_START SolidFFC
- //%MGSO% FUNCTIONS_END SolidFFC
- //%MGSO% FUNCTIONS_START BombArrow
- //bomb arrow functions
- void BombArrow(){
- if(UseBombArrow == 1){
- lweapon Arrow = Screen->CreateLWeapon(LW_ARROW);
- int x; int y;
- if(Link->Dir > 1) x = (Link->Dir-2)*16-8;
- else y = Link->Dir*16-8;
- Arrow->X = Link->X+x;
- Arrow->Y = Link->Y+y;
- Arrow->Dir = Link->Dir;
- Arrow->Tile = T_BOMBARROW;
- Arrow->Tile += Link->Dir;
- Arrow->Damage = ArrowDamage;
- Arrow->Step = ArrowSpeed;
- Game->PlaySound(SFX_ARROW);
- Link->Action = LA_ATTACKING;
- UseBombArrow++;
- }else{
- lweapon Arrow;
- bool Found;
- for(int i=1;i<=Screen->NumLWeapons();i++){
- Arrow = Screen->LoadLWeapon(i);
- if(Arrow->ID != LW_ARROW) continue;
- Found = true;
- }
- if(Found){
- ArrowX = Arrow->X;
- ArrowY = Arrow->Y;
- }else{
- lweapon Exp = Screen->CreateLWeapon(LW_BOMBBLAST);
- Exp->Damage = BombDamage;
- Exp->X = ArrowX;
- Exp->Y = ArrowY;
- UseBombArrow = 0;
- }
- }
- }
- //%MGSO% FUNCTIONS_END BombArrow
- }
- //Pushable Pillars
- const int PILLAR_SENSITIVITY=8; //Number of frames the block needs to be pushed before it starts moving
- ffc script PushablePillars{
- void run(int orientation, int distance){ //Horizontal/Vertical pushing
- distance=distance*16;
- int undercombo;
- int framecounter=0;
- int pushcounter=0;
- int anicounter=0;
- int anitile=0;
- int originaltile=this->Data;
- int pushspeed=1;
- int width=this->TileWidth;
- int height=this->TileHeight;
- Waitframe();
- undercombo=GetLayerComboD(1,this->Y+(this->X>>4));
- if(orientation==1){ SetSolidCombo(3,this->X,this->Y,width,height,this->Data); } //Horizontally
- if(orientation==2){ SetSolidCombo(1,this->X,this->Y,width,height,this->Data); } //Vertically
- while(true){
- if((Link->X==this->X-16 && (Link->Y<this->Y+4+((height-1)*16) && Link->Y>this->Y-4)
- && Link->InputRight && Link->Dir==DIR_RIGHT && orientation==1) || // Right
- (Link->X==this->X+16 && (Link->Y<this->Y+4+((height-1)*16) && Link->Y>this->Y-4)
- && Link->InputLeft && Link->Dir==DIR_LEFT && orientation==1) || // Left
- (Link->Y==this->Y-16 && (Link->X<this->X+4+((width-1)*16) && Link->X>this->X-4)
- && Link->InputDown && Link->Dir==DIR_DOWN && orientation==2) || // Down
- (Link->Y==this->Y+8 && (Link->X<this->X+4+((width-1)*16) && Link->X>this->X-4) //Change the 8 to 16 if you use big Link
- && Link->InputUp && Link->Dir==DIR_UP && orientation==2)
- ){ // Up
- framecounter++;
- }
- else{ framecounter=0; }
- if(framecounter>=PILLAR_SENSITIVITY){
- if(Link->Dir==DIR_RIGHT){
- while(
- this->X<240 &&
- !ComboFI(this->X+16,this->Y,CF_NOBLOCKS) &&
- NoSolidBlocks(4,this->X,this->Y,width,height)==true &&
- pushcounter<distance
- ){
- if(pushcounter==0){ Game->PlaySound(SFX_PUSHBLOCK); }
- if(pushcounter<distance/2){ NoAction(); }
- if(pushcounter%4==0 && pushcounter!=0){ anitile+=1; }
- if(anitile>3){ anitile=0; }
- SetSolidCombo(4,this->X,this->Y,width,height,undercombo);
- this->Vx=pushspeed;
- this->Data=originaltile+anitile;
- pushcounter+=pushspeed;
- Waitframe();
- if(pushcounter%16==0){ SetUnderCombo(4,this->X-16,this->Y,width,height); }
- }
- this->Vx=0;
- this->Data=originaltile;
- pushcounter=0;
- anitile=0;
- SetSolidCombo(4,this->X,this->Y,width,height,this->Data);
- }
- else if(Link->Dir==DIR_LEFT){
- while(
- this->X>0 &&
- !ComboFI(this->X-1,this->Y,CF_NOBLOCKS) &&
- NoSolidBlocks(3,this->X,this->Y,width,height)==true &&
- pushcounter<distance
- ){
- if(pushcounter==0){ Game->PlaySound(SFX_PUSHBLOCK); }
- if(pushcounter<distance/2){ NoAction(); }
- if(pushcounter%4==0 && pushcounter!=0){ anitile-=1; }
- if(anitile<0){ anitile=3; }
- SetSolidCombo(3,this->X,this->Y,width,height,undercombo);
- this->Vx=-pushspeed;
- this->Data=originaltile+anitile;
- pushcounter+=pushspeed;
- Waitframe();
- if(pushcounter%16==0){ SetUnderCombo(3,this->X+16,this->Y,width,height); }
- }
- this->Vx=0;
- this->Data=originaltile;
- pushcounter=0;
- anitile=0;
- SetSolidCombo(3,this->X,this->Y,width,height,this->Data);
- }
- else if(Link->Dir==DIR_DOWN){
- while(
- this->Y<160 &&
- !ComboFI(this->X, this->Y+16, CF_NOBLOCKS) &&
- NoSolidBlocks(2,this->X,this->Y,width,height)==true &&
- pushcounter<distance
- ){
- if(pushcounter==0){ Game->PlaySound(SFX_PUSHBLOCK); }
- if(pushcounter<distance/2){ NoAction(); }
- if(pushcounter%4==0 && pushcounter!=0){ anitile+=4; }
- if(anitile>12){ anitile=0; }
- SetSolidCombo(2,this->X,this->Y,width,height,undercombo);
- this->Vy=pushspeed;
- this->Data=originaltile+anitile;
- pushcounter+=pushspeed;
- Waitframe();
- if(pushcounter%16==0){ SetUnderCombo(2,this->X,this->Y-16,width,height); }
- }
- this->Vy=0;
- this->Data=originaltile;
- pushcounter=0;
- anitile=0;
- SetSolidCombo(2,this->X,this->Y,width,height,this->Data);
- }
- else if(Link->Dir==DIR_UP){
- while(
- this->Y>0 &&
- !ComboFI(this->X, this->Y-1, CF_NOBLOCKS) &&
- NoSolidBlocks(1,this->X,this->Y,width,height)==true &&
- pushcounter<distance
- ){
- if(pushcounter==0){ Game->PlaySound(SFX_PUSHBLOCK); }
- if(pushcounter<distance/2){ NoAction(); }
- if(pushcounter%4==0 && pushcounter!=0){ anitile-=4; }
- if(anitile<0){ anitile=12; }
- SetSolidCombo(1,this->X,this->Y,width,height,undercombo);
- this->Vy=-pushspeed;
- this->Data=originaltile+anitile;
- pushcounter+=pushspeed;
- Waitframe();
- if(pushcounter%16==0){ SetUnderCombo(1,this->X,this->Y+16,width,height); }
- }
- this->Vy=0;
- this->Data=originaltile;
- pushcounter=0;
- anitile=0;
- SetSolidCombo(1,this->X,this->Y,width,height,this->Data);
- }
- framecounter=0;
- }
- Waitframe();
- }
- }
- }
- bool NoSolidBlocks(int direction, int xpos, int ypos, int width, int height){
- int size=1;
- if(direction==1 || direction==2){ size=width; } //Vertical pushing
- if(direction==3 || direction==4){ size=height; } //Horizontal pushing
- for(int i=size-1; i>=0; i--){
- if(xpos%16==0 && ypos%16==0){
- if(direction==1){ if(Screen->ComboS[ypos-16+((xpos+(i*16))>>4)]!=0000b){ return(false); } }
- if(direction==2){ if(Screen->ComboS[ypos+16+((xpos+(i*16))>>4)]!=0000b){ return(false); } }
- if(direction==3){ if(Screen->ComboS[ypos+(i*16)+((xpos-16)>>4)]!=0000b){ return(false); } }
- if(direction==4){ if(Screen->ComboS[ypos+(i*16)+((xpos+16)>>4)]!=0000b){ return(false); } }
- }
- }
- return(true);
- }
- int SetSolidCombo(int direction, int xpos, int ypos, int width, int height, int data){
- int size=1;
- if(direction==1 || direction==2){ size=width; } //Vertical pushing
- if(direction==3 || direction==4){ size=height; } //Horizontal pushing
- for(int i=size-1; i>=0; i--){
- if(xpos%16==0 && ypos%16==0){
- if(direction==1){ Screen->ComboD[ypos+((xpos+(i*16))>>4)]=data; }
- if(direction==2){ Screen->ComboD[ypos+((xpos+(i*16))>>4)]=data; }
- if(direction==3){ Screen->ComboD[ypos+(i*16)+(xpos>>4)]=data; }
- if(direction==4){ Screen->ComboD[ypos+(i*16)+(xpos>>4)]=data; }
- }
- }
- }
- int SetUnderCombo(int direction, int xpos, int ypos, int width, int height){
- int size=1;
- if(direction==1 || direction==2){ size=width; } //Vertical pushing
- if(direction==3 || direction==4){ size=height; } //Horizontal pushing
- for(int i=size-1; i>=0; i--){
- if(xpos%16==0 && ypos%16==0){
- if(direction==1){ Screen->ComboD[ypos+((xpos+(i*16))>>4)]=GetLayerComboD(1,ComboAt(xpos+(i*16),ypos)); }
- if(direction==2){ Screen->ComboD[ypos+((xpos+(i*16))>>4)]=GetLayerComboD(1,ComboAt(xpos+(i*16),ypos)); }
- if(direction==3){ Screen->ComboD[ypos+(i*16)+(xpos>>4)]=GetLayerComboD(1,ComboAt(xpos,ypos+(i*16))); }
- if(direction==4){ Screen->ComboD[ypos+(i*16)+(xpos>>4)]=GetLayerComboD(1,ComboAt(xpos,ypos+(i*16))); }
- if(direction==1){ Screen->ComboT[ypos+((xpos+(i*16))>>4)]=GetLayerComboT(1,ComboAt(xpos+(i*16),ypos)); }
- if(direction==2){ Screen->ComboT[ypos+((xpos+(i*16))>>4)]=GetLayerComboT(1,ComboAt(xpos+(i*16),ypos)); }
- if(direction==3){ Screen->ComboT[ypos+(i*16)+(xpos>>4)]=GetLayerComboT(1,ComboAt(xpos,ypos+(i*16))); }
- if(direction==4){ Screen->ComboT[ypos+(i*16)+(xpos>>4)]=GetLayerComboT(1,ComboAt(xpos,ypos+(i*16))); }
- }
- }
- }
- //Different Armos
- ffc script differentArmos{
- void run ( int newTile, int cset ){
- while ( true ){
- for ( int i = Screen->NumNPCs(); i > 0; i-- ){
- npc enem = Screen->LoadNPC(i);
- if ( enem->ID == NPC_ARMOS && (enem->Misc[15] & 0xf0000) == 0 ){ //check some flag...
- enem->CSet = cset;
- enem->OriginalTile = newTile;
- enem->Misc[15] |= 0xf0000;
- }
- }
- Waitframe();
- }
- }
- }
- //Perm Push Blocks
- //Instructions:
- //1. Make a new combo with inherent flag 16 (or any secret flag)
- //2. Set this FFC to the above combo
- //3. When secrets are triggered by blocks, this script will make it permanent
- ffc script blockPermSecrets{
- void run(){
- int thisCombo = this->Data;
- while(!Screen->State[ST_SECRET]){
- if(this->Data != thisCombo) Screen->State[ST_SECRET] = true;
- Waitframe();
- }
- }
- }
- //MogShop
- const int MogShop_DefaultFailMessage = 1; // Default message to play when Link can't afford the item
- const int MogShop_PriceTag = 1; // use 0 if you don't want to display price tags, otherwise use 1
- const int MogShop_FontColour = 0x01; // colour of the price tag font (the 2 digits after "0x" is the code for your colour)
- const int MogShop_FontOutline = 0x0F; // colour of the price tag font's outline
- const int MogShop_FontType = 16; // which font to use (0 is the Z1 font, 16 is the LA font. you might have to look up std_constants.zh or just experiment)
- const int MogShop_FontYOffset = -8; // positional offset of the price tag on the Y axis relative to the FFC
- const int MogShop_SoldOutComboID = 1054; // ID of the combo for the FFC to be when the item is sold out (can't use 0)
- const int MogShop_SoldOutComboCSet = 8; // CSet of the combo
- const int MogShop_InteractComboID = 0; // ID of the combo to show above Link's head when he's standing in front of the item. Use 0 if you don't want any.
- const int MogShop_InteractComboCSet = 8; // CSet of the combo
- ffc script MogShop{
- void run(int ShopItem, int InfoMessage, int Price, int Currency, int OnlyOnceID, int FailMessage, int CollisionStyle){
- // Saves the width and height of the FFC for collision checks
- int Width = 16;
- int Height = 16;
- if(this->EffectWidth!=16)
- Width = this->EffectWidth;
- else if(this->TileWidth>1)
- Width = this->TileWidth*16;
- if(this->EffectHeight!=16)
- Height = this->EffectHeight;
- else if(this->TileHeight>1)
- Height = this->TileHeight*16;
- // Determine collision check position
- int HitX = this->X;
- int HitY = this->Y;
- if ( CollisionStyle != 0 )
- HitY = this->Y + 8;
- // Disable the shop if the item is sold out
- int SoldOutComboID = MogShop_SoldOutComboID;
- if ( SoldOutComboID < 0 )
- SoldOutComboID = 1;
- if ( OnlyOnceID >= 0 ) {
- if ( Screen->D[OnlyOnceID] == 1 ) {
- this->Data = SoldOutComboID;
- this->CSet = MogShop_SoldOutComboCSet;
- while(true){
- DrawOverUpdate(this, HitX, HitY, CollisionStyle);
- Waitframe();
- }
- }
- }
- // Determine currency
- int CounterToUse = Currency;
- if ( Currency <= 0 )
- CounterToUse = 1;
- // Create price tag string
- int PriceTag[100];
- itoa(PriceTag, Price);
- // Determine price tag layer
- int PriceTagLayer;
- if ( CollisionStyle != 0 )
- PriceTagLayer = 6;
- while(true){
- // Check collision with the item
- bool CanInteract;
- if ( LinkCanInteract() ) {
- // Facing Up
- if(Link->Dir==DIR_UP&&Link->Y>=HitY&&Link->Y<=HitY+Height-8&&Link->X>=HitX-8&&Link->X<=HitX+Width-8)
- CanInteract = true;
- else if ( CollisionStyle == 0 ) { // Only allow other directions when CollisionStyle is 0
- // Facing Down
- if(Link->Dir==DIR_DOWN&&Link->Y>=HitY-16&&Link->Y<=HitY+Height-16&&Link->X>=HitX-8&&Link->X<=HitX+Width-8)
- CanInteract = true;
- // Facing Left
- else if(Link->Dir==DIR_LEFT&&Link->Y>=HitY-8&&Link->Y<=HitY+Height-9&&Link->X>=HitX&&Link->X<=HitX+Width)
- CanInteract = true;
- // Facing Right
- else if(Link->Dir==DIR_RIGHT&&Link->Y>=HitY-8&&Link->Y<=HitY+Height-9&&Link->X>=HitX-16&&Link->X<=HitX+Width-16)
- CanInteract = true;
- }
- }
- DrawOverUpdate(this, HitX, HitY, CollisionStyle);
- // Draw price tag
- if ( MogShop_PriceTag == 1 ) {
- Screen->DrawString(PriceTagLayer, this->X+8 +1, this->Y+MogShop_FontYOffset, MogShop_FontType, MogShop_FontOutline, -1, TF_CENTERED, PriceTag, OP_OPAQUE);
- Screen->DrawString(PriceTagLayer, this->X+8 -1, this->Y+MogShop_FontYOffset, MogShop_FontType, MogShop_FontOutline, -1, TF_CENTERED, PriceTag, OP_OPAQUE);
- Screen->DrawString(PriceTagLayer, this->X+8, this->Y+MogShop_FontYOffset +1, MogShop_FontType, MogShop_FontOutline, -1, TF_CENTERED, PriceTag, OP_OPAQUE);
- Screen->DrawString(PriceTagLayer, this->X+8, this->Y+MogShop_FontYOffset -1, MogShop_FontType, MogShop_FontOutline, -1, TF_CENTERED, PriceTag, OP_OPAQUE);
- Screen->DrawString(PriceTagLayer, this->X+8, this->Y+MogShop_FontYOffset, MogShop_FontType, MogShop_FontColour, -1, TF_CENTERED, PriceTag, OP_OPAQUE);
- }
- // Handle interaction
- if ( CanInteract ) {
- if ( Link->PressA ) {
- Link->InputA = false;
- Link->PressA = false;
- Screen->Message(InfoMessage);
- }
- else if ( Link->PressR ) {
- Link->InputR = false;
- Link->PressR = false;
- // Check if affordable
- if ( Game->Counter[CounterToUse] >= Price && (CounterToUse != CR_LIFE || Game->Counter[CR_LIFE] - Price > 0) ) {
- Game->DCounter[CounterToUse] -= Price;
- item drop = CreateItemAt(ShopItem, Link->X, Link->Y);
- SetItemPickup(drop, IP_HOLDUP, true);
- if ( OnlyOnceID >= 0 ) { // Check if it can only be bought once
- Screen->D[OnlyOnceID] = 1;
- this->Data = SoldOutComboID;
- this->CSet = MogShop_SoldOutComboCSet;
- while(true){
- DrawOverUpdate(this, HitX, HitY, CollisionStyle);
- Waitframe();
- }
- }
- }
- else { // Can't afford
- if ( FailMessage > 0 )
- Screen->Message(FailMessage);
- else
- Screen->Message(MogShop_DefaultFailMessage);
- }
- }
- else if ( MogShop_InteractComboID > 0 )
- Screen->FastCombo(6, Link->X, Link->Y-16, MogShop_InteractComboID, MogShop_InteractComboCSet, OP_OPAQUE);
- }
- Waitframe();
- }
- }
- bool LinkCanInteract(){
- if ( Link->Action != LA_NONE && Link->Action != LA_WALKING )
- return false;
- if ( Link->Z > 0 )
- return false;
- return true;
- }
- void DrawOverUpdate(ffc this, int HitX, int HitY, int CollisionStyle){
- // Toggle draw-over if CollisionStyle is not 0
- if ( CollisionStyle != 0 ) {
- if ( Link->Y < HitY )
- this->Flags[FFCF_OVERLAY] = true;
- else
- this->Flags[FFCF_OVERLAY] = false;
- }
- }
- }
- //Don't move - Character Direction Script
- //Character Direction Script
- ffc script dontMove{
- void run(int dir){
- while(true){
- Link->Dir = dir;
- WaitNoAction();
- }
- }
- }
- //PlaySound
- //Trigger SFX Script
- ffc script TriggerSFX{
- void run(int sfx){
- int loc = ComboAt(this->X,this->Y);
- int orig = Screen->ComboD[loc];
- while(Screen->ComboD[loc] == orig) Waitframe();
- Game->PlaySound(sfx);
- }
- }
- //SFX On Screen Entry
- // D0 - The SFX ID that you want to play.
- ffc script OnEntrySound{
- void run(int sfx){
- // Play the sound effect.
- Game->PlaySound(sfx);
- // Quit the script.
- Quit();
- }
- }
- //True Push Block Under Combo
- //D0: If D0 >0, set to the map to use as reference for under combos
- //D1: If D0 >0, set to the screen to use as reference for under combos (convert screen numbers from Hex to Decimal)
- ffc script TruePushblockUnderCombo{
- void run(int refMap, int refScreen){
- int i;
- int pos;
- int cd; int cc; int cf; int ci;
- int pushBlockX;
- int pushBlockY;
- bool wasPushBlock; //Keeps track of whether a push block has started moving
- int underCMB[176];
- int underCS[176];
- int underFlag[176];
- //Mark which flags are push blocks
- bool pushFlags[105];
- pushFlags[CF_PUSHUPDOWN] = true;
- pushFlags[CF_PUSH4WAY] = true;
- pushFlags[CF_PUSHLR] = true;
- pushFlags[CF_PUSHUP] = true;
- pushFlags[CF_PUSHDOWN] = true;
- pushFlags[CF_PUSHLEFT] = true;
- pushFlags[CF_PUSHRIGHT] = true;
- pushFlags[CF_PUSHUPDOWNNS] = true;
- pushFlags[CF_PUSHLEFTRIGHTNS] = true;
- pushFlags[CF_PUSH4WAYNS] = true;
- pushFlags[CF_PUSHUPNS] = true;
- pushFlags[CF_PUSHDOWNNS] = true;
- pushFlags[CF_PUSHLEFTNS] = true;
- pushFlags[CF_PUSHRIGHTNS] = true;
- pushFlags[CF_PUSHUPDOWNINS] = true;
- pushFlags[CF_PUSHLEFTRIGHTINS] = true;
- pushFlags[CF_PUSH4WAYINS] = true;
- pushFlags[CF_PUSHUPINS] = true;
- pushFlags[CF_PUSHDOWNINS] = true;
- pushFlags[CF_PUSHLEFTINS] = true;
- pushFlags[CF_PUSHRIGHTINS] = true;
- //Set initial values for all combos on the screen
- for(i=0; i<176; i++){
- cd = Screen->ComboD[i];
- cc = Screen->ComboC[i];
- cf = Screen->ComboF[i];
- ci = Screen->ComboI[i];
- //Set combos underneath a push block
- if(pushFlags[cf] || pushFlags[ci]){
- //If a reference screen is set, draw from that
- if(refMap>0){
- underCMB[i] = Game->GetComboData(refMap, refScreen, i);
- underCS[i] = Game->GetComboCSet(refMap, refScreen, i);
- underFlag[i] = Game->GetComboFlag(refMap, refScreen, i);
- }
- //Otherwise use under combo
- else{
- underCMB[i] = Screen->UnderCombo;
- underCS[i] = Screen->UnderCSet;
- underFlag[i] = 0;
- }
- }
- else{
- underCMB[i] = cd;
- underCS[i] = cc;
- underFlag[i] = cf;
- }
- }
- while(true){
- //If there's a push block on the screen, manage undercombos
- if(Screen->MovingBlockX>-1){
- //If the block just started moving, set the undercombo
- if(!wasPushBlock){
- pos = ComboAt(Screen->MovingBlockX+8, Screen->MovingBlockY+8);
- Screen->ComboD[pos] = underCMB[pos];
- Screen->ComboC[pos] = underCS[pos];
- Screen->ComboF[pos] = underFlag[pos];
- }
- pushBlockX = Screen->MovingBlockX;
- pushBlockY = Screen->MovingBlockY;
- wasPushBlock = true;
- }
- else{
- wasPushBlock = false;
- for(i=0; i<176; i++){
- cd = Screen->ComboD[i];
- cc = Screen->ComboC[i];
- cf = Screen->ComboF[i];
- ci = Screen->ComboI[i];
- //Only update combos in the array if they aren't covered by a push block
- if(!(pushFlags[cf] || pushFlags[ci])){
- underCMB[i] = cd;
- underCS[i] = cc;
- underFlag[i] = cf;
- }
- }
- }
- Waitframe();
- }
- }
- }
- //Item Bundle Script
- // This script is a pickup script that will give some items.
- // This was mostly made to bundle the Bow and Arrows into one item,
- // but it could have other uses.
- // Bundle this with an item that increases a counter to also increase counters.
- // D0-D7: Items to give.
- // D0: If D0 is negative, it will display an item pickup message containing the positive version of the number entered...
- item script itemBundle{
- void run(int item1, int item2, int item3, int item4, int item5, int item6, int item7, int item8)
- {
- if(item1 > 0)
- Link->Item[item1] = true;
- if(item2 > 0)
- Link->Item[item2] = true;
- if(item3 > 0)
- Link->Item[item3] = true;
- if(item4 > 0)
- Link->Item[item4] = true;
- if(item5 > 0)
- Link->Item[item5] = true;
- if(item6 > 0)
- Link->Item[item6] = true;
- if(item7 > 0)
- Link->Item[item7] = true;
- if(item8 > 0)
- Link->Item[item8] = true;
- // Display Item pickup message?
- if(item1 < 0)
- {
- Screen->Message(item1 * -1);
- }
- }//!End void run()
- }//!End item script itemBundle
- //TieredItemPickup
- item script TieredItemPickup{
- void run(int lowTier, int secondTier, int thirdTier, int fourthTier, int fifthTier, int sixthTier, int highTier, int m){
- if (Link->Item[sixthTier]){
- Link->Item[highTier] = true;
- Screen->Message(m);
- }
- else if (Link->Item[fifthTier]){
- Link->Item[sixthTier] = true;
- Screen->Message(m);
- }
- else if (Link->Item[fourthTier]){
- Link->Item[fifthTier] = true;
- Screen->Message(m);
- }
- else if (Link->Item[thirdTier]){
- Link->Item[fourthTier] = true;
- Screen->Message(m);
- }
- else if (Link->Item[secondTier]){
- Link->Item[thirdTier] = true;
- Screen->Message(m);
- }
- else if (Link->Item[lowTier]){
- Link->Item[secondTier] = true;
- Screen->Message(m);
- }
- else {
- Link->Item[lowTier]= true;
- Screen->Message(m);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement