
Рассмотрим на базовом варианте плагина NPC AlienBoss от Alexander 3
Почему именно на нём? Да потому что это самый лучший из всех других альтернатив.
Не считая платных конечно.
Рассмотрим на базовом варианте плагина NPC AlienBoss от Alexander 3
Почему именно на нём? Да потому что это самый лучший из всех других альтернатив.
Не считая платных конечно.
Перед декомпилированием модели и зашивания в неё звуков, отредактируем сначала базовый исходник.
Собственно вот что у нас тут:
#include
#include
#include
#include
#define NAME \”AlienBoss Special For zombie-mod.com\”
#define VERSION \”Public\”
#define AUTHOR \”Alexander.3\”
const alien_hp = 25000
const boss_speed = 200
const Float:prepare_time = 15.0
const dmg_attack = 50
const dmg_ms = 50
const dmg_sw = 50
static Float:Origin[3]
static g_Alien
static g_BossTarget
static VictimID
static Float:g_Health
static Ability
new const Resource[][] = {
\”models/npc/alien/alien.mdl\”,
\”sprites/blood.spr\”,
\”sprites/bloodspray.spr\”,
\”sprites/npc/hp.spr\”,
\”sprites/shockwave.spr\”, // 4
\”sprites/npc/alien/fluxing.spr\” // 5
}
static g_Resource[sizeof Resource]
enum {
IDLE,
WALK,
MS,
ATTACK,
SW
}
public plugin_init() {
register_plugin(NAME, VERSION, AUTHOR)
register_clcmd(\”say /create\”, \”create\”)
register_clcmd(\”say /spawn\”, \”spawn\”)
register_think(\”AlienBossik\”, \”Think_Boss\”)
register_think(\”HP\”, \”Think_HP\”)
register_touch(\”AlienBossik\”, \”player\”, \”Touch_Boss\”)
RegisterHam(Ham_TakeDamage, \”info_target\”, \”TakeDamage\”)
RegisterHam(Ham_TraceAttack, \”info_target\”, \”TraceAttack\”)
}
public RandomAbility(taskid) {
if (Ability != WALK)
return
switch(random(2)) {
case 0: Ability = MS
case 1: Ability = SW
}
}
public create(id)
pev(id, pev_origin, Origin)
public spawn() {
g_Alien = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, \”info_target\”))
new HPspr = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, \”info_target\”))
engfunc(EngFunc_SetModel, g_Alien, Resource[0])
engfunc(EngFunc_SetSize, g_Alien, { -32.0, -32.0, -36.0 }, { 32.0, 32.0, 96.0 })
engfunc(EngFunc_SetOrigin, g_Alien, Origin)
set_pev(g_Alien, pev_classname, \”AlienBossik\”)
set_pev(g_Alien, pev_solid, SOLID_BBOX)
set_pev(g_Alien, pev_movetype, MOVETYPE_PUSHSTEP)
set_pev(g_Alien, pev_takedamage, DAMAGE_NO)
set_pev(g_Alien, pev_health, float(alien_hp))
set_pev(g_Alien, pev_deadflag, DEAD_NO)
set_pev(g_Alien, pev_nextthink, get_gametime() + prepare_time)
Ability = IDLE
Anim(g_Alien, 2)
static Float:Origin[3]
pev(g_Alien, pev_origin, Origin)
Origin[2] += 200.0
engfunc(EngFunc_SetOrigin, HPspr, Origin)
engfunc(EngFunc_SetModel, HPspr, Resource[3])
entity_set_float(HPspr, EV_FL_scale, 0.5)
set_pev(HPspr, pev_classname, \”HP\”)
set_pev(HPspr, pev_solid, SOLID_NOT)
set_pev(HPspr, pev_movetype, MOVETYPE_NOCLIP)
set_pev(HPspr, pev_frame, 100.0)
set_pev(HPspr, pev_nextthink, get_gametime() + prepare_time)
}
public Think_Boss(Ent) {
if (pev(Ent, pev_deadflag) == DEAD_DYING)
return
static bool:one
switch ( Ability ) {
case IDLE: {
Ability = WALK
set_task(10.0, \”RandomAbility\”, 1337, _, _, \”b\”)
set_pev(Ent, pev_nextthink, get_gametime() + 0.1)
return
}
case WALK: {
static Float:Origin[3], Float:Origin2[3], Float:Vector[3], Float:Angle[3]
if (!is_user_alive(g_BossTarget)) {
g_BossTarget = GetRandomAlive(random_num(1, GetAliveCount()))
set_pev(Ent, pev_nextthink, get_gametime() + 0.1)
return
}
if (one) {
set_pev(Ent, pev_movetype, MOVETYPE_PUSHSTEP)
Anim(Ent, 3)
one = false
}
pev(Ent, pev_origin, Origin)
pev(g_BossTarget, pev_origin, Origin2)
xs_vec_sub(Origin2, Origin, Vector)
vector_to_angle(Vector, Angle)
new Float:num = floatsqroot(float(boss_speed)*float(boss_speed) / (Vector[0]*Vector[0] + Vector[1]*Vector[1] + Vector[2]*Vector[2]))
Vector[0] *= num
Vector[1] *= num
Vector[2] ? (Vector[2] = 0.0) : (Vector[2] *= num)
set_pev(Ent, pev_velocity, Vector)
Angle[0] = 0.0
Angle[2] = 0.0
set_pev(Ent, pev_angles, Angle)
set_pev(Ent, pev_nextthink, get_gametime() + 0.1)
return
}
case ATTACK: {
static num
switch (num) {
case 0: {
Anim(Ent, 6)
num++
set_pev(Ent, pev_nextthink, get_gametime() + 1.0)
return
}
case 1: {
static Float:OriginA[3], Float:OriginA2[3], Float:LenA, Float:Vector[3], Float:Velocity[3]
pev(g_Alien, pev_origin, OriginA)
pev(VictimID, pev_origin, OriginA2)
xs_vec_sub(OriginA2, OriginA, Velocity)
xs_vec_sub(OriginA, OriginA2, Vector)
LenA = xs_vec_len(Vector)
if (LenA <= 170) {
xs_vec_normalize(Velocity, Velocity)
Velocity[2] = 0.5
xs_vec_mul_scalar(Velocity, 1000.0, Velocity)
ExecuteHamB(Ham_TakeDamage, VictimID, 0, VictimID, float(dmg_attack), DMG_BULLET)
ScreenFade(VictimID, 3, {255, 0, 0}, 120)
ScreenShake(VictimID)
set_pev(VictimID, pev_velocity, Velocity)
}
}
}
num = 0
one = true
Ability = WALK
set_pev(Ent, pev_nextthink, get_gametime() + 0.2)
}
case MS: {
static num, Float:Origin[3], Float:Origin2[3], Float:Vector[3], Float:Angle[3]
switch ( num ) {
case 0: {
new MS_Attack = GetRandomAlive(random_num(1, GetAliveCount()))
pev(MS_Attack, pev_origin, Origin)
pev(Ent, pev_origin, Origin2)
xs_vec_sub(Origin, Origin2, Vector)
vector_to_angle(Vector, Angle)
xs_vec_normalize(Vector, Vector)
xs_vec_mul_scalar(Vector, 2000.0, Vector)
Angle[0] = 0.0
Angle[2] = 0.0
Vector[2] = 0.0
set_pev(Ent, pev_angles, Angle)
set_pev(Ent, pev_movetype, MOVETYPE_NONE)
Anim(Ent, 7)
set_pev(Ent, pev_nextthink, get_gametime() + 1.0)
num++
return
}
case 1: {
set_pev(Ent, pev_movetype, MOVETYPE_FLY)
set_pev(Ent, pev_velocity, Vector)
set_pev(Ent, pev_nextthink, get_gametime() + 1.0)
num++
return
}
}
set_pev(Ent, pev_nextthink, get_gametime() + 0.1)
num = 0
Ability = WALK
one = true
return
}
case SW: {
static num, FluxSpr, Float:Origin[3], sw_random
switch ( num ) {
case 0: {
sw_random = random(3)
Anim(Ent, 2)
FluxSpr = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, \”env_sprite\”))
pev(Ent, pev_origin, Origin)
Origin[2] += 70
engfunc(EngFunc_SetOrigin, FluxSpr, Origin)
engfunc(EngFunc_SetModel, FluxSpr, Resource[5])
set_pev(FluxSpr, pev_solid, SOLID_NOT)
set_pev(FluxSpr, pev_movetype, MOVETYPE_NOCLIP)
switch(sw_random) {
case 0: {
set_rendering(FluxSpr, kRenderFxFadeSlow, 255, 0, 0, kRenderTransAdd, 255)
set_rendering(Ent, kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 30)
}
case 1: {
set_rendering(FluxSpr, kRenderFxFadeSlow, 255, 255, 0, kRenderTransAdd, 255)
set_rendering(Ent, kRenderFxGlowShell, 255, 255, 0, kRenderNormal, 30)
}
case 2: {
set_rendering(FluxSpr, kRenderFxFadeSlow, 0, 0, 255, kRenderTransAdd, 255)
set_rendering(Ent, kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 30)
}
}
set_pev(FluxSpr, pev_framerate, 5.0)
dllfunc(DLLFunc_Spawn, FluxSpr)
set_pev(Ent, pev_nextthink, get_gametime() + 0.1)
num++
return
}
case 1..10: {
for(new id = 1; id <= get_maxplayers(); id++) {
if (!is_user_alive(id))
continue
static Float:OriginSW[3], Float:OriginSW2[3], Float:Vector[3]
pev(Ent, pev_origin, OriginSW)
pev(id, pev_origin, OriginSW2)
xs_vec_sub(OriginSW, OriginSW2, Vector)
xs_vec_normalize(Vector, Vector)
xs_vec_mul_scalar(Vector, 800.0, Vector)
set_pev(id, pev_velocity, Vector)
set_pev(Ent, pev_nextthink, get_gametime() + 0.2)
num++
return
}
}
case 11: {
engfunc(EngFunc_RemoveEntity, FluxSpr)
Anim(Ent, 5)
set_pev(Ent, pev_nextthink, get_gametime() + 2.2)
num++
return
}
case 12: {
static Float:Orig[3]
pev(Ent, pev_origin, Orig)
set_rendering(Ent)
switch (sw_random) {
case 0: ShockWave(Orig, 5, 35, 1000.0, {255, 0, 0}) // 450
case 1: ShockWave(Orig, 5, 35, 1000.0, {255, 255, 0})
case 2: ShockWave(Orig, 5, 35, 1000.0, {0, 0, 255})
}
for(new id = 1; id <= get_maxplayers(); id++) {
if (!is_user_alive(id))
continue
if (pev(id, pev_flags) & FL_ONGROUND) {
static Float:gOrigin[3], Float:Vec[3], Float:Len
pev(id, pev_origin, gOrigin)
xs_vec_sub(Orig, gOrigin, Vec)
Len = xs_vec_len(Vec)
if (Len <= 450.0) {
switch (sw_random) {
case 0: user_kill(id)
case 1: {
ScreenFade(id, 5, {255, 0, 0}, 120)
ExecuteHamB(Ham_TakeDamage, id, 0, id, float(dmg_sw), DMG_SONIC)
ScreenShake(id)
}
case 2: {
client_cmd(id, \”drop\”)
ScreenShake(id)
}
}
}
}
}
Ability = WALK
one = true
num = 0
set_pev(Ent, pev_nextthink, get_gametime() + 0.2)
return
}
}
}
}
}
public Think_HP(Ent) {
static Float:Origin[3], num
pev(g_Alien, pev_origin, Origin)
Origin[2] += 200.0
set_pev(Ent, pev_origin, Origin)
switch ( num ) {
case 0: {
Anim(g_Alien, 3)
set_pev(g_Alien, pev_takedamage, DAMAGE_YES)
num++
}
case 1: {
static Float:frame
frame = g_Health * 100.0 / float(alien_hp)
if (frame)
set_pev(Ent, pev_frame, frame)
if (pev(g_Alien, pev_deadflag) == DEAD_DYING) {
engfunc(EngFunc_RemoveEntity, Ent)
return
}
}
}
set_pev(Ent, pev_nextthink, get_gametime() + 0.1)
}
public TraceAttack(victim, attacker, Float:damage, Float:direction[3], th, dt) {
static Float:End[3], ClassName[32]
pev(victim, pev_classname, ClassName, charsmax(ClassName))
if (equal(ClassName, \”AlienBossik\”)) {
get_tr2(th, TR_vecEndPos, End)
Blood(End)
}
}
public TakeDamage(victim, weapon, attacker, Float:damage, damagetype) {
static ClassName[32]
pev(victim, pev_classname, ClassName, charsmax(ClassName))
if (equal(ClassName, \”AlienBossik\”)) {
pev(victim, pev_health, g_Health)
if (g_Health <= damage) {
Anim(victim, 1)
set_pev(victim, pev_movetype, MOVETYPE_FLY)
set_pev(victim, pev_solid, SOLID_NOT)
set_pev(victim, pev_velocity, {0.0, 0.0, 0.0})
set_pev(victim, pev_deadflag, DEAD_DYING)
remove_task(1337)
return HAM_SUPERCEDE
}
}
return HAM_HANDLED
}
public Touch_Boss(Ent, WorldEnt) {
if (Ability == MS) {
static victim = -1, Float:Origin[3]
pev(Ent, pev_origin, Origin)
while((victim = engfunc(EngFunc_FindEntityInSphere, victim, Origin, 400.0)) != 0) {
if (!is_user_alive(victim))
continue
ExecuteHamB(Ham_TakeDamage, victim, 0, victim, float(dmg_ms), DMG_BULLET)
}
}
if (Ability == WALK) {
Ability = ATTACK
VictimID = WorldEnt
}
}
public plugin_precache() {
for(new i; i <= charsmax(Resource); i++)
g_Resource[i] = precache_model(Resource[i])
}
stock Blood(Float:Orig[3]) {
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BLOODSPRITE);
engfunc(EngFunc_WriteCoord, Orig[0])
engfunc(EngFunc_WriteCoord, Orig[1])
engfunc(EngFunc_WriteCoord, Orig[2])
write_short(g_Resource[1])
write_short(g_Resource[2])
write_byte(218)
write_byte(random_num(1, 2))
message_end();
}
stock Anim(ent, sequence) {
set_pev(ent, pev_sequence, sequence)
set_pev(ent, pev_animtime, halflife_time())
set_pev(ent, pev_framerate, 1.0)
}
stock ShockWave(Float:Orig[3], Life, Width, Float:Radius, Color[3]) {
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, Orig, 0)
write_byte(TE_BEAMCYLINDER) // TE id
engfunc(EngFunc_WriteCoord, Orig[0]) // x
engfunc(EngFunc_WriteCoord, Orig[1]) // y
engfunc(EngFunc_WriteCoord, Orig[2]-40.0) // z
engfunc(EngFunc_WriteCoord, Orig[0]) // x axis
engfunc(EngFunc_WriteCoord, Orig[1]) // y axis
engfunc(EngFunc_WriteCoord, Orig[2]+Radius) // z axis
write_short(g_Resource[4]) // sprite
write_byte(0) // startframe
write_byte(0) // framerate
write_byte(Life) // life (4)
write_byte(Width) // width (20)
write_byte(0) // noise
write_byte(Color[0]) // red
write_byte(Color[1]) // green
write_byte(Color[2]) // blue
write_byte(255) // brightness
write_byte(0) // speed
message_end()
}
stock ScreenFade(id, Timer, Colors[3], Alpha) {
message_begin(MSG_ONE_UNRELIABLE, get_user_msgid(\”ScreenFade\”), _, id);
write_short((1<<12) * Timer)
write_short(1<<12)
write_short(0)
write_byte(Colors[0])
write_byte(Colors[1])
write_byte(Colors[2])
write_byte(Alpha)
message_end()
}
stock ScreenShake(id) {
message_begin(MSG_ONE_UNRELIABLE, get_user_msgid(\”ScreenShake\”), _, id);
write_short(1<<14)
write_short(1<<12)
write_short(2<<12)
message_end();
}
GetRandomAlive(target_index) { // :3
new iAlive
for (new id = 1; id <= get_maxplayers(); id++) {
if (is_user_alive(id)) iAlive++
if (iAlive == target_index) return id
}
return -1
}
GetAliveCount() { // ^^
new iAlive
for (new id = 1; id <= get_maxplayers(); id++) if (is_user_alive(id)) iAlive++
return iAlive
}
/* AMXX-Studio Notes – DO NOT MODIFY BELOW HERE
*{\\\\ rtf1\\\\ ansi\\\\ deff0{\\\\ fonttbl{\\\\ f0\\\\ fnil Tahoma;}}\\n\\\\ viewkind4\\\\ uc1\\\\ pard\\\\ lang1049\\\\ f0\\\\ fs16 \\n\\\\ par }
*/
Редактируем.
Добавляем в него прекеш звуков, меняем анимацию модели, после того как всех убили можно также убрать нипа через remove_entity (например я использовал фиолетового фобоса и мне надо было, чтобы он пропадал перед началом нового раунда):
#include
#include
#include
#include
#define NAME \”AlienBoss Special For zombie-mod.com\”
#define VERSION \”Public\”
#define AUTHOR \”Alexander.3\”
const alien_hp = 25000
const boss_speed = 200
const Float:prepare_time = 15.0
const dmg_attack = 50
const dmg_ms = 50
const dmg_sw = 50
static Float:Origin[3]
static g_Alien
static g_BossTarget
static VictimID
static Float:g_Health
static Ability
new const Resource[][] = {
\”models/npc/alien/alien.mdl\”,
\”sprites/blood.spr\”,
\”sprites/bloodspray.spr\”,
\”sprites/npc/hp.spr\”,
\”sprites/shockwave.spr\”, // 4
\”sprites/npc/alien/fluxing.spr\” // 5
}
new const g_AlienSound[][] =
{
\”zombi/boss_dash.wav\”,
\”zombi/boss_death.wav\”,
\”zombi/boss_footstep_1.wav\”,
\”zombi/boss_footstep_2.wav\”,
\”zombi/boss_shokwave.wav\”,
\”zombi/boss_swing.wav\”,
\”zombi/boss_voice_1.wav\”
}
static g_Resource[sizeof Resource]
enum {
IDLE,
WALK,
MS,
ATTACK,
SW
}
public plugin_precache()
{
new i;
for(i = 0 ; i < sizeof g_AlienSound ; i++)
precache_sound(g_AlienSound[i]);
for(new i; i <= charsmax(Resource); i++)
g_Resource[i] = precache_model(Resource[i])
}
public plugin_init() {
register_plugin(NAME, VERSION, AUTHOR)
register_clcmd(\”say /create\”, \”create\”)
register_clcmd(\”say /spawn\”, \”spawn\”)
register_think(\”AlienBossik\”, \”Think_Boss\”)
register_think(\”HP\”, \”Think_HP\”)
register_touch(\”AlienBossik\”, \”player\”, \”Touch_Boss\”)
RegisterHam(Ham_TakeDamage, \”info_target\”, \”TakeDamage\”)
RegisterHam(Ham_TraceAttack, \”info_target\”, \”TraceAttack\”)
register_event(\”HLTV\”, \”event_newround\”, \”a\”, \”1=0\”, \”2=0\”)
}
public event_newround()
{
remove_entity_name(\”AlienBossik\”)
remove_entity_name(\”HP\”)
}
public RandomAbility(taskid) {
if (Ability != WALK)
return
switch(random(2)) {
case 0: Ability = MS
case 1: Ability = SW
}
}
public create(id)
pev(id, pev_origin, Origin)
public spawn() {
g_Alien = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, \”info_target\”))
new HPspr = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, \”info_target\”))
engfunc(EngFunc_SetModel, g_Alien, Resource[0])
engfunc(EngFunc_SetSize, g_Alien, { -32.0, -32.0, -36.0 }, { 32.0, 32.0, 96.0 })
engfunc(EngFunc_SetOrigin, g_Alien, Origin)
set_pev(g_Alien, pev_classname, \”AlienBossik\”)
set_pev(g_Alien, pev_solid, SOLID_BBOX)
set_pev(g_Alien, pev_movetype, MOVETYPE_PUSHSTEP)
set_pev(g_Alien, pev_takedamage, DAMAGE_NO)
set_pev(g_Alien, pev_health, float(alien_hp))
set_pev(g_Alien, pev_deadflag, DEAD_NO)
set_pev(g_Alien, pev_nextthink, get_gametime() + prepare_time)
Ability = IDLE
Anim(g_Alien, 5)
static Float:Origin[3]
pev(g_Alien, pev_origin, Origin)
Origin[2] += 200.0
engfunc(EngFunc_SetOrigin, HPspr, Origin)
engfunc(EngFunc_SetModel, HPspr, Resource[3])
entity_set_float(HPspr, EV_FL_scale, 0.5)
set_pev(HPspr, pev_classname, \”HP\”)
set_pev(HPspr, pev_solid, SOLID_NOT)
set_pev(HPspr, pev_movetype, MOVETYPE_NOCLIP)
set_pev(HPspr, pev_frame, 100.0)
set_pev(HPspr, pev_nextthink, get_gametime() + prepare_time)
}
public Think_Boss(Ent) {
if (pev(Ent, pev_deadflag) == DEAD_DYING)
return
static bool:one
switch ( Ability ) {
case IDLE: {
Ability = WALK
set_task(10.0, \”RandomAbility\”, 1337, _, _, \”b\”)
set_pev(Ent, pev_nextthink, get_gametime() + 0.1)
return
}
case WALK: {
static Float:Origin[3], Float:Origin2[3], Float:Vector[3], Float:Angle[3]
if (!is_user_alive(g_BossTarget)) {
g_BossTarget = GetRandomAlive(random_num(1, GetAliveCount()))
set_pev(Ent, pev_nextthink, get_gametime() + 0.1)
return
}
if (one) {
set_pev(Ent, pev_movetype, MOVETYPE_PUSHSTEP)
Anim(Ent, 7)
one = false
}
pev(Ent, pev_origin, Origin)
pev(g_BossTarget, pev_origin, Origin2)
xs_vec_sub(Origin2, Origin, Vector)
vector_to_angle(Vector, Angle)
new Float:num = floatsqroot(float(boss_speed)*float(boss_speed) / (Vector[0]*Vector[0] + Vector[1]*Vector[1] + Vector[2]*Vector[2]))
Vector[0] *= num
Vector[1] *= num
Vector[2] ? (Vector[2] = 0.0) : (Vector[2] *= num)
set_pev(Ent, pev_velocity, Vector)
Angle[0] = 0.0
Angle[2] = 0.0
set_pev(Ent, pev_angles, Angle)
set_pev(Ent, pev_nextthink, get_gametime() + 0.1)
return
}
case ATTACK: {
static num
switch (num) {
case 0: {
Anim(Ent, 10)
num++
set_pev(Ent, pev_nextthink, get_gametime() + 1.0)
return
}
case 1: {
static Float:OriginA[3], Float:OriginA2[3], Float:LenA, Float:Vector[3], Float:Velocity[3]
pev(g_Alien, pev_origin, OriginA)
pev(VictimID, pev_origin, OriginA2)
xs_vec_sub(OriginA2, OriginA, Velocity)
xs_vec_sub(OriginA, OriginA2, Vector)
LenA = xs_vec_len(Vector)
if (LenA <= 170) {
xs_vec_normalize(Velocity, Velocity)
Velocity[2] = 0.5
xs_vec_mul_scalar(Velocity, 1000.0, Velocity)
ExecuteHamB(Ham_TakeDamage, VictimID, 0, VictimID, float(dmg_attack), DMG_BULLET)
ScreenFade(VictimID, 3, {255, 0, 0}, 120)
ScreenShake(VictimID)
set_pev(VictimID, pev_velocity, Velocity)
}
}
}
num = 0
one = true
Ability = WALK
set_pev(Ent, pev_nextthink, get_gametime() + 0.2)
}
case MS: {
static num, Float:Origin[3], Float:Origin2[3], Float:Vector[3], Float:Angle[3]
switch ( num ) {
case 0: {
new MS_Attack = GetRandomAlive(random_num(1, GetAliveCount()))
pev(MS_Attack, pev_origin, Origin)
pev(Ent, pev_origin, Origin2)
xs_vec_sub(Origin, Origin2, Vector)
vector_to_angle(Vector, Angle)
xs_vec_normalize(Vector, Vector)
xs_vec_mul_scalar(Vector, 2000.0, Vector)
Angle[0] = 0.0
Angle[2] = 0.0
Vector[2] = 0.0
set_pev(Ent, pev_angles, Angle)
set_pev(Ent, pev_movetype, MOVETYPE_NONE)
Anim(Ent, 11)
set_pev(Ent, pev_nextthink, get_gametime() + 1.0)
num++
return
}
case 1: {
set_pev(Ent, pev_movetype, MOVETYPE_FLY)
set_pev(Ent, pev_velocity, Vector)
set_pev(Ent, pev_nextthink, get_gametime() + 1.0)
num++
return
}
}
set_pev(Ent, pev_nextthink, get_gametime() + 0.1)
num = 0
Ability = WALK
one = true
return
}
case SW: {
static num, FluxSpr, Float:Origin[3], sw_random
switch ( num ) {
case 0: {
sw_random = random(3)
Anim(Ent, 5)
FluxSpr = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, \”env_sprite\”))
pev(Ent, pev_origin, Origin)
Origin[2] += 70
engfunc(EngFunc_SetOrigin, FluxSpr, Origin)
engfunc(EngFunc_SetModel, FluxSpr, Resource[5])
set_pev(FluxSpr, pev_solid, SOLID_NOT)
set_pev(FluxSpr, pev_movetype, MOVETYPE_NOCLIP)
switch(sw_random) {
case 0: {
set_rendering(FluxSpr, kRenderFxFadeSlow, 255, 0, 0, kRenderTransAdd, 255)
set_rendering(Ent, kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 30)
}
case 1: {
set_rendering(FluxSpr, kRenderFxFadeSlow, 255, 255, 0, kRenderTransAdd, 255)
set_rendering(Ent, kRenderFxGlowShell, 255, 255, 0, kRenderNormal, 30)
}
case 2: {
set_rendering(FluxSpr, kRenderFxFadeSlow, 0, 0, 255, kRenderTransAdd, 255)
set_rendering(Ent, kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 30)
}
}
set_pev(FluxSpr, pev_framerate, 5.0)
dllfunc(DLLFunc_Spawn, FluxSpr)
set_pev(Ent, pev_nextthink, get_gametime() + 0.1)
num++
return
}
case 1..10: {
for(new id = 1; id <= get_maxplayers(); id++) {
if (!is_user_alive(id))
continue
static Float:OriginSW[3], Float:OriginSW2[3], Float:Vector[3]
pev(Ent, pev_origin, OriginSW)
pev(id, pev_origin, OriginSW2)
xs_vec_sub(OriginSW, OriginSW2, Vector)
xs_vec_normalize(Vector, Vector)
xs_vec_mul_scalar(Vector, 800.0, Vector)
set_pev(id, pev_velocity, Vector)
set_pev(Ent, pev_nextthink, get_gametime() + 0.2)
num++
return
}
}
case 11: {
engfunc(EngFunc_RemoveEntity, FluxSpr)
Anim(Ent, 9)
set_pev(Ent, pev_nextthink, get_gametime() + 2.2)
num++
return
}
case 12: {
static Float:Orig[3]
pev(Ent, pev_origin, Orig)
set_rendering(Ent)
switch (sw_random) {
case 0: ShockWave(Orig, 5, 35, 1000.0, {255, 0, 0}) // 450
case 1: ShockWave(Orig, 5, 35, 1000.0, {255, 255, 0})
case 2: ShockWave(Orig, 5, 35, 1000.0, {0, 0, 255})
}
for(new id = 1; id <= get_maxplayers(); id++) {
if (!is_user_alive(id))
continue
if (pev(id, pev_flags) & FL_ONGROUND) {
static Float:gOrigin[3], Float:Vec[3], Float:Len
pev(id, pev_origin, gOrigin)
xs_vec_sub(Orig, gOrigin, Vec)
Len = xs_vec_len(Vec)
if (Len <= 450.0) {
switch (sw_random) {
case 0: user_kill(id)
case 1: {
ScreenFade(id, 5, {255, 0, 0}, 120)
ExecuteHamB(Ham_TakeDamage, id, 0, id, float(dmg_sw), DMG_SONIC)
ScreenShake(id)
}
case 2: {
client_cmd(id, \”drop\”)
ScreenShake(id)
}
}
}
}
}
Ability = WALK
one = true
num = 0
set_pev(Ent, pev_nextthink, get_gametime() + 0.2)
return
}
}
}
}
}
public Think_HP(Ent) {
static Float:Origin[3], num
pev(g_Alien, pev_origin, Origin)
Origin[2] += 200.0
set_pev(Ent, pev_origin, Origin)
switch ( num ) {
case 0: {
Anim(g_Alien, 7)
set_pev(g_Alien, pev_takedamage, DAMAGE_YES)
num++
}
case 1: {
static Float:frame
frame = g_Health * 100.0 / float(alien_hp)
if (frame)
set_pev(Ent, pev_frame, frame)
if (pev(g_Alien, pev_deadflag) == DEAD_DYING) {
engfunc(EngFunc_RemoveEntity, Ent)
return
}
}
}
set_pev(Ent, pev_nextthink, get_gametime() + 0.1)
}
public TraceAttack(victim, attacker, Float:damage, Float:direction[3], th, dt) {
static Float:End[3], ClassName[32]
pev(victim, pev_classname, ClassName, charsmax(ClassName))
if (equal(ClassName, \”AlienBossik\”)) {
get_tr2(th, TR_vecEndPos, End)
Blood(End)
}
}
public TakeDamage(victim, weapon, attacker, Float:damage, damagetype) {
static ClassName[32]
pev(victim, pev_classname, ClassName, charsmax(ClassName))
if (equal(ClassName, \”AlienBossik\”)) {
pev(victim, pev_health, g_Health)
if (g_Health <= damage) {
Anim(victim, 4)
set_pev(victim, pev_movetype, MOVETYPE_FLY)
set_pev(victim, pev_solid, SOLID_NOT)
set_pev(victim, pev_velocity, {0.0, 0.0, 0.0})
set_pev(victim, pev_deadflag, DEAD_DYING)
remove_task(1337)
return HAM_SUPERCEDE
}
}
return HAM_HANDLED
}
public Touch_Boss(Ent, WorldEnt) {
if (Ability == MS) {
static victim = -1, Float:Origin[3]
pev(Ent, pev_origin, Origin)
while((victim = engfunc(EngFunc_FindEntityInSphere, victim, Origin, 400.0)) != 0) {
if (!is_user_alive(victim))
continue
ExecuteHamB(Ham_TakeDamage, victim, 0, victim, float(dmg_ms), DMG_BULLET)
}
}
if (Ability == WALK) {
Ability = ATTACK
VictimID = WorldEnt
}
}
stock Blood(Float:Orig[3]) {
message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
write_byte(TE_BLOODSPRITE);
engfunc(EngFunc_WriteCoord, Orig[0])
engfunc(EngFunc_WriteCoord, Orig[1])
engfunc(EngFunc_WriteCoord, Orig[2])
write_short(g_Resource[1])
write_short(g_Resource[2])
write_byte(218)
write_byte(random_num(1, 2))
message_end();
}
stock Anim(ent, sequence) {
set_pev(ent, pev_sequence, sequence)
set_pev(ent, pev_animtime, halflife_time())
set_pev(ent, pev_framerate, 1.0)
}
stock ShockWave(Float:Orig[3], Life, Width, Float:Radius, Color[3]) {
engfunc(EngFunc_MessageBegin, MSG_PVS, SVC_TEMPENTITY, Orig, 0)
write_byte(TE_BEAMCYLINDER) // TE id
engfunc(EngFunc_WriteCoord, Orig[0]) // x
engfunc(EngFunc_WriteCoord, Orig[1]) // y
engfunc(EngFunc_WriteCoord, Orig[2]-40.0) // z
engfunc(EngFunc_WriteCoord, Orig[0]) // x axis
engfunc(EngFunc_WriteCoord, Orig[1]) // y axis
engfunc(EngFunc_WriteCoord, Orig[2]+Radius) // z axis
write_short(g_Resource[4]) // sprite
write_byte(0) // startframe
write_byte(0) // framerate
write_byte(Life) // life (4)
write_byte(Width) // width (20)
write_byte(0) // noise
write_byte(Color[0]) // red
write_byte(Color[1]) // green
write_byte(Color[2]) // blue
write_byte(255) // brightness
write_byte(0) // speed
message_end()
}
stock ScreenFade(id, Timer, Colors[3], Alpha) {
message_begin(MSG_ONE_UNRELIABLE, get_user_msgid(\”ScreenFade\”), _, id);
write_short((1<<12) * Timer)
write_short(1<<12)
write_short(0)
write_byte(Colors[0])
write_byte(Colors[1])
write_byte(Colors[2])
write_byte(Alpha)
message_end()
}
stock ScreenShake(id) {
message_begin(MSG_ONE_UNRELIABLE, get_user_msgid(\”ScreenShake\”), _, id);
write_short(1<<14)
write_short(1<<12)
write_short(2<<12)
message_end();
}
GetRandomAlive(target_index) { // :3
new iAlive
for (new id = 1; id <= get_maxplayers(); id++) {
if (is_user_alive(id)) iAlive++
if (iAlive == target_index) return id
}
return -1
}
GetAliveCount() { // ^^
new iAlive
for (new id = 1; id <= get_maxplayers(); id++) if (is_user_alive(id)) iAlive++
return iAlive
}
/* AMXX-Studio Notes – DO NOT MODIFY BELOW HERE
*{\\\\ rtf1\\\\ ansi\\\\ deff0{\\\\ fonttbl{\\\\ f0\\\\ fnil Tahoma;}}\\n\\\\ viewkind4\\\\ uc1\\\\ pard\\\\ lang1049\\\\ f0\\\\ fs16 \\n\\\\ par }
*/
С самим исходником работа закончена.
Приступаем к раскомпилированию модели босса. Для этого нам понадобится утилитка MilkShape3D.
Можно и незарегистрированную копию, Kratisto декомпилятор для этого не нужен Вот что главное – нужно прописать во все анимы босса звуки и убрать из них ивенты из CSO – они нам не нужны (к таким ивентам относится 5008)
В милкшейпе выбираем Tools, Decompile Normal MDL File указываем путь к нашей модельке босса.
Нам нужно отредактировать звуки, привязка звуков находится в скрипте с расширением .qc
Открываем его и листаем в самый низ:
$sequence dummy \”dummy\” loop fps 15
$sequence gut_flinch \”gut_flinch\” fps 30
$sequence head_flinch \”head_flinch\” fps 30
$sequence head \”head\” fps 15 ACT_DIE_HEADSHOT 1 { event 2001 1 } { event 5004 1 \”Zombi/boss_death.wav\” }
$sequence gutshot \”gutshot\” fps 15 ACT_DIE_GUTSHOT 1 { event 2001 1 } { event 5004 1 \”Zombi/boss_death.wav\” }
$sequence zbs_idle1 \”zbs_idle1\” loop fps 30 ACT_IDLE 1
$sequence zbs_walk \”zbs_walk\” LX loop fps 20 { event 5008 23 } { event 5008 51 }
$sequence zbs_run \”zbs_run\” LX loop fps 30 { event 5008 23 } { event 5008 51 }
$sequence zbs_jump \”zbs_jump\” fps 30
$sequence zbs_attack_shockwave \”zbs_attack_shockwave\” fps 30 { event 5004 16 \”Zombi/boss_voice_1.wav\” } { event 5004 64 \”Zombi/boss_shokwave.wav\” }
$sequence zbs_attack_justiceSwing \”zbs_attack_justiceSwing\” fps 30 { event 5004 1 \”Zombi/boss_swing.wav\” }
$sequence zbs_attack_mahadash \”zbs_attack_mahadash\” loop fps 35 { event 5004 1 \”Zombi/boss_dash.wav\” }
Собственно красным я отметил ивенты, которые в CS 1.6 не используются.
Мы заменим их на стандартный ивент 5004, который воспроизводит звуки, а также добавим сами звуки. Код будет выглядеть вот так:
// 12 sequences
$sequence dummy \”dummy\” loop fps 15
$sequence gut_flinch \”gut_flinch\” fps 30
$sequence head_flinch \”head_flinch\” fps 30
$sequence head \”head\” fps 15 ACT_DIE_HEADSHOT 1 { event 2001 1 } { event 5004 1 \”Zombi/boss_death.wav\” }
$sequence gutshot \”gutshot\” fps 15 ACT_DIE_GUTSHOT 1 { event 2001 1 } { event 5004 1 \”Zombi/boss_death.wav\” }
$sequence zbs_idle1 \”zbs_idle1\” loop fps 30 ACT_IDLE 1
$sequence zbs_walk \”zbs_walk\” LX loop fps 20 { event 5004 23 \”Zombi/boss_footstep_1.wav\” } { event 5004 51 \”Zombi/boss_footstep_2.wav\” }
$sequence zbs_run \”zbs_run\” LX loop fps 30 { event 5004 23 \”Zombi/boss_footstep_1.wav\” } { event 5004 51 \”Zombi/boss_footstep_2.wav\” }
$sequence zbs_jump \”zbs_jump\” fps 30
$sequence zbs_attack_shockwave \”zbs_attack_shockwave\” fps 30 { event 5004 16 \”Zombi/boss_voice_1.wav\” } { event 5004 64 \”Zombi/boss_shokwave.wav\” }
$sequence zbs_attack_justiceSwing \”zbs_attack_justiceSwing\” fps 30 { event 5004 1 \”Zombi/boss_swing.wav\” }
$sequence zbs_attack_mahadash \”zbs_attack_mahadash\” loop fps 35 { event 5004 1 \”Zombi/boss_dash.wav\” }
Наверное многие замечали, что у них звуки NPC боссов иногда искажаются, хрипят. Исправив модельку таким образом, и удалив ивент 5008 мы избавляемся также и от этих проблем.
Всё, компилируем модель обратно. Также в Tools, Compile QC File, указываем путь к нашему .qc отредактированному файлику.
Меняем параметры босса в нашем исходнике, компилируем, собираем ресурсы – тестируем.
Что получилось:
Ресы:






