Пример #1
0
        public void Init()
        {
            mondat         = new MonsterData[MONSTERS];
            nextMonster    = 0;
            monsterGapTime = 45 - (Level.LevelOf10(game.Level) << 1);
            totalMonsters  = Level.LevelOf10(game.Level) + 5;
            switch (Level.LevelOf10(game.Level))
            {
            case 1:
                maxMonstersOnScreen = 3;
                break;

            case 2:
            case 3:
            case 4:
            case 5:
            case 6:
            case 7:
                maxMonstersOnScreen = 4;
                break;

            case 8:
            case 9:
            case 10:
                maxMonstersOnScreen = 5;
                break;
            }
            nextMonsterTime = 10;
            unBonusFlag     = true;
        }
Пример #2
0
        public void DoMonsters()
        {
            if (nextMonsterTime > 0)
            {
                nextMonsterTime--;
            }
            else
            {
                if (nextMonster < totalMonsters && MonstersOnScreenCount() < maxMonstersOnScreen && game.diggers.IsAnyAlive() && !game.diggers.isBonusMode)
                {
                    CreateMonster();
                }

                if (unBonusFlag && nextMonster == totalMonsters && nextMonsterTime == 0 && game.diggers.IsAnyAlive())
                {
                    unBonusFlag = false;
                    game.diggers.CreateBonus();
                }
            }

            for (int i = 0; i < MONSTERS; i++)
            {
                if (!mondat[i].exists)
                {
                    continue;
                }

                if (mondat[i].hnt > 10 - Level.LevelOf10(game.Level))
                {
                    if (mondat[i].isNobbin)
                    {
                        mondat[i].isNobbin = false;
                        mondat[i].hnt      = 0;
                    }
                }

                if (mondat[i].isAlive)
                {
                    if (mondat[i].t == 0)
                    {
                        MonsterAI(i);
                        if (game.RandNo(15 - Level.LevelOf10(game.Level)) == 0) /* Need to split for determinism */
                        {
                            if (mondat[i].isNobbin && mondat[i].isAlive)
                            {
                                MonsterAI(i);
                            }
                        }
                    }
                    else
                    {
                        mondat[i].t--;
                    }
                }
                else
                {
                    MonsterDie(i);
                }
            }
        }
Пример #3
0
 private void InitializeBonusMode()
 {
     isBonusMode = true;
     EraseBonus();
     game.video.SetIntensity(1);
     bonustimeleft      = 250 - Level.LevelOf10(game.Level) * 20;
     startbonustimeleft = 20;
     for (int i = 0; i < game.diggerCount; i++)
     {
         diggerData[i].msc = 1;
     }
 }
