Jump to content

Photo

Ice Wall spell


  • Please log in to reply
20 replies to this topic

#1 MoscowModder

MoscowModder

    Sometimes lurking. Rarely posting.

  • Members
  • Location:Wisconsin

Posted 23 May 2012 - 02:36 PM

This is my latest magic spell. It makes an icicle/stalagmite (if on land) or a patch of ice (on water) in front of Link.

It calculates the position by making an lweapon in front of Link with the inFrontLink() function (I do use the lweapon for the sprite and not just its location btw)... except that it actually appears right behind Link (at his position). Why is this?

CODE
//Usage in spellcasting script:
    //int args[1] = {duration}
    //if(!CountFFCsRunning(ffcScriptNum))
        //RunFFCScript(ffcScriptNum, args);

const int WPS_ICESPARKLE = 92; //Sprite of ice sparkle
const int WPS_ICEMELT = 106;
const int icicleCombo = 35528; //Icicle combo that forms on land (MUST BE 8-BIT)
const int iceTile = 53256; //Tile to draw over water
const int noIceFlag = 96; //Flag that prevents freezing combos (no enemies)
        
ffc script iceWall{
    void run ( int duration ){
        bool onLand = false; //Layer to restore to (0 for ice, 2 for icicle)
        
        int oldCombo; //Data of previous combo
        
        lweapon sparkle = NextToLink(LW_SPARKLE, 0); //Make a sparkle lweapon
        Waitframe(); //Wait a frame - if it is out of bounds it will become invalid
        if ( !sparkle->isValid() || Screen->isSolid(sparkle->X+8, sparkle->Y+8) || ComboFI(sparkle->X+8, sparkle->Y+8, noIceFlag)) return; //If combo is out of bounds or combo in front of Link is solid or combo has "no ice" flag, quit
        
        int inFront = ComboAt (sparkle->X+8, sparkle->Y+8); //Otherwise find combo under the sparkle
        sparkle->UseSprite(WPS_ICESPARKLE);
        sparkle->X = ComboX(inFront);
        sparkle->Y = ComboY(inFront); //Draw the sparkle on the combo
        if(IsPit(inFront)) return; //If it's a pit, exit
        if(IsWater(inFront)){ //If sparkle is over water,
            oldCombo = Screen->ComboT[inFront]; //Save layer 0 data
            Screen->ComboT[inFront] = CT_NONE; //Set combo to walkable ice
        }
        else{ //Otherwise if on land
            oldCombo = GetLayerComboD(1, inFront); //Save layer 2 data
            onLand = true;
            SetLayerComboD(1, inFront, icicleCombo); //Set layer 2 to icicle
        }
                                                                                                                Game->Counter[CR_RUPEES] = oldCombo;
        Game->PlaySound(SFX_ICE); //Play ice SFX
        
        for (; duration > 0; duration-- ){ //Wait for spell to wear off
            if ( (Link->X < 4 && Link->InputLeft)
            || (Link->X > 230 && Link->InputRight)
            || (Link->Y < 4 && Link->InputUp)
            || (Link->Y > 150 && Link->InputDown)    //If Link walks towards the edge of the screen
            || !Link->HP                            //Or dies
            || isWarp(ComboAt(Link->X+8, Link->Y+8))            //Or stands on a warp
            || isWarp(ComboAt(Link->X+8+InFrontX(Link->Dir, 0), Link->Y+8+InFrontY(Link->Dir, 0)))
            || isWarp(ComboAt(Link->X+8+InFrontX(Link->Dir, 4), Link->Y+8+InFrontY(Link->Dir, 4))) //Or is in front of a warp
            || (Link->Dir == DIR_UP && isWarp(ComboAt(Link->X+8, Link->Y+InFrontY(Link->Dir, 4)))) //Or is walking into a house/cave/etc
            ) duration = -1;                                //Exit the loop and let the script end
            if ( !onLand ) Screen->FastTile(0, ComboX(inFront), ComboY(inFront), iceTile, 7, 128 ); //Draw the ice tile rather than changing combo data - handles different water colors
            if ( duration == 10 || duration == -1 ){ //When 10 frames remain or loop quits early
                sparkle = CreateLWeaponAt(LW_SPARKLE, ComboX(inFront), ComboY(inFront)); //Make a melting sprite as it is about to vanish
                sparkle->UseSprite(WPS_ICEMELT);
            }
            Waitframe(); //Otherwise continue the game
        }
        
        if ( onLand )
            SetLayerComboD(1, inFront, oldCombo); //Restore old combo afterwards
        else
            Screen->ComboT[inFront] = oldCombo;
    }
}

bool isWarp(int loc){
    int type = Screen->ComboT[loc];
    return type == CT_DIVEWARP || type == CT_DIVEWARPB || type == CT_DIVEWARPC || type == CT_DIVEWARPD || type == CT_PIT || type == CT_PITB || type == CT_PITC || type == CT_PITD || type == CT_STAIR || type == CT_STAIRB || type == CT_STAIRC || type == CT_STAIRD || type == CT_STAIRR || type == CT_SWIMWARP || type == CT_SWIMWARPB || type == CT_SWIMWARPC || type == CT_SWIMWARPD;
}


If you help me fix this, I might let you use my script for yourself icon_slycool.gif

UPDATE: It now actually works. It's not perfect yet, though.
UPDATE 2: Has limited checking for exit by warp, and has animations for creating/melting ice

Edited by MoscowModder, 24 May 2012 - 10:18 PM.


#2 Saffith

Saffith

    IPv7 user

  • Members

Posted 23 May 2012 - 03:02 PM

You want NextToLink(LW_SPARKLE, 0). The distance actually refers to the space between their facing edges, not their top-left corners.

#3 MoscowModder

MoscowModder

    Sometimes lurking. Rarely posting.

  • Members
  • Location:Wisconsin

Posted 23 May 2012 - 05:08 PM

Great, thanks! Next problem: it doesn't change the combo beneath it. The line that changes the rupee counter does not change it at all. Why would that be?

#4 SUCCESSOR

SUCCESSOR

    Apprentice

  • Banned
  • Real Name:TJ

Posted 23 May 2012 - 06:04 PM

never mind the rupee counter is changing consistently now.

I noticed that if you don't have layer 2 set up the icicle doesn't work and if you go off screen the icicles become permanant


Edited by SUCCESSOR, 23 May 2012 - 06:20 PM.


#5 MoscowModder

MoscowModder

    Sometimes lurking. Rarely posting.

  • Members
  • Location:Wisconsin

Posted 23 May 2012 - 06:25 PM

Ohhh you need to have layer 2 set up! That explains it.

Yeah, I was wondering how to make it non-permanent...

Any ideas?

#6 SUCCESSOR

SUCCESSOR

    Apprentice

  • Banned
  • Real Name:TJ

Posted 23 May 2012 - 06:48 PM

A global script the checks if the screen changed and undoes the script? (Edit: Can you edit a screen if it is not the active screen?)

I had a similar problem using an item script to trigger a ffc. I ended up converting the whole thing to a global script.

Also noticed, I set up one screen with an invisible layer 2 using screen 00, when i use the item on a screen with no layer 2 it creates an icicle on screen 00 so it shows up on the screen that I have set up with 00 as layer 2.

Edited by SUCCESSOR, 23 May 2012 - 07:06 PM.


#7 MoscowModder

MoscowModder

    Sometimes lurking. Rarely posting.

  • Members
  • Location:Wisconsin

Posted 23 May 2012 - 07:24 PM

Okay, it's starting to work. I tried checking for Link nearing the edge of the screen to leave, but it doesn't undo the ice.

I had another idea, though - perhaps instead of changing combos it could make an lweapon that mimics the effect.

But how?

It might be possible to change enemy directions when they come really close to the ice block/icicle, but I can't think how to make the water walkable.

#8 SUCCESSOR

SUCCESSOR

    Apprentice

  • Banned
  • Real Name:TJ

Posted 23 May 2012 - 08:46 PM

you can't search the screen for the ice or icicle combo and return it to the saved combo when link is at the edge of the screen?

Edited by SUCCESSOR, 23 May 2012 - 08:46 PM.


#9 MoscowModder

MoscowModder

    Sometimes lurking. Rarely posting.

  • Members
  • Location:Wisconsin

Posted 23 May 2012 - 09:39 PM

I tried doing that but it doesn't work.

And I don't need to search for it - the script already knows where it is and can remove it after the timer is up.

#10 SUCCESSOR

SUCCESSOR

    Apprentice

  • Banned
  • Real Name:TJ

Posted 23 May 2012 - 09:44 PM

I realized that and tried it. I don't understand why it doesn't work. Do you have to map out every point near the edges of the screen for it to register that link is crossing it?

#11 MoscowModder

MoscowModder

    Sometimes lurking. Rarely posting.

  • Members
  • Location:Wisconsin

Posted 23 May 2012 - 10:00 PM

I doubt it... I thought I just had to check if Link is within 4px of the edge.

Actually, after experimenting a bit, it seems that it does work - I just picked the wrong right/down values.

#12 SUCCESSOR

SUCCESSOR

    Apprentice

  • Banned
  • Real Name:TJ

Posted 23 May 2012 - 10:38 PM

Nice I just put this in the for() loop:
CODE
if(Link->X == 4 || Link->Y == 4 || Link->X == 236 || Link->Y == 144 || Link->X == 6 || Link->Y == 6 || Link->X == 238 || Link->Y == 146)
            {
                if ( onLand )
                    SetLayerComboD(2, inFront, oldCombo); //Restore old combo afterwards
                else
                    Screen->ComboD[inFront] = oldCombo;
            }


I had to double up the coordinates or else it only worked sometimes. I haven't been able to make it fail so far. I tried this a couple hours ago but I put it in the wrong place so it was pointless.

when you use the item facing upward does the icicle appear diagonally to the left?

Edited by SUCCESSOR, 23 May 2012 - 10:47 PM.


#13 tox_von

tox_von

    Zelda Addict

  • Members
  • Real Name:Redgor
  • Location:Toxicville , Simcity

Posted 23 May 2012 - 11:22 PM

couldnt you set duration to 0 instead of breaking if link exits the screen.

#14 SUCCESSOR

SUCCESSOR

    Apprentice

  • Banned
  • Real Name:TJ

Posted 24 May 2012 - 12:07 AM

Why yes you can. Not like that is obvious or anything!

#15 MoscowModder

MoscowModder

    Sometimes lurking. Rarely posting.

  • Members
  • Location:Wisconsin

Posted 24 May 2012 - 08:35 AM

Tox: It has the exact same effect.
Successor: Actually, I got mine to work with the <= and >= after changing the values a bit.


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users