Raised This Month: $32 Target: $400
 8% 

Subplugin Submission [ZP] Addon + Extra Item: Knockback Bomb


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
zmd94
Veteran Member
Join Date: Nov 2013
Location: Malaysia (9w2zow).
Old 06-14-2014 , 12:20   [ZP] Addon + Extra Item: Knockback Bomb
Reply With Quote #1

Firstly, I want to mention that this is not my plugin. I'm just help to reorganize all the source that are related with this plugin "Knockback Bomb" in one place. So that, others can find it more easier.

The "Knockback Bomb" is divided into two types:
Quote:
1. Addon.
2. Extra item.

Question 1:
Quote:
Good job but what addon do and extra item do also?
Yes, it right. However the different is when you use the knockback bomb as an addon, you will only have it once after you respawn as a zombie. After you throw the bomb, you cannot have it anymore.

If you choose it to be as an extra item, you can have an option to buy it more than one and throw it to anyone as many as you want.


1
. [ZP] Addon: Knockback Bomb


Just use this PHP then compile it locally (the original thread, here):
PHP Code:
#include < amxmodx >
#include < cstrike >
#include < engine >
#include < fakemeta >
#include < fun >
#include < hamsandwich >
#include < zombieplague >

#define Plugin     "[ZP] Knockback Bomb"
#define Version   "1.0"
#define Author    "0"

// === Customization starts below! ===
new const g_PlayerModel [ ] = "models/zombie_plague/p_grenade_knock.mdl"
new const g_ViewModel [ ] = "models/zombie_plague/v_grenade_knockback.mdl"
new const g_WorldModel [ ] = "models/zombie_plague/w_grenade_knock.mdl"

// You can add more than 1 sound!
new const g_SoundGrenadeBuy [ ] [ ] = { "items/gunpickup2.wav" }
new const 
g_SoundAmmoPurchase [ ] [ ] = { "items/9mmclip1.wav" }
new const 
g_SoundBombExplode [ ] [ ] = { "zombie_plague/grenade_infect.wav" }

#define MAXCARRY    5 // How many grenades 1 player can hold at the same time
#define RADIUS        300.0 // Affect radius
// === Customization ends above! ===

#define MAXPLAYERS        32
#define pev_nade_type        pev_flTimeStepSound
#define NADE_TYPE_JUMPING    26517
#define AMMOID_SM        13

new g_iExplo

new g_iJumpingNadeCount MAXPLAYERS+]
new 
g_iCurrentWeapon MAXPLAYERS+]

new 
cvar_speed

new g_MaxPlayers
new g_msgAmmoPickup

public plugin_precache ( )
{
    
precache_model g_PlayerModel )
    
precache_model g_ViewModel )
    
precache_model g_WorldModel )
    
    new 
i
    
for ( 0sizeof g_SoundGrenadeBuyi++ )
        
precache_sound g_SoundGrenadeBuy ] )
    for ( 
0sizeof g_SoundAmmoPurchasei++ )
        
precache_sound g_SoundAmmoPurchase ] )
    for ( 
0sizeof g_SoundBombExplodei++ )
        
precache_sound g_SoundBombExplode ] )
    
    
g_iExplo precache_model "sprites/xfire.spr" )
}

public 
plugin_init ( )
{
    
register_plugin PluginVersionAuthor )
    
    
    
register_event "CurWeapon""EV_CurWeapon""be""1=1" )
    
register_event "HLTV""EV_NewRound""a""1=0""2=0" )
    
register_event "DeathMsg""EV_DeathMsg""a" )
    
    
register_forward FM_SetModel"fw_SetModel" )
    
RegisterHam Ham_Think"grenade""fw_ThinkGrenade" )
    
    
cvar_speed register_cvar "zp_zombiebomb_knockback""800" )
    
    
g_msgAmmoPickup get_user_msgid "AmmoPickup" )
    
    
g_MaxPlayers get_maxplayers ( )
}

public 
client_connect Player )
{
    
g_iJumpingNadeCount Player ] = 0
}


public 
zp_user_infected_post PlayerInfectorNemesis )
{
    
g_iJumpingNadeCount Player ] = 0
            
    give_item 
