Raised This Month: $51 Target: $400
 12% 

View Poll Results: Are you excited?
Hell yeah! 55 74.32%
A bit. 6 8.11%
Not really. 13 17.57%
Voters: 74. You may not vote on this poll

Superhero: Source, from the top!


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
API
Veteran Member
Join Date: May 2006
Old 07-12-2007 , 16:57   Superhero: Source, from the top!
Reply With Quote #1

Hey everyone, here I am finally revealing some information about my recent work, hopefully I drew some interest to all of you guys just by the name. Before I really get started, this post is mostly for those developers out there interested in the progress of the technical aspects of the plug in.

Everyone knows Superhero 1.6, personally my favorite way to play CS. It was so imaginative, made me want to actually play, because to be honest, I would rather shoot someone with an exploding bullet while running at the speed of a five year old hyped up on caffeine than tactically complete objectives.

Some people still have no idea what I am talking about. Basically, Superhero: Source is a plugin with an extensive API that allows users to create heroes for in-game play. One of the best things about SH: Source is the basic experience system, there is only one XP value, and one level value, unlike my brother project War3Source. Every time a player levels they are allowed to pick another hero to add to their arsenal. Whether it is Flash going at the speed of the child on caffeine, or Spiderman webbing from building to building, that is up to a programmers imagination.

To be honest, this is my favorite project. I have a passion for SH mods ever since 1.6 as noted before, I spend more time on this plug in than War3Source to be completely honest. The fact of the matter is that you need to be passionate about what you are doing, although passionate about both, I enjoy working on SH: Source more.

Just to note, there is no "official" Superhero plug in for Source, but this in my mind is the closest you are going to get. The API is very extensive with a lot of native functions as well as stocks and forwards for programmers to make their own additions to the hero vault.

One thing I want to cover before I forget, SH: Source supports XP saving as well as XP discarding, there will be as many save options as DBIs that get released. My main focuses are MySQL (finished) and SQLite (waiting for DBI release). For those of you that don't know what SQLite is, it is a local SQL database that doesn't require a connection to the internet to use. It is a popular replacement for binary or text based local saving as the parsing is much faster which leads to instance loading times.

Next, let us look at the interface draft.
Code:
/**
 * File: SHSource_Interface.inc
 * Description: The file to be included for creating heroes.
 * Author(s): Anthony Iacono  
 */

#include <sdktools>

// The types of immunities you can get/set from.
enum SHImmunity
{
    Immunity_HealthTake = 0, // Immune from health taking
    Immunity_Explosion = 1, // Immune from explosion based stuff
};

/**
 * Registers a new hero with the SHSource plugin.
 * @param name: The name of the hero. (max 64) 
 * @param short: The short name of the hero, no spaces! (max 16)
 * @param desc: The description of the hero. (max 256)
 * @param def_level: The default minimum level for the hero, SHORTNAME_level is automatically created! 
 * @param req_bind: A string with "1" is it requires a +power bind, with "0" if it doesn't.
 * @return The return value will be the heroID used for other interface functions, -1 on failure. 
 */     
native SH_CreateHero(const String:name[],const String:short[],const String:desc[],const String:def_level[],const String:req_bind[]);

/**
 * Registers a help command with the SHSource plugin for superherohelp
 * @param name: The name of the command. (max 64)
 * @param desc: The description of the command. (max 256) 
 * @noreturn
 */
native SH_CreateHelpCommand(String:name[],String:desc[]);

/**
 * Gets the current level for the provided player.
 * @param client: The client index.
 * @return The return value will be the level, if -1 then it failed.
 */
native SH_GetLevel(client);

/**
 * Sets the current leve for the provided player.
 * @param client: The client index.
 * @param level: The level to set at.
 * @noreturn
 */
native SH_SetLevel(client,level);    

/**
 * Gets the status of the ownership over a hero for a player.
 * @param client: The client index.
 * @param hero: The hero to check.
 * @return 1 if they have the hero, 0 if they don't.
 */   
native SH_GetHasHero(client,hero);

/**
 * Sets the status of the ownership over a hero for a player.
 * @param client: The client index.
 * @param hero: The hero to set.
 * @param has: Whether you want them to have it or to not have it.
 * @noreturn
 */   
