// Bomberman! - From the NES :)
/* CVARS - copy and paste to shconfig.cfg
//Bomberman
bomberman_level 0
bomberman_cooldown 5 //Cooldown time from bomb explostion until new planting
bomberman_bombs 1 //How Many Bombs does he start with (def=1)
bomberman_bpl 0 //How Many More Bombs Does he get each level (def=0)
bomberman_radius 400 //Radius of damage (def=400)
bomberman_maxdamage 100 //Maximum Damage to deal (def=100)
*/
//Thanks to TheLooser & Demonic_Frost for help testing
#include <superheromod>
// GLOBAL VARIABLES
new gHeroID
new const gHeroName[] = "Bomberman"
new bool:gHasBomberman[SH_MAXSLOTS+1]
new gBombEntity[SH_MAXSLOTS+1]
new gBombAmmo[SH_MAXSLOTS+1]
new const gSoundBombPlant[] = "weapons/c4_plant.wav"
new gBombModel[32] = "models/shmod/bomberman_bomb.mdl"
new gSpriteSmoke, gSpriteWhite, gSpriteFire, gSpriteExplode
new gPcvarLevel, gPcvarCooldown, gPcvarBombs
new gPcvarBPL, gPcvarRadius, gPcvarMaxDamage
//----------------------------------------------------------------------------------------------
public plugin_init()
{
// Plugin Info
register_plugin("SUPERHERO Bomberman", SH_VERSION_STR, "AssKicR")
register_dictionary("sh_bomberman.txt")
// DO NOT EDIT THIS FILE TO CHANGE CVARS, USE THE SHCONFIG.CFG
gPcvarLevel = register_cvar("bomberman_level", "0")
gPcvarCooldown = register_cvar("bomberman_cooldown", "5")
gPcvarBombs = register_cvar("bomberman_bombs", "1")
gPcvarBPL = register_cvar("bomberman_bpl", "0")
gPcvarRadius = register_cvar("bomberman_radius", "400")
gPcvarMaxDamage = register_cvar("bomberman_maxdamage", "100")
// FIRE THE EVENTS TO CREATE THIS SUPERHERO!
gHeroID = sh_create_hero(gHeroName, gPcvarLevel)
sh_set_hero_info(gHeroID, "Remote Bombs", "Press +power button to plant, and again to detonate")
sh_set_hero_bind(gHeroID)
}
//----------------------------------------------------------------------------------------------
public plugin_precache()
{
// What Skin Is The Bomb Gonna Have
if ( !file_exists(gBombModel) ) {
copy(gBombModel, charsmax(gBombModel), "models/w_c4.mdl")
}
precache_model(gBombModel)
precache_sound(gSoundBombPlant)
gSpriteExplode = precache_model("sprites/zerogxplode.spr")
gSpriteSmoke = precache_model("sprites/steam1.spr")
gSpriteWhite = precache_model("sprites/white.spr")
gSpriteFire = precache_model("sprites/explode1.spr")
}
//----------------------------------------------------------------------------------------------
public sh_hero_init(id, heroID, mode)
{
if ( gHeroID != heroID ) return
switch(mode) {
case SH_HERO_ADD: {
gHasBomberman[id] = true
bomberman_newsetup(id)
}
case SH_HERO_DROP: {
gHasBomberman[id] = false
}
}
sh_debug_message(id, 1, "%s %s", gHeroName, mode ? "ADDED" : "DROPPED")
}
//----------------------------------------------------------------------------------------------
public sh_client_spawn(id)
{
bomberman_newsetup(id)
}
//----------------------------------------------------------------------------------------------
bomberman_newsetup(id)
{
gPlayerInCooldown[id] = false
if ( !gHasBomberman[id] ) return
new bombent = gBombEntity[id]
if ( pev_valid(bombent) ) {
engfunc(EngFunc_RemoveEntity, bombent)
}
gBombEntity[id] = 0
new bombsPerLvl = get_pcvar_num(gPcvarBPL)
if ( bombsPerLvl > 0 ) {
//new bombs=((level he is - level he must be) * bombs per level) + starting bombs
new bombs = ((sh_get_user_lvl(id)-get_pcvar_num(gPcvarLevel)) * bombsPerLvl + get_pcvar_num(gPcvarBombs))
if ( bombs > 0 ) {
gBombAmmo[id] = bombs
}
else if ( bombs == 0 ) {
gBombAmmo[id] = 1
}
else {
gBombAmmo[id] = 0
}
}
else {
gBombAmmo[id] = get_pcvar_num(gPcvarBombs)
}
}
//----------------------------------------------------------------------------------------------
// RESPOND TO KEYDOWN
public sh_hero_key(id, heroID, key)
{
if ( gHeroID != heroID || sh_is_freezetime() ) return
if ( !is_user_alive(id) || !gHasBomberman[id] ) return
if ( key == SH_KEYDOWN ) {
if ( gBombEntity[id] > 0 ) {
explode_bomb(id)
}
else {
plant_bomb(id)
}
}
}
//----------------------------------------------------------------------------------------------
plant_bomb(id)
{
if ( gBombEntity[id] > 0 ) return
if ( gBombAmmo[id] == 0 ) {
sh_sound_deny(id)
client_print(id, print_center, "[SH] %L", LANG_PLAYER, "SH_BOMBERMAN_YH")
return
}
if ( gPlayerInCooldown[id]) {
sh_sound_deny(id)
return
}
new bombent
gBombEntity[id] = bombent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"))
if ( !pev_valid(bombent) ) {
gBombEntity[id] = 0
return
}
set_pev(bombent, pev_classname, "remote_bomb")
engfunc(EngFunc_SetModel, bombent, gBombModel)
new Float:PlayerOrigin[3]
pev(id, pev_origin, PlayerOrigin)
engfunc(EngFunc_SetSize, bombent, Float:{-4.0, -4.0, 2.0}, Float:{4.0, 4.0, 10.0})
engfunc(EngFunc_SetOrigin, bombent, PlayerOrigin)
set_pev(bombent, pev_solid, SOLID_NOT) //Maybe change this to SOLID_BBOX later
set_pev(bombent, pev_movetype, MOVETYPE_TOSS)
set_pev(bombent, pev_owner, id)
emit_sound(bombent, CHAN_WEAPON, gSoundBombPlant, VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
gBombAmmo[id]--
client_print(id, print_center, "[SH] %L", LANG_PLAYER, "SH_BOMBERMAN_BP", gBombAmmo[id], gBombAmmo[id] == 1 ? "" : "s")
}
//----------------------------------------------------------------------------------------------
explode_bomb(id)
{
new bombent = gBombEntity[id]
if ( pev_valid(bombent) ) {
sh_set_cooldown(id, get_pcvar_float(gPcvarCooldown))
new Float:explodeAt[3]
pev(bombent, pev_origin, explodeAt)
blow_up(id, explodeAt)
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_EXPLOSION)
engfunc(EngFunc_WriteCoord, explodeAt[0])
engfunc(EngFunc_WriteCoord, explodeAt[1])
engfunc(EngFunc_WriteCoord, explodeAt[2])
write_short(gSpriteExplode)
write_byte(50)
write_byte(15)
write_byte(0)
message_end()
engfunc(EngFunc_RemoveEntity, bombent)
}
gBombEntity[id] = 0
}
//----------------------------------------------------------------------------------------------
blow_up(id, Float:explodeAt[3])
{
new Float:dRatio, damage, Float:distanceBetween
new Float:dmgRadius = get_pcvar_float(gPcvarRadius)
new maxDamage = get_pcvar_num(gPcvarMaxDamage)
new bool:FFOn = sh_friendlyfire_on()
new CsTeams:idTeam = cs_get_user_team(id)
// blowup
explode(explodeAt)
new players[SH_MAXSLOTS], playerCount, player
new Float:playerOrigin[3]
get_players(players, playerCount, "ah")
for ( new i = 0; i < playerCount; i++ ) {
player = players[i]
pev(player, pev_origin, playerOrigin)
distanceBetween = vector_distance(explodeAt, playerOrigin)
if ( distanceBetween <= dmgRadius ) {
if ( FFOn || player == id || idTeam != cs_get_user_team(player) ) {
dRatio = distanceBetween / dmgRadius
damage = maxDamage - floatround(maxDamage * dRatio)
if ( !damage ) damage = 1 // Incase damage cvar is really low cause something if within the radius
sh_extra_damage(player, id, damage, "bomberman bomb", _, SH_DMG_NORM, true, _, explodeAt)
}
// Add some push and shake effects instead of dmgStun later, and cause it on everyone within radius
}
}
}
//----------------------------------------------------------------------------------------------
explode(Float:explodeAt[3])
{
// Raise the effects up a bit
explodeAt[2] += 37.0
// blast circles
engfunc(EngFunc_MessageBegin, MSG_BROADCAST, SVC_TEMPENTITY, explodeAt, 0)
write_byte(TE_BEAMCYLINDER) // 21
engfunc(EngFunc_WriteCoord, explodeAt[0])
engfunc(EngFunc_WriteCoord, explodeAt[1])
engfunc(EngFunc_WriteCoord, explodeAt[2] + 16.0)
engfunc(EngFunc_WriteCoord, explodeAt[0])
engfunc(EngFunc_WriteCoord, explodeAt[1])
engfunc(EngFunc_WriteCoord, explodeAt[2] + 1936.0)
write_short(gSpriteWhite)
write_byte(0) // startframe
write_byte(0) // framerate
write_byte(2) // life
write_byte(20) // width
write_byte(0) // noise
write_byte(188) // r
write_byte(220) // g
write_byte(255) // b
write_byte(255) // brightness
write_byte(0) // speed
message_end()
//Explosion2
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_EXPLOSION2) // 12
engfunc(EngFunc_WriteCoord, explodeAt[0])
engfunc(EngFunc_WriteCoord, explodeAt[1])
engfunc(EngFunc_WriteCoord, explodeAt[2])
write_byte(188) // scale in 0.1's
write_byte(10) // framerate
message_end()
//TE_Explosion
engfunc(EngFunc_MessageBegin, MSG_BROADCAST, SVC_TEMPENTITY, explodeAt, 0)
write_byte(TE_EXPLOSION) // 3
engfunc(EngFunc_WriteCoord, explodeAt[0])
engfunc(EngFunc_WriteCoord, explodeAt[1])
engfunc(EngFunc_WriteCoord, explodeAt[2])
write_short(gSpriteFire)
write_byte(60) // scale in 0.1's
write_byte(10) // framerate
write_byte(0) // flags
message_end()
//Smoke
engfunc(EngFunc_MessageBegin, MSG_BROADCAST, SVC_TEMPENTITY, explodeAt, 0)
write_byte(TE_SMOKE) // 5
engfunc(EngFunc_WriteCoord, explodeAt[0])
engfunc(EngFunc_WriteCoord, explodeAt[1])
engfunc(EngFunc_WriteCoord, explodeAt[2])
write_short(gSpriteSmoke)
write_byte(10) // scale in 0.1's
write_byte(10) // framerate
message_end()
}
//----------------------------------------------------------------------------------------------
public client_connect(id)
{
new bombent = gBombEntity[id]
if ( pev_valid(bombent) ) {
engfunc(EngFunc_RemoveEntity, bombent)
}
gBombEntity[id] = 0
gPlayerInCooldown[id] = false
gHasBomberman[id] = false
}
//----------------------------------------------------------------------------------------------
public client_disconnected(id)
{
new bombent = gBombEntity[id]
if ( pev_valid(bombent) ) {
engfunc(EngFunc_RemoveEntity, bombent)
}
gBombEntity[id] = 0
gPlayerInCooldown[id] = false
gHasBomberman[id] = false
}
//----------------------------------------------------------------------------------------------