Player"weapon_smokegrenade" )
    
    
emit_sound PlayerCHAN_ITEMg_SoundGrenadeBuy[random_num(0,  sizeof g_SoundGrenadeBuy-1)], VOL_NORMATTN_NORM0PITCH_NORM )
            
    
AmmoPickup PlayerAMMOID_SM)
            
    
g_iJumpingNadeCount Player ] = 1   
}

public 
zp_user_humanized_post PlayerSurvivor )
{
    if ( 
Survivor )
    {
        
g_iJumpingNadeCount Survivor ] = 0
    
}
}

public 
EV_CurWeapon Player )
{
    if ( !
is_user_alive Player ) || !zp_get_user_zombie Player ) )
        return 
PLUGIN_CONTINUE
    
    g_iCurrentWeapon 
Player ] = read_data )
    
    if ( 
g_iJumpingNadeCount Player ] > && g_iCurrentWeapon Player ] == CSW_SMOKEGRENADE )
    {
        
set_pev Playerpev_viewmodel2g_ViewModel )
        
set_pev Playerpev_weaponmodel2g_WorldModel )
    }
    
    return 
PLUGIN_CONTINUE
}

public 
EV_NewRound ( )
{
    
arrayset g_iJumpingNadeCount033 )
}

public 
EV_DeathMsg ( )
{
    new 
iVictim read_data )
    
    if ( !
is_user_connected iVictim ) )
        return
    
    
g_iJumpingNadeCount iVictim ] = 0
}

public 
fw_SetModel Entity, const Model [ ] )
{
    if ( 
Entity )
        return 
FMRES_IGNORED
    
    
if ( pev Entitypev_dmgtime ) == 0.0 )
        return 
FMRES_IGNORED
    
    
new iOwner entity_get_edict EntityEV_ENT_owner )    
    
    if ( 
g_iJumpingNadeCount iOwner ] >= && equal Model ], "w_sm") )
    {
        
// Reset any other nade
        
set_pev Entitypev_nade_type)
        
        
set_pev Entitypev_nade_typeNADE_TYPE_JUMPING )
        
        
g_iJumpingNadeCount iOwner ]--
        
        
entity_set_model Entityg_WorldModel )
        return 
FMRES_SUPERCEDE
    
}
    return 
FMRES_IGNORED
}

public 
fw_ThinkGrenade Entity )
{
    if ( !
pev_valid Entity ) )
        return 
HAM_IGNORED
    
    
static Float:dmg_time
    pev 
Entitypev_dmgtimedmg_time )
    
    if ( 
dmg_time get_gametime ( ) )
        return 
HAM_IGNORED
    
    
if ( pev Entitypev_nade_type ) == NADE_TYPE_JUMPING )
    {
        
jumping_explode Entity )
        return 
HAM_SUPERCEDE
    
}
    return 
HAM_IGNORED
}

public 
jumping_explode Entity )
{
    if ( 
Entity )
        return
    
    static 
Float:flOrigin ]
    
pev Entitypev_originflOrigin )
    
    
engfunc EngFunc_MessageBeginMSG_PVSSVC_TEMPENTITYflOrigin)
    
write_byte TE_SPRITE 
    
engfunc EngFunc_WriteCoordflOrigin ] )
    
engfunc EngFunc_WriteCoordflOrigin ] )
    
engfunc EngFunc_WriteCoordflOrigin ] + 45.0 )
    
write_short g_iExplo )
    
write_byte 35 )
    
write_byte 186 )
    
message_end ( )
    
    new 
iOwner entity_get_edict EntityEV_ENT_owner )
    
    
emit_sound EntityCHAN_WEAPONg_SoundBombExplode[random_num(0,  sizeof g_SoundBombExplode-1)], VOL_NORMATTN_NORM0PITCH_NORM )
    
    for ( new 
1g_MaxPlayersi++ )
    {
        if ( !
is_user_alive  ) )
            continue
       

        
        
// Debug!
        //client_print ( iOwner, print_chat, "Owner of Smoke Grenade!" )    
        
        
new Float:flVictimOrigin ]
        
pev ipev_originflVictimOrigin )
        
        new 
Float:flDistance get_distance_f flOriginflVictimOrigin )    
        
        if ( 
flDistance <= RADIUS )
        {
            static 
Float:flSpeed
            flSpeed 
get_pcvar_float cvar_speed )
            
            static 