Пример #4
0
        private void UpdateFire(int n)
        {
            int pix, fx = 0, fy = 0;

            int[] clfirst = new int[TYPES];
            int[] clcoll  = new int[SPRITES];
            int   i;
            bool  clflag;

            if (diggerData[n].notfiring)
            {
                if (diggerData[n].rechargetime != 0)
                {
                    diggerData[n].rechargetime--;
                    if (diggerData[n].rechargetime == 0)
                    {
                        diggerData[n].canFire = true;
                    }
                }
                else
                {
                    if (GetFirepFlag(n - game.currentPlayer))
                    {
                        if (diggerData[n].isAlive)
                        {
                            diggerData[n].canFire      = false;
                            diggerData[n].rechargetime = Level.LevelOf10(game.Level) * 3 + 60;
                            diggerData[n].notfiring    = false;
                            switch (diggerData[n].dir)
                            {
                            case Dir.Right:
                                fx = diggerData[n].x + 8;
                                fy = diggerData[n].y + 4;
                                break;

                            case Dir.Up:
                                fx = diggerData[n].x + 4;
                                fy = diggerData[n].y;
                                break;

                            case Dir.Left:
                                fx = diggerData[n].x;
                                fy = diggerData[n].y + 4;
                                break;

                            case Dir.Down:
                                fx = diggerData[n].x + 4;
                                fy = diggerData[n].y + 8;
                                break;

                            default:
                                throw new NotSupportedException($"Direction '{diggerData[n].dir}' is not supported.");
                            }
                            diggerData[n].bullet.Update(diggerData[n].dir, fx, fy);
                            diggerData[n].bullet.Put();
                        }
                    }
                }
            }
            else
            {
                pix = 0;
                switch (diggerData[n].bullet.dir)
                {
                case Dir.Right:
                    diggerData[n].bullet.x += 8;
                    pix = game.video.GetPixel(diggerData[n].bullet.x, diggerData[n].bullet.y + 4) |
                          game.video.GetPixel(diggerData[n].bullet.x + 4, diggerData[n].bullet.y + 4);
                    break;

                case Dir.Up:
                    diggerData[n].bullet.y -= 7;
                    pix = 0;
                    for (i = 0; i < 7; i++)
                    {
                        pix |= game.video.GetPixel(diggerData[n].bullet.x + 4, diggerData[n].bullet.y + i);
                    }
                    pix &= 0xc0;
                    break;

                case Dir.Left:
                    diggerData[n].bullet.x -= 8;
                    pix = game.video.GetPixel(diggerData[n].bullet.x, diggerData[n].bullet.y + 4) |
                          game.video.GetPixel(diggerData[n].bullet.x + 4, diggerData[n].bullet.y + 4);
                    break;

                case Dir.Down:
                    diggerData[n].bullet.y += 7;
                    pix = 0;
                    for (i = 0; i < 7; i++)
                    {
                        pix |= game.video.GetPixel(diggerData[n].bullet.x, diggerData[n].bullet.y + i);
                    }
                    pix &= 0x3;
                    break;
                }
                diggerData[n].bullet.Animate();
                for (i = 0; i < TYPES; i++)
                {
                    clfirst[i] = game.sprite.first[i];
                }
                for (i = 0; i < SPRITES; i++)
                {
                    clcoll[i] = game.sprite.coll[i];
                }
                game.IncrementPenalty();
                i = clfirst[2];
                while (i != -1)
                {
                    game.monsters.KillMonster(i - FIRSTMONSTER);
                    game.scores.ScoreKill(n);
                    diggerData[n].bullet.Explode();
                    i = clcoll[i];
                }
                i = clfirst[4];
                while (i != -1)
                {
                    if (i - FIRSTDIGGER + game.currentPlayer != n && !diggerData[i - FIRSTDIGGER + game.currentPlayer].invin &&
                        diggerData[i - FIRSTDIGGER + game.currentPlayer].isAlive)
                    {
                        KillDigger(i - FIRSTDIGGER + game.currentPlayer, 3, 0);
                        diggerData[n].bullet.Explode();
                    }
                    i = clcoll[i];
                }
                if (clfirst[0] != -1 || clfirst[1] != -1 || clfirst[2] != -1 || clfirst[3] != -1 ||
                    clfirst[4] != -1)
                {
                    clflag = true;
                }
                else
                {
                    clflag = false;
                }
                if (clfirst[0] != -1 || clfirst[1] != -1 || clfirst[3] != -1)
                {
                    diggerData[n].bullet.Explode();
                    i = clfirst[3];
                    while (i != -1)
                    {
                        if (diggerData[i - FIRSTFIREBALL + game.currentPlayer].bullet.expsn == 0)
                        {
                            diggerData[i - FIRSTFIREBALL + game.currentPlayer].bullet.Explode();
                        }
                        i = clcoll[i];
                    }
                }
                switch (diggerData[n].bullet.dir)
                {
                case Dir.Right:
                    if (diggerData[n].bullet.x > 296)
                    {
                        diggerData[n].bullet.Explode();
                    }
                    else
                    {
                        if (pix != 0 && !clflag)
                        {
                            diggerData[n].bullet.x -= 8;
                            diggerData[n].bullet.Animate();
                            diggerData[n].bullet.Explode();
                        }
                    }
                    break;

                case Dir.Up:
                    if (diggerData[n].bullet.y < 15)
                    {
                        diggerData[n].bullet.Explode();
                    }
                    else
                    {
                        if (pix != 0 && !clflag)
                        {
                            diggerData[n].bullet.y += 7;
                            diggerData[n].bullet.Animate();
                            diggerData[n].bullet.Explode();
                        }
                    }
                    break;

                case Dir.Left:
                    if (diggerData[n].bullet.x < 16)
                    {
                        diggerData[n].bullet.Explode();
                    }
                    else
                    {
                        if (pix != 0 && !clflag)
                        {
                            diggerData[n].bullet.x += 8;
                            diggerData[n].bullet.Animate();
                            diggerData[n].bullet.Explode();
                        }
                    }
                    break;

                case Dir.Down:
                    if (diggerData[n].bullet.y > 183)
                    {
                        diggerData[n].bullet.Explode();
                    }
                    else
                    {
                        if (pix != 0 && !clflag)
                        {
                            diggerData[n].bullet.y -= 7;
                            diggerData[n].bullet.Animate();
                            diggerData[n].bullet.Explode();
                        }
                    }
                    break;
                }
            }
        }
