Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
m0pt0pmatt

Need to count kills for zombie game idea

Recommended Posts

Hi there. I'm working on a new project of mine. I'm takng the first doom map, e1m1, and making a zombie survival arcade version of it, based mainly off of Call of Duty: World at War's zombies.
I need a point system. My idea was to give points every time he or she kills a zombie, but how do I do that? I want to avoid counting the total monster count. That just sounds too ineffective. Now, ZDaemon has a way where it displays how many monsters you killed. If I could figure out what that is, that would solve my problems I think. If anybody knows, that would be awesome

Share this post


Link to post

Here is a sample scriptset which you may insert into your map's SCRIPTS lump, which will do the dirty work of tracking kill points for 4 players (it should, anyway) and some of the miscellaneous Nazi Zombies stuff you'd need. Note that it does not actually draw the score or handle certain aspects of the newer Nazi Zombies maps, such as traps, turning on the power, or upgrading weapons (Der Riese). I left that out for you to plug in your own code.

This is meant to be inserted into an ACS script in either Hexen or UDMF format under ZDoom:

#include "zcommon.acs"

#define DEFAULTPLATSPEED 35  //This is a fairly normal platform lowering speed if I remember correctly. Feel free to experiment with this value.
#define OP_SUBTRACT 0
#define OP_ADD 1
#define CHESTFAILSND "*usefail"  //I recommend changing this
#define MAXWEAPONRANGE 4 //Change this define to a higher value if you have more than 4 weapons in your list
#define TREASURECHESTSPAWNERID 255 //Change this if your Treasure Chest uses a different Thing Tag than 255
#define DEFAULTSCORE 500 //Like the original Nazi Zombies game mode.

str WeaponsList[MAXWEAPONRANGE]={T_PISTOL,T_SHOTGUN,T_CHAINGUN,T_PLASMAGUN}; //These are predefined, but you should be able to assign actual class names here
str playerScore[4]={DEFAULTSCORE,DEFAULTSCORE,DEFAULTSCORE,DEFAULTSCORE}; //The player scores at map start

int RandomWeapon=0; //Initialized here because "static" is not a valid type specifier in ACS... :/

function int G_CalcScore(int base, int multiplier, int op)
{
  if(op==OP_SUBTRACT && (base*multiplier) > playerScore[PlayerNumber()])
    return 0;  //Player does not have enough points, indicate calling script
  else
  {
    switch(op)
    {
      case default:
      print(s:"Invalid op specified in G_CalcScore(base,mul,op).");
      return 0;
      Break;  //Just in case
      case OP_SUBTRACT:
      playerScore[PlayerNumber()] -= base*multiplier;
      return 1;
      Break;
      case OP_ADD:
      playerScore[PlayerNumber()] += base*multiplier;
      return 1;
      Break;
    }
  }

Script 250 (int points, int special) //In case you want to pass a special parameter to the Treasure Chest for whatever reason
{
  if(G_CalcScore(points,1,OP_SUBTRACT)) //This will evaluate to a "true" and will still attempt to subtract points if possible
  {
    RandomWeapon=random(0,MAXWEAPONRANGE); //This value is static between calls to the Treasure Chest script if you want to use this value for anything. Make sure you do anything involving this variable BEFORE it is re-initialized!
    SpawnSpot(WeaponsList[RandomWeapon],TREASURECHESTSPAWNERID); //This just spawns the weapon and does nothing else. Make sure you add a cool effect before this line.
  }
  //else AmbientSound(CHESTFAILSND,200); //Uncomment this line if you want to play a sound when the player doesn't have enough points
}

Script 254 (int hundreds, int SectorTag, int action) //To maintain Hexen format compatibility, this Script can only take 3 arguments. "hundreds" refers to how many hundreds of points are required for SectorTag to have action taken on it.
{
  if(G_CalcScore(hundreds,100,OP_SUBTRACT)) //See previous usage of this function for info
  {
     switch(action)
     {
       case default:
       Floor_LowerToHighest(SectorTag,DEFAULTPLATSPEED,136); //Default sector action. Lowers to 8 units above the nearest-highest floor.
       Break;
     }
  }
}

Script 255 (int points, int multiplier) //Actors can call this script from DECORATE to assign points when hurt or killed
{
  G_CalcScore(points,multiplier,OP_ADD);
}
That should give you a rough idea. If you want the player to receive more points for killing with melee, you can make a new weapon class that inherits from the Fists, and assign it a custom damage type. Then, when the zombie dies from that custom damage type, in it's DECORATE entry, you can make it do an ACS_ExecuteAlways to force it to assign points differently. Here's an example DECORATE lump:
Actor CallofDutyKnife : Fists //Inherits from Doom fists, so it will behave the same way
{
  DamageType Melee
}

Actor CallofDutyZombie : Zombieman //I recommend changing this inheritance so the zombies don't shoot back!
{
  PainChance 255 //Monster always gets put in a zero-duration pain state which calls a points script. This is the original Nazi Zombies behavior
  States
  {
    Pain:
    POSS G 0 ACS_ExecuteAlways(255,0,10,1) //10 points for successful bullet hit
    Goto See
    Death:
    POSS H 0 ACS_ExecuteAlways(255,0,60,1) //This will always give 70 points for a baseline kill
    POSS H 5
    POSS I 5 A_Scream
    POSS J 5 A_NoBlocking
    POSS K 5
    POSS L -1
    Death.Melee:
    POSS H 0 ACS_ExecuteAlways(255,0,130,1) //This will always give 130 points for a melee kill
    POSS H 5
    POSS I 5 A_Scream
    POSS J 5 A_NoBlocking
    POSS K 5
    POSS L -1
    stop
    Death.Buckshot:
    POSS H 0 ACS_ExecuteAlways(255,0,50,1) //This will always give 50 points for a weapon that's 1-hit-kill early in the game, such as explosives or shotguns
    POSS H 5
    POSS I 5 A_Scream
    POSS J 5 A_NoBlocking
    POSS K 5
    POSS L -1
  }
}
After this, it's probably a good idea to inherit a custom player class from the original Doom player and give it some different properties (viewheight I'm looking at you) and starting inventory items to better simulate the Nazi Zombies experience. You can do this in DECORATE, with this code:
Actor CallofDutyPlayer : DoomPlayer
{
  Player.DisplayName "USMC Trooper"
  Player.StartItem "Pistol"
  Player.StartItem "Clip",40  //You start with 32+8 rounds in Nazi Zombies
  Player.StartItem "CallofDutyKnife"
  Player.ViewHeight 45
}
Then you put this in the KEYCONF lump to make this new player class the default:
clearplayerclasses
addclass CallofDutyPlayer
If any of this doesn't work or if you need further scripting or coding help, I'd be glad to help.