Float:flNewSpeed
            flNewSpeed 
flSpeed * ( 1.0 - ( flDistance RADIUS ) )
            
            static 
Float:flVelocity ]
            
get_speed_vector flOriginflVictimOriginflNewSpeedflVelocity )
            
            
set_pev ipev_velocity,flVelocity )
        }
    }
    
    
engfunc EngFunc_RemoveEntityEntity )
}        

public 
AmmoPickup PlayerAmmoIDAmmoAmount )
{
    
message_begin MSG_ONEg_msgAmmoPickup_Player )
    
write_byte AmmoID )
    
write_byte AmmoAmount )
    
message_end ( )
}

stock get_speed_vector(const Float:origin1[3],const Float:origin2[3],Float:speedFloat:new_velocity[3])
{
    
new_velocity[0] = origin2[0] - origin1[0]
    
new_velocity[1] = origin2[1] - origin1[1]
    
new_velocity[2] = origin2[2] - origin1[2]
    new 
Float:num floatsqroot(speed*speed /  (new_velocity[0]*new_velocity[0] + new_velocity[1]*new_velocity[1] +  new_velocity[2]*new_velocity[2]))
    
new_velocity[0] *= num
    new_velocity
[1] *= num
    new_velocity
[2] *= num
    
    
return 1;

All respawn zombie will have the knock bomb automatically.

2. [ZP] Extra Item: Knockback Bomb

However, if you want to make the knock bomb as an extra item, just use this PHP (the original thread, here):
PHP Code:
#include < amxmodx >
#include < cstrike >
#include < engine >
#include < fakemeta >
#include < fun >
#include < hamsandwich >
#include < zombieplague >

#define Plugin    "[ZP] Knockback Bomb"
#define Version   "1.0"
#define Author    "0"

// === Customization starts below! ===
new const g_PlayerModel [ ] = "models/zombie_plague/p_grenade_knock.mdl"
new const g_ViewModel [ ] = "models/zombie_plague/v_grenade_knockback.mdl"
new const g_WorldModel [ ] = "models/zombie_plague/w_grenade_knock.mdl"

// You can add more than 1 sound!
new const g_SoundGrenadeBuy [ ] [ ] = { "items/gunpickup2.wav" }
new const 
g_SoundAmmoPurchase [ ] [ ] = { "items/9mmclip1.wav" }
new const 
g_SoundBombExplode [ ] [ ] = { "zombie_plague/grenade_infect.wav" }

new const 
g_szItemName [ ] = "Knockback Bomb" 
new const g_iItemPrice 7  

#define MAXCARRY    4 // How many grenades 1 player can hold at the same time
#define RADIUS        300.0 // Affect radius
// === Customization ends above! ===

#define MAXPLAYERS        32
#define pev_nade_type        pev_flTimeStepSound
#define NADE_TYPE_JUMPING    26517
#define AMMOID_SM        13

new g_iExplo

new g_iNadeID

new g_iJumpingNadeCount MAXPLAYERS+]
new 
g_iCurrentWeapon MAXPLAYERS+]

new 
cvar_speed

new g_MaxPlayers
new g_msgAmmoPickup

public plugin_precache ( )
{
    
precache_model g_PlayerModel )
    
precache_model g_ViewModel )
    
precache_model g_WorldModel )
    
    new 
i
    
for ( 0sizeof g_SoundGrenadeBuyi++ )
        
precache_sound g_SoundGrenadeBuy ] )
    for ( 
0sizeof g_SoundAmmoPurchasei++ )
        
precache_sound g_SoundAmmoPurchase ] )
    for ( 
0sizeof g_SoundBombExplodei++ )
        
precache_sound g_SoundBombExplode ] )
    
    
g_iExplo precache_model "sprites/xfire.spr" )
}

public 
plugin_init ( )
{
    
register_plugin PluginVersionAuthor )
    
    
g_iNadeID zp_register_extra_item g_szItemNameg_iItemPriceZP_TEAM_ZOMBIE )    

    
register_event "CurWeapon""EV_CurWeapon""be""1=1" )
    
register_event "HLTV""EV_NewRound""a""1=0""2=0" )
    