native SH_SetHasHero(client,hero,bool:has);

/**
 * Gets the XP value the client has.
 * @param client: The client index.
 * @return The value of XP, -1 on failure.
 */   
native SH_GetXP(client);

/**
 * Sets the XP value the client has.
 * @param client: The client index.
 * @param xp: The XP value to set.
 * @noreturn
 */    
native SH_SetXP(client,xp);

/**
 * Check the immunity status for a client.
 * @param client: The client index.
 * @param immunity: The immunity type, check SHImmunity for a list you can use.
 * @return Either 1 for they are immune, 0 for they aren't immune.
 */    
native SH_GetImmunity(client,SHImmunity:immunity);

/**
 * Set the immunity status for a client.
 * @param client: The client index.
 * @param immunity: The immunity type, check SHImmunity for a list you can use.
 * @param has: Whether to set them to have the immunity or not.
 * @noreturn
 */   
native SH_SetImmunity(client,SHImmunity:immunity,bool:has);

/**
 * Sets the speed for the player that is handled within the SHSource system, good for heros that set speed so you don't end up making the player slower.
 * Pass 1.0 as speed when they no longer should use the speed, make sure to do this when they no longer have the hero or whatever.
 * @param client: The client index.
 * @param speed: The speed you want to pass.
 * @noreturn
 */
native SH_SetMaxSpeed(client,Float:speed);

/**
 * Sets the gravity for the player that is handled within the SHSource system, good for heros that set speed so you don't end up making the player jump lower.
 * Pass 1.0 as gravity when they no longer should use the gravity, make sure to do this when they no longer have the hero or whatever.
 * @param client: The client index.
 * @param gravity: The gravity you want to pass.
 * @noreturn
 */
native SH_SetMinGravity(client,Float:gravity);

/**
 * Sets the visibility for the player that is handled within the SHSource system, good for heroes that set visibility as a power.
 * Pass 255 when you no longer should use this visibility, make sure you do this when they no longer have the power.
 * @param client: The client index.
 * @param visibility: The visibility to pass. (0-255)
 * @noreturn
 */
native SH_SetMinVisibility(client,visibility=255);

/**
 * Gets the minimum visibility for a player, this is searched through the whole system.
 * @param client: The client index.
 * @return The minimum visibility. (0-255)
 */
native SH_GetMinVisibility(client);

/**
 * Sets the override visibility for the player, could be useful for exposing players.
 * Pass 255 to rid your override.
 * @param client: The client index.
 * @param visibility: The visibility to pass. (0-255)
 * @noreturn
 */
native SH_SetOverrideVisibility(client,visibility=255);             

/**
 * Sets the health for the player if its greater than the other inquiries.
 * Pass 100 when they no longer should follow instruction.
 * @param client: The client index.
 * @param hp: The HP value you want to pass.
 * @noreturn
 */
native SH_SetMaxHealth(client,hp);

/**
 * Gets the max health in the global SH: Source system for the player, max sure to do this if you are regenerating health or whatever.
 * @param client: The client index.
 * @return The max health for the client.
 */
native SH_GetMaxHealth(client);

/**
 * Sets the armor for the player if its greater than the other inquiries.
 * Pass 0 when they no longer should follow instruction.
 * @param client: The client index.
 * @param armor: The armor value you want to pass.
 * @noreturn
 */
native SH_SetMaxArmor(client,armor);

/**
 * Gets the max armor in the global SH: Source system for the player, max sure to do this if you are regenerating armor or whatever.
 * @param client: The client index.
 * @return The max armor for the client.
 */
native SH_GetMaxArmor(client);
    
/**
 * Overrides the speed for SHSource, useful for punishing them or whatever.
 * Pass 0.0 as speed when you want the SHSource system to take over again, make sure to do this when they are no longer supposed to follow!
 * @param client: The client index.
 * @param speed: The speed you want to pass.
 * @noreturn
 */
native SH_SetOverrideSpeed(client,Float:speed);
          
/**
 * Overrides the gravity for SHSource, useful for punishing them or whatever.
 * Pass 0.0 as gravity when you want the SHSource system to take over again, make sure to do this when they are no longer supposed to follow!
 * @param client: The client index.
 * @param gravity: The gravity you want to pass.
 * @noreturn
 */
