Adding a Weapon into C4

From C4 Engine Wiki

Jump to: navigation, search
Image:warning.jpg Obsolete Article

Some or all of the information on this page is obsolete and needs to be updated.

Contents

Preface

This is a beginner's guide to adding your own weapon to the C4 Demo game module. In this tutorial we will be adding a basic sniper rifle.

Download

For your convenience I have included the resources used by this tutorial here. Please download and place all files into their respective directories within your C4 folder. SniperRifle.zip

The Code

These are the files we will be working with:

  • MGControllers.cpp
  • MGFighter.cpp
  • MGFighter.h
  • MGGame.cpp
  • MGGame.h
  • MGInput.cpp
  • MGInput.h
  • MGMultiplayer.cpp
  • MGMultiplayer.h
  • MGWeapons.h

We will also be adding two new files:

  • MGSniperRifle.cpp
  • MGSniperRifle.h

And making some minor additions to:

  • Input.txt
  • Engine.cfg

Adding the source code for our new weapon

All coding additions have been encased with:

// New weapon start
// New weapon end

MGSniperRifle.cpp & MGSniperRifle.h

  • Add MGSniperRIfle.cpp and MGSniperRifle.h (found within the zip file) to your project.

MGInput.cpp

  • Find void WeaponAction::Begin(void)
  • Add the following code to that function.
case kActionProtonCannon:

	weaponType = kWeaponProtonCannon;
	break;

// New weapon start
case kActionSniperRifle:

	weaponType = kWeaponSniperRifle;
	break;
// New weapon end

MGInput.h

  • Add the following code to the action types near the top of the file.
kActionProtonCannon		= 'cann',
// New weapon start
kActionSniperRifle		= 'snip',
// New weapon end
kActionNextWeapon		= 'next',

MGWeapons.h

  • Add the following code to the controller types near the top of the file.
kControllerPlasma		= 'plas',
// New weapon start
kControllerBullet		= 'blet'
// New weapon end
  • Add the following code to the entity types near the top of the file.
kEntityProtonCannon		= 'pcan',
// New weapon start
kEntitySniperRifle		= 'snip',
kEntityBullet		        = 'blet',
// New weapon end
kEntityRocketAmmo		= 'rkam',
  • At approx line 48 change the enum to:
enum
{
	kWeaponNone,
	kWeaponBlaster,
	kWeaponSpikeShooter,
	kWeaponQuantumCharger,
	kWeaponGrenadeLauncher,
	kWeaponRocketLauncher,
	kWeaponPlasmaGun,
	kWeaponProtonCannon,
	// New weapon start
	kWeaponSniperRifle,
	// New weapon end
	kWeaponCount
};

MGContollers.cpp

  • Find void CollectableController::Preprocess(void)
  • Add the following code to that function.
// This is a temporary piece of code to add a SpiralHelix effect to the weapons
switch (GetTargetNode()->GetEntityType())
{
	case kEntityGrenadeLauncher:
	case kEntityRocketLauncher:
	case kEntityPlasmaGun:
	case kEntityProtonCannon:
	// New weapon start
	case kEntitySniperRifle:
	// New weapon end
  • Find void CollectableController::Activate(Node *trigger, Node *activator)
  • Add the following code to that function.
case kEntityProtonCannon:
{
	player->AcquireWeapon(kWeaponProtonCannon);
	break;
}

// New weapon start
case kEntitySniperRifle:
{
	player->AcquireWeapon(kWeaponSniperRifle);
	break;
}
// New weapon end

MGFighter.cpp

  • Find void FighterController::SetWeapon(WeaponType weaponType)
  • Add our sniper rifle entity to the end of the constructor.
// New weapon start
static const EntityType entityType[kWeaponCount] =
{
	0, kEntityBlaster, 0, 0, kEntityGrenadeLauncher, kEntityRocketLauncher, kEntityPlasmaGun, kEntityProtonCannon, 
        kEntitySniperRifle
};
// New weapon end
  • Find void FighterController::UpdateWeapon(WorldCallback *callback, void *data)
  • Add the following case to the end of the switch statement.
// New weapon start
case kWeaponSniperRifle:
{
        time = MaxZero(time + 2000);
	shotIndex = fighter->GetWorld()->NewControllerIndex();

	TheMessageMgr->SendMessageAll(CreateBulletMessage(shotIndex, position, direction * 0.1F, player->GetPlayerKey()));
	break;
}
// New weapon end

MGFighter.h

  • Add the following include at the top of the file.
// New weapon start
#include "MGSniperRifle.h"
// New weapon end

MGGame.cpp

  • At approx line 268 register the sniper rifle entity,
protonCannonEntityReg(kEntityProtonCannon, "model/ProtonCannon/ProtonCannon", kEntityPrecache, kControllerCollectable),
// New weapon start
sniperRifleEntityReg(kEntitySniperRifle, "SniperRifle", kEntityPrecache, kControllerCollectable),
// New weapon end
  • A little further down do the same for the bullet entity,
rocketEntityReg(kEntityRocket, "model/RocketLauncher/Rocket", kEntityPrecache | kEntityPrivate),
// New weapon start
bulletEntityReg(kEntityBullet, "Bullet", kEntityPrecache | kEntityPrivate),
// New weapon end
  • At approx line 315 register the sniper rifle action,
protonCannonAction(kActionProtonCannon),
// New weapon start
sniperRifleAction(kActionSniperRifle),
// New weapon end
  • At approx line 334 register the sniper rifle entity size,
protonCannonEntityReg.SetEntitySize(0.6F, 0.25F, 0.25F);
// New weapon start
sniperRifleEntityReg.SetEntitySize(0.7F, 0.25F, 0.25F);
// New weapon end
  • Finally register our input action,
TheInputMgr->AddAction(&protonCannonAction);
// New weapon start
TheInputMgr->AddAction(&sniperRifleAction);
// New weapon end

MGGame.h

  • Find class Game : public Singleton<Game>, public Application
  • Register the sniper rifle entity.
EntityRegistration						plasmaAmmoEntityReg;
// New weapon start
EntityRegistration		                                sniperRifleEntityReg;
// New weapon end
  • A little further down do the same for the bullet entity,
EntityRegistration		                                rocketEntityReg;
// New weapon start
EntityRegistration		                                bulletEntityReg;
// New weapon end
  • A little further down do the same for the weapon action,
WeaponAction			                                protonCannonAction;
// New weapon start
WeaponAction			                                sniperRifleAction;
// New weapon end

MGMultiplayer.cpp

  • Find CreateEntityMessage *CreateEntityMessage::ConstructMessage(EntityMessageType type)
  • Add the following case to the switch statement.
case kEntityMessagePlasma:

	return (new CreatePlasmaMessage);

// New weapon start
case kEntityMessageBullet:

	return (new CreateBulletMessage);
// New weapon end
  • Find void Game::CreateEntity(const CreateEntityMessage *message)
  • Add the following case to the switch statement.
case kEntityMessagePlasma:
{
	const CreatePlasmaMessage *m = static_cast<const CreatePlasmaMessage *>(message);

	controller = new PlasmaController(m->GetInitialPosition(), m->GetInitialVelocity(), m->GetShooterKey());
	entity = Entity::Get(kEntityPlasma);
	break;
}

// New weapon start
case kEntityMessageBullet:
{
	const CreateBulletMessage *m = static_cast<const CreateBulletMessage *>(message);

	controller = new BulletController(m->GetInitialPosition(), m->GetInitialVelocity(), m->GetShooterKey());
	entity = Entity::Get(kEntityBullet);
	break;
}
// New weapon end

MGMultiplayer.h

  • At approx line 64 change the weapon message enum to:
enum
{
	kEntityMessageBlast		= 0,
	kEntityMessageBlast2		= 1,
	kEntityMessageGrenade		= 2,
	kEntityMessageRocket		= 3,
	kEntityMessagePlasma		= 4,
	kEntityMessageFireball		= 5,
	// New weapon start
	kEntityMessageBullet		= 6,
	// New weapon end
	kEntityMessageSoldier		= 7
};


That takes care of all the source code. Recompile now.

Keyboard Input

Now we have to bind a keyboard input for our weapon so that we may select it in game.

  • Open C4/Data/cfg/Engine.cfg.
  • Add the following under the key binding for the proton cannon.
bind "6" %snip; 
  • Open C4/Import/Demo/game/Input.txt
  • Add the following under the input for the proton cannon.
'snip' "Sniper Rifle"
  • Now run C4 and type "istring" into the console. Select the Input.txt file from the String Import Dialog. You will need to close and restart C4 for the string to be imported.

Test out the new weapon

Please make sure you have compiled all source code without error, included all the files within the zip file at the top of this tutorial, added the key binding and imported the Input.txt string before commencing with this step.

  • Open up any map of your choice in the World Editor.
  • From the Entity page select SniperRifle.
  • Make sure the zone where you want to place the gun is the active target zone. (Use Set Target Zone in the Node menu.)
  • Click within the active target zone to place the machine gun. (Check the Z-axis position in the side view.)

Now all you have to do is run your map, collect the sniper rifle, press 6 to select it, and SHOOT!

For you to do

  • Create your own weapon model.
  • Add in your own sounds, particle effects, decals, and whatever else you can think of to make your gun exciting.
  • Register some ammo for the sniper rifle.
Personal tools