register_event "DeathMsg""EV_DeathMsg""a" )
    
    
register_forward FM_SetModel"fw_SetModel" )
    
RegisterHam Ham_Think"grenade""fw_ThinkGrenade" )
    
    
cvar_speed register_cvar "zp_zombiebomb_knockback""800" )
    
    
g_msgAmmoPickup get_user_msgid "AmmoPickup" )
    
    
g_MaxPlayers get_maxplayers ( )
}

public 
client_connect Player )
{
    
g_iJumpingNadeCount Player ] = 0
}

public 
zp_extra_item_selected idItem )
{
   if ( 
Item == g_iNadeID )
   {
    if ( 
g_iJumpingNadeCount id ] >= MAXCARRY )
    {
         
client_print idprint_chat"[ZP] Cannot hold mode grenades!" )
         return 
ZP_PLUGIN_HANDLED
      
}
          
      new 
iBpAmmo cs_get_user_bpammo idCSW_SMOKEGRENADE )
          
      if ( 
g_iJumpingNadeCount id ] >= )
      {
         
cs_set_user_bpammo idCSW_SMOKEGRENADEiBpAmmo+)
             
         
emit_sound idCHAN_ITEMg_SoundAmmoPurchase[random_num(0,  sizeof g_SoundAmmoPurchase-1)], VOL_NORMATTN_NORM0PITCH_NORM )
             
         
AmmoPickup idAMMOID_SM)
             
         
g_iJumpingNadeCount id ]++
      }
      else
      {
         
give_item id"weapon_smokegrenade" )
             
         
emit_sound idCHAN_ITEMg_SoundGrenadeBuy[random_num(0,  sizeof g_SoundGrenadeBuy-1)], VOL_NORMATTN_NORM0PITCH_NORM )
             
         
AmmoPickup idAMMOID_SM)
             
         
g_iJumpingNadeCount id ] = 1
      
}
  }
  return 
PLUGIN_CONTINUE
}

public 
zp_user_infected_post PlayerInfectorNemesis )
{
    
g_iJumpingNadeCount Player ] = 0        
}

public 
zp_user_humanized_post PlayerSurvivor )
{
    if ( 
Survivor )
    {
        
g_iJumpingNadeCount Survivor ] = 0
    
}
}

public 
EV_CurWeapon Player )
{
    if ( !
is_user_alive Player ) || !zp_get_user_zombie Player ) )
        return 
PLUGIN_CONTINUE
    
    g_iCurrentWeapon 
Player ] = read_data )
    
    if ( 
g_iJumpingNadeCount Player ] > && g_iCurrentWeapon Player ] == CSW_SMOKEGRENADE )
    {
        
set_pev Playerpev_viewmodel2g_ViewModel )
        
set_pev Playerpev_weaponmodel2g_WorldModel )
    }
    
    return 
PLUGIN_CONTINUE
}

public 
EV_NewRound ( )
{
    
arrayset g_iJumpingNadeCount033 )
}

public 
EV_DeathMsg ( )
{
    new 
iVictim read_data )
    
    if ( !
is_user_connected iVictim ) )
        return
    
    
g_iJumpingNadeCount iVictim ] = 0
}

public 
fw_SetModel Entity, const Model [ ] )
{
    if ( 
Entity )
        return 
FMRES_IGNORED
    
    
if ( pev Entitypev_dmgtime ) == 0.0 )
        return 
FMRES_IGNORED
    
    
new iOwner entity_get_edict EntityEV_ENT_owner )    
    
    if ( 
g_iJumpingNadeCount iOwner ] >= && equal Model ], "w_sm") )
    {
        
// Reset any other nade
        
set_pev Entitypev_nade_type)
        
        
set_pev Entitypev_nade_typeNADE_TYPE_JUMPING )
        
        
g_iJumpingNadeCount iOwner ]--
        
        
entity_set_model Entityg_WorldModel )
        return 
FMRES_SUPERCEDE
    
}
    return 
FMRES_IGNORED
}

public 
fw_ThinkGrenade Entity )
{
    if ( !
pev_valid Entity ) )
        return 
HAM_IGNORED
    
    
static Float:dmg_time
    pev 
Entitypev_dmgtimedmg_time )
    
    if ( 
dmg_time get_gametime ( ) )
        return 
HAM_IGNORED
    
    
if ( pev Entitypev_nade_type ) == NADE_TYPE_JUMPING )
    {
        
jumping_explode Entity )
        return 
HAM_SUPERCEDE
    
}
    return 
HAM_IGNORED
}

public 
jumping_explode Entity )
{
    if ( 
Entity )
        return
    
    static 
Float:flOrigin ]
    
pev Entitypev_originflOrigin )
    
    
engfunc EngFunc_MessageBeginMSG_PVSSVC_TEMPENTITYflOrigin)
    
write_byte TE_SPRITE 
    
engfunc EngFunc_WriteCoordflOrigin ] )
    
engfunc EngFunc_WriteCoordflOrigin ] )
    
engfunc EngFunc_WriteCoordflOrigin ] + 45.0 )
    
write_short g_iExplo )
    
write_byte 35 )
    
write_byte 186 )
    
message_end ( )
    
    new 
iOwner entity_get_edict EntityEV_ENT_owner )
    
    
emit_sound EntityCHAN_WEAPONg_SoundBombExplode[random_num(0,  sizeof g_SoundBombExplode-1)], VOL_NORMATTN_NORM0PITCH_NORM )
    
    for ( new 
1g_MaxPlayersi++ )
    {
        if ( !
is_user_alive  ) )
            continue
       

        
        
// Debug!
        //client_print ( iOwner, print_chat, "Owner of Smoke Grenade!" )    
        
        
new Float:flVictimOrigin ]
        
pev ipev_originflVictimOrigin )
        
        new 
Float:flDistance get_distance_f flOriginflVictimOrigin )    
        
        if ( 
flDistance <= RADIUS )
        {
            static 
Float:flSpeed
            flSpeed 
get_pcvar_float cvar_speed )
            
            static 
Float:flNewSpeed
            flNewSpeed 
flSpeed * ( 1.0 - ( flDistance RADIUS ) )
            
            static 
Float:flVelocity ]
            
get_speed_vector flOriginflVictimOriginflNewSpeedflVelocity )
            
            
set_pev ipev_velocity,flVelocity )
        }
    }
    
    
engfunc EngFunc_RemoveEntityEntity )
}        

public 
AmmoPickup PlayerAmmoIDAmmoAmount )
{
    
message_begin MSG_ONEg_msgAmmoPickup_Player )
    
write_byte AmmoID )
    
write_byte AmmoAmount )
    
message_end ( )
}