native SH_SetOverrideGravity(client,Float:gravity);

/**
 * Give the amount of XP someone would get for a kill.
 * @param client: The client index.
 * @noreturn
 */
native SH_GiveKillXP(client);

/**
 * Makes the client commit suicide.
 * @param client: The client index.
 * @noreturn
 */
native SH_CommitSuicide(client);

/**
 * Checks if a client is alive.
 * @param client: The client index.
 * @return True if they are alive, false if dead.
 */
native bool:SH_IsAlive(client);

/**
 * Gets the eye position of the client.
 * @param client: The client index.
 * @param position: The array to put the eye position into.
 * @noreturn
 */
native SH_EyePosition(client,Float:position[3]);

/**
 * Gets the eye angles of the client.
 * @param client: The client index.
 * @param angles: The array to put the eye angles into.
 * @noreturn
 */
native SH_EyeAngles(client,Float:angles[3]);

/**
 * Create an entity by name, returns the index.
 * @param classname: The entity's classname. (E.G: prop_physics)
 * @return The entity index, -1 on failure.
 */
native SH_CreateEntity(const String:classname[]);

/**
 * Spawns an entity, MUST BE CALLED AFTER ENTITY CREATION!
 * @param entity: The entity index.
 * @noreturn
 */
native SH_SpawnEntity(entity);

/**
 * Removes an entity safely.
 * @param entity: The entity index.
 * @noreturn
 */
native SH_RemoveEntity(entity);

/**
 * Calls CBaseEntity::FollowEntity from the SDK, makes entity follow to_follow.
 * @param entity: The entity index.
 * @param to_follow: The entity to follow.
 * @noreturn
 */
native SH_CBE_FollowEntity(entity,to_follow);

/**
 * Sets an origin of an entity, this isn't the only way to do it, but its easy.
 * @param entity: The entity index.
 * @param origin: The origin to set.
 * @noreturn
 */
native SH_SetOrigin(entity,const Float:origin[3]);

/**
 * Gets an origin of an entity, this isn't the only way to do it, but its easy.
 * @param entity: The entity index.
 * @param origin: The origin of the entity.
 * @noreturn
 */
native SH_GetOrigin(entity,Float:origin[3]);    
     
/**
 * Set the velocity of an entity, this isn't the only way to do it, but its easy.
 * @param entity: The entity index.
 * @param velocity: The velocity to set.
 * @noreturn
 */
native SH_SetVelocity(entity,Float:velocity[3]);

/**
 * Gets the velocity of an entity.
 * @param entity: The entity index.
 * @param velocity: The array to copy to.
 * @noretunr
 */
native SH_GetVelocity(entity,Float:velocity[3]);    

/**
 * Sets an entity's model. MAKE SURE YOU PRECACHE THE MODEL FIRST!
 * @param entity: The entity index.
 * @param model: The path to the model. (E.G: props_junk/plasticbucket001a.mdl ) 
 */
native SH_SetModel(entity,const String:model[]);   

/**
 * Sets the health for a client, PLEASE MAX SURE YOU USE MAX HEALTH NATIVES IF YOU ARE USING IT TO GIVE THEM ADDITIONAL HEALTH AS A POWER.
 * @param client: The client index.
 * @param hp: The HP to set.
 * @noreturn
 */
native SH_SetHealth(client,hp);

/**
 * Sets the armor for a client, PLEASE MAX SURE YOU USE MAX ARMOR NATIVES IF YOU ARE USING IT TO GIVE THEM ADDITIONAL ARMOR AS A POWER.
 * @param client: The client index.
 * @param armor: The armor to set.
 * @noreturn
 */
native SH_SetArmor(client,armor);

/**
 * Sets the render color of an entity. It is suggested that you use other natives for players.
 * @param entity: The entity index.
 * @param r: The red amount. (0-255)
 * @param g: The green amount. (0-255)
 * @param b: The blue amount. (0-255)
 * @param a: The alpha amount. (0-255)
 * @noreturn
 */
native SH_SetRenderColor(entity,r,g,b,a=255);

/**
 * Sets the movetype of an entity.
 * @param entity: The entity index.
 * @param movetype: The movetype to set.
 * @noreturn
 */
native SH_SetMoveType(entity,movetype);

#define    SF_ENVEXPLOSION_NODAMAGE    0x00000001 // when set, ENV_EXPLOSION will not actually inflict damage
#define    SF_ENVEXPLOSION_REPEATABLE    0x00000002 // can this entity be refired?
#define SF_ENVEXPLOSION_NOFIREBALL    0x00000004 // don't draw the fireball
#define SF_ENVEXPLOSION_NOSMOKE        0x00000008 // don't draw the smoke
#define SF_ENVEXPLOSION_NODECAL        0x00000010 // don't make a scorch mark
#define SF_ENVEXPLOSION_NOSPARKS    0x00000020 // don't make sparks
#define SF_ENVEXPLOSION_NOSOUND        0x00000040 // don't play explosion sound.
#define SF_ENVEXPLOSION_RND_ORIENT    0x00000080    // randomly oriented sprites
#define SF_ENVEXPLOSION_NOFIREBALLSMOKE 0x0100
#define SF_ENVEXPLOSION_NOPARTICLES 0x00000200
#define SF_ENVEXPLOSION_NODLIGHTS    0x00000400
#define SF_ENVEXPLOSION_NOCLAMPMIN    0x00000800 // don't clamp the minimum size of the fireball sprite
#define SF_ENVEXPLOSION_NOCLAMPMAX    0x00001000 // don't clamp the maximum size of the fireball sprite
#define SF_ENVEXPLOSION_SURFACEONLY    0x00002000 // don't damage the player if he's underwater.

/**
 * Create an explosion.
 * @param origin: The origin of the explosion.
 * @param angle: The angle of the explosion.
 * @param owner_ent: The owner of the explosion, when in doubt, use 0.
 * @param magnitude: The magnitude of the explosion.
 * @param radius: The radius of the explosion.
 * @param spawnflags: The spawn flags for the explosion, see above for a list, use 0 for no flags.
 * @param explosion_force: The force of the explosion.
 * @param inflictor_ent: The entity to use as the damage inflictor, when in doubt, use 0.
 * @noreturn
 */  
native SH_CreateExplosion(const Float:origin[3],const Float:angle[3],owner_ent,magnitude,radius,spawnflags,Float:explosion_force,inflictor_ent);

/**
 * Called when a player gets authenticated with the SHSource plugin.
 * @client: The client index.
 */  
forward OnSHPlayerAuthed(client);

/**
 * Called when the ownership of a hero is set for a player, this doesn't mean toggle!!!
 * @client: The client index.
 * @hero: The heroID that is changed, make sure you don't assume it is for you!!!
 * @has: Whether the change was that they got the hero or were set to not having the hero.
 */
forward OnHeroChanged(client,hero,bool:has);

/**
 * Called when a user uses +power_shortname or -power_shortname
 * @client: The client index.
 * @hero: The hero that it is called for.
 * @pressed: If they used +power_shortname, true, else, -power_shortname
 */
forward OnPowerCommand(client,hero,bool:pressed);   

/**
 * Called when the SHSource system is loaded, register heroes here!
 */ 
forward OnSHPluginReady();

/**
 * Precache all files here. (E.G: Sounds/Materials/Models)
 */
forward OnSHPrecache(); 

// For traceline you should be making a trace filter rather than doing math.
// If you DO want a traceable pos without making a filter, use the stock.
stock SH_CreateVecFromPoints(Float:vec1[3],Float:vec2[3],Float:output[3])
{
    output[0]=vec2[0]-vec1[0];
    output[1]=vec2[1]-vec1[1];
    output[2]=vec2[2]-vec1[2];
}

stock SH_GetTraceablePos(Float:pos[3],const Float:angle[3])
{
    new Float:vecdir[3];
    GetAngleVectors(angle,vecdir,NULL_VECTOR,NULL_VECTOR);
    NormalizeVector(vecdir,vecdir);
    pos[0]+=vecdir[0]*64;
    pos[1]+=vecdir[1]*64;
    pos[2]+=vecdir[2]*64;
}

