Exemplo n.º 1
0
//
// P_GiveItemToPlayer
//
// [STRIFE] New function
// haleyjd 09/03/10: Sorts out how to give something to the player.
// Not strictly just for inventory items.
// villsa 09/09/10: Fleshed out function
//
boolean P_GiveItemToPlayer(player_t *player, int sprnum, mobjtype_t type)
{
    int i = 0;
    line_t junk;
    int sound = sfx_itemup; // haleyjd 09/21/10: different sounds for items

    // set quest if mf_givequest flag is set
    if(mobjinfo[type].flags & MF_GIVEQUEST)
        player->questflags |= 1 << (mobjinfo[type].speed - 1);

    // check for keys
    if(type >= MT_KEY_BASE && type <= MT_NEWKEY5)
    {
        P_GiveCard(player, type - MT_KEY_BASE);
        return true;
    }

    // check for quest tokens
    if(type >= MT_TOKEN_QUEST1 && type <= MT_TOKEN_QUEST31)
    {
        if(mobjinfo[type].name)
        {
            M_StringCopy(pickupstring, DEH_String(mobjinfo[type].name), 39);
            player->message = pickupstring;
        }
        player->questflags |= 1 << (type - MT_TOKEN_QUEST1);

        if(player == &players[consoleplayer])
            S_StartSound(NULL, sound);
        return true;
    }

    // haleyjd 09/22/10: Refactored to give sprites higher priority than
    // mobjtypes and to implement missing logic.
    switch(sprnum)
    {
    case SPR_HELT: // This is given only by the "DONNYTRUMP" cheat (aka Midas)
        P_GiveInventoryItem(player, SPR_HELT, MT_TOKEN_TOUGHNESS);
        P_GiveInventoryItem(player, SPR_GUNT, MT_TOKEN_ACCURACY);

        // [STRIFE] Bizarre...
        for(i = 0; i < 5 * player->accuracy + 300; i++)
            P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1);
        break;

    case SPR_ARM1: // Armor 1
        if(!P_GiveArmor(player, -2))
            P_GiveInventoryItem(player, sprnum, type);
        break;

    case SPR_ARM2: // Armor 2
        if(!P_GiveArmor(player, -1))
            P_GiveInventoryItem(player, sprnum, type);
        break;

    case SPR_COIN: // 1 Gold
        P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1);
        break;

    case SPR_CRED: // 10 Gold
        for(i = 0; i < 10; i++)
            P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1);
        break;

    case SPR_SACK: // 25 gold
        for(i = 0; i < 25; i++)
            P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1);
        break;

    case SPR_CHST: // 50 gold
        for(i = 0; i < 50; i++)
            P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1);

    case SPR_BBOX: // Box of Bullets
        if(!P_GiveAmmo(player, am_bullets, 5))
            return false;
        break;

    case SPR_BLIT: // Bullet Clip
        if(!P_GiveAmmo(player, am_bullets, 1))
            return false;
        break;

    case SPR_PMAP: // Map powerup
        if(!P_GivePower(player, pw_allmap))
            return false;
        sound = sfx_yeah; // bluh-doop!
        break;

    case SPR_COMM: // Communicator
        if(!P_GivePower(player, pw_communicator))
            return false;
        sound = sfx_yeah; // bluh-doop!
        break;

    case SPR_MSSL: // Mini-missile
        if(!P_GiveAmmo(player, am_missiles, 1))
            return false;
        break;

    case SPR_ROKT: // Crate of missiles
        if(!P_GiveAmmo(player, am_missiles, 5))
            return false;
        break;

    case SPR_BRY1: // Battery cell
        if(!P_GiveAmmo(player, am_cell, 1))
            return false;
        break;

    case SPR_CPAC: // Cell pack
        if(!P_GiveAmmo(player, am_cell, 5))
            return false;
        break;

    case SPR_PQRL: // Poison bolts
        if(!P_GiveAmmo(player, am_poisonbolts, 5))
            return false;
        break;

    case SPR_XQRL: // Electric bolts
        if(!P_GiveAmmo(player, am_elecbolts, 5))
            return false;
        break;

    case SPR_GRN1: // HE Grenades
        if(!P_GiveAmmo(player, am_hegrenades, 1))
            return false;
        break;

    case SPR_GRN2: // WP Grenades
        if(!P_GiveAmmo(player, am_wpgrenades, 1))
            return false;
        break;

    case SPR_BKPK: // Backpack (aka Ammo Satchel)
        if(!player->backpack)
        {
            for(i = 0; i < NUMAMMO; i++)
                player->maxammo[i] *= 2;

            player->backpack = true;
        }
        for(i = 0; i < NUMAMMO; i++)
            P_GiveAmmo(player, i, 1);
        break;

    case SPR_RIFL: // Assault Rifle
        if(player->weaponowned[wp_rifle])
            return false;

        if(!P_GiveWeapon(player, wp_rifle, false))
            return false;
        
        sound = sfx_wpnup; // SHK-CHK!
        break;

    case SPR_FLAM: // Flamethrower
        if(player->weaponowned[wp_flame])
            return false;

        if(!P_GiveWeapon(player, wp_flame, false))
            return false;

        sound = sfx_wpnup; // SHK-CHK!
        break;

    case SPR_MMSL: // Mini-missile Launcher
        if(player->weaponowned[wp_missile])
            return false;

        if(!P_GiveWeapon(player, wp_missile, false))
            return false;

        sound = sfx_wpnup; // SHK-CHK!
        break;

    case SPR_TRPD: // Mauler
        if(player->weaponowned[wp_mauler])
            return false;

        if(!P_GiveWeapon(player, wp_mauler, false))
            return false;

        sound = sfx_wpnup; // SHK-CHK!
        break;

    case SPR_CBOW: // Here's a crossbow. Just aim straight, and *SPLAT!*
        if(player->weaponowned[wp_elecbow])
            return false;

        if(!P_GiveWeapon(player, wp_elecbow, false))
            return false;

        sound = sfx_wpnup; // SHK-CHK!
        break;

    case SPR_TOKN: // Miscellaneous items - These are determined by thingtype.
        switch(type)
        {
        case MT_KEY_HAND: // Severed hand
            P_GiveCard(player, key_SeveredHand);
            break;

        case MT_MONY_300: // 300 Gold (this is the only way to get it, in fact)
            for(i = 0; i < 300; i++)
                P_GiveInventoryItem(player, SPR_COIN, MT_MONY_1);
            break;

        case MT_TOKEN_AMMO: // Ammo token - you get this from the Weapons Trainer
            if(player->ammo[am_bullets] >= 50)
                return false;

            player->ammo[am_bullets] = 50;
            break;

        case MT_TOKEN_HEALTH: // Health token - from the Front's doctor
            if(!P_GiveBody(player, healthamounts[gameskill]))
                return false;
            break;

        case MT_TOKEN_ALARM: // Alarm token - particularly from the Oracle.
            P_NoiseAlert(player->mo, player->mo);
            A_AlertSpectreC(dialogtalker); // BUG: assumes in a dialog o_O
            break;

        case MT_TOKEN_DOOR1: // Door special 1
            junk.tag = 222;
            EV_DoDoor(&junk, vld_open);
            break;

        case MT_TOKEN_PRISON_PASS: // Door special 1 - Prison pass
            junk.tag = 223;
            EV_DoDoor(&junk, vld_open);
            if(gamemap == 2) // If on Tarnhill, give Prison pass object
                P_GiveInventoryItem(player, sprnum, type);
            break;

        case MT_TOKEN_SHOPCLOSE: // Door special 3 - "Shop close" - unused?
            junk.tag = 222;
            EV_DoDoor(&junk, vld_close);
            break;

        case MT_TOKEN_DOOR3: // Door special 4 (or 3? :P ) 
            junk.tag = 224;
            EV_DoDoor(&junk, vld_close);
            break;

        case MT_TOKEN_STAMINA: // Stamina upgrade
            if(player->stamina >= 100)
                return false;

            player->stamina += 10;
            P_GiveBody(player, 200); // full healing
            break;

        case MT_TOKEN_NEW_ACCURACY: // Accuracy upgrade
            if(player->accuracy >= 100)
                return false;

            player->accuracy += 10;
            break;

        case MT_SLIDESHOW: // Slideshow (start a finale)
            gameaction = ga_victory;
            if(gamemap == 10)
                P_GiveItemToPlayer(player, SPR_TOKN, MT_TOKEN_QUEST17);
            break;
        
        default: // The default is to just give it as an inventory item.
            P_GiveInventoryItem(player, sprnum, type);
            break;
        }
        break;

    default: // The ultimate default: Give it as an inventory item.
        if(!P_GiveInventoryItem(player, sprnum, type))
            return false;
        break;
    }

    // Play sound.
    if(player == &players[consoleplayer])
        S_StartSound(NULL, sound);

    return true;
}
Exemplo n.º 2
0
/**
 * @param plr      Player being given item.
 * @param item     Type of item being given.
 * @param dropped  @c true = the item was dropped by some entity.
 *
 * @return  @c true iff the item should be destroyed.
 */
