Beispiel #1
0
void cht_Give (player_t *player, const char *name, int amount)
{
    enum { ALL_NO, ALL_YES, ALL_YESYES } giveall;
    int i;
    PClassActor *type;

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

    if (player->mo == NULL || player->health <= 0)
    {
        return;
    }

    giveall = ALL_NO;
    if (stricmp (name, "all") == 0)
    {
        giveall = ALL_YES;
    }
    else if (stricmp (name, "everything") == 0)
    {
        giveall = ALL_YESYES;
    }

    if (stricmp (name, "health") == 0)
    {
        if (amount > 0)
        {
            player->mo->health += amount;
            player->health = player->mo->health;
        }
        else
        {
            player->health = player->mo->health = player->mo->GetMaxHealth();
        }
    }

    if (giveall || stricmp (name, "backpack") == 0)
    {
        // Select the correct type of backpack based on the game
        type = PClass::FindActor(gameinfo.backpacktype);
        if (type != NULL)
        {
            player->mo->GiveInventory(static_cast<PClassInventory *>(type), 1, true);
        }

        if (!giveall)
            return;
    }

    if (giveall || stricmp (name, "ammo") == 0)
    {
        // Find every unique type of ammo. Give it to the player if
        // he doesn't have it already, and set each to its maximum.
        for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
        {
            PClassActor *type = PClassActor::AllActorClasses[i];

            if (type->ParentClass == RUNTIME_CLASS(AAmmo))
            {
                PClassAmmo *atype = static_cast<PClassAmmo *>(type);
                AInventory *ammo = player->mo->FindInventory(atype);
                if (ammo == NULL)
                {
                    ammo = static_cast<AInventory *>(Spawn (atype));
                    ammo->AttachToOwner (player->mo);
                    ammo->Amount = ammo->MaxAmount;
                }
                else if (ammo->Amount < ammo->MaxAmount)
                {
                    ammo->Amount = ammo->MaxAmount;
                }
            }
        }

        if (!giveall)
            return;
    }

    if (giveall || stricmp (name, "armor") == 0)
    {
        if (gameinfo.gametype != GAME_Hexen)
        {
            ABasicArmorPickup *armor = Spawn<ABasicArmorPickup> ();
            armor->SaveAmount = 100*deh.BlueAC;
            armor->SavePercent = gameinfo.Armor2Percent > 0? gameinfo.Armor2Percent : 0.5;
            if (!armor->CallTryPickup (player->mo))
            {
                armor->Destroy ();
            }
        }
        else
        {
            for (i = 0; i < 4; ++i)
            {
                AHexenArmor *armor = Spawn<AHexenArmor> ();
                armor->health = i;
                armor->Amount = 0;
                if (!armor->CallTryPickup (player->mo))
                {
                    armor->Destroy ();
                }
            }
        }

        if (!giveall)
            return;
    }

    if (giveall || stricmp (name, "keys") == 0)
    {
        for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
        {
            if (PClassActor::AllActorClasses[i]->IsDescendantOf (RUNTIME_CLASS(AKey)))
            {
                AKey *key = (AKey *)GetDefaultByType (PClassActor::AllActorClasses[i]);
                if (key->KeyNumber != 0)
                {
                    key = static_cast<AKey *>(Spawn(static_cast<PClassActor *>(PClassActor::AllActorClasses[i])));
                    if (!key->CallTryPickup (player->mo))
                    {
                        key->Destroy ();
                    }
                }
            }
        }
        if (!giveall)
            return;
    }

    if (giveall || stricmp (name, "weapons") == 0)
    {
        AWeapon *savedpending = player->PendingWeapon;
        for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
        {
            type = PClassActor::AllActorClasses[i];
            // Don't give replaced weapons unless the replacement was done by Dehacked.
            if (type != RUNTIME_CLASS(AWeapon) &&
                    type->IsDescendantOf (RUNTIME_CLASS(AWeapon)) &&
                    (static_cast<PClassActor *>(type)->GetReplacement() == type ||
                     static_cast<PClassActor *>(type)->GetReplacement()->IsDescendantOf(RUNTIME_CLASS(ADehackedPickup))))
            {
                // Give the weapon only if it belongs to the current game or
                if (player->weapons.LocateWeapon(static_cast<PClassWeapon*>(type), NULL, NULL))
                {
                    AWeapon *def = (AWeapon*)GetDefaultByType (type);
                    if (giveall == ALL_YESYES || !(def->WeaponFlags & WIF_CHEATNOTWEAPON))
                    {
                        player->mo->GiveInventory(static_cast<PClassInventory *>(type), 1, true);
                    }
                }
            }
        }
        player->PendingWeapon = savedpending;

        if (!giveall)
            return;
    }

    if (giveall || stricmp (name, "artifacts") == 0)
    {
        for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
        {
            type = PClassActor::AllActorClasses[i];
            if (type->IsDescendantOf (RUNTIME_CLASS(AInventory)))
            {
                AInventory *def = (AInventory*)GetDefaultByType (type);
                if (def->Icon.isValid() && def->MaxAmount > 1 &&
                        !type->IsDescendantOf (RUNTIME_CLASS(APuzzleItem)) &&
                        !type->IsDescendantOf (RUNTIME_CLASS(APowerup)) &&
                        !type->IsDescendantOf (RUNTIME_CLASS(AArmor)))
                {
                    // Do not give replaced items unless using "give everything"
                    if (giveall == ALL_YESYES || type->GetReplacement() == type)
                    {
                        player->mo->GiveInventory(static_cast<PClassInventory *>(type), amount <= 0 ? def->MaxAmount : amount, true);
                    }
                }
            }
        }
        if (!giveall)
            return;
    }

    if (giveall || stricmp (name, "puzzlepieces") == 0)
    {
        for (unsigned int i = 0; i < PClassActor::AllActorClasses.Size(); ++i)
        {
            type = PClassActor::AllActorClasses[i];
            if (type->IsDescendantOf (RUNTIME_CLASS(APuzzleItem)))
            {
                AInventory *def = (AInventory*)GetDefaultByType (type);
                if (def->Icon.isValid())
                {
                    // Do not give replaced items unless using "give everything"
                    if (giveall == ALL_YESYES || type->GetReplacement() == type)
                    {
                        player->mo->GiveInventory(static_cast<PClassInventory *>(type), amount <= 0 ? def->MaxAmount : amount, true);
                    }
                }
            }
        }
        if (!giveall)
            return;
    }

    if (giveall)
        return;

    type = PClass::FindActor(name);
    if (type == NULL || !type->IsDescendantOf (RUNTIME_CLASS(AInventory)))
    {
        if (player == &players[consoleplayer])
            Printf ("Unknown item \"%s\"\n", name);
    }
    else
    {
        player->mo->GiveInventory(static_cast<PClassInventory *>(type), amount, true);
    }
    return;
}
Beispiel #2
0
bool AInventory::TryPickup (AActor *&toucher)
{
	AActor *newtoucher = toucher; // in case changed by the powerup

	// If HandlePickup() returns true, it will set the IF_PICKUPGOOD flag
	// to indicate that this item has been picked up. If the item cannot be
	// picked up, then it leaves the flag cleared.

	ItemFlags &= ~IF_PICKUPGOOD;
	if (toucher->Inventory != NULL && toucher->Inventory->HandlePickup (this))
	{
		// Let something else the player is holding intercept the pickup.
		if (!(ItemFlags & IF_PICKUPGOOD))
		{
			return false;
		}
		ItemFlags &= ~IF_PICKUPGOOD;
		GoAwayAndDie ();
	}
	else if (MaxAmount == 0 && !IsKindOf(RUNTIME_CLASS(AAmmo)))
	{
		// Special case: If an item's MaxAmount is 0, you can still pick it
		// up if it is autoactivate-able.
		if (!(ItemFlags & IF_AUTOACTIVATE))
		{
			return false;
		}
		// The item is placed in the inventory just long enough to be used.
		toucher->AddInventory (this);
		bool usegood = Use (true);
		toucher->RemoveInventory (this);

		if (usegood)
		{
			GoAwayAndDie ();
		}
		else
		{
			return false;
		}
	}
	else
	{
		// Add the item to the inventory. It is not already there, or HandlePickup
		// would have already taken care of it.
		AInventory *copy = CreateCopy (toucher);
		if (copy == NULL)
		{
			return false;
		}
		// Some powerups cannot activate absolutely, for
		// example, PowerMorph; fail the pickup if so.
		if (copy->ItemFlags & IF_INITEFFECTFAILED)
		{
			if (copy != this) copy->Destroy();
			else ItemFlags &= ~IF_INITEFFECTFAILED;
			return false;
		}
		// Handle owner-changing powerups
		if (copy->ItemFlags & IF_CREATECOPYMOVED)
		{
			newtoucher = copy->Owner;
			copy->Owner = NULL;
			copy->ItemFlags &= ~IF_CREATECOPYMOVED;
		}
		// Continue onwards with the rest
		copy->AttachToOwner (newtoucher);
		if (ItemFlags & IF_AUTOACTIVATE)
		{
			if (copy->Use (true))
			{
				if (--copy->Amount <= 0)
				{
					copy->flags &= ~MF_SPECIAL;
					copy->SetState (copy->FindState("HoldAndDestroy"));
				}
			}
		}
	}
	return true;
}
Beispiel #3
0
void cht_Give (player_t *player, const char *name, int amount)
{
	enum { ALL_NO, ALL_YES, ALL_YESYES } giveall;
	int i;
	const PClass *type;

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

	if (player->mo == NULL || player->health <= 0)
	{
		return;
	}

	giveall = ALL_NO;
	if (stricmp (name, "all") == 0)
	{
		giveall = ALL_YES;
	}
	else if (stricmp (name, "everything") == 0)
	{
		giveall = ALL_YESYES;
	}

	if (stricmp (name, "health") == 0)
	{
		if (amount > 0)
		{
			if (player->mo)
			{
				player->mo->health += amount;
	  			player->health = player->mo->health;
			}
			else
			{
				player->health += amount;
			}
		}
		else
		{
			if (player->mo != NULL)
			{
				player->health = player->mo->health = player->mo->GetMaxHealth();
			}
			else
			{
				player->health = deh.GodHealth;
			}
		}
		// [BB]: The server has to inform the clients that this player's health has changed.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		{
			ULONG playerIdx = static_cast<ULONG> ( player - players );
			SERVERCOMMANDS_SetPlayerHealth( playerIdx );
		}
	}

	if (giveall || stricmp (name, "backpack") == 0)
	{
		// Select the correct type of backpack based on the game
		type = PClass::FindClass(gameinfo.backpacktype);
		if (type != NULL)
		{
			GiveSpawner (player, type, 1);
		}

		if (!giveall)
			return;
	}

	if (giveall || stricmp (name, "ammo") == 0)
	{
		// Find every unique type of ammo. Give it to the player if
		// he doesn't have it already, and set each to its maximum.
		for (unsigned int i = 0; i < PClass::m_Types.Size(); ++i)
		{
			const PClass *type = PClass::m_Types[i];

			if (type->ParentClass == RUNTIME_CLASS(AAmmo))
			{
				AInventory *ammo = player->mo->FindInventory (type);
				if (ammo == NULL)
				{
					ammo = static_cast<AInventory *>(Spawn (type, 0, 0, 0, NO_REPLACE));
					ammo->AttachToOwner (player->mo);
					ammo->Amount = ammo->MaxAmount;
				}
				else if (ammo->Amount < ammo->MaxAmount)
				{
					ammo->Amount = ammo->MaxAmount;
				}
				// [BB] This construction is more or less a hack, but at least the give cheats are now working.
				SERVER_GiveInventoryToPlayer( player, ammo );
			}
		}

		if (!giveall)
			return;
	}

	if (giveall || stricmp (name, "armor") == 0)
	{
		if (gameinfo.gametype != GAME_Hexen)
		{
			ABasicArmorPickup *armor = Spawn<ABasicArmorPickup> (0,0,0, NO_REPLACE);
			armor->SaveAmount = 100*deh.BlueAC;
			armor->SavePercent = gameinfo.Armor2Percent > 0? gameinfo.Armor2Percent : FRACUNIT/2;
			if (!armor->CallTryPickup (player->mo))
			{
				armor->Destroy ();
			}
			else
			{
				// [BB] This construction is more or less a hack, but at least the give cheats are now working.
				SERVER_GiveInventoryToPlayer( player, armor );
			}
		}
		else
		{
			for (i = 0; i < 4; ++i)
			{
				AHexenArmor *armor = Spawn<AHexenArmor> (0,0,0, NO_REPLACE);
				armor->health = i;
				armor->Amount = 0;
				if (!armor->CallTryPickup (player->mo))
				{
					armor->Destroy ();
				}
				else
				{
					// [BB] This construction is more or less a hack, but at least the give cheats are now working.
					if ( NETWORK_GetState( ) == NETSTATE_SERVER )
					{
						SERVER_GiveInventoryToPlayer( player, armor );
						SERVERCOMMANDS_SyncHexenArmorSlots ( static_cast<ULONG> ( player - players ) );
					}
				}
			}
		}

		if (!giveall)
			return;
	}

	if (giveall || stricmp (name, "keys") == 0)
	{
		for (unsigned int i = 0; i < PClass::m_Types.Size(); ++i)
		{
			if (PClass::m_Types[i]->IsDescendantOf (RUNTIME_CLASS(AKey)))
			{
				AKey *key = (AKey *)GetDefaultByType (PClass::m_Types[i]);
				if (key->KeyNumber != 0)
				{
					key = static_cast<AKey *>(Spawn (PClass::m_Types[i], 0,0,0, NO_REPLACE));
					if (!key->CallTryPickup (player->mo))
					{
						key->Destroy ();
					}
					else
					{
						// [BB] This construction is more or less a hack, but at least the give cheats are now working.
						SERVER_GiveInventoryToPlayer( player, key );
					}
				}
			}
		}
		if (!giveall)
			return;
	}

	if (giveall || stricmp (name, "weapons") == 0 || stricmp (name, "stdweapons") == 0)
	{
		// [BB] Don't give the ST weapons if this it true. Useful if you want
		// to start a game in the middle of a Doom coop megawad for example.
		bool stdweapons = (stricmp (name, "stdweapons") == 0);

		AWeapon *savedpending = player->PendingWeapon;
		for (unsigned int i = 0; i < PClass::m_Types.Size(); ++i)
		{
			type = PClass::m_Types[i];
			// Don't give replaced weapons unless the replacement was done by Dehacked.
			if (type != RUNTIME_CLASS(AWeapon) &&
				type->IsDescendantOf (RUNTIME_CLASS(AWeapon)) &&
				(type->ActorInfo->GetReplacement() == type->ActorInfo ||
				 type->ActorInfo->GetReplacement()->Class->IsDescendantOf(RUNTIME_CLASS(ADehackedPickup))))

			{
				// Give the weapon only if it belongs to the current game or
				// is in a weapon slot. 
				if (type->ActorInfo->GameFilter == GAME_Any || 
					(type->ActorInfo->GameFilter & gameinfo.gametype) ||	
					player->weapons.LocateWeapon(type, NULL, NULL))
				{
				if (stdweapons)
				{
					const char *WeaponName = type->TypeName.GetChars();
					if ( !stricmp (WeaponName, "Railgun")
					     || !stricmp (WeaponName, "Minigun")
					     || !stricmp (WeaponName, "GrenadeLauncher")
					     || !stricmp (WeaponName, "Bfg10K") )
						continue;
				}

					AWeapon *def = (AWeapon*)GetDefaultByType (type);
					if (giveall == ALL_YESYES || !(def->WeaponFlags & WIF_CHEATNOTWEAPON))
					{
						GiveSpawner (player, type, 1);
					}
				}
			}
		}
		player->PendingWeapon = savedpending;

		// [BB] If we're the server, also tell the client to restore the original weapon.
		if ( NETWORK_GetState( ) == NETSTATE_SERVER )
		{
			// [BB] We need to make sure that the client has its old weapon up instantly.
			// Since there is no net command for this and I don't want to add another net command
			// just for this cheat, we use a workaround here.
			const bool playerHasInstantWeapSwitch = !!(player->cheats & CF_INSTANTWEAPSWITCH);
			const ULONG ulPlayer = static_cast<ULONG>( player - players );
			if ( playerHasInstantWeapSwitch == false )
			{
				player->cheats |= CF_INSTANTWEAPSWITCH;
				SERVERCOMMANDS_SetPlayerCheats( ulPlayer );
			}
			SERVERCOMMANDS_WeaponChange( ulPlayer );
			if ( playerHasInstantWeapSwitch == false )
			{
				player->cheats &= ~CF_INSTANTWEAPSWITCH;
				SERVERCOMMANDS_SetPlayerCheats( ulPlayer );
			}
		}

		if (!giveall)
			return;
	}

	if (giveall || stricmp (name, "artifacts") == 0)
	{
		for (unsigned int i = 0; i < PClass::m_Types.Size(); ++i)
		{
			type = PClass::m_Types[i];
			if (type->IsDescendantOf (RUNTIME_CLASS(AInventory)))
			{
				AInventory *def = (AInventory*)GetDefaultByType (type);
				if (def->Icon.isValid() && def->MaxAmount > 1 &&
					!type->IsDescendantOf (RUNTIME_CLASS(APuzzleItem)) &&
					!type->IsDescendantOf (RUNTIME_CLASS(APowerup)) &&
					!type->IsDescendantOf (RUNTIME_CLASS(AArmor)))
				{
					GiveSpawner (player, type, amount <= 0 ? def->MaxAmount : amount);
				}
			}
		}
		if (!giveall)
			return;
	}

	if (giveall || stricmp (name, "puzzlepieces") == 0)
	{
		for (unsigned int i = 0; i < PClass::m_Types.Size(); ++i)
		{
			type = PClass::m_Types[i];
			if (type->IsDescendantOf (RUNTIME_CLASS(APuzzleItem)))
			{
				AInventory *def = (AInventory*)GetDefaultByType (type);
				if (def->Icon.isValid())
				{
					GiveSpawner (player, type, amount <= 0 ? def->MaxAmount : amount);
				}
			}
		}
		if (!giveall)
			return;
	}

	if (giveall)
		return;

	type = PClass::FindClass (name);
	if (type == NULL || !type->IsDescendantOf (RUNTIME_CLASS(AInventory)))
	{
		if (player == &players[consoleplayer])
			Printf ("Unknown item \"%s\"\n", name);
	}
	else
	{
		GiveSpawner (player, type, amount);
	}
	return;
}