[page=New weapon (Melee)]
Ok, first we need to define the fire function.
Open up g_weapon.c, head to the bottom, all the way to the bottom... further... after fire_bfg.. further... yes, right there. Add all this in straight from the bottom:
/*
/*
==================
Fire_Punch
Commented for Moddb Tutorial
==================
*/
void fire_punch (edict_t *self, vec3_t start, vec3_t aim, int reach, int damage, int kick, int quiet, int mod)
{
vec3_t forward, right, up;
vec3_t v;
vec3_t point;
trace_t tr;
vectoangles2 (aim, v); //
AngleVectors (v, forward, right, up); //
VectorNormalize (forward); //
VectorMA( start, reach, forward, point); // Aiming stuff
//see if the hit connects
tr = gi.trace(start, NULL, NULL, point, self, MASK_SHOT);
if(tr.fraction == 1.0)
{
if(!quiet) //not needed, it's better to follow my later steps
//gi.sound (self, CHAN_WEAPON, gi.soundindex ("weapons/swish.wav"), 1, ATTN_NORM, 0);
return;
}
if(tr.ent->takedamage == DAMAGE_YES || tr.ent->takedamage == DAMAGE_AIM) // Make sure they took damage
{
// pull the player forward if you do damage
VectorMA(self->velocity, 75, forward, self->velocity); // Pull forward
VectorMA(self->velocity, 75, up, self->velocity); // Pull up a tad bit. You can't slide;)
// do the damage
// FIXME - make the damage appear at right spot and direction
T_Damage (tr.ent, self, self, vec3_origin, tr.ent->s.origin, vec3_origin, damage, kick/2,
DAMAGE_ENERGY, mod); // Time to Slice my friends
gi.sound(self, CHAN_WEAPON, gi.soundindex("weapons/phitw1.wav"), 1, ATTN_IDLE, 0); // Used for my Punch.
//Rename and use for whatever
if(!quiet)
gi.sound (self, CHAN_WEAPON, gi.soundindex ("weapons/meatht.wav"), 1, ATTN_NORM, 0); // Don't change this.
//This is only used if your weapon is not quiet.. Chainfist isn't quiet, knife is
}
else
{
if(!quiet)
gi.sound (self, CHAN_WEAPON, gi.soundindex ("weapons/tink1.wav"), 1, ATTN_NORM, 0); //same as above
VectorScale (tr.plane.normal, 256, point);
gi.WriteByte (svc_temp_entity);
gi.WriteByte (TE_SPARKS); //make sparks, not gunshot..
gi.WritePosition (tr.endpos);
gi.WriteDir (point);
gi.multicast (tr.endpos, MULTICAST_PVS);
gi.sound (self, CHAN_AUTO, gi.soundindex("weapons/phitw2.wav") , 1, ATTN_NORM, 0); //hit wall sound
}
}
Whew. That's alot of code.
Now, let's go to p_weapon.c, and make sure you've got a model! Put this code to the way bottom, like g_weapon
/*
=======================
Punching/Melee
=======================
*/
void Null_Fire(edict_t *ent)
{
int i;
vec3_t start;
vec3_t forward, right;
vec3_t angles;
int damage = 5; //change to whatever
int kick = 2; //ditto here
vec3_t offset;
if (ent->client->ps.gunframe == 11) //rename 11 to after you're attack frame
{
ent->client->ps.gunframe++;
return;
}
AngleVectors (ent->client->v_angle, forward, right, NULL);
VectorScale (forward, -2, ent->client->kick_origin);
ent->client->kick_angles[0] = -2;
VectorSet(offset, 0, 8, ent->viewheight-8 );
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start); //where does the hit start from?
if (is_quad)
{
damage *= 4;
kick *= 4;
}
// get start / end positions
VectorAdd (ent->client->v_angle, ent->client->kick_angles, angles);
AngleVectors (angles, forward, right, NULL);
VectorSet(offset, 0, 8, ent->viewheight-8 );
P_ProjectSource (ent->client, ent->s.origin, offset, forward, right, start);
fire_punch (ent, start, forward, 45, damage, 200, 1, MOD_PUNCH); // yep, matches the fire_ function
ent->client->ps.gunframe++; //NEEDED
PlayerNoise(ent, start, PNOISE_WEAPON); //NEEDED
// if (! ( (int)dmflags->value & DF_INFINITE_AMMO ) )
// ent->client->pers.inventory[ent->client->ammo_index]--; // comment these out to prevent the Minus NULL Ammo bug
}
void Weapon_Null (edict_t *ent)
{
static int pause_frames[] = {10, 21, 0};
static int fire_frames[] = {6, 0}; // Frame stuff here
Weapon_Generic (ent, 3, 9, 22, 24, pause_frames, fire_frames, Null_Fire);
}
Ok, now, let's head to g_items.c, near the beginning.
You'll see
void Weapon_Blaster (edict_t *ent);
void Weapon_Shotgun (edict_t *ent);
void Weapon_SuperShotgun (edict_t *ent);
void Weapon_Machinegun (edict_t *ent);
void Weapon_Chaingun (edict_t *ent);
void Weapon_HyperBlaster (edict_t *ent);
void Weapon_RocketLauncher (edict_t *ent);
void Weapon_Grenade (edict_t *ent);
void Weapon_GrenadeLauncher (edict_t *ent);
void Weapon_Railgun (edict_t *ent);
void Weapon_BFG (edict_t *ent);
under that, add
void Weapon_Null (edict_t *ent);
That was easy! now, go lower, and find:
/* weapon_blaster (.3 .3 1) (-16 -16 -16) (16 16 16)
always owned, never in the world
*/
{
"weapon_blaster",
NULL,
Use_Weapon,
NULL,
Weapon_Blaster,
"misc/w_pkup.wav",
NULL, 0,
"models/weapons/v_blast/tris.md2",
/* icon */ "w_blaster",
/* pickup */ "Blaster",
0,
0,
NULL,
IT_WEAPON|IT_STAY_COOP,
WEAP_BLASTER,
NULL,
0,
/* precache */ "weapons/blastf1a.wav misc/lasfly.wav"
},
above that, add this:
{
"weapon_null", // The map entity name. dont include this in a map whatever you do.
NULL, // The pickup function
Use_Weapon, // How to use
NULL, // the drop function
Weapon_Null, //What the use function is
"misc/w_pkup.wav",
"models/nullweapon.md2",0,
"models/nullweapon.md2", //The models stuff.(This is my Hands model)
"w_blaster", //Icon to be used. you could create another, you probably should
"Hands", //Pickup name. use this to give the item to someone at the start of the game
0,
0,
NULL,
IT_WEAPON|IT_STAY_COOP,
WEAP_BLASTER, // the model index, just an integer defined in g_local.h
NULL,
0,
""
},
Ok, now that that's done, let's head on over to g_local.c Find:
#define MOD_EXIT 28
#define MOD_SPLASH 29
#define MOD_TARGET_LASER 30
#define MOD_TRIGGER_HURT 31
#define MOD_HIT 32
#define MOD_TARGET_BLASTER 33
#define MOD_FRIENDLY_FIRE 0x8000000
below them, add
#define MOD_PUNCH 34
Now, go to p_client.c, and find
case MOD_TELEFRAG:
message = "tried to invade";
message2 = "'s personal space";
break;
under it, add this:
case MOD_PUNCH:
message = "took";
message2 = "'s fist in the face";
break;
Now that we have the means of death, let's replace the blaster with it! Find:
PrecacheItem (FindItem ("Blaster"));
replace with
PrecacheItem (FindItem ("Hands"));
Find
if (weapon && !oldcount)
{
if (other->client->pers.weapon != ent->item && ( !deathmatch->value || other->client->pers.weapon == FindItem("Blaster") ) )
other->client->newweapon = ent->item;
}
Replace with
if (weapon && !oldcount)
{
if (other->client->pers.weapon != ent->item && ( !deathmatch->value || other->client->pers.weapon == FindItem("Hands") ) )
other->client->newweapon = ent->item;
}
Find
item = self->client->pers.weapon;
if (! self->client->pers.inventory[self->client->ammo_index] )
item = NULL;
if (item && (strcmp (item->pickup_name, "Blaster") == 0))
item = NULL;
Replace again with
item = self->client->pers.weapon;
if (! self->client->pers.inventory[self->client->ammo_index] )
item = NULL;
if (item && (strcmp (item->pickup_name, "Hands") == 0))
item = NULL;
Find
if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("shells"))]
&& ent->client->pers.inventory[ITEM_INDEX(FindItem("shotgun"))] )
{
ent->client->newweapon = FindItem ("shotgun");
return;
}
ent->client->newweapon = FindItem ("Blaster");
}
Replace with
if ( ent->client->pers.inventory[ITEM_INDEX(FindItem("shells"))]
&& ent->client->pers.inventory[ITEM_INDEX(FindItem("shotgun"))] )
{
ent->client->newweapon = FindItem ("shotgun");
return;
}
ent->client->newweapon = FindItem ("Hands");
}
Find
item = FindItem("Blaster");
client->pers.selected_item = ITEM_INDEX(item);
client->pers.inventory[client->pers.selected_item] = 1;
Replace with
item = FindItem("Hands");
client->pers.selected_item = ITEM_INDEX(item);
client->pers.inventory[client->pers.selected_item] = 1;
There you go! Now go punch some Strogg, and go punch and humiliate your foes.
Why is this in the f.e.a.r. section?
Shouldn't be..?
good
Jesus! Look at all the coding! When I tried to do even a basic mod with quake 3 and just changed the rocket speed, then clicked compile, It wrecked the game. It always happens to what I do with other ones like Doom.
man you are ok,believe it...me? i don't even know how to compile.
Man this code doesn't work!
First I wasn't able to find some lines (maybe the source code changed?) second, please can you add some files to make it easy for people who only want to play?