Пример #5
0
        private void MonsterAI(int mon)
        {
            int monox, monoy, dir, mdirp1, mdirp2, mdirp3, mdirp4, t, i, m, dig;

            int[] clcoll = new int[SPRITES];
            int[] clfirst = new int[TYPES];
            bool  push, bagf;

            monox = mondat[mon].x;
            monoy = mondat[mon].y;
            if (mondat[mon].xr == 0 && mondat[mon].yr == 0)
            {
                /* If we are here the monster needs to know which way to turn next. */

                /* Turn hobbin back into nobbin if it's had its time */

                if (mondat[mon].hnt > 30 + (Level.LevelOf10(game.Level) << 1))
                {
                    if (!mondat[mon].isNobbin)
                    {
                        mondat[mon].hnt      = 0;
                        mondat[mon].isNobbin = true;
                    }
                }

                /* Set up monster direction properties to chase Digger */

                dig = mondat[mon].chase;
                if (!game.diggers.IsDiggerAlive(dig) && game.diggerCount > 1)
                {
                    dig = dig == 0 ? 1 : 0;
                }

                if (Math.Abs(game.diggers.DiggerY(dig) - mondat[mon].y) > Math.Abs(game.diggers.DiggerX(dig) - mondat[mon].x))
                {
                    if (game.diggers.DiggerY(dig) < mondat[mon].y)
                    {
                        mdirp1 = Dir.Up; mdirp4 = Dir.Down;
                    }
                    else
                    {
                        mdirp1 = Dir.Down; mdirp4 = Dir.Up;
                    }
                    if (game.diggers.DiggerX(dig) < mondat[mon].x)
                    {
                        mdirp2 = Dir.Left; mdirp3 = Dir.Right;
                    }
                    else
                    {
                        mdirp2 = Dir.Right; mdirp3 = Dir.Left;
                    }
                }
                else
                {
                    if (game.diggers.DiggerX(dig) < mondat[mon].x)
                    {
                        mdirp1 = Dir.Left; mdirp4 = Dir.Right;
                    }
                    else
                    {
                        mdirp1 = Dir.Right; mdirp4 = Dir.Left;
                    }
                    if (game.diggers.DiggerY(dig) < mondat[mon].y)
                    {
                        mdirp2 = Dir.Up; mdirp3 = Dir.Down;
                    }
                    else
                    {
                        mdirp2 = Dir.Down; mdirp3 = Dir.Up;
                    }
                }

                /* In bonus mode, run away from Digger */

                if (game.diggers.isBonusMode)
                {
                    t = mdirp1; mdirp1 = mdirp4; mdirp4 = t;
                    t = mdirp2; mdirp2 = mdirp3; mdirp3 = t;
                }

                /* Adjust priorities so that monsters don't reverse direction unless they
                 * really have to */

                dir = Dir.Reverse(mondat[mon].dir);
                if (dir == mdirp1)
                {
                    mdirp1 = mdirp2;
                    mdirp2 = mdirp3;
                    mdirp3 = mdirp4;
                    mdirp4 = dir;
                }
                if (dir == mdirp2)
                {
                    mdirp2 = mdirp3;
                    mdirp3 = mdirp4;
                    mdirp4 = dir;
                }
                if (dir == mdirp3)
                {
                    mdirp3 = mdirp4;
                    mdirp4 = dir;
                }

                /* Introduce a random element on levels <6 : occasionally swap p1 and p3 */

                if (game.RandNo(Level.LevelOf10(game.Level) + 5) == 1) /* Need to split for determinism */
                {
                    if (Level.LevelOf10(game.Level) < 6)
                    {
                        t      = mdirp1;
                        mdirp1 = mdirp3;
                        mdirp3 = t;
                    }
                }

                /* Check field and find direction */

                if (FieldClear(mdirp1, mondat[mon].h, mondat[mon].v))
                {
                    dir = mdirp1;
                }
                else
                if (FieldClear(mdirp2, mondat[mon].h, mondat[mon].v))
                {
                    dir = mdirp2;
                }
                else
                if (FieldClear(mdirp3, mondat[mon].h, mondat[mon].v))
                {
                    dir = mdirp3;
                }
                else
                if (FieldClear(mdirp4, mondat[mon].h, mondat[mon].v))
                {
                    dir = mdirp4;
                }

                /* Hobbins don't care about the field: they go where they want. */

                if (!mondat[mon].isNobbin)
                {
                    dir = mdirp1;
                }

                /* Monsters take a time g_Penalty for changing direction */

                if (mondat[mon].dir != dir)
                {
                    mondat[mon].t++;
                }

                /* Save the new direction */

                mondat[mon].dir = dir;
            }

            /* If monster is about to go off edge of screen, stop it. */

            if ((mondat[mon].x == 292 && mondat[mon].dir == Dir.Right) ||
                (mondat[mon].x == 12 && mondat[mon].dir == Dir.Left) ||
                (mondat[mon].y == 180 && mondat[mon].dir == Dir.Down) ||
                (mondat[mon].y == 18 && mondat[mon].dir == Dir.Up))
            {
                mondat[mon].dir = Dir.None;
            }

            /* Change hdir for hobbin */

            if (mondat[mon].dir == Dir.Left || mondat[mon].dir == Dir.Right)
            {
                mondat[mon].hdir = mondat[mon].dir;
            }

            /* Hobbins dig */

            if (!mondat[mon].isNobbin)
            {
                game.drawing.EatField(mondat[mon].x, mondat[mon].y, mondat[mon].dir);
            }

            /* (Draw new tunnels) and move monster */

            switch (mondat[mon].dir)
            {
            case Dir.Right:
                if (!mondat[mon].isNobbin)
                {
                    game.drawing.DrawRightBlob(mondat[mon].x, mondat[mon].y);
                }
                mondat[mon].x += 4;
                break;

            case Dir.Up:
                if (!mondat[mon].isNobbin)
                {
                    game.drawing.DrawTopBlob(mondat[mon].x, mondat[mon].y);
                }
                mondat[mon].y -= 3;
                break;

            case Dir.Left:
                if (!mondat[mon].isNobbin)
                {
                    game.drawing.DrawLeftBlob(mondat[mon].x, mondat[mon].y);
                }
                mondat[mon].x -= 4;
                break;

            case Dir.Down:
                if (!mondat[mon].isNobbin)
                {
                    game.drawing.DrawBottomBlob(mondat[mon].x, mondat[mon].y);
                }
                mondat[mon].y += 3;
                break;
            }

            /* Hobbins can eat emeralds */

            if (!mondat[mon].isNobbin)
            {
                game.emeralds.HitEmerald((mondat[mon].x - 12) / 20, (mondat[mon].y - 18) / 18,
                                         (mondat[mon].x - 12) % 20, (mondat[mon].y - 18) % 18,
                                         mondat[mon].dir);
            }

            /* If Digger's gone, don't bother */

            if (!game.diggers.IsAnyAlive())
            {
                mondat[mon].x = monox;
                mondat[mon].y = monoy;
            }

            /* If monster's just started, don't move yet */

            if (mondat[mon].stime != 0)
            {
                mondat[mon].stime--;
                mondat[mon].x = monox;
                mondat[mon].y = monoy;
            }

            /* Increase time counter for hobbin */

            if (!mondat[mon].isNobbin && mondat[mon].hnt < 100)
            {
                mondat[mon].hnt++;
            }

            /* Draw monster */

            push = true;
            game.drawing.DrawMonster(mon, mondat[mon].isNobbin, mondat[mon].hdir, mondat[mon].x, mondat[mon].y);
            for (i = 0; i < TYPES; i++)
            {
                clfirst[i] = game.sprite.first[i];
            }
            for (i = 0; i < SPRITES; i++)
            {
                clcoll[i] = game.sprite.coll[i];
            }
            game.IncrementPenalty();

            /* Collision with another monster */

            if (clfirst[2] != -1)
            {
                mondat[mon].t++; /* Time g_Penalty */
                                 /* Ensure both aren't moving in the same dir. */
                i = clfirst[2];
                do
                {
                    m = i - FIRSTMONSTER;
                    if (mondat[mon].dir == mondat[m].dir && mondat[m].stime == 0 &&
                        mondat[mon].stime == 0)
                    {
                        mondat[m].dir = Dir.Reverse(mondat[m].dir);
                    }

                    /* The kludge here is to preserve playback for a bug in previous
                     * versions. */
                    if (!game.record.kludge)
                    {
                        game.IncrementPenalty();
                    }
                    else
                    if ((m & 1) == 0)
                    {
                        game.IncrementPenalty();
                    }
                    i = clcoll[i];
                } while (i != -1);
                if (game.record.kludge)
                {
                    if (clfirst[0] != -1)
                    {
                        game.IncrementPenalty();
                    }
                }
            }

            /* Check for collision with bag */

            i    = clfirst[1];
            bagf = false;
            while (i != -1)
            {
                if (game.bags.BagExists(i - FIRSTBAG))
                {
                    bagf = true;
                    break;
                }
                i = clcoll[i];
            }

            if (bagf)
            {
                mondat[mon].t++; /* Time g_Penalty */
                monsterGotGold = false;
                if (mondat[mon].dir == Dir.Right || mondat[mon].dir == Dir.Left)
                {
                    push = game.bags.PushBags(mondat[mon].dir, clfirst, clcoll); /* Horizontal push */
                    mondat[mon].t++;                                             /* Time g_Penalty */
                }
                else
                if (!game.bags.PushBagsUp(clfirst, clcoll))     /* Vertical push */
                {
                    push = false;
                }
                if (monsterGotGold) /* No time g_Penalty if monster eats gold */
                {
                    mondat[mon].t = 0;
                }
                if (!mondat[mon].isNobbin && mondat[mon].hnt > 1)
                {
                    game.bags.RemoveBags(clfirst, clcoll); /* Hobbins eat bags */
                }
            }

            /* Increase hobbin cross counter */

            if (mondat[mon].isNobbin && clfirst[2] != -1 && game.diggers.IsAnyAlive())
            {
                mondat[mon].hnt++;
            }

            /* See if bags push monster back */

            if (!push)
            {
                mondat[mon].x = monox;
                mondat[mon].y = monoy;
                game.drawing.DrawMonster(mon, mondat[mon].isNobbin, mondat[mon].hdir, mondat[mon].x, mondat[mon].y);
                game.IncrementPenalty();
                if (mondat[mon].isNobbin) /* The other way to create hobbin: stuck on h-bag */
                {
                    mondat[mon].hnt++;
                }
                if ((mondat[mon].dir == Dir.Up || mondat[mon].dir == Dir.Down) &&
                    mondat[mon].isNobbin)
                {
                    mondat[mon].dir = Dir.Reverse(mondat[mon].dir); /* If vertical, give up */
                }
            }

            /* Collision with Digger */

            if (clfirst[4] != -1 && game.diggers.IsAnyAlive())
            {
                if (game.diggers.isBonusMode)
                {
                    KillMonster(mon);
                    i = clfirst[4];
                    while (i != -1)
                    {
                        if (game.diggers.IsDiggerAlive(i - FIRSTDIGGER + game.currentPlayer))
                        {
                            game.diggers.ScoreEatMonster(i - FIRSTDIGGER + game.currentPlayer);
                        }
                        i = clcoll[i];
                    }
                    game.sound.SoundEatMonster(); /* Collision in bonus mode */
                }
                else
                {
                    i = clfirst[4];
                    while (i != -1)
                    {
                        if (game.diggers.IsDiggerAlive(i - FIRSTDIGGER + game.currentPlayer))
                        {
                            game.diggers.KillDigger(i - FIRSTDIGGER + game.currentPlayer, 3, 0); /* Kill Digger */
                        }
                        i = clcoll[i];
                    }
                }
            }

            /* Update co-ordinates */

            mondat[mon].h  = (mondat[mon].x - 12) / 20;
            mondat[mon].v  = (mondat[mon].y - 18) / 18;
            mondat[mon].xr = (mondat[mon].x - 12) % 20;
            mondat[mon].yr = (mondat[mon].y - 18) % 18;
        }