Share this post


Link to post

I updated my previous post with a bugfixed set of scripts and a newer DECORATE definition that behaves more closely to the real Nazi Zombies enemies. Also, I developed a quick hack that will allow the player to access the Double Tap Root Beer perk in your level:

DECORATE:

Actor DoubleTapRootBeer : ArtiTomeofPower 32001 //Dummy item that replaces the player's weapons with Double Tap versions
{
  +INVENTORY.AUTOACTIVATE
  Inventory.MaxAmount 0
  Inventory.PickupMessage "Double-Tap! Rack 'em up!"
  Powerup.Duration 0x7FFFFFFF //This is as high as this value can go. It corresponds to about 2 years game time, so it can safely be considered "permanent".
}

Actor CallofDutyPistol : Pistol
{
  Weapon.SisterWeapon DoubleTapPistol
}

Actor DoubleTapPistol : Pistol
{
  +POWERED_UP
  Weapon.SisterWeapon CallofDutyPistol
  States
  {
  Fire:
    PISG A 2
    PISG B 3 A_FirePistol
    PISG C 2
    PISG B 3 A_ReFire
    Goto Ready
  Flash:
    PISF A 3 Bright A_Light1
    Goto LightDone
    PISF A 4 Bright A_Light0
    Goto LightDone
  }
}
Then just replace "Pistol" with "CallofDutyPistol" in the CallofDutyPlayer class starting items and you can now have Double Tap Root Beer.

Now for the cool part. The player regenerates health like in NZ and can get Juggernog!

DECORATE:
Actor PlayerHealthRegeneration : PowerRegeneration
{
  Powerup.Duration 0x7FFFFFFF
  inventory.maxamount 0
  +INVENTORY.AUTOACTIVATE
}

Actor JuggerNog : UpgradeStamina
{
  Inventory.Amount 100
  Inventory.MaxAmount 100
  Inventory.PickupMessage "Juggernog! Walk tall!"
}
Make sure you add "PlayerHealthGeneration" as an item the CallofDutyPlayer starts with for this health system to work.

Share this post


Link to post

omg, tysm! Now, I dont want an exact replica, but ur code is amazing! however, as much as I hate to bring this up, there's some errors that are being diffecult.

Line 24:
str WeaponsList[MAXWEAPONRANGE]={T_PISTOL,T_SHOTGUN,T_CHAINGUN,T_PLASMAGUN}; //These are predefined, but you should be able to assign actual class names here

has the error:

Line 24 in file "script.acs" ...
script.acs:24: Syntax error in constant expression.
> str WeaponsList[MAXWEAPONRANGE]={T_PISTOL,
> ^

Line 37:
case default:

has the error:

script.acs:37: Syntax error in constant expression.
> case default:
> ^


I cant figure it out. :( The second batch of ur code is all commented for now.

Share this post


Link to post

Hmm... Certainly took a bit of effort to get this working again. I suppose either my ACS is rusty or ACC is acting up. Either way - here's a fixed scriptset that compiles, but you may wish to play with it some more.

Strange though... While all of this stuff seems syntactically correct, alot of it fails to function as intended. I'll spend some more time on it and I'll repost with fixed code.

#include "zcommon.acs"

#define DEFAULTPLATSPEED 35  //This is a fairly normal platform lowering speed if I remember correctly. Feel free to experiment with this value.
#define OP_SUBTRACT 0
#define OP_ADD 1
#define CHESTFAILSND "*usefail"  //I recommend changing this
#define MAXWEAPONRANGE 4 //Change this define to a higher value if you have more than 4 weapons in your list
#define TREASURECHESTSPAWNERID 255 //Change this if your Treasure Chest uses a different Thing Tag than 255
#define DEFAULTSCORE 500 //Like the original Nazi Zombies game mode.
#define DEBUGSCORE 950

#define DEBUGMODE 1 //Switch this to 0 if debug mode should be disabled (doesn't dump debug info anymore)

str WeaponsList[4]={"Pistol","Shotgun","Chaingun","PlasmaRifle"}; //These are predefined, but you should be able to assign actual class names here
str playerScore[4]={DEBUGSCORE,DEFAULTSCORE,DEFAULTSCORE,DEFAULTSCORE}; //The player scores at map start

int RandomWeapon=0; //Initialized here because "static" is not a valid type specifier in ACS... :/

function int G_CalcScore(int base, int multiplier, int op)
{
  if(op==OP_SUBTRACT && (base*multiplier) > playerScore[PlayerNumber()])
    return 0;  //Player does not have enough points, indicate calling script
    switch(op)
    {
      //case default:
      //print(s:"Invalid op specified in G_CalcScore(base,mul,op).");
      //return 0;
      //Break;  //Just in case
      case OP_SUBTRACT:
      playerScore[PlayerNumber()] -= base*multiplier;
      return 1;
      Break;
      case OP_ADD:
      playerScore[PlayerNumber()] += base*multiplier;
      return 1;
      Break;
    }
    return 1;
}

Script 250 (int points, int extradata) //In case you want to pass a special parameter to the Treasure Chest for whatever reason
{
  if(G_CalcScore(points,1,OP_SUBTRACT)) //This will evaluate to a "true" and will still attempt to subtract points if possible
  {
        RandomWeapon=random(0,MAXWEAPONRANGE-1);
        SpawnSpot(WeaponsList[RandomWeapon],TREASURECHESTSPAWNERID,0,0);
  }
  //else AmbientSound(CHESTFAILSND,200); //Uncomment this line if you want to play a sound when the player doesn't have enough points
}

Script 254 (int hundreds, int SectorTag, int action) //To maintain Hexen format compatibility, this Script can only take 3 arguments. "hundreds" refers to how many hundreds of points are required for SectorTag to have action taken on it.
{
  if(G_CalcScore(hundreds,100,OP_SUBTRACT)) //See previous usage of this function for info
  {
     switch(action)
     {
       case 0:
       Floor_LowerToHighest(SectorTag,DEFAULTPLATSPEED,136); //Default sector action. Lowers to 8 units above the nearest-highest floor.
       Break;
     }
  }
}

Script 253 OPEN
{
    if(DEBUGMODE==1)
    {
        SetFont("DBIGFONT");
        HudMessage(s:playerScore[0]; HUDMSG_FADEOUT,300,CR_LIGHTBLUE,0.75,0.75,1.0);
        Delay(5);
        Restart;
    }
}

Script 255 (int points, int multiplier) //Actors can call this script from DECORATE to assign points when hurt or killed
{
  G_CalcScore(points,multiplier,OP_ADD);
}

Share this post


Link to post

so, i've decided to have a score timer. If the player(s) get so far, they will have enough points to open stuff up. They can choose which doors they want open. i should be able to make the code myself for this.

BUT WHAT I CANT DO CAUSE IM A NOOB is get the zombies to follow me once they spawn. I have my zombies spawn in various locations, all of them being under toxic sludge. When the zombies spawn, i need them to intantly know where the player(s) is. Is there a way to do that in my level's script?

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×