Jump to content

Photo

Script Request: Enemies gain power as Link progresses


  • Please log in to reply
14 replies to this topic

#1 Silence429

Silence429

    Recipient of Ways

  • Members
  • Real Name:Brian
  • Location:Tampa Bay Area

Posted 17 January 2009 - 07:39 PM

Here's the problem:

I'm creating a quest with a bit of backtracking, including visiting previous dungeons. The issue that arises is in maintaining consistent difficulty. When I'll have Link return to these earlier areas, he'll pretty much uber-pwn the enemies there because he has more health and better weapons. I do not want this to happen. The only fix I can think of is making multiple copies of the maps with the harder versions of the previous enemies...I'd prefer not to go through this.

So, my script request:
When Link picks up a heart container, I want all of the enemies in the quest to increase their maximum health a little bit, too. Same with upgrading the sword, I want the enemies to gain a little attack power. I'm not sure what type of script this would have to be for my idea to work, and I have no idea if this is even possible.

I've been searching around quite a bit for this type of script, so I hope this isn't a repeat thread. I hope my description makes sense, and thank you in advance for your help.

Edited by Silence429, 17 January 2009 - 07:40 PM.


#2 Elmensajero

Elmensajero

    Doyen(ne)

  • Members
  • Real Name:John
  • Location:Raleigh, North Carolina

Posted 17 January 2009 - 10:28 PM