stock Float:SH_DistanceBetween(const Float:pos1[3],const Float:pos2[3])
{
    return SquareRoot((pos2[0]-pos1[0])*(pos2[0]-pos1[0])+(pos2[1]-pos1[1])*(pos2[1]-pos1[1])+(pos2[2]-pos1[2])*(pos2[2]-pos1[2]));
}

stock SH_BeamPointsToAll(Float:delay,const Float:start[3],const Float:end[3],modelindex,startframe,framerate,Float:life,Float:width,Float:endwidth,fadelength,Float:amplitude,r,g,b,a,speed)
{
    new color[4];
    color[0]=r;
    color[1]=g;
    color[2]=b;
    color[3]=a;
    TE_SetupBeamPoints(start,end,modelindex,0,startframe,framerate,life,width,endwidth,fadelength,amplitude,color,speed);
    TE_SendToAll(delay);
}

stock SH_BeamPoints(client,Float:delay,const Float:start[3],const Float:end[3],modelindex,startframe,framerate,Float:life,Float:width,Float:endwidth,fadelength,Float:amplitude,r,g,b,a,speed)
{
    new color[4];
    color[0]=r;
    color[1]=g;
    color[2]=b;
    color[3]=a;
    TE_SetupBeamPoints(start,end,modelindex,0,startframe,framerate,life,width,endwidth,fadelength,amplitude,color,speed);
    TE_SendToClient(client,delay);
}

stock SH_BeamFollowToAll(Float:delay,follow_ent,modelindex,Float:life,Float:width,Float:endwidth,fadelength,r,g,b,a)
{
    new color[4];
    color[0]=r;
    color[1]=g;
    color[2]=b;
    color[3]=a;
    TE_SetupBeamFollow(follow_ent,modelindex,0,life,width,endwidth,fadelength,color);
    TE_SendToAll(delay);
}

stock SH_BeamFollow(client,Float:delay,follow_ent,modelindex,Float:life,Float:width,Float:endwidth,fadelength,r,g,b,a)
{
    new color[4];
    color[0]=r;
    color[1]=g;
    color[2]=b;
    color[3]=a;
    TE_SetupBeamFollow(follow_ent,modelindex,0,life,width,endwidth,fadelength,color);
    TE_SendToClient(client,delay);
}
Now, let us look at a very basic hero such as Cola Lover, a caffeine addicted hero.

Code:
#include <sourcemod>
#include "SHSource/SHSource_Interface.inc"
new heroID;
new Handle:cvarSpeed,Handle:cvarHealth,Handle:cvarRegenInterval,Handle:cvarRegenHealth;
new maxClientCount;

public OnSHPluginReady()
{
    heroID=SH_CreateHero("Cola Lover","cola","Run faster and have more\nHP + regen because of caffine!","10","0");
    cvarSpeed=CreateConVar("cola_speed","1.5625");
    cvarHealth=CreateConVar("cola_health","700");
    cvarRegenInterval=CreateConVar("cola_regen_interval","2.5");
    cvarRegenHealth=CreateConVar("cola_regen_health","20");
    CreateTimer(GetConVarFloat(cvarRegenInterval),RegenTimer);
    maxClientCount=GetMaxClients();
}

public OnHeroChanged(client,hero,bool:has)
{
    if(hero==heroID)
    {
        if(has)
        {
            SH_SetMaxSpeed(client,GetConVarFloat(cvarSpeed));
            SH_SetMaxHealth(client,GetConVarInt(cvarHealth));
        }
        else
        {
            SH_SetMaxSpeed(client,1.0);
            SH_SetMaxHealth(client,100);
        }
    }
}