static dd_bool pickupItem(player_t *plr, itemtype_t item, dd_bool dropped)
{
    if(!plr)
        return false;

    switch(item)
    {
    case IT_ARMOR_GREEN:
        if(!P_GiveArmor(plr, armorClass[0],
                        armorPoints[MINMAX_OF(0, armorClass[0] - 1, 1)]))
            return false;

        P_SetMessage(plr, 0, GOTARMOR);
        if(!mapSetup)
            S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        break;

    case IT_ARMOR_BLUE:
        if(!P_GiveArmor(plr, armorClass[1],
                        armorPoints[MINMAX_OF(0, armorClass[1] - 1, 1)]))
            return false;
        P_SetMessage(plr, 0, GOTMEGA);
        if(!mapSetup)
            S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        break;

    case IT_ARMOR_BONUS:
        if(!plr->armorType)
            P_PlayerSetArmorType(plr, armorClass[0]);
        if(plr->armorPoints < armorPoints[1])
            P_PlayerGiveArmorBonus(plr, 1);

        P_SetMessage(plr, 0, GOTARMBONUS);
        if(!mapSetup)
        {
            S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
            // Maybe unhide the HUD?
            ST_HUDUnHide(plr - players, HUE_ON_PICKUP_ARMOR);
        }
        break;

    case IT_HEALTH_PACK:
        if(!P_GiveHealth(plr, 10))
            return false;
        P_SetMessage(plr, 0, GOTSTIM);
        if(!mapSetup)
            S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        break;

    case IT_HEALTH_KIT: {
        int oldHealth = plr->health;

        /**
         * DOOM bug:
         * The following test was originaly placed AFTER the call to
         * P_GiveHealth thereby making the first outcome impossible as
         * the medikit gives 25 points of health. This resulted that
         * the GOTMEDINEED "Picked up a medikit that you REALLY need"
         * was never used.
         */

        if(!P_GiveHealth(plr, 25)) return false;

        P_SetMessage(plr, 0, GET_TXT((oldHealth < 25)? TXT_GOTMEDINEED : TXT_GOTMEDIKIT));
        if(!mapSetup)
            S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        break; }

    case IT_HEALTH_BONUS:
        plr->health++; // Can go over 100%.
        if(plr->health > healthLimit)
            plr->health = healthLimit;
        plr->plr->mo->health = plr->health;
        plr->update |= PSF_HEALTH;
        P_SetMessage(plr, 0, GOTHTHBONUS);
        if(!mapSetup)
        {
            S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
            // Maybe unhide the HUD?
            ST_HUDUnHide(plr - players, HUE_ON_PICKUP_HEALTH);
        }
        break;

    case IT_HEALTH_SOULSPHERE:
        plr->health += soulSphereHealth;
        if(plr->health > soulSphereLimit)
            plr->health = soulSphereLimit;
        plr->plr->mo->health = plr->health;
        plr->update |= PSF_HEALTH;
        P_SetMessage(plr, 0, GOTSUPER);
        if(!mapSetup)
        {
            S_ConsoleSound(SFX_GETPOW, NULL, plr - players);
            // Maybe unhide the HUD?
            ST_HUDUnHide(plr - players, HUE_ON_PICKUP_HEALTH);
        }
        break;

    case IT_KEY_BLUE:
        if(!plr->keys[KT_BLUECARD])
        {
            P_GiveKey(plr, KT_BLUECARD);
            P_SetMessage(plr, 0, GOTBLUECARD);
            if(!mapSetup)
                S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        }
        if(IS_NETGAME)
            return false;
        break;

    case IT_KEY_YELLOW:
        if(!plr->keys[KT_YELLOWCARD])
        {
            P_GiveKey(plr, KT_YELLOWCARD);
            P_SetMessage(plr, 0, GOTYELWCARD);
            if(!mapSetup)
                S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        }
        if(IS_NETGAME)
            return false;
        break;

    case IT_KEY_RED:
        if(!plr->keys[KT_REDCARD])
        {
            P_GiveKey(plr, KT_REDCARD);
            P_SetMessage(plr, 0, GOTREDCARD);
            if(!mapSetup)
                S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        }
        if(IS_NETGAME)
            return false;
        break;

    case IT_KEY_BLUESKULL:
        if(!plr->keys[KT_BLUESKULL])
        {
            P_GiveKey(plr, KT_BLUESKULL);
            P_SetMessage(plr, 0, GOTBLUESKUL);
            if(!mapSetup)
                S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        }
        if(IS_NETGAME)
            return false;
        break;

    case IT_KEY_YELLOWSKULL:
        if(!plr->keys[KT_YELLOWSKULL])
        {
            P_GiveKey(plr, KT_YELLOWSKULL);
            P_SetMessage(plr, 0,  GOTYELWSKUL);
            if(!mapSetup)
                S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        }
        if(IS_NETGAME)
            return false;
        break;

    case IT_KEY_REDSKULL:
        if(!plr->keys[KT_REDSKULL])
        {
            P_GiveKey(plr, KT_REDSKULL);
            P_SetMessage(plr, 0, GOTREDSKULL);
            if(!mapSetup)
                S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        }
        if(IS_NETGAME)
            return false;
        break;

    case IT_MEGASPHERE:
        if(!(gameModeBits & GM_ANY_DOOM2))
            return false;
        plr->health = megaSphereHealth;
        plr->plr->mo->health = plr->health;
        plr->update |= PSF_HEALTH;
        P_GiveArmor(plr, armorClass[1],
                    armorPoints[MINMAX_OF(0, armorClass[1] - 1, 1)]);
        P_SetMessage(plr, 0, GOTMSPHERE);
        if(!mapSetup)
        {
            S_ConsoleSound(SFX_GETPOW, NULL, plr - players);
            // Maybe unhide the HUD?
            ST_HUDUnHide(plr - players, HUE_ON_PICKUP_HEALTH);
        }
        break;

    case IT_INVUL:
        if(!P_GivePower(plr, PT_INVULNERABILITY))
            return false;

        P_SetMessage(plr, 0, GOTINVUL);
        if(!mapSetup)
            S_ConsoleSound(SFX_GETPOW, NULL, plr - players);
        break;

    case IT_BERSERK:
        if(!P_GivePower(plr, PT_STRENGTH))
            return false;

        P_SetMessage(plr, 0, GOTBERSERK);
        if(plr->readyWeapon != WT_FIRST && cfg.berserkAutoSwitch)
        {
            plr->pendingWeapon = WT_FIRST;
            plr->update |= PSF_PENDING_WEAPON | PSF_READY_WEAPON;
        }
        if(!mapSetup)
            S_ConsoleSound(SFX_GETPOW, NULL, plr - players);
        break;

    case IT_INVIS:
        if(!P_GivePower(plr, PT_INVISIBILITY))
            return false;

        P_SetMessage(plr, 0, GOTINVIS);
        if(!mapSetup)
            S_ConsoleSound(SFX_GETPOW, NULL, plr - players);
        break;

    case IT_SUIT:
        if(!P_GivePower(plr, PT_IRONFEET))
            return false;

        P_SetMessage(plr, 0, GOTSUIT);
        if(!mapSetup)
            S_ConsoleSound(SFX_GETPOW, NULL, plr - players);
        break;

    case IT_ALLMAP:
        if(!P_GivePower(plr, PT_ALLMAP))
            return false;

        P_SetMessage(plr, 0, GOTMAP);
        if(!mapSetup)
            S_ConsoleSound(SFX_GETPOW, NULL, plr - players);
        break;

    case IT_VISOR:
        if(!P_GivePower(plr, PT_INFRARED))
            return false;

        P_SetMessage(plr, 0, GOTVISOR);
        if(!mapSetup)
            S_ConsoleSound(SFX_GETPOW, NULL, plr - players);
        break;

    case IT_BACKPACK:
        P_GiveBackpack(plr);
        if(!mapSetup)
            S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        break;

    case IT_AMMO_CLIP:
        if(!P_GiveAmmo(plr, AT_CLIP, dropped? 0 /*half a clip*/ : 1))
            return false;

        P_SetMessage(plr, 0, GOTCLIP);
        if(!mapSetup)
            S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        break;

    case IT_AMMO_CLIP_BOX:
        if(!P_GiveAmmo(plr, AT_CLIP, 5))
            return false;

        P_SetMessage(plr, 0, GOTCLIPBOX);
        if(!mapSetup)
            S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        break;

    case IT_AMMO_ROCKET:
        if(!P_GiveAmmo(plr, AT_MISSILE, 1))
            return false;

        P_SetMessage(plr, 0, GOTROCKET);
        if(!mapSetup)
            S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        break;

    case IT_AMMO_ROCKET_BOX:
        if(!P_GiveAmmo(plr, AT_MISSILE, 5))
            return false;

        P_SetMessage(plr, 0, GOTROCKBOX);
        if(!mapSetup)
            S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        break;

    case IT_AMMO_CELL:
        if(!P_GiveAmmo(plr, AT_CELL, 1))
            return false;

        P_SetMessage(plr, 0, GOTCELL);
        if(!mapSetup)
            S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        break;

    case IT_AMMO_CELL_BOX:
        if(!P_GiveAmmo(plr, AT_CELL, 5))
            return false;

        P_SetMessage(plr, 0, GOTCELLBOX);
        if(!mapSetup)
            S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        break;

    case IT_AMMO_SHELL:
        if(!P_GiveAmmo(plr, AT_SHELL, 1))
            return false;

        P_SetMessage(plr, 0, GOTSHELLS);
        if(!mapSetup)
            S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        break;

    case IT_AMMO_SHELL_BOX:
        if(!P_GiveAmmo(plr, AT_SHELL, 5))
            return false;

        P_SetMessage(plr, 0, GOTSHELLBOX);
        if(!mapSetup)
            S_ConsoleSound(SFX_ITEMUP, NULL, plr - players);
        break;

    case IT_WEAPON_BFG:
        return pickupWeapon(plr, WT_SEVENTH, dropped, GOTBFG9000);

    case IT_WEAPON_CHAINGUN:
        return pickupWeapon(plr, WT_FOURTH, dropped, GOTCHAINGUN);

    case IT_WEAPON_CHAINSAW:
        return pickupWeapon(plr, WT_EIGHTH, dropped, GOTCHAINSAW);

    case IT_WEAPON_RLAUNCHER:
        return pickupWeapon(plr, WT_FIFTH, dropped, GOTLAUNCHER);

    case IT_WEAPON_PLASMARIFLE:
        return pickupWeapon(plr, WT_SIXTH, dropped, GOTPLASMA);

    case IT_WEAPON_SHOTGUN:
        return pickupWeapon(plr, WT_THIRD, dropped, GOTSHOTGUN);

    case IT_WEAPON_SSHOTGUN:
        return pickupWeapon(plr, WT_NINETH, dropped, GOTSHOTGUN2);

    default:
        Con_Error("pickupItem: Unknown item %i.", (int) item);
    }

    return true;
}
Exemplo n.º 3
0
void cht_Give (player_t *player, const char *name)
{
	BOOL giveall;
	int i;
	gitem_t *it;

	if (player != &consoleplayer())
		Printf (PRINT_HIGH, "%s is a cheater: give %s\n", player->userinfo.netname, name);

	if (stricmp (name, "all") == 0)
		giveall = true;
	else
		giveall = false;

	if (giveall || strnicmp (name, "health", 6) == 0) {
		int h;

		if (0 < (h = atoi (name + 6))) {
			if (player->mo) {
				player->mo->health += h;
	  			player->health = player->mo->health;
			} else {
				player->health += h;
			}
		} else {
			if (player->mo)
				player->mo->health = deh.GodHealth;
	  
			player->health = deh.GodHealth;
		}

		if (!giveall)
			return;
	}

	if (giveall || stricmp (name, "backpack") == 0) {
		if (!player->backpack) {
			for (i=0 ; i<NUMAMMO ; i++)
			player->maxammo[i] *= 2;
			player->backpack = true;
		}
		for (i=0 ; i<NUMAMMO ; i++)
			P_GiveAmmo (player, (ammotype_t)i, 1);

		if (!giveall)
			return;
	}

	if (giveall || stricmp (name, "weapons") == 0) {
		weapontype_t pendweap = player->pendingweapon;
		for (i = 0; i<NUMWEAPONS; i++)
			P_GiveWeapon (player, (weapontype_t)i, false);
		player->pendingweapon = pendweap;

		if (!giveall)
			return;
	}

	if (giveall || stricmp (name, "ammo") == 0) {
		for (i=0;i<NUMAMMO;i++)
			player->ammo[i] = player->maxammo[i];

		if (!giveall)
			return;
	}

	if (giveall || stricmp (name, "armor") == 0) {
		player->armorpoints = 200;
		player->armortype = 2;

		if (!giveall)
			return;
	}

	if (giveall || stricmp (name, "keys") == 0) {
		for (i=0;i<NUMCARDS;i++)
			player->cards[i] = true;

		if (!giveall)
			return;
	}

	if (giveall)
		return;

	it = FindItem (name);
	if (!it) {
		it = FindItemByClassname (name);
		if (!it) {
			if (player == &consoleplayer())
				Printf (PRINT_HIGH, "Unknown item\n");
			return;
		}
	}

	if (it->flags & IT_AMMO) {
		int howmuch;

	/*	if (argc == 3)
			howmuch = atoi (argv[2]);
		else */
			howmuch = it->quantity;

		P_GiveAmmo (player, (ammotype_t)it->offset, howmuch);
	} else if (it->flags & IT_WEAPON) {
		P_GiveWeapon (player, (weapontype_t)it->offset, 0);
	} else if (it->flags & IT_KEY) {
		P_GiveCard (player, (card_t)it->offset);
	} else if (it->flags & IT_POWERUP) {
		P_GivePower (player, it->offset);
	} else if (it->flags & IT_ARMOR) {
		P_GiveArmor (player, it->offset);
	}
}
Exemplo n.º 4
0
//
// P_TouchSpecialThing
//
void P_TouchSpecialThing(mobj_t* special, mobj_t* toucher) {
    player_t*   player;
    fixed_t     delta;
    int         sound;
    int            i = 0;

    delta = special->z - toucher->z;

    if(delta > toucher->height
            || delta < -8*FRACUNIT) {
        // out of reach
        return;
    }


    sound = sfx_itemup;
    player = toucher->player;

    // Dead thing touching.
    // Can happen with a sliding player corpse.
    if(toucher->health <= 0) {
        return;
    }

    // Identify by sprite.
    switch(special->sprite) {
    // armor
    case SPR_ARM1:
        if(!P_GiveArmor(player, 1)) {
            return;
        }
        player->message = GOTARMOR;
        player->messagepic = 23;
        break;

    case SPR_ARM2:
        if(!P_GiveArmor(player, 2)) {
            return;
        }
        player->message = GOTMEGA;
        player->messagepic = 24;
        break;

    // bonus items
    case SPR_BON1:
        player->health+=2;               // can go over 100%
        if(player->health > 200) {
            player->health = 200;
        }
        player->mo->health = player->health;
        player->message = GOTHTHBONUS;
        player->messagepic = 3;
        break;

    case SPR_BON2:
        player->armorpoints+=2;          // can go over 100%
        if(player->armorpoints > 200) {
            player->armorpoints = 200;
        }
        if(!player->armortype) {
            player->armortype = 1;
        }
        player->message = GOTARMBONUS;
        player->messagepic = 4;
        break;

    case SPR_SOUL:
        player->health += 100;
        if(player->health > 200) {
            player->health = 200;
        }
        player->mo->health = player->health;
        player->message = GOTSUPER;
        player->messagepic = 5;
        sound = sfx_powerup;
        break;

    case SPR_MEGA:
        player->health = 200;
        player->mo->health = player->health;
        P_GiveArmor(player,2);
        player->message = GOTMSPHERE;
        player->messagepic = 6;
        sound = sfx_powerup;
        break;

    // cards
    // leave cards for everyone
    case SPR_BKEY:
        if(!(P_GiveCard(player, special, it_bluecard))) {
            return;
        }
        break;

    case SPR_YKEY:
        if(!(P_GiveCard(player, special, it_yellowcard))) {
            return;
        }
        break;

    case SPR_RKEY:
        if(!(P_GiveCard(player, special, it_redcard))) {
            return;
        }
        break;

    case SPR_BSKU:
        if(!(P_GiveCard(player, special, it_blueskull))) {
            return;
        }
        break;

    case SPR_YSKU:
        if(!(P_GiveCard(player, special, it_yellowskull))) {
            return;
        }
        break;

    case SPR_RSKU:
        if(!(P_GiveCard(player, special, it_redskull))) {
            return;
        }
        break;

    // medikits, heals
    case SPR_STIM:
        if(!P_GiveBody(player, 10)) {
            return;
        }
        player->message = GOTSTIM;
        player->messagepic = 31;
        break;

    case SPR_MEDI:
        if(!P_GiveBody(player, 25)) {
            return;
        }

        if(player->health < 25) {
            player->message = GOTMEDINEED;
            player->messagepic = 32;
        }
        else {
            player->message = GOTMEDIKIT;
            player->messagepic = 33;
        }
        break;


    // power ups
    case SPR_PINV:
        if(!P_GivePower(player, pw_invulnerability)) {
            return;
        }
        player->message = GOTINVUL;
        player->messagepic = 34;
        sound = sfx_powerup;
        break;

    case SPR_PSTR:
        if(!P_GivePower(player, pw_strength)) {
            return;
        }
        player->message = GOTBERSERK;
        player->messagepic = 35;
        if(player->readyweapon != wp_fist) {
            player->pendingweapon = wp_fist;
        }
        sound = sfx_powerup;
        break;

    case SPR_PINS:
        if(!P_GivePower(player, pw_invisibility)) {
            return;
        }
        player->message = GOTINVIS;
        player->messagepic = 36;
        sound = sfx_powerup;
        break;

    case SPR_SUIT:
        if(!P_GivePower(player, pw_ironfeet)) {
            return;
        }
        player->message = GOTSUIT;
        player->messagepic = 37;
        sound = sfx_powerup;
        break;

    case SPR_PMAP:
        if(!P_GivePower(player, pw_allmap)) {
            return;
        }
        player->message = GOTMAP;
        player->messagepic = 38;
        sound = sfx_powerup;
        break;

    case SPR_PVIS:
        if(!P_GivePower(player, pw_infrared)) {
            return;
        }
        player->message = GOTVISOR;
        player->messagepic = 39;
        sound = sfx_powerup;
        break;

    // ammo
    case SPR_CLIP:
        if(special->flags & MF_DROPPED) {
            if(!P_GiveAmmo(player,am_clip,0)) {
                return;
            }
        }
        else {
            if(!P_GiveAmmo(player,am_clip,1)) {
                return;
            }
        }
        player->message = GOTCLIP;
        player->messagepic = 7;
        break;

    case SPR_AMMO:
        if(!P_GiveAmmo(player, am_clip,5)) {
            return;
        }
        player->message = GOTCLIPBOX;
        player->messagepic = 8;
        break;

    case SPR_RCKT:
        if(!P_GiveAmmo(player, am_misl,1)) {
            return;
        }
        player->message = GOTROCKET;
        player->messagepic = 9;
        break;

    case SPR_BROK:
        if(!P_GiveAmmo(player, am_misl,5)) {
            return;
        }
        player->message = GOTROCKBOX;
        player->messagepic = 10;
        break;

    case SPR_CELL:
        if(!P_GiveAmmo(player, am_cell,1)) {
            return;
        }
        player->message = GOTCELL;
        player->messagepic = 11;
        break;

    case SPR_CELP:
        if(!P_GiveAmmo(player, am_cell,5)) {
            return;
        }
        player->message = GOTCELLBOX;
        player->messagepic = 12;
        break;

    case SPR_SHEL:
        if(!P_GiveAmmo(player, am_shell,1)) {
            return;
        }
        player->message = (gameskill == sk_baby)?GOTSHELLS2:GOTSHELLS;    //villsa
        player->messagepic = 13;
        break;

    case SPR_SBOX:
        if(!P_GiveAmmo(player, am_shell,5)) {
            return;
        }
        player->message = GOTSHELLBOX;
        player->messagepic = 14;
        break;

    case SPR_BPAK:
        if(!player->backpack) {
            for(i = 0; i < NUMAMMO; i++) {
                player->maxammo[i] *= 2;
            }

            player->backpack = true;
        }
        for(i = 0; i < NUMAMMO; i++) {
            P_GiveAmmo(player, i, 1);
        }

        player->message = GOTBACKPACK;
        player->messagepic = 15;
        break;

    // weapons
    case SPR_BFUG:
        if(!P_GiveWeapon(player, special, wp_bfg, false)) {
            return;
        }
        player->message = GOTBFG9000;
        player->messagepic = 16;
        sound = sfx_sgcock;
        break;

    case SPR_MGUN:
        if(!P_GiveWeapon(player, special, wp_chaingun, special->flags&MF_DROPPED)) {
            return;
        }
        player->message = GOTCHAINGUN;
        player->messagepic = 17;
        sound = sfx_sgcock;
        break;

    case SPR_CSAW:
        if(!P_GiveWeapon(player, special, wp_chainsaw, false)) {
            return;
        }
        player->message = GOTCHAINSAW;
        player->messagepic = 18;
        sound = sfx_sgcock;
        break;

    case SPR_LAUN:
        if(!P_GiveWeapon(player, special, wp_missile, false)) {
            return;
        }
        player->message = GOTLAUNCHER;
        player->messagepic = 19;
        sound = sfx_sgcock;
        break;

    case SPR_PLSM:
        if(!P_GiveWeapon(player, special, wp_plasma, false)) {
            return;
        }
        player->message = GOTPLASMA;
        player->messagepic = 20;
        sound = sfx_sgcock;
        break;

    case SPR_SHOT:
        if(!P_GiveWeapon(player, special, wp_shotgun, special->flags&MF_DROPPED)) {
            return;
        }
        player->message = GOTSHOTGUN;
        player->messagepic = 21;
        sound = sfx_sgcock;
        break;

    case SPR_SGN2:
        if(!P_GiveWeapon(player, special, wp_supershotgun, special->flags&MF_DROPPED)) {
            return;
        }
        player->message = GOTSHOTGUN2;
        player->messagepic = 22;
        sound = sfx_sgcock;
        break;

    case SPR_LSRG:
        if(!P_GiveWeapon(player, special, wp_laser, false)) {
            return;
        }
        player->message = GOTLASER;
        sound = sfx_sgcock;
        break;

    case SPR_ART1:
        if(netgame && player->artifacts & (1<<ART_FAST)) {
            return;
        }

        player->artifacts |= (1<<ART_FAST);
        player->message = GOTARTIFACT1;
        player->messagepic = 41;
        break;

    case SPR_ART2:
        if(netgame && player->artifacts & (1<<ART_DOUBLE)) {
            return;
        }

        player->artifacts |= (1<<ART_DOUBLE);
        player->message = GOTARTIFACT2;
        player->messagepic = 42;
        break;

    case SPR_ART3:
        if(netgame && player->artifacts & (1<<ART_TRIPLE)) {
            return;
        }

        player->artifacts |= (1<<ART_TRIPLE);
        player->message = GOTARTIFACT3;
        player->messagepic = 43;
        break;

    default:
        if(special->type != MT_FAKEITEM) {
            CON_Printf(YELLOW, "P_SpecialThing: Unknown gettable thing: %s\n", sprnames[special->sprite]);
            special->flags &= ~MF_SPECIAL;
            return;
        }
        break;
    }

    if(special->flags & MF_TRIGTOUCH || special->type == MT_FAKEITEM) {
        if(special->tid) {
            P_QueueSpecial(special);
        }
    }

    if(special->type != MT_FAKEITEM) {
        if(special->flags & MF_COUNTITEM) {
            player->itemcount++;
        }

        if(special->flags & MF_COUNTSECRET) {
            player->secretcount++;
        }

        P_RemoveMobj(special);
        player->bonuscount += BONUSADD;

        if(player == &players[consoleplayer]) {
            S_StartSound(NULL, sound);
        }
    }
}