This could probably be done with a global script similar to code below (the script doesn't do anything at the moment though.) How exactly do you want the enemies health and attack power to increase? (As an example, "increase an enemy's hp by 2 for every heart that Link has". A weapon with a power of 1 deals 2 hitpoints of damage to an enemy as a reference.) Next, are there any other items besides the swords you want to trigger this power-up enemies script (like the hammer perhaps?) Also, remember that with the way you specified it above, all of the enemies, including harder ones like Gleeoks, will have the increase done to them, so this may make later parts of the quest extremely difficult. Of course, it could be designed so that the enemies are only powered up if Link has gotten the Triforce piece for that dungeon, or if you have any additional ideas, just ask to see if they are possible.

CODE

import "std.zh"

global script slot2
{
    void run()
    {
        int currentscreen=Game->GetCurScreen();
        int currentmap=Game->GetCurMap();
        
        while(true)
        {
            if(currentscreen!=Game->GetCurScreen() || currentmap!=GetCurMap())
            {
                Waitframes(4);
                increaseEnemyHealth();
                increaseEnemyAttack();
            }
            Waitframe();
        }
    }
    
    void increaseEnemyHealth()
    {
        int totalenemies=Screen->NumNPCs();
        for(int enemy=0;enemy<totalenemies;enemy++)
        {
            enemy->HP+=0;
        }
    }
    
    void increaseEnemyAttack()
    {
        int totalenemies=Screen->NumNPCs();
        int attlevel=1;
        if(Link->Item[SWORD2]) attlevel=2;
        if(Link->Item[SWORD3]) attlevel=3;
        if(Link->Item[SWORD4]) attlevel=4;
        for(int enemy=0;enemy<totalenemies;enemy++)
        {
            enemy->Damage+=0;
            enemy->WeaponDamage+=0;
        }
    }
}

Edited by Elmensajero, 17 January 2009 - 10:30 PM.


#3 Silence429

Silence429

    Recipient of Ways

  • Members
  • Real Name:Brian
  • Location:Tampa Bay Area

Posted 18 January 2009 - 01:05 AM

Hmmm, well I was thinking:
*Upgrade sword -> increase damage caused by enemies by 1/2 heart
Obtain hammer, gain/upgrade candle, gain/upgrade arrows, gain/upgrade bombs -> increase damage by 1/4 heart
Obtain wand -> increase damage by 1/2 heart

*Obtain Heart container -> increase enemy hp by 2 points
Upgrade ring -> double enemy hp (or would that be too evil in some cases? icon_razz.gif)

* = the main things I'd like, just in case it isn't possible to do everything I listed.

I see what you're saying about the more difficult enemies, but what I'll probably do is lower their initial HP and damage numbers in the enemy editor. So, when Link's progression adds on to these values, it shouldn't be too overwhelming for the player in the later portions of the quest.

Edited by Silence429, 18 January 2009 - 01:08 AM.


#4 Elmensajero

Elmensajero

    Doyen(ne)

  • Members
  • Real Name:John
  • Location:Raleigh, North Carolina

Posted 21 January 2009 - 01:05 AM

I added everything you suggested so far in the previous post. I have not tested it to see if it works, but I know that it does compile with no errors. All you have to do is set the global script to slot2 and thats it. I also wrote an ffc script called noincrease(). If there is a screen where you don't want the enemies to be powered up, just attach that script to it. Test it and see if it works, and let me know if there any changes you would like.

CODE

import "std.zh"

//global variables
int upattack;
int uphealth;
int startinghp;
bool doincrease=true;

global script slot2
{
    void run()
    {
        int currentscreen=Game->GetCurScreen();
        int currentmap=Game->GetCurMap();
        if(startinghp==0) startinghp=Link->MaxHP;
        
        while(true)
        {
            //Every time Link enters a new screen...
            if(currentscreen!=Game->GetCurScreen() || currentmap!=Game->GetCurMap())
            {
                currentscreen=Game->GetCurScreen();
                currentmap=Game->GetCurMap();
                freezelink(4); //Wait until the enemies are loaded
                calculatePowerup(); //Calculate amount to power up enemies on the screen
                increaseEnemyPower(); //Increase enemy health and attack
            }
            Waitframe();
        }
    }
    
    void increaseEnemyPower()
    {
        int totalenemies=Screen->NumNPCs();
        
        //if noincrease() is applied to current screen, don't power up enemies
        if(doincrease==false)
        {
            doincrease=true; //reset global variable for next screen
            return; //go back to main function of global script before enemies are powered up
        }
        
        //otherwise, power up each enemy on the screen
        for(int e=1;e<=totalenemies;e++)
        {
            npc enemy=Screen->LoadNPC(e);
            enemy->HP+=uphealth;
            enemy->Damage+=upattack;
            enemy->WeaponDamage+=upattack;
        }
    }
    
    void calculatePowerup()
    {
        //calculate amount to increase enemy's health
        uphealth=(Link->MaxHP-startinghp)/8;
        if(Link->Item[I_RING1]) uphealth*=2;
        if(Link->Item[I_RING2]) uphealth*=2;
        if(Link->Item[I_RING3]) uphealth*=2;
        
        //calculate amount to increase enemy's attack (in quarter-heart increments)
        upattack=0;
        if(Link->Item[I_SWORD2])   upattack+=2;
        if(Link->Item[I_SWORD3])   upattack+=2;
        if(Link->Item[I_SWORD4])   upattack+=2;
        if(Link->Item[I_WAND])     upattack+=2;
        if(Link->Item[I_HAMMER])   upattack+=1;
        if(Link->Item[I_CANDLE1])  upattack+=1;
        if(Link->Item[I_CANDLE2])  upattack+=1;
        if(Link->Item[I_ARROW1])   upattack+=1;
        if(Link->Item[I_ARROW2])   upattack+=1;
        if(Link->Item[I_ARROW3])   upattack+=1;
        if(Link->Item[I_BOMBBAG1]) upattack+=1;
        if(Link->Item[I_BOMBBAG2]) upattack+=1;
        if(Link->Item[I_BOMBBAG3]) upattack+=1;
        if(Link->Item[I_BOMBBAG4]) upattack+=1;
    }
}

void freezelink(int frames)
{
    for(int counter=frames;counter>0;counter--)
    {
        Link->InputUp=false;
        Link->InputDown=false;
        Link->InputLeft=false;
        Link->InputRight=false;
        Waitframe();
    }
}

//apply this ffc script to any screen where you don't want the enemies to be powered up on
ffc script noincrease
{
    void run()
    {
        doincrease=false;
    }
}


Edit: Fixed small bug where the last enemy on a screen would not get powered up, thanks to Joe for looking over the script. icon_biggrin.gif
Edit 2: Fixed a few other bugs, listed in post #11.
Edit 3: Fixed bug caused by quickly leaving/entering a screen.

Edited by Elmensajero, 03 February 2009 - 12:39 AM.


#5 Joe123

Joe123

    Retired

  • Members

Posted 21 January 2009 - 12:02 PM

Don't you need to reset the upattack and uphealth variables when you enter a new screen?
The enemies might get slightly overpowered otherwise.

Although if you use 'for(int e=1;e<totalenemies;e++)', I don't think you'll catch the last enemy.

#6 Elmensajero

Elmensajero

    Doyen(ne)

  • Members
  • Real Name:John
  • Location:Raleigh, North Carolina

Posted 21 January 2009 - 11:41 PM

Well, they are essentially reset. The function calculatePowerup() runs before the enemies are powered up, and inside that function, uphealth is set equal to the number of heart pieces times 2, and upattack is set to 0 before it is recalculated. Though now that I think about, uphealth should be set to the number of heart containers, not heart pieces. Does the heart pieces index in the generic array keep track of heart containers too, so I could just divide that number by 4? I will have to look at that later...

As for the second thing you mentioned, that is indeed a bug, and I fixed it in the above post. Thanks!

#7 Joe123

Joe123

    Retired

  • Members

Posted 22 January 2009 - 03:18 AM

Oh sorry, I missed that >_<

The heart pieces index is only ever a number from 0 to 3 (well, unless you have more than 4 heart pieces per heart container), so it doesn't keep track of heart containers no.

#8 Silence429

Silence429

    Recipient of Ways

  • Members
  • Real Name:Brian
  • Location:Tampa Bay Area

Posted 22 January 2009 - 11:58 AM

Wow thanks for the script! icon_thumbsup.gif I'll give it a shot either tonight or tomorrow, when I get some free time.

Edited by Silence429, 22 January 2009 - 12:06 PM.


#9 SpacemanDan

SpacemanDan

  • Members
  • Location:Ontario, Canada

Posted 22 January 2009 - 12:36 PM

That's a pretty interesting script. Is it free for use? (And modify it?)

Edited by Blaman, 22 January 2009 - 12:36 PM.


#10 Silence429

Silence429

    Recipient of Ways

  • Members
  • Real Name:Brian
  • Location:Tampa Bay Area

Posted 23 January 2009 - 09:31 PM

Well I just tested the script, and I'm getting some odd results. When I upgrade to the L2 sword, the damage caused by enemies has increased by random large amounts (my testing so far has consisted of those who normally do 1/2 heart of damage). This sometimes results in an instant death. Also, enemy health doesn't seem to increase with Link's heart containers.

#11 Elmensajero

Elmensajero

    Doyen(ne)

  • Members
  • Real Name:John
  • Location:Raleigh, North Carolina

Posted 24 January 2009 - 09:41 AM

Blaman: Sure! I have no problem with you either using it or modifying it.

Silence429: Okay, I updated the script in post #4 above. The enemies health increase will work correctly now, and I also fixed a bug where the variable containing Link's starting health would get changed every time the player died or saved. I didn't realize that global scripts restarted from the beginning when those two things happen. The last bug was that the script was running every 4 frames instead of when the player enters a new screen, but this prob wouldn't have been noticeable.

Now, as far as the weapons being way too overpowered, I will double check that tonight. (I made my own test quest which I will prob post a link to later to show anyone the effects of the script in a game.) I was thinking though, wouldn't it make more sense to increase an enemy's weapon power when Link gains health/rings, and increase their hp when Link gains better weapons, instead of the way it is calculated now?

Edited by Elmensajero, 24 January 2009 - 09:42 AM.


#12 Silence429

Silence429

    Recipient of Ways

  • Members
  • Real Name:Brian
  • Location:Tampa Bay Area

Posted 24 January 2009 - 05:32 PM

Thanks, I'll try out the updated script in a few minutes. The concept I had in mind was that, if Link gets more/upgraded weaponry, the enemies in the quest would decide to mimic that action to keep up with him; the same thing with health. That's why I wanted it calculated that way.

Edit: I tested the script again. The enemy health aspect seems to be working, except I needed to edit the line that says "uphealth=(Link->MaxHP-startinghp)/2", changing the 2 to an 8. I had noticed that, after getting a heart container, the L1 sword required 5 hits to kill a L1 Octorok when it should have been just 2. Then, I remembered that Link's hp is in increments of 16 per heart.

Anyways if you exit and re-enter the screen quickly, it seems that uphealth adds on again. For example, that L1 Octorok will now take 3 hits to die. This does fix itself if you wait a second or two to re-enter. This may be a bug in the script or the build itself (I'm using 887 now - should I upgrade?). Also, after getting the heart, that Octorok starts causing 3/4 heart in damage (instead of just 1/2) with no weapon upgrades.

Edited by Silence429, 24 January 2009 - 08:37 PM.


#13 Silence429

Silence429

    Recipient of Ways

  • Members
  • Real Name:Brian
  • Location:Tampa Bay Area

Posted 02 February 2009 - 07:36 PM

*Bump*
After close inspection, just about everything in the script is working (if you include the enemy health fix I suggested above. There are just a few remaining issues currently:
1. Picking up stray bombs dropped by enemies activates the bomb part of the script. My intent was for the bomb bag to do this. Sorry for not clarifying that.
2. With the screen exiting/re-entering issue I mentioned above, perhaps the script could be edited so that Link is halted 4 frames every time he comes to a new screen?
3. The noincrease script won't compile. I get the error message "Variable doincrease is undeclared"

Thanks again for your help! icon_biggrin.gif

#14 Elmensajero

Elmensajero

    Doyen(ne)

  • Members
  • Real Name:John
  • Location:Raleigh, North Carolina

Posted 03 February 2009 - 01:00 AM

Sorry I didn't see your edit from before icon_sorry.gif ... I fixed the enemy health thing you suggested, and also updated a few other changes in the post above.

1) Okay, I took out the bombs and added in the bomb bags. By the way, if you want to add more weapons to it, it's really easy to modify that portion of the code. Just go to the method "calculatePowerup()", and after the statement "upattack=0", add a line "if(Link->Item[I_ITEM]) upattack+=num;", where "I_ITEM" is the constant for whatever item you want (look in std.zh for a list of all of the item constants), and "num" is that actual amount to increase the enemy's attack power by.

2) I was able to reproduce this in b887, and your suggestion worked to fix that. However, I wasn't able to reproduce the bug where the enemy's attack would increase when the player gets a heart container, can you post a quest showing that bug occurring?

3) You have to compile the entire script at one time, then assign the scripts to where they are supposed to go. If you try compiling just the global part of the script, and then compile the noincrease function, it will overwrite the script buffer, and you would lose the global function. (By the way, it is giving you that error because the variable "doincrease" is a global variable declared at the top of the script.)

Your welcome icon_smile.gif

Edited by Elmensajero, 03 February 2009 - 01:01 AM.


#15 Silence429

Silence429

    Recipient of Ways

  • Members
  • Real Name:Brian
  • Location:Tampa Bay Area

Posted 03 February 2009 - 08:18 PM

Excellent. I just tested it again, and all seems to be working well now. icon_thumbsup.gif
QUOTE(Elmensajero @ Feb 3 2009, 01:00 AM) View Post

However, I wasn't able to reproduce the bug where the enemy's attack would increase when the player gets a heart container, can you post a quest showing that bug occurring?

Ahh, when I posted that bug, it was before I discovered the issue was actually the stray bombs. I wasn't paying close attention at the time, so I assumed it was the heart container.


0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users