public Action:RegenTimer(Handle:timer)
{
    for(new x=1;x<=maxClientCount;x++)
    {
        if(IsClientInGame(x)&&SH_IsAlive(x)&&SH_GetHasHero(x,heroID))
        {
            new max_hp=SH_GetMaxHealth(x);
            new new_hp=GetClientHealth(x)+GetConVarInt(cvarRegenHealth);
            if(new_hp>max_hp)
                new_hp=max_hp;
            SH_SetHealth(x,new_hp);
        }
    }
    CreateTimer(GetConVarFloat(cvarRegenInterval),RegenTimer);
}
You notice that heroes are registered with the native "SH_CreateHero", which returns an integer value containing the unique hero ID. This hero ID is used with natives to check status of hero ownership, as well as other stuff. For example, if you want to check if a player has a hero, you do the following.
Code:
if ( SH_GetHasHero( client_index, heroID ) )
{
    // they have the hero, do stuff
}
else
{
    // they DO NOT have the hero, do other stuff
}
Next, lets look at the forward "OnHeroChanged". This is called whenever the ownership of a hero changes for a player, this means when they first join as well. Parameter "client" is the client's index. Parameter "hero" is the hero that the status changed for, if you haven't figured it out yet, you need to check if hero is equal to hero ID before you are allowed to assume that the client either got or dropped your hero. Parameter "has" will be either a true or false value. If it is true, then the player has obtained "hero", if it is false they have dropped "hero".

Now here is an example of the interface's extensiveness, look at the natives "SH_SetMaxSpeed" and "SH_SetMaxHealth". Those two natives can be used to set speed and health only if it is the greatest of all heroes setting the speed or health. You can notice that you only have to set them twice, when they get the hero and when they lose it, the SH: Source plug in core does all the hard work. One other native showed off in this hero is "SH_GetMaxHealth", which might be deceiving at first look. It doesn't return what YOU put for max health, it returns the health that SH: Source considers the highest request. This makes regeneration functions or auto-health refills very easy.

The cool thing about the interface is that most of the engine functions that you would normally have to use SDKTools to expose, are exposed through SH: Source. They are wrappers around the SDKTools calls, which basically just makes your life easier and also ensures that it is going to work without hassle.

Lets say you want to create a prop! First precache your model.
Code:
public OnSHPrecache()
{
    PrecacheModel("models/props_c17/woodbarrel001.mdl");
}
Next, put this where you want to create the prop.
Code:
new prop_ent=SH_CreateEntity("prop_physics");
SH_SetModel(prop_ent,"props_c17/woodbarrel001.mdl");
new Float:pos_to_spawn[3];
pos_to_spawn[0]=500.0; // x location, 500.0 for an example
pos_to_spawn[1]=250.0; // y location, 250.0 for an example
pos_to_spawn[2]=100.0; // z location, 100.0 for an example
SH_SetOrigin(prop_ent,pos_to_spawn);
SH_SpawnEntity(prop_ent); // spawn it into the game
Pretty easy to do compared to what you would normally have to go through.

Anyway, I'll probably release a developer's version of SH: Source soon, so stay tuned!

Thanks for reading. Please post any questions or comments.
__________________

Last edited by API; 07-19-2007 at 23:08. Reason: added visibility natives
API is offline
Send a message via AIM to API
sumguy14
Senior Member
Join Date: Apr 2006
Old 07-12-2007 , 19:06   Re: Superhero: Source, from the top!
Reply With Quote #2

Woot, this plugin owns right now! I can't imagine how awesome it will be when it's finished

The interface is awesome, makes hero-creating so easy.

<3 Soccer
sumguy14 is offline
Prime
Member
Join Date: Jul 2007
Old 07-17-2007 , 20:27   Re: Superhero: Source, from the top!
Reply With Quote #3

Well this will be awesome...im going to begin coding for this shortly. Keep Up the Good Work.
Prime is offline
scrizo
New Member
Join Date: May 2006
Old 09-29-2007 , 01:08   Re: Superhero: Source, from the top!
Reply With Quote #4

will this be ported to linux
scrizo is offline
joakimdj
BANNED
Join Date: Dec 2007
Location: norway
Old 12-13-2007 , 18:00   Re: Superhero: Source, from the top!
Reply With Quote #5

THIS ROCKS !
joakimdj is offline
Send a message via MSN to joakimdj
{LOD}Scarecrow
Member
Join Date: Dec 2004
Location: AZ
Old 01-15-2008 , 00:01   Re: Superhero: Source, from the top!
Reply With Quote #6

Any timeline on a linux port??
{LOD}Scarecrow is offline
Send a message via AIM to {LOD}Scarecrow
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 00:40.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode