header general

Making items spawn based on character class

  • Ultimate Freedoomer
  • Ultimate Freedoomer's Avatar Topic Author
  • Wraith
  • Wraith
More
7 years 9 months ago #1 by Ultimate Freedoomer
Making items spawn based on character class was created by Ultimate Freedoomer
Hi. I am working on a Brutal Doom v20b meta-mod (I'll post the attachment to the thread when I get the chance. It's currently almost 10:00 in my time zone). Everything is done except for 1 thing: the player class item-spawning script. Basically, I need help with creating a script (or set thereof) that will make appropriate weapons & ammo for your player-class spawn based on what class you're playing as (kind of like what the equipment spawner does in Hexen: Beyond Heretic).

Please Log in or Create an account to join the conversation.

  • BadMojo
  • BadMojo's Avatar
  • Wicked
  • Wicked
More
7 years 9 months ago #2 by BadMojo
Replied by BadMojo on topic Making items spawn based on character class
This probably isn't the best place to ask this, try zdoom forums.

But that been said, Ill help if I can. There are a few ways you could do this I'm sure, but as far as simplicity goes, you could try to create a custom inventory actor http://zdoom.org/wiki/Classes:CustomInventory and use that as the weapon/ammo spawn

Then at the pickup state you could use A_JumpIfInventory http://zdoom.org/wiki/A_JumpIfInventory to check weather the player has say, its own starting weapon (assuming your player classes have their own unique starting weapons) OR a dummy actor in its inventory at spawn. After each jump function you would jump to a custom state then use A_GiveInventory http://zdoom.org/wiki/A_GiveInventory to give the player the desired weapon.

example:
Code:
actor weaponclassa : CustomInventory 10492 { ... Pickup: TNT1 A 0 A_JumpIfInventory("startingweaponclass1", 1, "classa") //if the player has startingweapon1, jump to classa state TNT1 A 0 A_JumpIfInventory("startingweaponclass2", 1, "classb") // etc.. TNT1 A 0 A_JumpIfInventory("startingweaponclass3", 1, "classc") // etc.. stop // if none of the above, pickup fail fail classa: TNT1 A 0 A_GiveInventory("newweapon1",1) //give player new weapon stop classb: TNT1 A 0 A_GiveInventory("newweapon2",1) //etc.. stop classc: TNT1 A 0 A_GiveInventory("newweapon3",1) //etc.. stop } }

As far as individual pickup sprites go, I dont know... anything more complicated than basic scripts is beyond my knowledge at the present time. Like I said, your probably better off asking at the zdoom forums, but I hope this helps somewhat. :)

Please Log in or Create an account to join the conversation.

  • MagicWazard
  • MagicWazard's Avatar
  • Moderator
  • Moderator
More
7 years 9 months ago - 7 years 9 months ago #3 by MagicWazard
Replied by MagicWazard on topic Making items spawn based on character class
Actually, this is a problem I was dealing with just a few months ago!

Hexen's weapons are dropped into maps as normal, and don't contain any special code to determine which class they appear for. This is because each class has a "Player.SpawnClass" property; "Fighter" is 1, "Cleric" is 2, and "Mage" is 3. Then, in your map editor, you pick which class the weapon should appear for. If you're building a Doom map in Hexen format, you can assign your custom player classes one of these 3 numbers; then, in your map editor, pick whichever Hexen class's number corresponds with your custom class. In UDMF format maps, you can explicitly pick "Class 1" through "Class 8".

Now, this method works well for Hexen, because there's only 3 weapons per class, weapons are scarcely found, and enemies don't drop weapons. For a Doom map, this method can get very difficult to manage, due to all the actors you'll have to hand-configure to spawn for each class--not to mention that you'll need to create custom versions of every monster that drops a weapon, so you can have the right "version" of the monster for whichever custom class is in use. Luckily, ACS provides an easier solution.

Note that for this ACS-based method, you don't have to assign a "Player.SpawnClass" value to your custom classes. You just need to make sure they're defined in your MAPINFO lump, in the "gameinfo" section:
Code:
gameinfo { PlayerClasses = "CustomClass1", "CustomClass2", "CustomClass3" }

("CustomClass#" can be replaced by whatever name you want to use for your custom class, as defined by that class's Actor Name.)

For example, let's say you want to have an item you can place into the map that spawns a Shotgun type appropriate to the custom class. Here's an example of how I have mine set up:
Code:
Actor ShotgunSpawner : Weapon 12101 { //$Category Weapons States { Spawn: TNT1 A 0 NoDelay ACS_NamedExecuteWithResult("ShotgunSpawn") stop } }

This item doesn't define which shotguns are potentially dropped. Instead, it calls an ACS script which does that task; the script is written as so:
Code:
script "ShotgunSpawn" (void) { Switch(PlayerClass(0)) { case 0: SpawnForced("Shotgun", GetActorX(0), GetActorY(0), GetActorZ(0) ); break; case 1: SpawnForced("DukeShotgun", GetActorX(0), GetActorY(0), GetActorZ(0) ); break; case 2: SpawnForced("Yellowboy", GetActorX(0), GetActorY(0), GetActorZ(0) ); break; default: DropItem(0, "SuperArmorBonus"); break; } }

By using this script in conjunction with the "generic" Shotgun drop, you can have an item which you simply place into the map; then, at game-time, it reads the current player class, and spawns the correct item based off the character that's being used. It'll spawn "Shotgun" for Class 1 (a.k.a. "Fighter"), "DukeShotgun" for Class 2 ("Cleric"), or "Yellowboy" for Class 3 ("Mage"). In the event of an error (such as an undefined player class), it'll spawn a "SuperArmorBonus" instead.

As for monster drops? They're supposed to contain less ammo than pickups, but the game won't know this if a monster drops one of the spawners produced above--it'll drop with full ammo. Maybe you want to avoid that, like I did. So, I made a "drop" variant of the weapon spawner, which looks like this:
Code:
script "ShotgunDrop" (void) { Switch(PlayerClass(0)) { case 0: SetActorPosition(0, GetActorX(0), GetActorY(0), (GetActorZ(0) - 12.0), 0); DropItem(0, "Shotgun"); break; case 1: SetActorPosition(0, GetActorX(0), GetActorY(0), (GetActorZ(0) - 12.0), 0); DropItem(0, "DukeShotgun"); break; case 2: SetActorPosition(0, GetActorX(0), GetActorY(0), (GetActorZ(0) - 12.0), 0); DropItem(0, "Yellowboy"); break; default: SetActorPosition(0, GetActorX(0), GetActorY(0), (GetActorZ(0) - 12.0), 0); DropItem(0, "SuperArmorBonus"); break; } }

The "SetActorPosition" parameters are supposed to approximate what it would look like if the monster dropped a regular item with the settings configured to have monsters "toss" their drops instead of spawn them on the floor. It's not 100% perfect, since the monster "toss" is randomized, but it's pretty damn close. And since we're using "DropItem" instead of "SpawnForced", the weapons will be dropped with 1/2 ammo.

Then, you set up your monster to drop the "dropper" variant, like so:
Code:
actor ModifiedShotgunGuy : ShotgunGuy replaces ShotgunGuy { Decal "BulletChip" DropItem "ShotgunDropper" }

When you kill him, the item he drops runs the ACS script that determines what item gets dropped; and, the drop command in ACS will produce the weapon with 1/2 ammo, like a normal drop.

Note that this assumes you're playing single-player mode--it won't work in multiplayer. I don't have a solution worked out for multiplayer yet, but that's because my campaign is single-player only. If you're planning single-player only, then you can follow this general format to get something functional. If you plan on supporting multiplayer, this framework won't work right as-is, and more logic will be required. We can talk about that once we've determined if your mod is designed for multiplayer or not. :) But, the method will rely on something very similar to what BadMojo suggested, along with additional logic.


Oh, and a lot of the credit for this scripting goes to BlueShadow for helping me with syntax and troubleshooting.
Last edit: 7 years 9 months ago by MagicWazard.

Please Log in or Create an account to join the conversation.

  • Ultimate Freedoomer
  • Ultimate Freedoomer's Avatar Topic Author
  • Wraith
  • Wraith
More
7 years 9 months ago #4 by Ultimate Freedoomer
Replied by Ultimate Freedoomer on topic Making items spawn based on character class

MagicWazard wrote: Actually, this is a problem I was dealing with just a few months ago!

Hexen's weapons are dropped into maps as normal, and don't contain any special code to determine which class they appear for. This is because each class has a "Player.SpawnClass" property; "Fighter" is 1, "Cleric" is 2, and "Mage" is 3. Then, in your map editor, you pick which class the weapon should appear for. If you're building a Doom map in Hexen format, you can assign your custom player classes one of these 3 numbers; then, in your map editor, pick whichever Hexen class's number corresponds with your custom class. In UDMF format maps, you can explicitly pick "Class 1" through "Class 8".

Now, this method works well for Hexen, because there's only 3 weapons per class, weapons are scarcely found, and enemies don't drop weapons. For a Doom map, this method can get very difficult to manage, due to all the actors you'll have to hand-configure to spawn for each class--not to mention that you'll need to create custom versions of every monster that drops a weapon, so you can have the right "version" of the monster for whichever custom class is in use. Luckily, ACS provides an easier solution.

Note that for this ACS-based method, you don't have to assign a "Player.SpawnClass" value to your custom classes. You just need to make sure they're defined in your MAPINFO lump, in the "gameinfo" section:

Code:
gameinfo { PlayerClasses = "CustomClass1", "CustomClass2", "CustomClass3" }

("CustomClass#" can be replaced by whatever name you want to use for your custom class, as defined by that class's Actor Name.)

For example, let's say you want to have an item you can place into the map that spawns a Shotgun type appropriate to the custom class. Here's an example of how I have mine set up:
Code:
Actor ShotgunSpawner : Weapon 12101 { //$Category Weapons States { Spawn: TNT1 A 0 NoDelay ACS_NamedExecuteWithResult("ShotgunSpawn") stop } }

This item doesn't define which shotguns are potentially dropped. Instead, it calls an ACS script which does that task; the script is written as so:
Code:
script "ShotgunSpawn" (void) { Switch(PlayerClass(0)) { case 0: SpawnForced("Shotgun", GetActorX(0), GetActorY(0), GetActorZ(0) ); break; case 1: SpawnForced("DukeShotgun", GetActorX(0), GetActorY(0), GetActorZ(0) ); break; case 2: SpawnForced("Yellowboy", GetActorX(0), GetActorY(0), GetActorZ(0) ); break; default: DropItem(0, "SuperArmorBonus"); break; } }

By using this script in conjunction with the "generic" Shotgun drop, you can have an item which you simply place into the map; then, at game-time, it reads the current player class, and spawns the correct item based off the character that's being used. It'll spawn "Shotgun" for Class 1 (a.k.a. "Fighter"), "DukeShotgun" for Class 2 ("Cleric"), or "Yellowboy" for Class 3 ("Mage"). In the event of an error (such as an undefined player class), it'll spawn a "SuperArmorBonus" instead.

As for monster drops? They're supposed to contain less ammo than pickups, but the game won't know this if a monster drops one of the spawners produced above--it'll drop with full ammo. Maybe you want to avoid that, like I did. So, I made a "drop" variant of the weapon spawner, which looks like this:
Code:
script "ShotgunDrop" (void) { Switch(PlayerClass(0)) { case 0: SetActorPosition(0, GetActorX(0), GetActorY(0), (GetActorZ(0) - 12.0), 0); DropItem(0, "Shotgun"); break; case 1: SetActorPosition(0, GetActorX(0), GetActorY(0), (GetActorZ(0) - 12.0), 0); DropItem(0, "DukeShotgun"); break; case 2: SetActorPosition(0, GetActorX(0), GetActorY(0), (GetActorZ(0) - 12.0), 0); DropItem(0, "Yellowboy"); break; default: SetActorPosition(0, GetActorX(0), GetActorY(0), (GetActorZ(0) - 12.0), 0); DropItem(0, "SuperArmorBonus"); break; } }

The "SetActorPosition" parameters are supposed to approximate what it would look like if the monster dropped a regular item with the settings configured to have monsters "toss" their drops instead of spawn them on the floor. It's not 100% perfect, since the monster "toss" is randomized, but it's pretty damn close. And since we're using "DropItem" instead of "SpawnForced", the weapons will be dropped with 1/2 ammo.

Then, you set up your monster to drop the "dropper" variant, like so:
Code:
actor ModifiedShotgunGuy : ShotgunGuy replaces ShotgunGuy { Decal "BulletChip" DropItem "ShotgunDropper" }

When you kill him, the item he drops runs the ACS script that determines what item gets dropped; and, the drop command in ACS will produce the weapon with 1/2 ammo, like a normal drop.

Note that this assumes you're playing single-player mode--it won't work in multiplayer. I don't have a solution worked out for multiplayer yet, but that's because my campaign is single-player only. If you're planning single-player only, then you can follow this general format to get something functional. If you plan on supporting multiplayer, this framework won't work right as-is, and more logic will be required. We can talk about that once we've determined if your mod is designed for multiplayer or not. :) But, the method will rely on something very similar to what BadMojo suggested, along with additional logic.


Oh, and a lot of the credit for this scripting goes to BlueShadow for helping me with syntax and troubleshooting.

Will this work on pre-existing actors in a map? For instance, will this script work if the map includes the shotgun spawn, but the class script is part of the gameplay mod itself & NOT a map?

Please Log in or Create an account to join the conversation.

  • Ultimate Freedoomer
  • Ultimate Freedoomer's Avatar Topic Author
  • Wraith
  • Wraith
More
7 years 9 months ago #5 by Ultimate Freedoomer
Replied by Ultimate Freedoomer on topic Making items spawn based on character class
I got it to work. There's just 1 teensy little problem: while the map spawns get replaced, a pile of equipment also spawns at the singleplayer player start area when the player enters the map.

Please Log in or Create an account to join the conversation.

  • MagicWazard
  • MagicWazard's Avatar
  • Moderator
  • Moderator
More
7 years 9 months ago #6 by MagicWazard
Replied by MagicWazard on topic Making items spawn based on character class

Ultimate Freedoomer wrote: I got it to work. There's just 1 teensy little problem: while the map spawns get replaced, a pile of equipment also spawns at the singleplayer player start area when the player enters the map.


Offhand, I'm not sure why that would happen. The only think I could think of is that perhaps you're placing weapon/item spawners in the player's starting inventory, instead of directly giving the player the weapon/items he/she should have. Even then, I wouldn't imagine that would happen--but I've never tried it, so I can't say for sure.

In any event, you can provide a small example if you want one of us to take a look at it. Just enough to illustrate the problem--you don't need to provide or link to the whole mod.

Please Log in or Create an account to join the conversation.

  • BadMojo
  • BadMojo's Avatar
  • Wicked
  • Wicked
More
7 years 9 months ago #7 by BadMojo
Replied by BadMojo on topic Making items spawn based on character class
If you tried my method, it may or may not be the doomed number conflicting with something ... But yea I don't see anything in mw's solution that could have done that either if you haven't already fixed it

Please Log in or Create an account to join the conversation.

  • MagicWazard
  • MagicWazard's Avatar
  • Moderator
  • Moderator
More
7 years 9 months ago #8 by MagicWazard
Replied by MagicWazard on topic Making items spawn based on character class
Oh, and it's worth pointing out that if you're modding on top of another mod, God only knows what may be conflicting and causing unexpected behavior. Especially since Brutal Doom is known for not being particularly well-coded, so making a mod for that could be a bit of a challenge. Probably the best thing to do--if you haven't already--would be to create your mod around standard, unmodded Doom first, to ensure there's no issues with your logic. Then, after that, you can start modifying it around Brutal Doom.

Please Log in or Create an account to join the conversation.

  • Ultimate Freedoomer
  • Ultimate Freedoomer's Avatar Topic Author
  • Wraith
  • Wraith
More
7 years 9 months ago #9 by Ultimate Freedoomer
Replied by Ultimate Freedoomer on topic Making items spawn based on character class
Here's the spawn scripts with new actors they rely on. Also, Brutal Doom's code quality has improved A LOT in recent versions.

File Attachment:

File Name: Spawners.zip
File Size:48 KB
Attachments:

Please Log in or Create an account to join the conversation.

  • MagicWazard
  • MagicWazard's Avatar
  • Moderator
  • Moderator
More
7 years 9 months ago #10 by MagicWazard
Replied by MagicWazard on topic Making items spawn based on character class
I think I see the problem: the scripts all have a special script type of "Enter", meaning they run as soon as the map starts, and not just when called. They should have the closed type of "(void)", instead, like so:

script "PistolSpawn" (void)

Try changing all the "Enter" to "(void)" and see if that resolves it.

Please Log in or Create an account to join the conversation.