stock get_speed_vector(const Float:origin1[3],const Float:origin2[3],Float:speedFloat:new_velocity[3])
{
    
new_velocity[0] = origin2[0] - origin1[0]
    
new_velocity[1] = origin2[1] - origin1[1]
    
new_velocity[2] = origin2[2] - origin1[2]
    new 
Float:num floatsqroot(speed*speed /  (new_velocity[0]*new_velocity[0] + new_velocity[1]*new_velocity[1] +  new_velocity[2]*new_velocity[2]))
    
new_velocity[0] *= num
    new_velocity
[1] *= num
    new_velocity
[2] *= num
    
    
return 1;

If you want to change the cost, just find this:
Quote:
new const g_iItemPrice = 7
This plugin is working in ZP 5.0.5 and ZPA 1.6.1 but I'm not sure whether it will working in ZP 4.3 (I have tested it).

Quote:
zp_knockback_bomb.sma is for addon.
zp_extra_knockback_bomb.sma is for extra items.
Please download the model, below.
Attached Files
File Type: zip models.zip (349.9 KB, 1193 views)
File Type: sma Get Plugin or Get Source (zp_extra_knockback_bomb.sma - 1999 views - 8.1 KB)
File Type: sma Get Plugin or Get Source (zp_knockback_bomb.sma - 1749 views - 7.1 KB)

Last edited by zmd94; 06-14-2014 at 13:15.
zmd94 is offline
ArabicMan
Veteran Member
Join Date: Feb 2014
Location: مصر
Old 06-14-2014 , 12:37   Re: [ZP] Addon + Extra Item: Knockback Bomb
Reply With Quote #2

Good job but what addon do and extra item do also?
ArabicMan is offline
zmd94
Veteran Member
Join Date: Nov 2013
Location: Malaysia (9w2zow).
Old 06-14-2014 , 13:10   Re: [ZP] Addon + Extra Item: Knockback Bomb
Reply With Quote #3

Quote:
Good job but what addon do and extra item do also?
Yes, it right. However the different is when you use the knockback bomb as an addon, you will only have it once after you respawn as a zombie. After you throw the bomb, you cannot have it anymore.

If you choose it to be as an extra item, you can have an option to buy it more than one and throw it to anyone as many as you want.


Last edited by zmd94; 06-14-2014 at 13:15.
zmd94 is offline
ArabicMan
Veteran Member
Join Date: Feb 2014
Location: مصر
Old 06-14-2014 , 22:46   Re: [ZP] Addon + Extra Item: Knockback Bomb
Reply With Quote #4

Quote:
Originally Posted by zmd94 View Post
Yes, it right. However the different is when you use the knockback bomb as an addon, you will only have it once after you respawn as a zombie. After you throw the bomb, you cannot have it anymore.

If you choose it to be as an extra item, you can have an option to buy it more than one and throw it to anyone as many as you want.

Nice bomb thanks for sharing it.
ArabicMan is offline
Just4Games
Senior Member
Join Date: Jan 2013
Location: Romania
Old 06-26-2014 , 13:33   Re: [ZP] Addon + Extra Item: Knockback Bomb
Reply With Quote #5

Using it as an extra item on zpa 1.6.1 and i get 3 errors when i try to compile:
PHP Code:
WarningLoose indentation on line 99
Warning
Loose indentation on line 122
Warning
Symbol is assigned a value that is never used"iOwner" on line 266 

Last edited by Just4Games; 06-26-2014 at 13:34.
Just4Games is offline
zmd94
Veteran Member
Join Date: Nov 2013
Location: Malaysia (9w2zow).
Old 06-26-2014 , 21:09   Re: [ZP] Addon + Extra Item: Knockback Bomb
Reply With Quote #6

PHP Code:
WarningLoose indentation on line 99
Warning
Loose indentation on line 122
Warning
Symbol is assigned a value that is never used"iOwner" on line 266 
Nevermind, the error will not affect the game. Just ignore it. Loose indentation only happen when the code is not set up into "paragraphs" correctly. It is not an error; it is just a warning.

The most important is the extra item still can be used and working as it should.

Last edited by zmd94; 06-27-2014 at 07:33.
zmd94 is offline
Just4Games
Senior Member
Join Date: Jan 2013
Location: Romania
Old 06-27-2014 , 07:08   Re: [ZP] Addon + Extra Item: Knockback Bomb
Reply With Quote #7

Well it doesn't work, it's just a simple smoke grenade not a knockback bomb.
Just4Games is offline
zmd94
Veteran Member
Join Date: Nov 2013
Location: Malaysia (9w2zow).
Old 06-27-2014 , 07:28   Re: [ZP] Addon + Extra Item: Knockback Bomb
Reply With Quote #8

I'm not sure why. I'm using it in my server and it is working well. Please post your error or try to reinstall. If this step do not solve your problems. maybe you should do this:
Quote:
Please disable and enable one by one your plugin in plugins-zplague.ini
Maybe there are some plugin that caused the problem especially other grenade plugin.

Last edited by zmd94; 06-27-2014 at 07:32.
zmd94 is offline
Just4Games
Senior Member
Join Date: Jan 2013
Location: Romania
Old 06-27-2014 , 08:09   Re: [ZP] Addon + Extra Item: Knockback Bomb
Reply With Quote #9

Other grenade plugin i'm using is NadeModes because i don't use LaserMines
Just4Games is offline
zmd94
Veteran Member
Join Date: Nov 2013
Location: Malaysia (9w2zow).
Old 06-27-2014 , 12:45   Re: [ZP] Addon + Extra Item: Knockback Bomb
Reply With Quote #10

@ Just4Games. Have you tried the to disable the nade modes plugin?

After that, if the knockback bomb is working, this indicated that the nade modes plugin that you used have a problem. I recommend you to use this nade mode:
If the problem still the same. Please post your plugins-zplague.ini file.

Last edited by zmd94; 06-27-2014 at 19:31.
zmd94 is offline
Reply


Thread Tools
Display Modes

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 20:48.


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