void GegnerFahrstuhl::GegnerExplode(void)
{
	FahrstuhlPos = -1.0f;

	ShakeScreen (10);
	pSoundManager->PlayWave (100, 128, 11025, SOUND_EXPLOSION2);

	for (int j=0; j < 100; j++)
		pPartikelSystem->PushPartikel(xPos + rand()%400, yPos + rand()%100, SPIDERSPLITTER);

	for (int j=0; j < 50; j++)
	{
		pPartikelSystem->PushPartikel(xPos + rand()%400, yPos + rand()%100, ROCKETSMOKE);
		pPartikelSystem->PushPartikel(xPos - 30 + rand()%400, yPos - 30 + rand()%100, EXPLOSION_MEDIUM2);
	}

	for (int j=0; j < 20; j++)
		pPartikelSystem->PushPartikel(xPos + rand()%400, yPos + rand()%100, SPLITTER);

	pTileEngine->Zustand = ZUSTAND_SCROLLBAR;

	// Spieler springt ab
	//
	for (int p = 0; p < NUMPLAYERS; p++)
	{
		pPlayer[p]->JumpPossible = false;
		pPlayer[p]->AnimPhase = 0;
		pPlayer[p]->Handlung  = SPRINGEN;
		pPlayer[p]->JumpStart = pPlayer[p]->ypos;
		pPlayer[p]->yspeed    = -PLAYER_MAXJUMPSPEED;
		pPlayer[p]->JumpAdd	  =  0.0f;
		pPlayer[p]->AufPlattform = NULL;
	}
}
void GegnerFahrstuhlBoss::GegnerExplode(void)
{
	ShakeScreen (10);
	pSoundManager->PlayWave (100, 128, 11025, SOUND_EXPLOSION2);
	pPlayer[0]->Score += 9000;

	// Level Musik wieder einfaden lassen (aus Pause Zustand)
	pSoundManager->FadeSong(MUSIC_STAGEMUSIC, 2.0f, 100, true);

	//pTileEngine->YOffset = float (Value1);
}
Example #3
0
void daMegaGoomba_c::executeState_Walk() { 
	/* 800345e0 - daEnLkuribo_c::executeState_Walk() */
	this->bodyModel._vf1C();
	//HOMEMADE//
	this->HandleXSpeed();
	this->HandleYSpeed();
	this->doSpriteMovement();
	u16 amt = (this->direction == 0) ? 0x2000 : 0xE000;
	SmoothRotation(&this->rot.y, amt, 0x200);
	/*this->_vf2D0();	//nullsub();*/
	int ret = SomeStrangeModification(this);
	if(ret & 1)
		this->speed.y = 0.0;
	u32 bitfield = this->collMgr.outputMaybe;
	if(bitfield & (0x15<<this->direction)) {
		this->pos.x = this->last_pos.x;
		this->doStateChange(&StateID_Turn);
		//this->acState.setField10ToOne();
	}
	/*u32 bitfield2 = this->collMgr.adjacentTileProps[this->direction];
	if(bitfield2) {
		this->doStateChange(&StateID_Turn);
	}*/
	DoStuffAndMarkDead(this, this->pos, 1.0);


	int frame = (int)(this->animationChr.getCurrentFrame() * 5.0);
	if ((frame == 100) || (frame == 325) || (frame == 550) || (frame == 775)) {
		ShakeScreen(StageScreen, 0, 1, 0, 0);
		stunPlayers();
		PlaySound(this, SE_BOSS_MORTON_GROUND_SHAKE);
	}

	if (isBigBoss) {
		if ((frame == 250) || (frame == 500) || (frame == 700) || (frame == 900))
			unstunPlayers();
	}
	else {
		if ((frame == 200) || (frame == 425) || (frame == 650) || (frame == 875))
			unstunPlayers();
	}

	if(this->animationChr.isAnimationDone()) {
		this->animationChr.setCurrentFrame(0.0);

		int new_dir = dSprite_c__getXDirectionOfFurthestPlayerRelativeToVEC3(this, pos);
		if(this->direction != new_dir)
			doStateChange(&StateID_Turn);
	}
}
Example #4
0
void World::OnKeyDown(SDL_KeyboardEvent *evt)
{
    if (complete_) return;

    script_->Call<void>("key_down", script_state_.get(),
        std::string(SDL_GetKeyName(evt->keysym.sym)));

    if (!alt_control_) { 
        if (characters_.find(active_character_) != characters_.end()) {
            characters_[active_character_]->OnKeyDown(evt);
        }
    } else {
        if (key_map_.find(evt->keysym.sym) != key_map_.end()) {
            auto p = key_map_[evt->keysym.sym];
            SDLKey old = evt->keysym.sym;
            evt->keysym.sym = p.second;
            characters_[p.first]->OnKeyDown(evt);
            evt->keysym.sym = old;
        }
    }

    switch (evt->keysym.sym) {
        case SDLK_1:
            active_character_ = "heavy";
            break;
        case SDLK_2:
            active_character_ = "jump";
            break;
        case SDLK_3:
            active_character_ = "strong";
            break;
        case SDLK_4:
            active_character_ = "ranger";
            break;
        case SDLK_p:
            if (evt->keysym.mod == KMOD_LSHIFT) {
                for (auto& ch : characters_) {
                    ch.second->Explode();
                }
                ShakeScreen(0.05, 2, 0.9, math::Vector(0.0, 1.0));
            }
            break;
        case SDLK_F5:
            alt_control_ = !alt_control_;
            break;
        default:
            break;
    }
}
Example #5
0
void GegnerColumn::GegnerExplode(void)
{
    for (int i = 0; i < 30; i++)
        pPartikelSystem->PushPartikel (xPos + rand ()%100, yPos + 80 + rand()%40, SMOKE);

    for (int i = 0; i < 40; i++)
    {
        pPartikelSystem->PushPartikel (xPos + rand ()%90 + 10, yPos + 60 + rand()%40, ROCKSPLITTERSMALL);
        pPartikelSystem->PushPartikel (xPos + rand ()%90 + 10, yPos + 60 + rand()%40, ROCKSPLITTER);
    }

    pSoundManager->PlayWave(100, 128, 11025 + rand()%2000, SOUND_STONEEXPLODE);

    ShakeScreen (2.0f);
}
void GegnerWasserMine::GegnerExplode(void)
{
	pSoundManager->PlayWave (100, 128, 8000, SOUND_EXPLOSION3);
	pSoundManager->PlayWave (100, 128,14000, SOUND_EXPLOSION4);

	ShakeScreen(5.0f);

	for (int i = 0; i < 50; i++)
		pPartikelSystem->PushPartikel(xPos - 5 + rand()%40, yPos - 5 + rand()%60, WATERFLUSH_HIGH);

	for (int i = 0; i < 25; i++)
		pPartikelSystem->PushPartikel(xPos - 5 + rand()%40, yPos - 50 + rand()%110, SPIDERSPLITTER);

	pPartikelSystem->PushPartikel(xPos - 40, yPos - 55, EXPLOSION_GIANT);
}
Example #7
0
void GegnerBigFish::GegnerExplode(void)
{
	pSoundManager->PlayWave(100, 128, 11025, SOUND_EXPLOSION2);

	// Blut
	for (int i=0; i<80; i++)
		pPartikelSystem->PushPartikel(xPos + rand()%200+40,
									  yPos + 50 + rand()%100,
									  PIRANHABLUT);

	for (int i=0; i<20; i++)
		pGegner->PushGegner(xPos + rand()%200+40,
							yPos + 30 + rand()%80, PIRANHA, 99, 0, false);

	for (int i = 0; i < NUMPLAYERS; i++)
		DirectInput.Joysticks[pPlayer[i]->JoystickIndex].ForceFeedbackEffect(FFE_BIGRUMBLE);

	ShakeScreen(4);

	pPlayer[0]->Score += 5000;
}
Example #8
0
void daMegaGoomba_c::executeState_Turn() { 
	this->bodyModel._vf1C();

	this->HandleYSpeed();
	this->doSpriteMovement();

	/*this->_vf2D0();	//nullsub();*/
	int ret = SomeStrangeModification(this);

	if(ret & 1)
		this->speed.y = 0.0;
	if(ret & 4)
		this->pos.x = this->last_pos.x;
	DoStuffAndMarkDead(this, this->pos, 1.0);
	u16 amt = (this->direction == 0) ? 0x2000 : 0xE000;
	int done = SmoothRotation(&this->rot.y, amt, 0x80);
	if(done) {
		this->doStateChange(&StateID_Walk);
	}

	int frame = (int)(this->animationChr.getCurrentFrame() * 5.0);
	if ((frame == 100) || (frame == 325) || (frame == 550) || (frame == 775)) {
		ShakeScreen(StageScreen, 0, 1, 0, 0);
		stunPlayers();
		PlaySound(this, SE_BOSS_MORTON_GROUND_SHAKE);
	}

	if (isBigBoss) {
		if ((frame == 250) || (frame == 500) || (frame == 700) || (frame == 900))
			unstunPlayers();
	}
	else {
		if ((frame == 200) || (frame == 425) || (frame == 650) || (frame == 875))
			unstunPlayers();
	}
}
Example #9
0
void GegnerPokeNuke::GegnerExplode(void)
{
	pSoundManager->PlayWave (100, 128, 8000 + rand ()%4000, SOUND_EXPLOSION2);
	ShakeScreen (7);

	pAim = pPlayer[0];
	if (PlayerAbstand() < 160)	
		pAim->DamagePlayer (50);

	if (NUMPLAYERS == 2)
	{
		pAim = pPlayer[1];
		if (PlayerAbstand() < 160)	
			pAim->DamagePlayer (50);
	}

	for (int i = 0; i < 16; i++)	pPartikelSystem->PushPartikel (xPos - 60 + rand ()%90, yPos - 40 + rand ()%200, SMOKEBIG);	
	for (int i = 0; i < 8; i++)			pPartikelSystem->PushPartikel (xPos - 50 + rand ()%90, yPos - 30 + rand ()%200, EXPLOSION_BIG);
	for (int i = 0; i < 12; i++)		pPartikelSystem->PushPartikel (xPos - 30 + rand ()%90, yPos - 20 + rand ()%200, EXPLOSION_MEDIUM2);
	for (int i = 0; i < 12; i++)		pPartikelSystem->PushPartikel (xPos - 30 + rand ()%90, yPos + 100 + rand ()%100, SPLITTER);
	for (int i = 0; i < 200; i++)		pPartikelSystem->PushPartikel (xPos + rand ()%90, yPos + 50 + rand ()%150, FUNKE);

	for (int i = 0; i < 48; i++)		pPartikelSystem->PushPartikel (xPos - 67 + rand ()%130, yPos - 30 + rand ()%200, EXPLOSIONFLARE);
}
Example #10
0
void GegnerTheWall::DoKI(void)
{
    // Auf den Spieler schiessen?
    if (Energy < 1500.0f &&
            Value1 == 1)
    {
        SkullShotDelay -= 1.0f SYNC;

        if (SkullShotDelay < 0.0f)
        {
            SkullShotDelay = 15.0f;
            pProjectiles->PushProjectile(xPos, yPos + 240.0f, SUCHSCHUSS2, pAim);
            pSoundManager->PlayWave(50, 128, 14000 + rand()%2000, SOUND_GOLEMSHOT);
        }
    }

    if (Laughing > 0.0f)
    {
        Laughing -= 1.0f SYNC;
        return;
    }

    if (Handlung != GEGNER_EXPLODIEREN)
    {
        // Vorderteil zurückfahren?
        if (VorneX > 0.0f)
            VorneX -= 1.0f SYNC;
        else
            VorneX = 0.0f;

        // getroffen? Dann dem Schädel die Energie abziehen
        if (Energy < OldEnergy)
        {
            if (SkullEnergy > 0.0f)
            {
                SkullEnergy -= (OldEnergy - Energy);
                Energy = OldEnergy;
            }
            else
            {
                if (Handlung != GEGNER_OEFFNEN &&
                        Handlung != GEGNER_SCHLIESSEN)
                {
                    CountOpen = 0;
                    NeueAktion();
                }
            }
        }

        Destroyable = false;

        // Schädel kann man treffen?
        if (Handlung != GEGNER_OEFFNEN &&
                Handlung != GEGNER_SCHLIESSEN &&
                Value1 == 1)
        {
            GegnerRect[GegnerArt].left   = 5;
            GegnerRect[GegnerArt].top    = 232;
            GegnerRect[GegnerArt].right  = 5 + 20;
            GegnerRect[GegnerArt].bottom = 232 + 28;
            Destroyable = true;
        }

        // Herz kann man treffen
        if (Handlung == GEGNER_OEFFNEN ||
                Handlung == GEGNER_SCHLIESSEN)
        {
            GegnerRect[GegnerArt].left   = TunnelOffx + 116;
            GegnerRect[GegnerArt].top    = TunnelOffY + 59;
            GegnerRect[GegnerArt].right  = TunnelOffx + 116 + 38;
            GegnerRect[GegnerArt].bottom = TunnelOffY + 59 + 42;
            Destroyable = true;
        }

        // Kringel drehen lassen
        KringelWinkel += 10.0f SYNC;

        if (KringelWinkel > 360.0f)
            KringelWinkel -= 360.0f;

        // Herz klopfen lassen
        float e = 1.0f;

        if (Energy < 3500.0f) e = 1.0f;
        if (Energy < 3000.0f) e = 2.0f;
        if (Energy < 2500.0f) e = 3.0f;
        if (Energy < 2000.0f) e = 4.0f;
        if (Energy < 1500.0f) e = 5.0f;
        if (Energy < 1000.0f) e = 6.0f;
        if (Energy <  500.0f) e = 7.0f;
        if (Energy <  250.0f) e = 8.0f;
        if (Energy <  150.0f) e = 9.0f;

        HeartBeat += e SYNC;

        if (HeartBeat > 10.0f)
        {
            if (HeartAnim == 0)
            {
                HeartAnim = 1;
                HeartBeat = 5.0f;

                if (Handlung == GEGNER_OEFFNEN ||
                        Handlung == GEGNER_SCHLIESSEN)
                    pSoundManager->PlayWave(100, 128, 11025, SOUND_HEART2);
            }
            else
            {
                HeartAnim = 0;
                HeartBeat = 0.0f;

                if (Handlung == GEGNER_OEFFNEN ||
                        Handlung == GEGNER_SCHLIESSEN)
                    pSoundManager->PlayWave(100, 128, 11025, SOUND_HEART1);
            }
        }

        // Rauch
        SmokeDelay -= 1.0f SYNC;

        if (SmokeDelay < 0.0f)
        {
            SmokeDelay = 0.2f;

            if (Energy < 3500)
                pPartikelSystem->PushPartikel(xPos + 82, yPos + 260, SMOKE3);

            if (Energy < 3000)
                pPartikelSystem->PushPartikel(xPos + 180, yPos + 250, SMOKE3);

            if (Energy < 2500)
                pPartikelSystem->PushPartikel(xPos + 110, yPos + 320, SMOKE3);

            if (Energy < 2000)
                pPartikelSystem->PushPartikel(xPos + 255, yPos + 130, SMOKE3);

            if (Energy < 1500)
                if (rand()%20 == 0)
                {
                    pPartikelSystem->PushPartikel(xPos - 10 + rand()%10,
                                                  yPos + 220 + rand()%10, LASERFLAME);

                    for (int i = 0; i < 10; i++)
                        pPartikelSystem->PushPartikel(xPos + 10 + rand()%10,
                                                      yPos + 240 + rand()%10, FUNKE);

                    for (int i = 0; i < 10; i++)
                        pPartikelSystem->PushPartikel(xPos + 20 + rand()%2,
                                                      yPos + 240 + rand()%10, LASERFUNKE2);
                }
        }

        // Energie anzeigen
        if (Handlung != GEGNER_INIT)
            pHUD->ShowBossHUD(4000, Energy);

        // Boss aktivieren und Mucke laufen lassen
        //
        if (Active == true &&
                pTileEngine->Zustand == ZUSTAND_SCROLLBAR)
        {
            if (PlayerAbstand() < 800 &&
                    PlayerAbstandHoriz() < 400.0f)
            {
                pTileEngine->ScrollLevel(xPos - 355,
                                         yPos, ZUSTAND_SCROLLTOLOCK);		// Level auf den Boss zentrieren
                pSoundManager->FadeSong(MUSIC_STAGEMUSIC, -2.0f, 0, true);  // Ausfaden und pausieren
            }
        }

        // Keine Energie mehr? Dann explodieren lassen
        if (Energy < 100.0f)
        {
            Energy = 100.0f;
            Destroyable = false;

            // Level wieder zum Spieler scrollen und dann weiterscrollen lassen
            pTileEngine->ScrollLevel(pPlayer[0]->xpos - 300,
                                     pPlayer[0]->ypos - 280, ZUSTAND_SCROLLTOPLAYER);

            // Rad checken
            for (int p = 0; p < NUMPLAYERS; p++)
            {
                if (pPlayer[p]->Handlung == RADELN ||
                        pPlayer[p]->Handlung == RADELN_FALL)
                    pPlayer[p]->Handlung = LAUFEN;
            }

            ShotCount = 1;
            Handlung = GEGNER_EXPLODIEREN;
            Laughing = 0.0f;

            // Alle Schüsse löschen
            pProjectiles->ClearAll();

            // Zeitlupe
            pTimer->SetMoveSpeed(1.0f);

            // Musiken anhalten
            pSoundManager->StopAllSongs(true);
            pSoundManager->StopAllSounds();

            // Glassplitter
            pSoundManager->PlayWave(100, 128, 11025, SOUND_GLASSBREAK);

            int i;
            for (i = 0; i < 20; i++)
                pPartikelSystem->PushPartikel(xPos + TunnelOffx + 114 + rand()%30,
                                              yPos + TunnelOffY +  59 + rand()%45, SCHLEIM);

            for (i = 0; i < 80; i++)
                pPartikelSystem->PushPartikel(xPos + TunnelOffx + 114 + rand()%30,
                                              yPos + TunnelOffY +  59 + rand()%45, GLASSPLITTER);

            // Wie lange warten?
            AnimCount = 100.0f;

            // Den Schädel verschwinden lassen
            GegnerClass *pTemp;
            pTemp = pGegner->pStart;

            while (pTemp != NULL)
            {
                if (pTemp->GegnerArt == SKULL)
                {
                    pTemp->Value1 = 0;
                    pTemp->AnimCount = 0.5f;
                    pTemp->Handlung = GEGNER_SPECIAL3;
                }

                pTemp = pTemp->pNext;
            }
        }
    }
    else
    {
        //int x = 0;    // PICKLE not used
    }


    // je nach handlung richtig verhalten
    switch (Handlung)
    {
    case GEGNER_INIT:
    {
        if (PlayerAbstandHoriz() < 400.0f &&
                PlayerAbstandVert() < 400.0f &&
                PlayerAbstand(true) < 600.0f)
        {
            // Den Schädel wieder zurückpfeiffen
            if (Value1 == -1)
            {
                Value1 = -2;
                ReturnSkull();
                pSoundManager->PlayWave(100, 128, 10000 + rand()%2000, SOUND_LAUGH);
            }

            // und loslegen (nach kurzer Pause)
            if (Value1 == 1)
            {
                AnimCount -= 1.0f SYNC;
                if (AnimCount <= 0.0f)
                    NeueAktion();
            }
        }
    }
    break;

    case GEGNER_SPECIAL:
    {
        ShotDelay -= 1.0f SYNC;

        if (ShotDelay < 0.0f)
        {
            WinkelUebergabe = dummy;

            pSoundManager->PlayWave(50, 128, 8000 + rand()%2000, SOUND_GOLEMSHOT);

            pProjectiles->PushProjectile(xPos, yPos + 332, GOLEMSCHUSS);
            pPartikelSystem->PushPartikel(xPos - 30, yPos + 295, EXPLOSIONFLARE);
            pPartikelSystem->PushPartikel(xPos, yPos + 320, SMOKEBIG);
            ShotDelay = 1.2f;
            VorneX = 5.0f;
            ShotCount--;

            if (ShotCount <= 0)
                NeueAktion();
        }
    }
    break;

    // lila boller schiessen
    case GEGNER_SPECIAL2:
    {
        ShotDelay -= 1.0f SYNC;

        if (ShotDelay < 0.0f)
        {
            pSoundManager->PlayWave(100, 128, 10000 + rand()%2000, SOUND_LILA);
            pProjectiles->PushProjectile(xPos, yPos + 332, SPIDERSHOT2);
            pPartikelSystem->PushPartikel(xPos - 30, yPos + 295, EXPLOSIONFLARE);
            pPartikelSystem->PushPartikel(xPos, yPos + 320, SMOKEBIG);
            ShotDelay = 5.0f;
            VorneX = 5.0f;
            ShotCount--;

            if (ShotCount <= 0)
                NeueAktion();
        }
    }
    break;

    // Elektropampe schiessen
    case GEGNER_SPECIAL3:
    {
        ShotDelay -= 1.0f SYNC;

        if (ShotDelay < 0.0f)
        {
            if (ShotCount > 1)
            {
                pSoundManager->PlayWave(128, 100, 11025, SOUND_LILA);
                pSoundManager->PlayWave(128, 100, 25050, SOUND_GOLEMLOAD);
                pProjectiles->PushProjectile(xPos + 220.0f,
                                             yPos + 210.0f,
                                             ELEKTROSCHUSS);
            }

            ShotDelay = 30.0f;
            ShotCount--;

            if (ShotCount <= 0)
                NeueAktion();
        }
    }
    break;

    // Fetten Laser schiessen
    case GEGNER_BOMBARDIEREN:
    {
        ShotDelay -= 1.0f SYNC;

        if (ShotDelay < 0.0f)
        {
            if (ShotCount > 1)
            {
                pProjectiles->PushProjectile((float) pTileEngine->XOffset - 40.0f,
                                             yPos + 240.0f, SPIDERLASER);
                pSoundManager->PlayWave (100, 128, 11025, SOUND_BEAMLOAD2);
            }

            ShotDelay = 60.0f;
            ShotCount--;

            if (ShotCount <= 0)
                NeueAktion();
        }
    }
    break;

    case GEGNER_STEHEN:
    {
        if (Value1 == 1)
            NeueAktion();
    }
    break;

    case GEGNER_OEFFNEN:
    {
        // Tür bewegen
        if (DoorOffset < PI / 2.0f)
            DoorOffset += 0.075f SYNC;

        // Tür offen? Dann countdown, bis sie wieder zugeht
        else
        {
            DoorOffset = PI / 2.0f;

            // Tür öffnen Sound anhalten
            if (pSoundManager->its_Sounds[SOUND_DOOR]->isPlaying)
            {
                pSoundManager->StopWave(SOUND_DOOR);
                pSoundManager->PlayWave(100, 128, 22000, SOUND_STEAM2);
            }

            AnimCount -= 1.0f SYNC;
            if (AnimCount < 0.0f)
            {
                pSoundManager->PlayWave(100, 128, 10000 + rand()%1000, SOUND_DOOR);
                Handlung = GEGNER_SCHLIESSEN;
            }
        }


    }
    break;

    case GEGNER_SCHLIESSEN:
    {
        // Tür
        DoorOffset += 0.125f SYNC;

        if (DoorOffset > PI)
        {
            DoorOffset = 0.0f;
            ShakeScreen(2.0f);
            pSoundManager->PlayWave(100, 128, 11000 + rand()%1500, SOUND_DOORSTOP);

            // Tür öffnen Sound anhalten
            if (pSoundManager->its_Sounds[SOUND_DOOR]->isPlaying)
                pSoundManager->StopWave(SOUND_DOOR);

            for (int i = 0; i < 36; i++)
                pPartikelSystem->PushPartikel(xPos + TunnelOffx + 110 + rand()%30,
                                              yPos + TunnelOffY + rand()%10 + i * 5 - 25, SMOKE);

            for (int i = 0; i < 15; i++)
                pPartikelSystem->PushPartikel(xPos + TunnelOffx + 95 + rand()%30,
                                              yPos + TunnelOffY + rand()%10 + i * 10 - 25, SMOKEBIG);

            Handlung = GEGNER_STEHEN;
            AnimCount = 20.0f;
            OldEnergy = Energy;
            SkullEnergy = 250.0f;

            // Den Schädel wieder zurückpfeiffen
            ReturnSkull();
        }
    }
    break;

    case GEGNER_EXPLODIEREN:
    {
        AnimCount -= 1.0f SYNC;

        if (AnimCount < 0.0f)
        {
            if (ShotCount > 0)
            {
                ShotCount = 0;
                ScrolltoPlayeAfterBoss();
            }
        }
    }
    break;
    }

}
void GegnerPresswurst::DoKI(void)
{
	// Spieler kann von unten nicht durchspringen
	//
	for (int p = 0; p < NUMPLAYERS; p++)
	if (SpriteCollision(pPlayer[p]->xpos, 
						pPlayer[p]->ypos, 
						pPlayer[p]->CollideRect,
						xPos, yPos, GegnerRect[GegnerArt]) == true &&
						yPos < pPlayer[p]->ypos					   && 
						pPlayer[p]->yspeed < 0.0f)
						pPlayer[p]->yspeed *= -0.25f;

	// Kollisionsrechteck fürs Wegschieben
	GegnerRect[GegnerArt].top = 0;	
	Wegschieben(GegnerRect[GegnerArt], 0.0f);	

	// Kollisionsrechteck für das Unterteil	
	GegnerRect[GegnerArt].top = 251;	

	blocko = pTileEngine->BlockOben		  (xPos, yPos, yPosOld, yPosOld, GegnerRect[GegnerArt]);
	blocku = pTileEngine->BlockUntenNormal(xPos, yPos, yPosOld, yPosOld, GegnerRect[GegnerArt]);	

	// Ja nach Handlung richtig verhalten
	switch (Handlung)
	{
		// Am Anfang einmal initialisieren
		case GEGNER_INIT:
		{			
			yPos -= GegnerRect[GegnerArt].top;
			oldy = yPos;
			Handlung = GEGNER_INIT2;

		} break;

		// Auf Spieler warten
		case GEGNER_INIT2:
		{
			for (int p = 0; p < NUMPLAYERS; p++)
			if (pPlayer[p]->ypos > yPos		&&
				PlayerAbstandHoriz(pPlayer[p]) < 200  &&
				PlayerAbstandVert(pPlayer[p])  < 500)
			{
				Handlung = GEGNER_LAUFEN;
				ySpeed = 10.0f;
				yAcc = 2.5f;

				if (PlayerAbstand(true) < 600)
					pSoundManager->PlayWave3D((int)(xPos + 90), (int)(yPos + 330), 11025, SOUND_PRESSE);
			}
		} break;

		// Pressen
		case GEGNER_LAUFEN :
		{
			// Spieler beim Runterfallen berührt? Dann stirbt er leider ;)
			//
			for (int p = 0; p < NUMPLAYERS; p++)
			if (SpriteCollision(pPlayer[p]->xpos, 
								pPlayer[p]->ypos, 
								pPlayer[p]->CollideRect,
								xPos, yPos, GegnerRect[GegnerArt]) == true &&
								pPlayer[p]->ypos > yPos)
			{
				// wenn er steht, dann gleich zerquetschen
				if (pPlayer[p]->Handlung != SPRINGEN)
					pPlayer[p]->DamagePlayer(500.0f);

				// wenn er springt, dann runterdrücken
				else
				{
					//pPlayer->yspeed = 0.0f;
					//pPlayer->yadd = 0.0f;
					pPlayer[p]->ypos = yPos + GegnerRect[PRESSWURST].bottom;
				}
			}
			

			// Am Boden ? Dann Partikel erzeugen und zum "Produzieren" wechseln
			if (ySpeed > 0.0f &&
			   (blocku & BLOCKWERT_WAND		  ||
				blocku & BLOCKWERT_GEGNERWAND))
			{		
				// Spieler beim Runterfallen berührt? Dann stirbt er leider ;)
				//
				for (int p = 0; p < NUMPLAYERS; p++)
				if (SpriteCollision(pPlayer[p]->xpos, 
									pPlayer[p]->ypos, 
									pPlayer[p]->CollideRect,
									xPos, yPos, GegnerRect[GegnerArt]) == true &&
									pPlayer[p]->ypos > yPos)
									pPlayer[p]->DamagePlayer(500.0f);

				pTileEngine->BlockUnten(xPos, yPos, yPosOld, yPosOld, GegnerRect[GegnerArt]);	

				ySpeed = 0.0f;
				yAcc   = 0.0f;
				SmokeCount = 5.0f;
				
				if (PlayerAbstand() < 600)
					pSoundManager->PlayWave3D((int)(xPos + 90), (int)(yPos + 330), 11025, SOUND_DOORSTOP);

				ShakeScreen(2.0f);

				Handlung = GEGNER_SPECIAL;
			}

			// An der Decke ? Dann wieder in den Wartezustand setzen
			if (ySpeed < 0.0f &&
			   (blocko & BLOCKWERT_WAND		  ||
				blocko & BLOCKWERT_GEGNERWAND))
			{				
				ySpeed = 0.0f;
				yAcc   = 0.0f;				
							
				Handlung = GEGNER_INIT2;
			}

		} break;

		// Presse wartet unten und spuckt dann Dampf
		case GEGNER_SPECIAL:
		{
			SmokeCount -= 1.0f SYNC;

			if (SmokeCount <= 0.0f)
			{
				Handlung  = GEGNER_SPECIAL2;
				AnimCount = 28.0f;
				if (PlayerAbstand() < 600)
					pSoundManager->PlayWave3D((int)(xPos + 90), (int)(yPos + 330), 13000, SOUND_STEAM2);
			}
		} break;

		// Presse dampft
		case GEGNER_SPECIAL2:
		{
			// rauchen lassen
			SmokeCount -= 1.0f SYNC;
			if (SmokeCount <= 0.0f)
			{
				SmokeCount = 0.2f;

				pPartikelSystem->PushPartikel(xPos + 30.0f, yPos + 300.0f, SMOKE3_LU);
				pPartikelSystem->PushPartikel(xPos + 135.0f, yPos + 300.0f, SMOKE3_RU);
			}

			// Spinne spawnen
			AnimCount -= 1.0f SYNC;
			if (AnimCount < 0.0f)
			{
				// Spinne spawnen
				pGegner->PushGegner(xPos + 60.0f, yPos + 357 - GegnerRect[SPIDERBOMB].bottom, SPIDERBOMB, 0, 0, false, true);

				// wieder hochfahren
				Handlung = GEGNER_LAUFEN;
				ySpeed   = -15.0f;
				yAcc     = 0.2f;

				if (PlayerAbstand() < 600)
					pSoundManager->PlayWave3D((int)(xPos + 90), (int)(yPos + 330), 11025, SOUND_PRESSE);
			}
		} break;

	} // switch	
}
void GegnerFahrstuhlBoss::DoKI(void)
{
	if (x1 < 0)
		x1 = 0;

	// Energie anzeigen
	if (Handlung != GEGNER_NOTVISIBLE && Handlung != GEGNER_EXPLODIEREN)
		pHUD->ShowBossHUD(6000, Energy);

	// Boss aktivieren und Mucke laufen lassen
	if (Active == true && Activated == false)
	{
		pSoundManager->FadeSong(MUSIC_STAGEMUSIC, -2.0f, 0, true);  // Ausfaden und pausieren
		Activated = true;
		Value1 = int (pTileEngine->YOffset + 100.0f);
	}

	// Zwischenboss blinkt nicht so lange wie die restlichen Gegner
	if (DamageTaken > 0.0f)
		DamageTaken -= 50 SYNC;					// Rotwerden langsam ausfaden lassen
	else
		DamageTaken = 0.0f;						// oder ganz anhalten

	// Hat der Boss keine Energie mehr ? Dann explodiert er
	if (Energy <= 100.0f && Handlung != GEGNER_EXPLODIEREN)
	{
		Handlung  = GEGNER_EXPLODIEREN;
		ShotDelay = 1.0f;
		g_Fahrstuhl_Speed = -1.0f;
		dx1		  = 0.0f;
		dx2		  = 0.0f;

		// Level wieder auf Spieler zentrieren
		//
		pTileEngine->ScrollLevel(pPlayer[0]->xpos - 300, 
								 pPlayer[0]->ypos - 280, ZUSTAND_SCROLLTOPLAYER, 10.0f, 50.0f);

		// Endboss-Musik ausfaden und abschalten
		pSoundManager->FadeSong(MUSIC_BOSS, -2.0f, 0, false);
	}

	static float smokecount = 0.0f;

	// Füße an der Seite rauchen lassen
	//
	smokecount -= 1.0f SYNC;
	if (smokecount < 0.0f)
	{
		smokecount = 1.0f;
	
		pPartikelSystem->PushPartikel(xPos + rand()%10 - 15, yPos,  SMOKEBIG);
		pPartikelSystem->PushPartikel(xPos + rand()%10 - 15, yPos + 210, SMOKEBIG);

		pPartikelSystem->PushPartikel(xPos + rand()%10 + 375, yPos,  SMOKEBIG);
		pPartikelSystem->PushPartikel(xPos + rand()%10 + 375, yPos + 210, SMOKEBIG);

		// Wunden Punkt rauchen lassen bei wenig Energy
		if (Energy <= 1500.0f)	
		{
			pPartikelSystem->PushPartikel(xPos + x1 + 35 + rand()%20, yPos + y1 + rand()%15,  SMOKEBIG);

			if (rand()%10 == 0)
			{
				pPartikelSystem->PushPartikel(xPos + x1 + 50 + rand()%20, yPos + y1 + 35 + rand()%15, LASERFLAME);
			}
		}
	}	

	// Kanonen bewegen
	x1 += dx1 SYNC;
	x2 += dx2 SYNC;
	x3 -= dx2 SYNC;

	CanonAnim += dx2 SYNC;
	if (CanonAnim >= 6.0f) CanonAnim = 0.0f;
	if (CanonAnim <  0.0f) CanonAnim = 6.0f;

	if (x2 > 340) { x2 = 25;  x3 = 340; }

	// Riesen Wumme begradigen
	if (Handlung == GEGNER_EINFLIEGEN ||
		Handlung == GEGNER_ABSENKEN   ||
		Handlung == GEGNER_AUFRICHTEN)
	{
			if ((dx1 < 0.0f && x1 < 140.0f) ||
				(dx1 > 0.0f && x1 > 140.0f))
			{ 
				x1 = 140.0f; 
				dx1 = 0.0f; 
			}
	}

// Je nach Handlung richtig verhalten
	switch (Handlung)
	{
		case GEGNER_NOTVISIBLE:			// Boss einfliegen lassen
		{
			// Warten bis die Level Mucke ausgefadet ist
			if (pSoundManager->its_Songs[MUSIC_STAGEMUSIC]->Volume == pSoundManager->its_Songs[MUSIC_STAGEMUSIC]->FadingEnd)
			{
				// Zwischenboss-Musik abspielen, sofern diese noch nicht gespielt wird
				if (FMUSIC_IsPlaying(pSoundManager->its_Songs[MUSIC_BOSS]->SongData) == false)
					pSoundManager->PlaySong(MUSIC_BOSS, false);

				Handlung = GEGNER_EINFLIEGEN2;				// Und Boss erscheinen lassen
			}
		} break;

		case GEGNER_EINFLIEGEN2:	// Gegner kommt in den Screen geflogen am Anfang (einmalig)
		{
			Energy = 6000;
			DamageTaken = 0.0f;

			TempY -= 5.0f SYNC;
			
			// Gegner an der richtigen Position ?
			if (TempY < 500.0f)
			{
				Handlung = GEGNER_ABSENKEN;
				TempY    = 500.0f;
				dx2		 = 5.0f;
			}

			// Levelausschnitt weiter nach unten scrollen damit man mehr vom Boss sieht
			if (g_Fahrstuhl_Offset < 150.0f)
				g_Fahrstuhl_Offset += 4.0f SYNC;
			else
				g_Fahrstuhl_Offset = 150.0f;
		} break;

		case GEGNER_EINFLIEGEN:		// Gegner kommt in den Screen geflogen
		{
			TempY -= 5.0f SYNC;
			
			// Gegner an der richtigen Position ?
			if (TempY < 500.0f)
			{
				int j = rand ()%6;
				if (j == 0)
				{
					Handlung = GEGNER_ABSENKEN;
					TempY    = 500.0f;
					dx2		 = 0.0f;
				}
				else
				if (j == 1 || j == 2)
				{
					Handlung = GEGNER_ABSENKEN;
					TempY    = 500.0f;
					dx2		 = 5.0f;
				}
				else
				if (j == 3)
				{
					Handlung = GEGNER_AUSSPUCKEN;
					TempY    = 500.0f;
					Shots    = 1 + rand ()% 2;
				}
				else
				if (j == 4 || j == 5)
				{
					Handlung  = GEGNER_CRUSHEN;
					TempY     = 500.0f;
					Shots     = 10 + rand ()%20;
					ShotDelay = 2.0f;
				}
			}

			// Levelausschnitt weiter nach unten scrollen damit man mehr vom Boss sieht
			if (g_Fahrstuhl_Offset < 150.0f)
				g_Fahrstuhl_Offset += 4.0f SYNC;
			else
				g_Fahrstuhl_Offset = 150.0f;
		} break;

		case GEGNER_LAUFEN:			// yPos über dem Fahrstuhl
		{
		} break;

		case GEGNER_ABSENKEN:		// Gegner kommt nach unten
		{
			TempY -= 5.0f SYNC;
			
			// Gegner an der richtigen Position ?
			if (TempY < 380.0f)
			{
				if (dx2 != 0.0f)
				{
					Handlung  = GEGNER_SCHIESSEN;
					TempY     = 380.0f;
					ShotDelay = 1.0f;
					Shots     = rand()%10 + 10;
				}
				else
				{
					Handlung  = GEGNER_AUSSPUCKEN;
					TempY     = 380.0f;
					ShotDelay = 5.0f;
					Shots    = 2 + rand ()% 2;
				}
			}
		} break;

		case GEGNER_AUFRICHTEN:		// Gegner fährt wieder hoch
		{
			TempY += 5.0f SYNC;
			
			// Gegner an der richtigen Position ?
			if (TempY > 600.0f)
			{
				int j = rand()%3;
				if (j == 0)
				{
					Handlung  = GEGNER_BOMBARDIEREN;
					dx1	      = 40.0f;
					TempY     = 600.0f;
					ShotDelay = 1.0f;
					Shots     = rand()%8 + 5;
				}
				else
				if (j == 1)
				{
					Handlung  = GEGNER_SPECIAL;
					dx1	      = 0.0f;
					TempY     = 600.0f;
					ShotDelay = 5.0f;
					Shots     = rand()%8 + 5;
				}
				else
				if (j == 2)
				{
					Handlung  = GEGNER_AUSSPUCKEN;
					dx1	      = 0.0f;
					TempY     = 600.0f;
					ShotDelay = 5.0f;
					Shots     = rand()%4 + 2;
				}
			}
		} break;

		case GEGNER_SCHIESSEN:		// Mit zwei lasern ballern
		{
			ShotDelay -= 1.0f SYNC;

			if (ShotDelay < 0.0f)
			{
				ShotDelay = 6.0f;

				pSoundManager->PlayWave(100, 128, 44100, SOUND_LASERSHOT);
				
				pProjectiles->PushProjectile (xPos + x2 + 28,      yPos + y2 + 95,     KRABBLERLASER1);
				pPartikelSystem->PushPartikel(xPos + x2 + 28 - 25, yPos + y2 + 95 - 4, LASERFLAME);

				pProjectiles->PushProjectile (xPos + x3 + 28,      yPos + y2 + 95,     KRABBLERLASER1);
				pPartikelSystem->PushPartikel(xPos + x3 + 28 - 25, yPos + y2 + 95 - 4, LASERFLAME);

				y2 = 75;

				// Genug geschossen ?
				Shots--;
				if (Shots <= 0)
				{
					dx2 = 0.0f;
					Handlung = GEGNER_AUFRICHTEN;
				}
			}
		} break;

		case GEGNER_BOMBARDIEREN:		// Steine bröckeln lassen
		{
			// An der Seite angekommen ? Dann ruckeln lassen und Steine werfen
			if ((x1 > 280 && dx1 > 0.0f) || 
				(x1 < 0   && dx1 < 0.0f))
			{
				ShakeScreen(3);
				dx1 *= -1.0f;

				pGegner->PushGegner (xPos + 10 + rand ()%360, yPos+480, BOULDER, 40+rand()%20, 0, false);

				// aufhören damit ?
				Shots--;
				if (Shots <= 0)
				{
					Handlung = GEGNER_EINFLIEGEN;

					if (x1 < 140.0f)
						dx1 = 10.0f;
					else
						dx1 = -10.0f;
				}
			}
		} break;

		case GEGNER_SPECIAL:			// Hurri anvisieren und Laser ballern
		{
			if (ShotDelay > 0.0f)
				ShotDelay -= 1.0f SYNC;

			// Bewegen
			if (pAim->xpos + 35 < xPos + x1 + 60) x1 -= 8.0f SYNC;
			if (pAim->xpos + 35 > xPos + x1 + 80) x1 += 8.0f SYNC;

			// Schiessen
			if (pAim->xpos + 35 < xPos + x1 + 100 &&
				pAim->xpos + 35 > xPos + x1 + 40 &&
				ShotDelay <= 0.0f)
			{
				ShotDelay = 8.0f;

				pSoundManager->PlayWave (100, 128, 10000 + rand()%2000, SOUND_LASERSHOT);

				pProjectiles->PushProjectile  (xPos + x1 + 80 - 28, yPos + y1 + 155, UFOLASER);
				pPartikelSystem->PushPartikel (xPos + x1 + 80 - 90, yPos + y1 + 110, UFOLASERFLARE);

				y1 = 155;

				// Aufhören zu ballern
				Shots--;
				if (Shots <= 0)
				{
					Handlung = GEGNER_EINFLIEGEN;

					if (x1 < 140.0f)
						dx1 = 10.0f;
					else
						dx1 = -10.0f;
				}
			}
		} break;

		case GEGNER_AUSSPUCKEN:				// Stelzis herbeirufen =)
		{
			ShotDelay -= 1.0f SYNC;

			if (ShotDelay < 0.0f)
			{
				ShotDelay = 35.0f;

				pGegner->PushGegner (xPos + 10 + rand ()%360, yPos+480, STELZSACK, 80, 0, false);

				// Genug losgelassen ?
				Shots--;
				if (Shots <= 0)
				{
					dx2 = 0.0f;
					if (TempY != 380.0f)
						Handlung = GEGNER_EINFLIEGEN;
					else
						Handlung = GEGNER_AUFRICHTEN;

					if (x1 < 140.0f)
						dx1 = 10.0f;
					else
						dx1 = -10.0f;
				}
			}
			
		} break;

		case GEGNER_CRUSHEN:				// Suchschüsse ballern
		{
			ShotDelay -= 1.0f SYNC;

			if (ShotDelay < 0.0f)
			{
				ShotDelay = 5.0f;

				pSoundManager->PlayWave(100, 128, 8000 + rand ()%4000, SOUND_CANON);
				
				pProjectiles->PushProjectile (xPos + x2 + 28,      yPos + y2 + 95+5, SUCHSCHUSS);
				pPartikelSystem->PushPartikel(xPos + x2 + 28 - 10, yPos + y2 + 95,   SMOKE);

				pProjectiles->PushProjectile (xPos + x3 + 28,      yPos + y2 + 95+5, SUCHSCHUSS);
				pPartikelSystem->PushPartikel(xPos + x3 + 28 - 10, yPos + y2 + 95,   SMOKE);

				y2 = 77;
				
				// Genug losgelassen ?
				Shots--;
				if (Shots <= 0)
				{
					dx2		 = 5.0f;
					Handlung = GEGNER_ABSENKEN;

					if (x1 < 140.0f)
						dx1 = 10.0f;
					else
						dx1 = -10.0f;
				}
			}
			
		} break;

		case GEGNER_FALLEN:
		{
		} break;

		// Gegner fliegt in die Luft
		//
		case GEGNER_EXPLODIEREN:
		{
			ShotDelay -= 1.0f SYNC;

			if (ShotDelay < 0.0f)
			{
				ShotDelay = 0.5f;
				pSoundManager->PlayWave (100, 128, 8000 + rand()%4000, SOUND_EXPLOSION1);

				pPartikelSystem->PushPartikel (xPos -30 + rand()%400, yPos + rand()%280, EXPLOSION_MEDIUM2);
				pPartikelSystem->PushPartikel (xPos -50 + rand()%400, yPos + rand()%280, EXPLOSION_BIG);

				if (rand ()%2 == 0)
					pPartikelSystem->PushPartikel (xPos + rand()%400, yPos + rand()%280, SPLITTER);
			}

			Energy = 100.0f;

			// Levelausschnitt wieder weiter nach oben Scrollen
			if (g_Fahrstuhl_Offset > 20.0f)
				g_Fahrstuhl_Offset -= 4.0f SYNC;
			else
				g_Fahrstuhl_Offset = 20.0f;

			TempY -= 10.0f SYNC;

			// Gegner aus dem Screen, dann fetzen
			if (TempY < -400.0f)
				Energy = 0.0f;

		} break;

		default : break;
	} // switch

	// yPosition über dem Fahrstuhl setzen
	yPos = g_Fahrstuhl_yPos - TempY;

	if (yPos < 0.0f)
		yPos = 0.0f;

	// Anhängsel am Fahrstuhl richtig positionieren
	if (y2 <  80.0f) y2 += 2.0f SYNC; else y2 =  80.0f;
	if (y1 < 160.0f) y1 += 2.0f SYNC; else y1 = 160.0f;

	// Schüsse und Partikel jeweils anpassen, damit sie gerade fliegen und nicht nach oben
	// abdriften wegen der FahrstuhlGeschwindigkeit

	for (int i = 0; i < NUMPLAYERS; i++)
	if (pPlayer[i]->AufPlattform == NULL)
	{
		pPlayer[i]->ypos	  += 40.0f SYNC;
		pPlayer[i]->yposold   += 40.0f SYNC;
		pPlayer[i]->JumpStart += 40.0f SYNC;
	}

	PartikelClass *pTemp = pPartikelSystem->pStart; // Zeiger auf den ersten Partikel
	while (pTemp != NULL)						 	// Ende der Liste erreicht ?
	{
		if (pTemp->PartikelArt != FUNKE  &&
			pTemp->PartikelArt != BULLET &&
			pTemp->PartikelArt != SMOKE)
		{
			pTemp->yPos	   += 40.0f SYNC;			// Nach unten bewegen
			pTemp->yPosOld += 40.0f SYNC;
		}
		pTemp = pTemp->pNext;						// Zeiger auf das nächste Element
	}

	ProjectileClass *pTemp2 = pProjectiles->pStart;	// Zeiger auf den ersten Schuss
	while (pTemp2 != NULL)							// Ende der Liste erreicht ?
	{
		if (pTemp2->ShotArt != STELZLASER)
		{
			pTemp2->yPos	+= 40.0f SYNC;			// Nach unten bewegen
			pTemp2->yPosOld += 40.0f SYNC;
		}
			pTemp2 = pTemp2->pNext;					// Zeiger auf das nächste Element
	}

	// Level-Hintergrund wiederholen und alle Objekte wieder nach oben setzen
	const int A = 2 * 24 * 20;
	if (yPos > Value1 + A)
	{
		pTileEngine->YOffset -= A;

		for (int p = 0; p < NUMPLAYERS; p++)
			pPlayer[p]->ypos -= A;

		GegnerClass *pTemp    = pGegner->pStart;		// Zeiger auf den ersten Gegner
		while (pTemp != NULL)							// Ende der Liste erreicht ?
		{
			if (pTemp->GegnerArt >= SPITTER &&
				pTemp->GegnerArt <= FAHRSTUHL)
			{
				pTemp->yPos	   -= A;				// Nach oben bewegen
				pTemp->yPosOld -= A;
			}

			pTemp = pTemp->pNext;						// Zeiger auf das nächste Element
		}

		ProjectileClass *pTemp2 = pProjectiles->pStart;	// Zeiger auf den ersten Schuss
		while (pTemp2 != NULL)							// Ende der Liste erreicht ?
		{
			pTemp2->yPos	-= A;				// Nach oben bewegen
			pTemp2->yPosOld -= A;
			pTemp2 = pTemp2->pNext;						// Zeiger auf das nächste Element
		}

		PartikelClass *pTemp3 = pPartikelSystem->pStart;// Zeiger auf den ersten Partikel
		while (pTemp3 != NULL)							// Ende der Liste erreicht ?
		{
			pTemp3->yPos	-= A;				// Nach oben bewegen
			pTemp3->yPosOld -= A;
			pTemp3 = pTemp3->pNext;						// Zeiger auf das nächste Element
		}
	}
}
Example #13
0
void DoRage(Guy *me)
{
	int cx, cy, i;

	if (player.rageClock > 0)
		player.rageClock--;

	if (player.rageClock > 59)
		switch (rageWpn) {
			case WPN_NONE:
				switch (opt.playAs) {
					case PLAYAS_BOUAPHA:
						if (player.rageClock == (player.rageClock / 4)*4)
							HammerLaunch(me->x, me->y, me->facing, 5, HMR_REVERSE | HMR_REFLECT);
						break;
					case PLAYAS_LUNATIC:
						if (player.rageClock == (player.rageClock / 4)*4)
						{
							for (i = 0; i < 10; i++)
								FireBullet(me->x, me->y, (byte) MGL_random(8), BLT_BALLLIGHTNING, 1);
						}
						break;
					case PLAYAS_HAPPY:
						if (player.rageClock == (player.rageClock / 4)*4)
							HappyLaunch(me->x, me->y, me->facing, 5, HMR_REVERSE | HMR_REFLECT);
						break;
				}
				break;
			case WPN_MISSILES:
				FireBullet(me->x, me->y, (player.rageClock & 7), BLT_MISSILE, 1);
				break;
			case WPN_BOMBS:
				GetCamera(&cx, &cy);
				cx -= 320;
				cy -= 240;
				FireBullet((cx + MGL_random(640)) << FIXSHIFT, (cy + MGL_random(480)) << FIXSHIFT,
						0, BLT_BOOM, 1);
				ShakeScreen(10); // make the screen shake!
				break;
			case WPN_AK8087:
				FireBullet(me->x, me->y, (byte) MGL_random(8), BLT_LASER, 1);
				FireBullet(me->x, me->y, (byte) MGL_random(8), BLT_LASER, 1);
				FireBullet(me->x, me->y, (byte) MGL_random(8), BLT_LASER, 1);
				break;
			case WPN_FLAME:
				GetCamera(&cx, &cy);
				cx -= 320;
				cy -= 240;
				for (i = 0; i < 3; i++)
					FireBullet((cx + MGL_random(640)) << FIXSHIFT, (cy + MGL_random(480)) << FIXSHIFT,
						(byte) MGL_random(8), BLT_FLAME, 1);
				break;
			case WPN_BIGAXE:
				if (player.rageClock == (player.rageClock / 5)*5)
				{
					MakeSound(SND_BOMBTHROW, me->x, me->y, SND_CUTOFF, 1200);
					FireBullet(me->x, me->y, me->facing, BLT_BIGAXE, 1);
				}
				break;
			case WPN_LIGHTNING:
				GetCamera(&cx, &cy);
				cx -= 320;
				cy -= 240;
				FireBullet((cx + MGL_random(640)) << FIXSHIFT, (cy + MGL_random(480)) << FIXSHIFT,
						(byte) MGL_random(8), BLT_LIGHTNING, 1);
				break;
			case WPN_SPEAR:
				if (player.rageClock == (player.rageClock / 3)*3)
				{
					MakeSound(SND_BOMBTHROW, me->x, me->y, SND_CUTOFF, 1200);
					FireBullet(me->x, me->y, (me->facing + 7)&7, BLT_SPEAR, 1);
					FireBullet(me->x, me->y, me->facing, BLT_SPEAR, 1);
					FireBullet(me->x, me->y, (me->facing + 1)&7, BLT_SPEAR, 1);
				}
				break;
			case WPN_MACHETE:
				GetCamera(&cx, &cy);
				cx -= 320;
				cy -= 240;
				for (i = 0; i < 10; i++)
					FireBullet((cx + MGL_random(640)) << FIXSHIFT, (cy + MGL_random(480)) << FIXSHIFT,
						(byte) MGL_random(8), BLT_SLASH, 1);
				break;
			case WPN_MINES:
				if (player.rageClock == (player.rageClock / 8)*8)
				{
					cx = 32 / 8 - ((player.rageClock - 60) / 8) + 1;
					for (i = 0; i < 8; i++)
						FireBullet(me->x + Cosine(i * 32)*(cx * 32), me->y + Sine(i * 32)*(cx * 32),
							0, BLT_BOOM, 1);
				}
				break;
			case WPN_MINDCONTROL:
				if (player.rageClock & 1)
					for (i = 0; i < 8; i++)
						FireBullet(me->x, me->y, i, BLT_MINDWIPE, 1);
				break;
			case WPN_REFLECTOR:
				FireBullet(me->x, me->y, 0, BLT_REFLECT, 1);
				break;
			case WPN_TURRET:
			case WPN_SWAPGUN:
				for (i = 0; i < 4; i++)
					FireBullet(me->x, me->y, (i * 64 + player.rageClock)&255, BLT_GREEN, 1);
				break;
			case WPN_JETPACK:
				for (i = 0; i < 8; i++)
					FireBullet(me->x, me->y, i, BLT_FLAME, 1);
				break;
		}
}