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; }
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); } } }
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; } }
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; } } }
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; }