Welcome to The Beginner’s Superhero Tutorial.
Helpful Links:
In this tutoiral you will learn how to create a hero with:
- Increased Health
- Increased Armor
- Decreased Gravity
- Increased Speed
- A Damage Multiplier
- Player Models
- Weapon Models (p_, v_)
- Lasers
- Invisibility
- No Clip
- Infinate Ammo
- Giving Weapons at Spawn
- Creating Hooks
- Creating Spiderman Web-Swing
- Respawning Upon Death
- Exploding Bullets
- Scope on All Weapons
Introduction/Prolouge
Beaware that anywhere you see "Super" or "Super Hero" should be changed to your hero's name.
Also know that everytime you see this: "//..." it means you should know what goes there, if anything does.
Now before we begin these things you must know how to make a superhero:
First (conventionally) are your includes, basic includes for most heroes are as follows:
Code:
#include <amxmodx>
#include <superheromod>
if you need other includes besides these I will note them for you, otherwise these are always included in a superhero script
Next you declare your glabal varriables which will include your hero's name, and if they have your hero's powers or not. (other varrs will be added later for special powers), in this tutorial the hero's name is: Super, but of course you will change Super to whatever you want your hero to be called.
Code:
new gHeroName[]="Super Hero" //creates a string varr to hold your hearo's name
new bool:gHasSuperPower[SH_MAXSLOTS+1] //creates a varr with an aray, with 1 slot per player
Now comes the plugin_init this is where all registers go that will be used in your plugin:
Code:
public plugin_init() {
register_plugin("SUPERHERO Super", "1.0", "Rolnaaba"); //register plugin (you should know what this is)
register_cvar("Super_level", "1"); //level required to select hero
shCreateHero(gHeroName, "Hero Power List", "Hero Discription", false, "Super_level");
//superheromod.inc:
//stock shCreateHero(heroName[], heroPower[], heroHelp[], bool:requiresKeyEvents, heroLevel[])
register_srvcmd("Super_init", "Super_init"); //register your hero's init function with server
shRegHeroInit(gHeroName, "Super_init"); //register your hero's init with superheromod
}
Now your Hero's Init function, this is called anytime someone picks your hero:
Code:
public Super_init() {
new temp[6]; //declare a temperary varriable
read_argv(1,temp,5); //reading the first argument will give you the id of the person who selected your hero
new id = str_to_num(temp); //transfer the string returned into a number and store it as the id
read_argv(2,temp,5); //second argument is whether they have the power or not
new hasPowers = str_to_num(temp);
gHasSuperPower[id] = (hasPowers != 0); //(hasPowers != 0) will either return 1 (if it is true that hasPowers != 0), or 0 (if it is false that hasPowers != 0)
}
Putting these together creates:
Code:
#include <amxmodx>
#include <superheromod>
new gHeroName[]="Super Hero" //creates a string varr to hold your hero's name
new bool:gHasSuperPower[SH_MAXSLOTS+1] //creates a varr with an aray, with 1 slot per player
public plugin_init() {
register_plugin("SUPERHERO Super", "1.0", "[x]Rol Sources"); //register plugin (you should know what this is)
register_cvar("Super_level", "1"); //level required to select hero
shCreateHero(gHeroName, "Hero Powers", "Hero Discription", false, "Super_level"); //superheromod.inc: stock shCreateHero(heroName[], heroPower[], heroHelp[], bool:requiresKeyEvents, heroLevel[])
register_srvcmd("Super_init", "Super_init"); //register your hero's init function with server
shRegHeroInit(gHeroName, "Super_init"); //register your hero's init with superheromod
}
public Super_init() {
new temp[6]; //declare a temperary varriable
read_argv(1,temp,5); //reading the first argument will give you the id of the person who selected your hero
new id = str_to_num(temp); //transfer the string returned into a number and store it as the id
read_argv(2,temp,5); //second argument is whether they have the power or not
new hasPowers = str_to_num(temp);
gHasSuperPower[id] = (hasPowers != 0); //(hasPowers != 0) will either return 1 (if it is true that hasPowers != 0), or 0 (if it is false that hasPowers != 0)
}
This Hero doesnt do anything but let you select them so lets make it actually do something:
1) To create a hero with increased health simply do the following:
Code:
public plugin_init() {
//...
register_cvar("Super_health", "150"); //cvar for health
shSetMaxHealth(gHeroName, "Super_health"); //set health
}
public Super_init() {
//...
if (!hasPowers && gHasSuperPower[id] && is_user_alive(id)) { //check if they had power but dont know and are alive
shRemHealthPower(id); //remove health power if this is the case
}
}
This function will allow the superhero mod to determine which hero gives the player the highest amount of health each round then give it to the player all for us.
2) Armor is pretty much the same way except the function is different:
Code:
public plugin_init() {
//...
register_cvar("Super_armor", "150"); //cvar for armor
shSetMaxArmor(gHeroName, "Super_armor"); //set armor
}
public Super_init() {
//...
if (!hasPowers && gHasSuperPower[id] && is_user_alive(id)) { //check if they had power but dont know and are alive
shRemArmorPower(id); //remove armor power if this is the case
}
}
3) Gravity is the finall item (covered here) that is done the same way:
Code:
public plugin_init() {
//...
register_cvar("Super_grav", "0.25"); //cvar for grav
shSetMinGravity(gHeroName, "Super_grav"); //set grav
}
public Super_init() {
//...
if (!hasPowers && gHasSuperPower[id] && is_user_alive(id)) { //check if they had power but dont know and are alive
shRemGravityPower(id); //remove gravity power if this is the case
}
}
4) Increased speed is a little different:
Code:
public plugin_init() {
//...
register_cvar("Super_speed", "600.0"); //cvar for grav
shSetMaxSpeed(gHeroName, "Super_speed", "[0]"); //set speed
//see below for explination
}
public Super_init() {
//...
if (!hasPowers && gHasSuperPower[id] && is_user_alive(id)) { //check if they had power but dont know and are alive
shRemSpeedPower(id); //remove speed power if this is the case
}
}
superheromod.inc:
Code:
stock shSetMaxSpeed(heroName[], heroSpeedCVAR[], heroWeapons[] )
{
// Hero Weapons is a list of weapons this speed is good for in a wierd delimination
// "[0]" would equal all weapons
// "[29][30]" would equal weapons 29,30 etc.
// By making heroSpeed a CVAR - this can be changed on the fly (or at least between rounds)
server_cmd("sh_setmaxspeed ^"%s^" ^"%s^" ^"%s^"", heroName, heroSpeedCVAR, heroWeapons )
}
5) Now the Damage Multiplier. There are a couple ways of doing this, but this is what i recomend:
Code:
public plugin_init() {
//...
//see helpful links for event info
register_event("Damage", "Event_damage","b");
register_cvar("Supher_mult", "1.5"); //how much damage to do (1.5 x normal_damage)
}
public Event_damage(id) {
if (!shModActive() || !is_user_alive(id)) return PLUGIN_CONTINUE;
new damage = read_data(2); //this is covered in my events tut. (in helpful links)
new weapon, bodypart, attacker = get_user_attacker(id, weapon, bodypart) //store what weapon used, bodypart hit, and attacker
new headshot = bodypart == 1 ? 1 : 0 //this is just short for:
/*if (bodypart == 1) {
headshot = 1;
} else {
headshot = 0;
}*/
if(attacker <= 0 || attacker > SH_MAXSLOTS ) return PLUGIN_CONTINUE; //checks ifs it was world that did the damage, and if so just end function.
if(gHasSuperPower[attacker] && is_user_alive(id)) { //if alive and have power
new extraDamage = floatround(damage * get_cvar_float("Super_mult") - damage); //calculate extra damage ([damage done x multiplier] - damage done = extra damage)
if (extraDamage > 0) {
shExtraDamage( id, attacker, extraDamage, "Super damage Mult", headshot ); //superheromod.inc: stock shExtraDamage(id, attacker, damage, weaponDescription[], headshot = 0);
}
}
}
6) Player models are simple, you precache them then apply them:
Code:
#include <cstrike> //you need to include this for cs_set_user_model
new g_model; //must be outside plugin_init so it can be global
public plugin_precache() {
//...
g_model = precache_model("models/shmod/Super/PLAYER_MODEL.mdl"); //makes players download the model
}
public Super_init() {
//...
if(hasPowers) { //if they have power
Super_set_model(id) //go to set model funciton
}
//...
}
public Super_set_model(id) {
if (!shModActive() || !is_user_alive(id) || !gHasSuperPower[id]) return PLUGIN_CONTINUE; //if shmod if off, or they are dead, or the dont have the power end function
cs_set_user_model(id, g_model); //set player model
return PLUGIN_CONTINUE;
}
7) Weapon Models, are similar, but slightly different this will show you the use of p_ (player view, someone looking at you), v_ (view, 1st person view).
This will show you the fakemeta way:
Code:
#include <fakemeta> //for model setting
new g_p_model; //must be outside plugin_init so it can be global
new g_v_model;
public plugin_precache() {
//...
g_p_model = precache_model("models/shmod/Super/p_weapon_model.mdl"); //makes players download the model
g_v_model = precache_model("models/shmod/Super/v_weapon_model.mdl");
}
public Super_init() {
//...
if(hasPowers) { //if they have power
Super_set_model(id) //go to set model funciton
}
//...
}
public Super_set_model(id) {
if (!shModActive() || !is_user_alive(id) || !HasSuperPower[id]) return;
new clip, ammo, wpnid = get_user_weapon(id,clip,ammo);
if(wpnid == WEAPON_ID_TO_CHANGE) {
set_pev(id, pev_viewmodel, engfunc(EngFunc_AllocString, g_v_model));//view model
set_pev(id, pev_weaponmodel, engfunc(EngFunc_AllocString, g_p_model));//player model
}
}
where you replace MY_WEAPON_ID with the id of the weapon you want the model on...id's for Counter-Strike are as follows:
Quote:
Originally Posted by CSW List
CSW_M3
CSW_XM1014
CSW_MP5NAVY
CSW_TMP
CSW_P90
CSW_MAC10
CSW_UMP45
CSW_AK47
CSW_SG552
CSW_M4A1
CSW_AUG
CSW_SCOUT
CSW_AWP
CSW_G3SG1
CSW_SG550
CSW_M249
CSW_USP
CSW_GLOCK18
CSW_DEAGLE
CSW_P228
CSW_ELITE
CSW_FIVESEVEN
CSW_FAMAS
CSW_SMOKEGRENADE
CSW_FLASHBANG
CSW_HEGRENADE
|
8 ) For lasers(iun superhero) you must register a keydown, and/or a keyup. This will let the superheromod know that when they press the key they have bound to your power to execute the function you set:
Code:
public plugin_init() {
//...
register_srvcmd("Super_kd", "Super_kd"); //let server know of keydown
shRegKeyDown(gHeroName, "Super_kd"); //let superhero know of keydown
register_srvcmd("Super_ku", "Super_ku"); //let server know of keyup
shRegKeyUp(gHeroName, "Super_ku"); //let superhero know of keyup
}
After registering your keyup/downs you create their functions, since this laser will only use the keydown func thats all I will do, but I just wanted to show you how to register a keydown.
Code:
//keydown func:
public Super_kd() {
//look familiar? you get the id same way you did in your hero's init function
new temp[6];
read_argv(1,temp,5);
new id = str_to_num(temp);
if(!is_user_alive(id)) return; //make sure they are not dead
new aimvec[3]; //aiming vectors (used in get_user_origin)
new tid, tbody; //area hit by laser
new FFOn = get_cvar_num("mp_friendlyfire"); //is friendly fire on?
get_user_origin(id, aimvec, 3); //this will get where they are aiming at
Super_laser_effects(id, aimvec); //execute effects function (this is what creates the laser you see in game, it will be discussed later)
get_user_aiming(id, tid, tbody);
//this gets where they are aiming with respect to the person they see
//and stores where the laser hits
if(is_user_alive(tid) && (FFOn || get_user_team(id) != get_user_team(tid))) { //target id has to be alive, and FF has to be on or person be on other team
new damage;
switch(tbody) {
case 1: damage = 200; //head shot
case 2: damage = 50; //body shot
case 3: damage = 50; //stomach shot
case 4: damage = 20; //arm shot
case 5: damage = 20; //arm shot
case 6: damage = 20; //leg shot
case 7: damage = 20; //leg shot
}
shExtraDamage(tid, id, damage, "Super Laser"); //does damage
}
}
Now We never did the effects right? Well if you dont understand the following code you might want to read
this post I did a while ago.
I am not explaining the write_byte and other message functions but I will show you how to make a red beam.
Anyway:
Code:
new laser_spr;
public plugin_precache() {
laser_spr = precache_model("sprites/laserbeam.spr");
}
public Super_laser_effects(id, aimvec[3]) {
new origin[3];
get_user_origin(id, origin, 1);
//DELIGHT
message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
write_byte(27)
write_coord(origin[0]) //pos
write_coord(origin[1])
write_coord(origin[2])
write_byte(10)
write_byte(250) //r,g,b value
write_byte(0) //r,g,b value
write_byte(0) //r,g,b value
write_byte(2) //life
write_byte(1) //decay
message_end()
//BEAMENTPOINTS
message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
write_byte (0)
write_coord(origin[0])
write_coord(origin[1])
write_coord(origin[2])
write_coord(aimvec[0])
write_coord(aimvec[1])
write_coord(aimvec[2])
write_short(laser_spr) //sprite we precached
write_byte(1) // framestart
write_byte(5) // framerate
write_byte(2) // life
write_byte(40) // width
write_byte(0) // noise
write_byte(250) // r, g, b
write_byte(0) // r, g, b
write_byte(0) // r, g, b
write_byte(200) // brightness
write_byte(200) // speed
message_end()
}
This will just shoot a beam, it wont leave a burn spot, or make a sound, or anything but show a red lazer beam.
9) Now for invisibility, its very easy all you do is set their rgb value and amount...depending on how invis you want them:
just use this function:
Code:
set_user_rendering(id, kRenderFxGlowShell, 8, 8, 8, kRenderTransAlpha, 12);
this will give them about 95%ish invis.
func.inc:
Code:
/* Sets player rendering mode. */
native set_user_rendering(index, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16);
Now say you wanted to make them turn invis upon keydown and then uninvis on key up:
Code:
#include <fun> //for set_user_rendering function
plugin_init() {
//...
register_srvcmd("Super_kd", "Super_kd");
shRegKeyDown(gHeroName, "Super_kd");
register_srvcmd("Super_ku", "Super_ku");
shRegKeyUp(gHeroName, "Super_ku");
}
public Super_kd() {
new temp[6];
read_argv(1,temp,5);
new id = str_to_num(temp); //get id
if (!is_user_alive(id)) return; //if they not alive just end
set_user_rendering(id, kRenderFxGlowShell, 8, 8, 8, kRenderTransAlpha, 12); //sets invis
}
public Super_ku() {
new temp[6];
read_argv(1,temp,5);
new id = str_to_num(temp); //get id
if (!is_user_alive(id)) return;
set_user_rendering(id);//sets rendering back to normal
}
10) No Clip is easy to set, and easy to remove. But wall checking is..."fun":
Code:
#include <fakemeta> //velocity checks
new g_pos[SH_MAXSLOTS][3]; //for wall check, will store pos they are when no clip ends
plugin_init() {
//...
register_srvcmd("Super_kd", "Super_kd");
shRegKeyDown(gHeroName, "Super_kd");
//dont need a key up, this hero will let them press the button
//then they have 20sec of no clip
}
public Super_kd() {
if (!is_user_alive(id)) return; //check if alive
new temp[6];
read_argv(1, temp, 5);
new id = str_to_num(temp);//gets id
set_user_noclip(id, 1); //gives them no clip
set_task(20.0, "Super_remove_clip", id); //set delayed task for remove clip passing their id to the new function
}
public Super_remove_clip(id) {
remove_task(id);//make sure the task is deleted
set_user_noclip(id, 0); //turn off no clip
get_user_origin(id, g_pos[id]); //saves their position
new Float:velocity[3];
pev(id,pev_velocity,velocity); //gets velocity
if(velocity[0] == 0.0 && velocity[1] == 0.0) { //if they aren't moving
velocity[0] += 20.0
velocity[2] += 100.0
set_pev(entity, pev_velocity, velocity); //makes them do a small jump
}
set_task(0.5, "Super_wall_check", id); //go to wall check function
}
public Super_wall_check(id) {
if(!is_user_alive(id)) return;
new origin[3];
get_user_origin(id, origin);
//this checks if they didnt move (which the jump we did should have made them, unless they in a wall), and that they are alive
if (g_pos[id][0] == origin[0] && g_pos[id][1] == origin[1] && g_posn[id][2] == origin[2] && is_user_alive(id)) {
user_kill(id); //kill them
}
}
11) Infinate Ammo is very easy:
Code:
public plugin_init() {
//...
register_event("CurWeapon", "Event_weapon","be","1=1");
}
public Event_weapon(id) {
new clip = read_data(3); //get how much ammo left
if (clip == 0) { //if out of ammo
shReloadAmmo(id); //reload ammo
}
}
12)To give weapons at spawn hook the spawn event, then give them weapons:
Code:
public plugin_init() {
//...
register_event("ResetHUD", "Event_spawn","b"); //called when someone joins or new spawn
//...
}
public Event_spawn(id) {
if(gHasSuperPower[id] && is_user_alive(id) && shModActive()) { //has power and alive and mod on
shGiveWeapon(id,"weapon_name"); //give a weapon
}
}
replace "weapon_name" with the weapon name you want:
THIS will show you info on all counter-strike weapon information, including the name, which you use in this function.
13) To create a hook is more complicated than anything we have done so far but stay with me:
First we need a keyup/down for the hook,and some varriables:
Code:
#include <xtrafun> //in addition to normal includes you need this one too because I use some constants in it
new g_hookLocation[SH_MAXSLOTS+1][3] //location for hook to shoot hook to
new g_hookLength[SH_MAXSLOTS+1] //length of the hook
new bool:g_hooked[SH_MAXSLOTS+1] //person using hook?
public plugin_init() {
//...
register_cvar("Super_moveacc", "650"); //speed on hook
register_cvar("Super_reelspeed", "1000"); //reel speed
register_cvar("Super_hooksky", "0"); //can they hook sky? 0=no, 1=yes
register_srvcmd("Super_kd", "Super_kd");
shRegKeyDown(gHeroName, "Super_kd"); //key down
register_srvcmd("Super_ku", "Super_ku");
shRegKeyUp(gHeroName, "Super_ku"); //key up
register_event("DeathMsg", "Super_death", "a")
//...
}
next we do...well...everything else:
Code:
public Super_kd() {
new temp[6];
read_argv(1,temp,5);
new id=str_to_num(temp); //get id
if(g_hooked[id] || !is_user_alive(id) || !g_hasSuperPower[id] || !hasRoundStarted()) return;
if(PassAimTest(id)) Super_hookOn(id); //if they pass aim test turn on hook
}
public Super_ku() {
new temp[10];
read_argv(1,temp,9);
new id=str_to_num(temp); //get id
if(g_hooked[id]) Super_hookOff(id); //turn off hook if they had one on
}
public Super_death() {
new id=read_data(2); //get id
if (g_hooked[id]) Super_hookOff(id); //if hooked turn off
return PLUGIN_CONTINUE;
}
PassAimTest(id) {
new origin[3]; //will hold aiming origin
new Float:Orig[3]; //float version of origin
get_user_origin(id, origin, 3); //get aiming origin and store in origin varr
Orig[0] = float(origin[0]); //convert into float
Orig[1] = float(origin[1]); //convert into float
Orig[2] = float(origin[2]); //convert into float
new AimAt = PointContents(Orig); //get id of object your aiming at
if (AimAt == CONTENTS_SKY && !get_cvar_num("Super_hooksky")) { //if your aiming at sky and cvar says no sky hooking...
return false; //return false
}
return true; //true
}
public Super_hookOn(id) {
new user_origin[3] //to store current origin
if(!is_user_alive(id)) return PLUGIN_HANDLED; //if dead dont turn on hook
g_hooked[id] = true; //make sure we set this so we know they are hooking
get_user_origin(id, user_origin); //get current origin
get_user_origin(id, g_hookLocation[id], 3); //get aiming origin
g_hookLength[id] = get_distance(g_hookLocation[id],user_origin); //get hook length
set_user_gravity(id,0.001); //lower gravity for easy movement
Super_hook_effects(id); //create effects
set_task(HOOK_DELTA_T, "Super_hook_pull", id, _, 0, "b"); //loop pulling sequence
return PLUGIN_CONTINUE;
}
public Super_hookOff(id) {
g_hooked[id] = false; //no longer hooking
killbeam(id); //turn off effects
if(is_user_connected(id)) shSetGravityPower(id); //reset gravity
remove_task(id); //remove pull loop
}
public killbeam(id) {
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(HOOKKILLBEAM);
write_short(id);
message_end();
}
public Super_hook_effects(id) {
//not going to delve into messages
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(HOOKBEAMPOINT)
write_short(id)
write_coord(g_hookLocation[id][0])
write_coord(g_hookLocation[id][1])
write_coord(g_hookLocation[id][2])
write_short(g_spriteWeb ) // sprite index
write_byte(0) // start frame
write_byte(0) // framerate
write_byte(HOOKBEAMLIFE) // life
write_byte(10) // width
write_byte(0) // noise
// Terrorist
if (get_user_team(id)==1) {
write_byte(255) // r, g, b
write_byte(0) // r, g, b
write_byte(0) // r, g, b
}
// Counter-Terrorist
else {
write_byte(0) // r, g, b
write_byte(0) // r, g, b
write_byte(255) // r, g, b
}
write_byte(150) // brightness
write_byte(0) // speed
message_end()
}
public Super_hook_pull(id) {
if (!g_hooked[id]) return; //if not using hook
new user_origin[3]; //current origin
new Float:velocity[3]; //velocity
if (!is_user_alive(id)) {
batgirl_hookOff(id); //if dead turn off hook
return;
}
get_user_origin(id, user_origin); //store current origin
pev(id,pev_velocity,velocity); //gets velocity
new distance = get_distance(g_hookLocation[id], user_origin); //distance left to go
if (distance > 60) {
//set velocity...
velocity[0] = (g_hookLocation[id][0] - user_origin[0]) * (1.0 * get_cvar_num("Super_reelspeed") / distance)
velocity[1] = (g_hookLocation[id][1] - user_origin[1]) * (1.0 * get_cvar_num("Super_reelspeed") / distance)
velocity[2] = (g_hookLocation[id][2] - user_origin[2]) * (1.0 * get_cvar_num("Super_reelspeed") / distance)
}
else {
//set velocity
velocity[0] = 0.0
velocity[1] = 0.0
velocity[2] = 0.0
}
set_pev(entity, pev_velocity, velocity); //set velocity
}
(credits to:
Batgirl)
13) Same as above but:
create a global varr like this:
Code:
new g_hookCreated[SH_MAXSLOTS+1]
add this:
Code:
g_hookCreated[id] = get_gametime();
to the end of the Super_hook_effects() function,
and change the Super_hook_pull(id) function to this:
Code:
public Super_hook_pull(id) {
//current origin, looking origin, button direction being pressed, actual move direction
new user_origin[3], user_look[3], user_direction[3], move_direction[3];
//..., ...., amount to be adjusted due to button being pressed
new A[3], D[3], buttonadjust[3];
new acceleration, Float:vTowards_A, Float:DvTowards_A;
//current velocity, null, button being pressed
new Float:velocity[3], null[3], buttonpress;
if (!g_hooked[id]) return;
if (!is_user_alive(id)) {
Super_hookOff(id);
return;
}
if (g_hookCreated[id] + HOOKBEAMLIFE/10 <= get_gametime()) {
Super_hook_effects(id);
}
null[0] = 0;
null[1] = 0;
null[2] = 0;
get_user_origin(id, user_origin) //store current origin
get_user_origin(id, user_look,2) //store looking origin
pev(id,pev_velocity,velocity); //gets velocity
buttonadjust[0]=0;
buttonadjust[1]=0;
buttonpress = get_user_button(id); //get button being pressed
//where to adjust if such button is pressed
if (buttonpress&IN_FORWARD) {
buttonadjust[0]+=1;
}
if (buttonpress&IN_BACK) {
buttonadjust[0]-=1;
}
if (buttonpress&IN_MOVERIGHT) {
buttonadjust[1]+=1;
}
if (buttonpress&IN_MOVELEFT) {
buttonadjust[1]-=1;
}
if (buttonpress&IN_JUMP) {
buttonadjust[2]+=1;
}
if (buttonpress&IN_DUCK) {
buttonadjust[2]-=1;
}
//----------------------
//ADJUST DIRECTION BEGIN
//----------------------
if (buttonadjust[0] || buttonadjust[1]) {
user_direction[0] = user_look[0] - user_origin[0];
user_direction[1] = user_look[1] - user_origin[1];
move_direction[0] = buttonadjust[0]*user_direction[0] + user_direction[1]*buttonadjust[1];
move_direction[1] = buttonadjust[0]*user_direction[1] - user_direction[0]*buttonadjust[1];
move_direction[2] = 0;
velocity[0] += move_direction[0] * get_cvar_float("batgirl_moveacc") * HOOK_DELTA_T / get_distance(null,move_direction)
velocity[1] += move_direction[1] * get_cvar_float("batgirl_moveacc") * HOOK_DELTA_T / get_distance(null,move_direction)
}
if (buttonadjust[2] < 0 || (buttonadjust[2] && g_hookLength[id] >= 60)) {
g_hookLength[id] -= floatround(buttonadjust[2] * get_cvar_float("batgirl_reelspeed") * HOOK_DELTA_T)
}
else if (!(buttonpress&IN_DUCK) && g_hookLength[id] >= 200) {
buttonadjust[2] += 1
g_hookLength[id] -= floatround(buttonadjust[2] * get_cvar_float("batgirl_reelspeed") * HOOK_DELTA_T)
}
A[0] = g_hookLocation[id][0] - user_origin[0]
A[1] = g_hookLocation[id][1] - user_origin[1]
A[2] = g_hookLocation[id][2] - user_origin[2]
D[0] = A[0]*A[2] / get_distance(null,A)
D[1] = A[1]*A[2] / get_distance(null,A)
D[2] = -(A[1]*A[1] + A[0]*A[0]) / get_distance(null,A)
new aDistance = get_distance(null,D) ? get_distance(null,D) : 1
acceleration = (-get_cvar_num("sv_gravity")) * D[2] / aDistance
vTowards_A = (velocity[0] * A[0] + velocity[1] * A[1] + velocity[2] * A[2]) / get_distance(null,A)
DvTowards_A = float((get_distance(user_origin,g_hookLocation[id]) - g_hookLength[id]) * 4)
if (get_distance(null,D)>10) {
velocity[0] += (acceleration * HOOK_DELTA_T * D[0]) / get_distance(null,D)
velocity[1] += (acceleration * HOOK_DELTA_T * D[1]) / get_distance(null,D)
velocity[2] += (acceleration * HOOK_DELTA_T * D[2]) / get_distance(null,D)
}
velocity[0] += ((DvTowards_A - vTowards_A) * A[0]) / get_distance(null,A)
velocity[1] += ((DvTowards_A - vTowards_A) * A[1]) / get_distance(null,A)
velocity[2] += ((DvTowards_A - vTowards_A) * A[2]) / get_distance(null,A)
//--------------------
//ADJUST DIRECTION END
//--------------------
set_pev(entity, pev_velocity, velocity); //set velocity
}
14) Very Easy, hook death event, then use cs_user_spawn:
Code:
#include <cstrike> //needed for cs_user_spawn
public plugin_init() {
//...
register_event("DeathMsg", "Event_death", "a"); //register death event
//...
}
public Event_death() {
new victim = read_data(2); //read data to collect victim's id
cs_user_spawn(victim); //respawn victim
}
15) To create exploding bullets you need a sprite for the traser round, explosion, and smoke.
For this tutorial the deagle will have exploding shots.
Code:
//shots left
new gShotsLeft[SH_MAXSLOTS+1];
//sprites
new glaser;
new gsplode;
new gsmoke;
//for CurWeapon Event, you will see
new gLastWeapon[33];
new gLastClipCount[33;
new lastammo[33];
new lastweap[33];
public plugin_precache() {
glaser = precache_model("sprites/laser.spr");
gsplode = precache_model("sprites/xplode.spr");
gsmoke = precache_model("sprites/smoke.spr");
}
public plugin_init() {
//...
register_cvar("Super_shots", "5"); //cvar for amount of exploding bullets
register_event("ResetHUD","Super_newRound","b"); //on new round
register_event("Damage", "Super_damage", "b", "2!0"); //called when damage is done
register_event("CurWeapon","Super_changeWeapon","be","1=1"); //weapon change/fire
register_event("CurWeapon","Super_make_tracer", "be", "1=1", "3>0"); //weapon change/fire and has ammo left
//...
}
public Super_newRound(id) { //new round event
gShotsLeft[id] = get_cvar_num("Super_shots"); //reset ammo of sloping bullets
if(gHasSuperPower[id]) shGiveWeapon(id,"weapon_deagle"); //give them a deagle
gLastWeapon[id]=-1 //reset last weapon
}
public Super_damage(id) {
if (!shModActive()) return PLUGIN_CONTINUE; //if mod of
new damage = read_data(2); //damage done
new weapon, bodypart, attacker = get_user_attacker(id,weapon,bodypart); //get attacker
if (attacker <=0 || attacker>SH_MAXSLOTS) return; //this means was world that did damage not a player
if (gHasSuperPower[attacker_id] && weapon == CSW_DEAGLE && is_user_alive(id) && gShotsLeft[id] != 0) {
new health = get_user_health(id);
if (!is_user_connected(attacker_id)) return PLUGIN_CONTINUE; //another world check
if (attacker == id) return PLUGIN_CONTINUE; //if hurt self
new origin[3]; //current origin (for tracer)
new attacker_team[2], victim_team[2]; //for get_user_team
get_user_origin(id, origin); //store current origin
//explosion effects
message_begin(MSG_ALL, SVC_TEMPENTITY)
write_byte(3) // TE_EXPLOSION
write_coord(origin[0])
write_coord(origin[1])
write_coord(origin[2]-22)
write_short(gsmoke) //smoke
write_byte(40) // scale in 0.1u
write_byte(12) // frame rate
write_byte(12) // TE_EXPLFLAG_NOPARTICLES & TE_EXPLFLAG_NOSOUND
message_end()
//blood effects
message_begin(MSG_ALL, SVC_TEMPENTITY)
write_byte(10) // TE_LAVASPLASH
write_coord(origin[0])
write_coord(origin[1])
write_coord(origin[2]-26)
message_end()
// kill victim
user_kill(id, 1);
//we killed player, so lets call deathmsg event and send deagle as weapon
message_begin(MSG_ALL, get_user_msgid("DeathMsg"),{0,0,0},0)
write_byte(attacker_id)
write_byte(id)
write_byte(0)
write_string("deagle")
message_end()
// team check!
get_user_team(attacker, attacker_team, 1);
get_user_team(id, victim_team, 1);
//check teams, and add frags/give some money for kill/and some exp
if (!equali(attacker_team, victim_team)) { //if not on same team
set_user_frags(attacker, get_user_frags(attacker)+1); //add frag
set_user_money(attacker, get_user_money(attacker)+150); //+$150
shAddXP(attacker, id, 1); //give 1 exp
}
else { //same team
set_user_frags(attacker, get_user_frags(attacker)-1); //remove 1 frag
set_user_money(attacker, get_user_money(attacker)-150, 0); //subtract $150
shAddXP(attacker, id, -1); //take 1 exp
}
return PLUGIN_CONTINUE;
}
return PLUGIN_CONTINUE;
}
public Super_changeWeapon(id) {
if (!gHasSuperPower[id] || !shModActive()) return PLUGIN_CONTINUE; //mod on and has power
new clip, ammo, wpnid = get_user_weapon(id, clip, ammo); //get wpnid
if (wpn_id!=CSW_DEAGLE) return PLUGIN_CONTINUE; //not using the weapon we have for exploding shots
if (wpn_id != gLastWeapon[id]) {
gLastWeapon[id] = wpn_id //set new weapon
return PLUGIN_CONTINUE; // user just switched weapons
}
if (clip >= gLastClipCount[id]) {
gLastClipCount[id] = clip //set new clip
return PLUGIN_CONTINUE; //user just reloaded
}
gLastClipCount[id]=clip //set new clip because they fired a shot
gShotsleft[id]-- //decrement(subtract 1) the gshots left varr
return PLUGIN_CONTINUE;
}
public make_tracer(id) {
if (!shModActive()) return PLUGIN_CONTINUE; //if mod off
new weap = read_data(2); // id of the weapon
new ammo = read_data(3); // ammo left in clip
if (gHasSuperPower[id] && weap == CSW_DEAGLE && is_user_alive(id) && gShotsLeft[id] != 0) {
if (lastweap[id] == 0) lastweap[id] = weap //set new lastweapon
if (lastammo[id] > ammo && lastweap[id] == weap) {
new vec1[3], vec2[3];
get_user_origin(id, vec1, 1) // origin; where you are
get_user_origin(id, vec2, 4) // termina; where your bullet goes
// tracer beam
message_begin(MSG_PAS, SVC_TEMPENTITY, vec1)
write_byte(0) // TE_BEAMPOINTS
write_coord(vec1[0])
write_coord(vec1[1])
write_coord(vec1[2])
write_coord(vec2[0])
write_coord(vec2[1])
write_coord(vec2[2])
write_short(glaser) // laserbeam sprite
write_byte(0) // starting frame
write_byte(10) // frame rate
write_byte(2) // life in 0.1s
write_byte(4) // line width in 0.1u
write_byte(1) // noise in 0.1u
write_byte(153) // red
write_byte(0) // green
write_byte(0) // blue
write_byte(80) // brightness
write_byte(100) // scroll speed
message_end()
// bullet impact explosion
message_begin(MSG_PAS, SVC_TEMPENTITY, vec2)
write_byte(3) // TE_EXPLOSION
write_coord(vec2[0]) // end point of beam
write_coord(vec2[1])
write_coord(vec2[2])
write_short(gsplode) // blast sprite
write_byte(10) // scale in 0.1u
write_byte(30) // frame rate
write_byte(8) // TE_EXPLFLAG_NOPARTICLES
message_end() // ..unless i'm mistaken, noparticles helps avoid a crash
}
lastammo[id] = ammo;
lastweap[id] = weap;
return PLUGIN_CONTINUE;
}
return PLUGIN_CONTINUE;
}
16) Easy to put scope on weapons, using cstrike.inc:
Code:
#include <cstrike>
public plugin_init() {
//...
register_srvcmd("Super_kd", "Super_kd"); //let server know of keydown
shRegKeyDown(gHeroName, "Super_kd"); //let superhero know of keydown
//no need for key-up we just want to zoom on keydown
}
public Super_kd() {
new temp[6];
read_argv(1,temp,5);
new id = str_to_num(temp); //get id
new curr_zoom = cs_get_user_zoom(id);
switch(curr_zoom) {
case 0: return PLUGIN_HANDLED;
case CS_SET_NO_ZOOM: cs_set_user_zoom(id, CS_SET_FIRST_ZOOM, 1); //see excerpt from cstrike below for info on this native
case CS_SET_FIRST_ZOOM: cs_set_user_zoom(id, CS_SET_SECOND_ZOOM, 1);
case CS_SET_SECOND_ZOOM: cs_set_user_zoom(id, CS_SET_NO_ZOOM, 1);
default: return PLUGIN_HANDLED;
}
}
from cstrike.inc:
Code:
/* Zoom type enum. Used for get/set_user_zoom() natives.
*/
enum
{
CS_RESET_ZOOM = 0, // Reset any zoom blocking (when using this type, mode has no effect)
CS_SET_NO_ZOOM, // Disable any sort of zoom (ie: to disable zoom in all weapons use this with mode=0)
CS_SET_FIRST_ZOOM, // Set first zoom (awp style)
CS_SET_SECOND_ZOOM, // Set second zoom (awp style)
CS_SET_AUGSG552_ZOOM, // Set aug/sg552 zoom style
};
/* Sets a weapon zoom type on a player, any zoom type will work for all weapons, so you can even set an awp zoom to pistols :D
* The 2nd param has to be one of the above zoom types in the enum. Mode can only be 0 or 1.
* If mode=0 (blocking mode), the user will be forced to use the zoom type set by the native, and wont be able to change it (even by changing weapon)
* until the native resets the zoom with CS_RESET_ZOOM.
* If mode=1 the user will be able to restore back to a normal view by changing weapon.
*/
native cs_set_user_zoom(index, type, mode);
/* Returns how a user is zooming during the native call. Values correspond to the above enum, but will return 0 if an error occurred.
*/
native cs_get_user_zoom(index);