why can not move forward:

- Code: Select all
#define MONSTES_ENABLED
#ifdef MONSTES_ENABLED
#define crab_anim_idle 0
#define crab_anim_walk 1
#define crab_anim_spawn 2
#define crab_anim_die 3
#define crab_anim_dead 4
#define CRAB_MIN '-5 -5 0'
#define CRAB_MAX '5 5 5'
#define CR_IDLE 10
#define CR_PATH 100
#define CR_HUNT 200
#define CR_ATTACK_FIND 10
#define CR_ATTACK_RUN 20
#define CR_ATTACK_STAND 30
#define CR_PATH2 10000
#define MONSTERFLAG_NORESPAWN_CR 2
void crab_spawn();
float crab_scoretarget(entity trg) // Оценка цели
{
float tmp; // Определяем 32 разрядную переменную tmp
vector ang1; // Определяем вектор
if (trg.takedamage == DAMAGE_AIM) // Если не цель, не трогать
if not (trg.flags & FL_NOTARGET) // Если нет флага notarget
if (trg.deadflag == DEAD_NO) // Если мертв, не трогать
// if (trg.team != self.team) // Если свой, не трогать
if (trg.classname == "point")
{
if((self.origin_z - trg.origin_z) < 128) // Определяем расстояние по Z
{
ang1 = normalize(self.origin - trg.origin); // Определяем расстояние по Z
tmp = vlen(ang1 - v_forward); // Возвращает длину вектора (Расстояние - смотреть вперед)
if(tmp > 1.5) // НЕ ПОНЯТНО !!!
{
traceline(self.origin + '0 0 5',trg.origin + '0 0 1',MOVE_NORMAL,self); // Функция: traceline
if(trace_ent != trg) // Получаем глобадбную переменную, если не равна trg возвращаем 0
return 0;
return (cvar("g_monster_crab_targetrange") - vlen(self.origin - trg.origin)) * tmp; // Цель враг
}
else if(self.enemy == trg)
return (cvar("g_monster_crab_targetrange") - vlen(self.origin - trg.origin)) * tmp; // Цель враг
}
}
return 0; // Цель не враг
}
void crab_corpse_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force) // остатки , если стрелять разлетаются
{
// dprint("crab_corpse_damage\n");
Violence_GibSplash_At(hitloc, force, 2, bound(0, damage, 200) / 160, self, attacker);
self.health -= damage; // Вычитаем урон
if(self.health < 0) // Если у тела переменная health<0 то переходим дальше
{
remove(self); // Удалить тело после выстрела
}
}
void crab_die(vector dir) // die
{
entity dummy; // Определяем лицо-пустышку
dummy = spawn(); // Создаем точку входа пустышки
setmodel(dummy,"models/monsters/crab.dpm"); // Определяем модель пустышки
setorigin(dummy, self.origin); // Указываем позицию по вектору self.origin
dummy.velocity = self.velocity; // Направление отскакивания тела
dummy.movetype = MOVETYPE_BOUNCE; // Тип движения (MOVETYPE_BOUNCE = отскакивают от стен)
dummy.think = SUB_Remove; // ? функция удаления
dummy.nextthink = time + 3; // Вызывать каждые n число секунд
dummy.health = 50; // жизней у трупа, если ноль то куски
dummy.takedamage = DAMAGE_YES; // Тип Damage (DAMAGE_YES) Гранаты не взрываются при прикосновении
dummy.event_damage = crab_corpse_damage; // В случае повреждения вызываем функцию "crab_corpse_damage" !!!!!!!!!
dummy.solid = SOLID_CORPSE; // тип бокса тела
setsize(dummy,self.mins,self.maxs); // Размер бокса тела setsize(entity, vector_min, vector_max);
SUB_SetFade(dummy,time + 50,2); // Время жизни тела
dummy.frame = crab_anim_die; // play die animation
if(self.spawnflags & MONSTERFLAG_NORESPAWN_CR) // Если спаун флаг стоит и MONSTERFLAG_NORESPAWN присутствует
{
self.think = SUB_Remove; // ? функция удаления или обновления
self.nextthink = time; // обновлять по времени
return;
}
setmodel(self,""); // Удаляем все
self.solid = SOLID_NOT;
self.takedamage = DAMAGE_NO;
self.event_damage = SUB_Null;
self.enemy = world;
self.think = crab_spawn;
self.nextthink = time + cvar("g_monster_crab_respawntime"); // Ждем конца времени респавна
self.pain_finished = self.nextthink;
}
void crab_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
{
self.health -= damage;
self.velocity = self.velocity + force;
if(self.health <= 0)
{
crab_die(hitloc);
return;
}
Violence_GibSplash_At(hitloc, force, 2, bound(0, damage, 200) / 160, self, attacker);
if (damage > 50)
Violence_GibSplash_At(hitloc, force * -0.1, 3, 1, self, attacker);
if (damage > 100)
Violence_GibSplash_At(hitloc, force * -0.2, 3, 1, self, attacker);
}
.vector bvec;
.float bvec_time;
void crab_move() // Движение
{
vector real_angle; // Объявляем вектор
float vz, tdiff, tspeed; // Объявляем переменные
tdiff = time - self.zoomstate; // Присваеваем значение
tspeed = tdiff * cvar("g_monster_crab_turnspeed"); // Присваеваем значение g_monster_crab_turnspeed(скорость)
vz = self.velocity_z; //
if(self.bvec_time < time) // вращение
{
self.bvec_time = time + 0.2;
self.bvec = steerlib_beamsteer(steerlib_attract2(self.moveto,0.5,500,0.95),512,32,34,64);
}
if(self.enemy) // Если виден враг, то двигатьсяк к нему
self.moveto = self.enemy.origin; // Координаты врага self.enemy.origin
else
self.moveto = self.origin + v_forward; // Двигаться вперед
self.steerto = normalize(steerlib_attract2(self.moveto,500,500,0.95) + self.bvec);
self.angles_x = safeangle(self.angles_x);
self.angles_y = safeangle(self.angles_y);
self.angles_z = safeangle(self.angles_z);
dprint("x= ", ftos(self.angles_x), "\n");
dprint("y= ", ftos(self.angles_y), "\n");
dprint("z= ", ftos(self.angles_z), "\n");
real_angle = vectoangles(self.steerto) - self.angles;
dprint("real_angle= ", vtos(real_angle), "\n");
self.angles_y += bound(-10, real_angle_y, 10); // Угол поворота 10
if(vlen(self.origin - self.moveto) > 15)
{
movelib_move_simple(v_forward ,cvar("g_monster_crab_movespeed"),0.6);
if(time > self.pain_finished)
if(self.attack_finished_single < time)
self.frame = crab_anim_walk; // Анимация crab_anim_runforward
}
else
{
movelib_beak_simple(cvar("g_monster_crab_stopspeed"));
if(time > self.pain_finished)
if(self.attack_finished_single < time)
self.frame = crab_anim_idle; // Анимация crab_anim_idle
}
self.velocity_z = vz;
self.steerto = self.origin;
}
float crab_verb_idle_roam(float eval)
{
switch (eval)
{
case VCM_EVAL:
if(self.enemy)
return VS_CALL_NO;
return verb.verb_static_value;
case VCM_DO:
self.moveto = v_forward * 128;
self.steerto = v_forward; //steerlib_beamsteer(v_forward,512,32,34,64);
return VS_CALL_YES_DOING;
}
return VS_CALL_YES_DONE;
}
float crab_verb_idle_stand(float eval)
{
switch (eval)
{
case VCM_EVAL:
if(self.enemy)
return VS_CALL_NO;
return verb.verb_static_value;
case VCM_DO:
self.moveto = self.origin;
self.frame = crab_anim_idle;
self.velocity = '0 0 0';
return VS_CALL_YES_DOING;
}
return VS_CALL_YES_DONE;
}
float crab_verb_idle(float eval) // Ожидаем
{
switch (eval)
{
case VCM_EVAL: // Случай
if(self.enemy) // Если лицо-ВРАГ возвращаем VS_CALL_NO
return VS_CALL_NO;
return verb.verb_static_value; // Возвращаем verb.verb_static_value
case VCM_DO:
float t;
t = cvar("g_monster_crab_idle_timer_max") - cvar("g_monster_crab_idle_timer_min");
t = cvar("g_monster_crab_idle_timer_min") + (random() * t);
if(random() < 0.5)
{
verbstack_push(self.verbs_idle, crab_verb_idle_roam, CR_IDLE + 1, t, self);
}
else
{
verbstack_push(self.verbs_idle, crab_verb_idle_stand, CR_IDLE + 1, 0.1, self);
}
return VS_CALL_YES_DOING;
}
return VS_CALL_YES_DONE;
}
float crab_verb_attack_findtarget(float eval)
{
switch (eval)
{
case VCM_EVAL:
if(self.enemy)
return VS_CALL_NO;
return verb.verb_static_value;
case VCM_DO:
entity trg, best_trg;
float trg_score, best_trg_score;
trg = findradius(self.origin,cvar("g_monster_crab_targetrange"));
while(trg)
{
trg_score = crab_scoretarget(trg);
if(trg_score > best_trg_score)
{
best_trg = trg;
best_trg_score = trg_score;
}
trg = trg.chain;
}
if(best_trg)
{
self.enemy = best_trg;
dprint("Crab sees: ",best_trg.netname, " as target.\n");
}
return VS_CALL_YES_DOING;
}
return VS_CALL_YES_DONE;
}
void crab_runattack_damage()
{
entity oldself;
oldself = self;
self = self.owner;
if(vlen(self.origin - self.enemy.origin) > cvar("g_monster_crab_attack_run_hitrange"))
return;
if(vlen(normalize(self.origin - self.enemy.origin) - v_forward) < 1.6)
return;
Damage(self.enemy, self, self, cvar("g_monster_crab_attack_run_damage"), DEATH_TURRET, self.enemy.origin, normalize(self.enemy.origin - self.origin) * cvar("g_monster_crab_attack_run_force"));
self = oldself;
self.think = SUB_Remove;
self.nextthink = time;
}
float crab_verb_attack_run(float eval)
{
switch (eval)
{
case VCM_EVAL:
if not (self.enemy)
return VS_CALL_NO;
if(self.attack_finished_single > time)
return VS_CALL_NO;
if(vlen(self.origin - self.enemy.origin) > cvar("g_monster_crab_attack_run_range"))
return VS_CALL_NO;
if(vlen(normalize(self.origin - self.enemy.origin) - v_forward) < 1.6)
return VS_CALL_NO;
return verb.verb_static_value;
case VCM_DO:
entity pain;
pain = spawn();
pain.owner = self;
pain.think = crab_runattack_damage;
pain.nextthink = time + cvar("g_monster_crab_attack_run_delay");
self.attack_finished_single = time + 0.7;
self.frame = crab_anim_idle;
return VS_CALL_YES_DOING;
}
return VS_CALL_YES_DONE;
}
void crab_standattack_damage()
{
//entity oldself;
//oldself = self;
//self = self.owner;
setorigin(self,self.owner.origin + v_forward * 32);
RadiusDamage(self, self.owner, cvar("g_monster_crab_attack_stand_damage"),cvar("g_monster_crab_attack_stand_damage"),16,self, cvar("g_monster_crab_attack_stand_force"),DEATH_TURRET,world);
//float RadiusDamage (entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity ignore, float forceintensity, float deathtype, entity directhitentity)
//self = oldself;
self.think = SUB_Remove;
self.nextthink = time;
}
float crab_verb_attack_stand(float eval)
{
switch (eval)
{
case VCM_EVAL:
if not (self.enemy)
return VS_CALL_NO;
if(self.attack_finished_single > time)
return VS_CALL_NO;
if(vlen(self.origin - self.enemy.origin) > cvar("g_monster_crab_attack_stand_range"))
return VS_CALL_NO;
if(vlen(normalize(self.origin - self.enemy.origin) - v_forward) < 1.8)
return VS_CALL_NO;
return verb.verb_static_value;
case VCM_DO:
entity pain;
pain = spawn();
pain.owner = self;
pain.think = crab_runattack_damage;
pain.nextthink = time + cvar("g_monster_crab_attack_stand_delay");
self.attack_finished_single = time + 0.7;
self.frame = crab_anim_idle;
dprint("frame:",ftos(self.frame),"\n");
return VS_CALL_YES_DOING;
}
return VS_CALL_YES_DONE;
}
void crab_think() // Размышлегия оО
{
self.angles_x *= -1; // Векторы
makevectors(self.angles);
self.angles_x *= -1;
if (crab_scoretarget(self.enemy) == 0) // Поиск врага по функции crab_scoretarget()
self.enemy = world; // не найден, продолжаем поиск
verbstack_pop(self.verbs_attack); // найден
if not (self.enemy) // Если не враг, ожидание
verbstack_pop(self.verbs_idle);
crab_move(); // Движение
if(self.enemy) // Счетчик ?
self.nextthink = time;
else
self.nextthink = time + 0.2;
}
void crab_spawn() // Spawn()
{
setmodel(self,"models/monsters/crab.dpm"); // Указываем модель
self.solid = SOLID_BBOX; // Тип бокса
self.takedamage = DAMAGE_AIM; // Тип Damage
self.event_damage = crab_damage; // В случае повреждения вызывается функция crab_damage()
self.enemy = world; // Что-то про врага
self.frame = crab_anim_spawn; // Проигрываем анимацию crab_anim_spawn
self.think = crab_think; // вызывается функция crab_think()
self.nextthink = time + 2.1; // Следующий вызов через time + 2.1
self.pain_finished = self.nextthink; // time when pain sound is finished
self.movetype = MOVETYPE_WALK; // Тип передвижения
self.health = cvar("g_monster_crab_health"); // Количество жизней
self.velocity = '0 0 0'; // Направление вектора
self.angles = self.pos2; //
self.moveto = self.origin; //
self.flags = FL_MONSTER; // Определяем как монстра
setorigin(self,self.pos1); // Позиция
setsize(self,CRAB_MIN,CRAB_MAX); // Размер бокса
}
void spawnfunc_monster_crab()
{
if not(cvar("g_monsters")) // Если нет переменной то все удаляем лицо
{
remove(self);
return;
}
precache_model("models/monsters/crab.dpm"); // Кешируем модель
self.verbs_idle = spawn(); // прикрепляем ожидание
self.verbs_attack = spawn(); // .... атаку
self.verbs_idle.owner = self; // что то там с владельцем
self.verbs_attack.owner = self;
self.think = crab_spawn; // Намеринья ) переходим на функцию crab_spawn()
self.nextthink = time + 2; // Ждем перед слдуюжим действием
traceline(self.origin + '0 0 0', self.origin - '0 0 5', MOVE_WORLDONLY, self); // Функция: traceline
self.pos1 = trace_endpos; // ?
self.pos2 = self.angles; // ?
self.team = MAX_SHOT_DISTANCE -1; // ?
verbstack_push(self.verbs_idle, crab_verb_idle, CR_IDLE,0 , self); // Переходим на функцию crab_verb_idle
verbstack_push(self.verbs_attack, crab_verb_attack_findtarget, CR_ATTACK_FIND,0 , self);
verbstack_push(self.verbs_attack, crab_verb_attack_run, CR_ATTACK_RUN,0 , self);
verbstack_push(self.verbs_attack, crab_verb_attack_stand, CR_ATTACK_STAND,0 , self);
}
#endif // MONSTES_ENABLED
I can not solve the problem:
1. motion parallel to the surface
2. why slips