Annotation of quake2/xatrix/m_gekk.c, revision 1.1

1.1     ! root        1: /*
        !             2:        xatrix
        !             3:        gekk.c
        !             4: */
        !             5: 
        !             6: #include "g_local.h"
        !             7: #include "m_gekk.h"
        !             8: 
        !             9: static int     sound_swing;
        !            10: static int     sound_hit;
        !            11: static int     sound_hit2;
        !            12: static int     sound_death;
        !            13: static int     sound_pain1;
        !            14: static int     sound_sight;
        !            15: static int     sound_search;
        !            16: static int     sound_step1;
        !            17: static int     sound_step2;
        !            18: static int     sound_step3;
        !            19: static int     sound_thud;
        !            20: static int  sound_chantlow;
        !            21: static int  sound_chantmid;
        !            22: static int  sound_chanthigh;
        !            23: 
        !            24: void gekk_swim (edict_t *self);
        !            25: 
        !            26: extern void gekk_jump_takeoff (edict_t *self);
        !            27: extern void gekk_jump_takeoff2 (edict_t *self);
        !            28: extern void gekk_check_landing (edict_t *self);
        !            29: extern void gekk_check_landing2 (edict_t *self);
        !            30: extern void gekk_stop_skid (edict_t *self);
        !            31: 
        !            32: extern void water_to_land (edict_t *self);
        !            33: extern void land_to_water (edict_t *self);
        !            34: 
        !            35: extern void gekk_check_underwater (edict_t *self);
        !            36: extern void gekk_bite (edict_t *self);
        !            37: 
        !            38: extern void gekk_hit_left (edict_t *self);
        !            39: extern void gekk_hit_right (edict_t *self);
        !            40: extern void gekk_run_start (edict_t *self);
        !            41: 
        !            42: extern mmove_t gekk_move_attack1;
        !            43: extern mmove_t gekk_move_attack2;
        !            44: extern mmove_t gekk_move_chant;
        !            45: extern mmove_t gekk_move_swim_start;
        !            46: extern mmove_t gekk_move_swim_loop;
        !            47: extern mmove_t gekk_move_spit;
        !            48: extern mmove_t gekk_move_run_start;
        !            49: 
        !            50: extern qboolean gekk_check_jump (edict_t *self);
        !            51: 
        !            52: //
        !            53: // CHECKATTACK
        !            54: //
        !            55: 
        !            56: qboolean gekk_check_melee (edict_t *self)
        !            57: {
        !            58:        if (!self->enemy && self->enemy->health <= 0)
        !            59:                return false;
        !            60: 
        !            61:        if (range (self, self->enemy) == RANGE_MELEE)
        !            62:                return true;
        !            63:        return false;
        !            64: }
        !            65: 
        !            66: qboolean gekk_check_jump (edict_t *self)
        !            67: {
        !            68:        vec3_t  v;
        !            69:        float   distance;
        !            70: 
        !            71:        if (self->absmin[2] > (self->enemy->absmin[2] + 0.75 * self->enemy->size[2]))
        !            72:                return false;
        !            73: 
        !            74:        if (self->absmax[2] < (self->enemy->absmin[2] + 0.25 * self->enemy->size[2]))
        !            75:                return false;
        !            76: 
        !            77:        v[0] = self->s.origin[0] - self->enemy->s.origin[0];
        !            78:        v[1] = self->s.origin[1] - self->enemy->s.origin[1];
        !            79:        v[2] = 0;
        !            80:        distance = VectorLength(v);
        !            81: 
        !            82:        if (distance < 100)
        !            83:        {
        !            84:                return false;
        !            85:        }
        !            86:        if (distance > 100)
        !            87:        {
        !            88:                if (random() < 0.9)
        !            89:                        return false;
        !            90:        }
        !            91: 
        !            92:        return true;
        !            93: }
        !            94: 
        !            95: qboolean gekk_check_jump_close (edict_t *self)
        !            96: {
        !            97:        vec3_t  v;
        !            98:        float   distance;
        !            99: 
        !           100:        v[0] = self->s.origin[0] - self->enemy->s.origin[0];
        !           101:        v[1] = self->s.origin[1] - self->enemy->s.origin[1];
        !           102:        v[2] = 0;
        !           103:        
        !           104:        distance = VectorLength(v);
        !           105: 
        !           106:        if (distance < 100)
        !           107:        {
        !           108:                if (self->s.origin[2] < self->enemy->s.origin[2])
        !           109:                        return true;
        !           110:                else
        !           111:                        return false;
        !           112:        }
        !           113:        
        !           114:        return true;
        !           115: }
        !           116: 
        !           117: 
        !           118: qboolean gekk_checkattack (edict_t *self)
        !           119: {
        !           120:        if (!self->enemy || self->enemy->health <= 0)
        !           121:                return false;
        !           122: 
        !           123:        if (gekk_check_melee(self))
        !           124:        {
        !           125:                self->monsterinfo.attack_state = AS_MELEE;
        !           126:                return true;
        !           127:        }
        !           128: 
        !           129:        if (gekk_check_jump(self))
        !           130:        {
        !           131:                self->monsterinfo.attack_state = AS_MISSILE;
        !           132:                return true;
        !           133:        }
        !           134: 
        !           135:        if (gekk_check_jump_close (self) && !self->waterlevel)
        !           136:        {       
        !           137:                self->monsterinfo.attack_state = AS_MISSILE;
        !           138:                return true;
        !           139:        }
        !           140: 
        !           141:        return false;
        !           142: }
        !           143: 
        !           144: 
        !           145: //
        !           146: // SOUNDS
        !           147: //
        !           148: 
        !           149: void gekk_step (edict_t *self)
        !           150: {
        !           151:        int             n;
        !           152:        n = (rand() + 1) % 3;
        !           153:        if (n == 0)
        !           154:                gi.sound (self, CHAN_VOICE, sound_step1, 1, ATTN_NORM, 0);              
        !           155:        else if (n == 1)
        !           156:                gi.sound (self, CHAN_VOICE, sound_step2, 1, ATTN_NORM, 0);
        !           157:        else
        !           158:                gi.sound (self, CHAN_VOICE, sound_step3, 1, ATTN_NORM, 0);
        !           159: }
        !           160: 
        !           161: void gekk_sight (edict_t *self, edict_t *other)
        !           162: {
        !           163:        gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
        !           164: }
        !           165: 
        !           166: void gekk_search (edict_t *self)
        !           167: {
        !           168:        float r;
        !           169: 
        !           170:        if (self->spawnflags & 8)
        !           171:        {
        !           172:                r = random();
        !           173:                if (r < 0.33)
        !           174:                        gi.sound (self, CHAN_VOICE, sound_chantlow, 1, ATTN_NORM, 0);
        !           175:                else if (r < 0.66)
        !           176:                        gi.sound (self, CHAN_VOICE, sound_chantmid, 1, ATTN_NORM, 0);
        !           177:                else
        !           178:                        gi.sound (self, CHAN_VOICE, sound_chanthigh, 1, ATTN_NORM, 0);
        !           179:        }
        !           180:        else
        !           181:                gi.sound (self, CHAN_VOICE, sound_search, 1, ATTN_NORM, 0);
        !           182:        
        !           183: 
        !           184:        self->health += 10 + (10 * random());
        !           185:        if (self->health > self->max_health)
        !           186:                self->health = self->max_health;
        !           187: 
        !           188:        if (self->health < (self->max_health /4))
        !           189:                self->s.skinnum = 2;
        !           190:        else if (self->health < (self->max_health / 2))
        !           191:                self->s.skinnum = 1;
        !           192:        else 
        !           193:                self->s.skinnum = 0;
        !           194: }
        !           195: 
        !           196: void gekk_swing (edict_t *self)
        !           197: {
        !           198:        gi.sound (self, CHAN_VOICE, sound_swing, 1, ATTN_NORM, 0);
        !           199: }
        !           200: 
        !           201: extern mmove_t gekk_move_run;
        !           202: void gekk_face (edict_t *self)
        !           203: {
        !           204:        self->monsterinfo.currentmove = &gekk_move_run; 
        !           205: }
        !           206: 
        !           207: //
        !           208: // STAND
        !           209: //
        !           210: 
        !           211: void ai_stand2 (edict_t *self, float dist)
        !           212: {
        !           213:        if (self->spawnflags & 8)
        !           214:        {
        !           215:                ai_move (self, dist);
        !           216:                if (!(self->spawnflags & 1) && (self->monsterinfo.idle) && (level.time > self->monsterinfo.idle_time))
        !           217:                {
        !           218:                        if (self->monsterinfo.idle_time)
        !           219:                        {
        !           220:                                self->monsterinfo.idle (self);
        !           221:                                self->monsterinfo.idle_time = level.time + 15 + random() * 15;
        !           222:                        }
        !           223:                        else
        !           224:                        {
        !           225:                                self->monsterinfo.idle_time = level.time + random() * 15;
        !           226:                        }
        !           227:                }
        !           228:        }
        !           229:        else
        !           230:                ai_stand (self, dist);
        !           231: }
        !           232: 
        !           233: mframe_t gekk_frames_stand [] =
        !           234: {
        !           235:        ai_stand2, 0, NULL,
        !           236:        ai_stand2, 0, NULL,
        !           237:        ai_stand2, 0, NULL,
        !           238:        ai_stand2, 0, NULL,
        !           239:        ai_stand2, 0, NULL,
        !           240:        ai_stand2, 0, NULL,
        !           241:        ai_stand2, 0, NULL,
        !           242:        ai_stand2, 0, NULL,
        !           243:        ai_stand2, 0, NULL,
        !           244:        ai_stand2, 0, NULL,             // 10
        !           245: 
        !           246:        ai_stand2, 0, NULL,
        !           247:        ai_stand2, 0, NULL,
        !           248:        ai_stand2, 0, NULL,
        !           249:        ai_stand2, 0, NULL,
        !           250:        ai_stand2, 0, NULL,
        !           251:        ai_stand2, 0, NULL,
        !           252:        ai_stand2, 0, NULL,
        !           253:        ai_stand2, 0, NULL,
        !           254:        ai_stand2, 0, NULL,
        !           255:        ai_stand2, 0, NULL,             // 20
        !           256: 
        !           257:        ai_stand2, 0, NULL,
        !           258:        ai_stand2, 0, NULL,
        !           259:        ai_stand2, 0, NULL,
        !           260:        ai_stand2, 0, NULL,
        !           261:        ai_stand2, 0, NULL,
        !           262:        ai_stand2, 0, NULL,
        !           263:        ai_stand2, 0, NULL,
        !           264:        ai_stand2, 0, NULL,
        !           265:        ai_stand2, 0, NULL,
        !           266:        ai_stand2, 0, NULL,             // 30
        !           267: 
        !           268:        ai_stand2, 0, NULL,
        !           269:        ai_stand2, 0, NULL,
        !           270:        ai_stand2, 0, NULL,
        !           271:        ai_stand2, 0, NULL,
        !           272:        ai_stand2, 0, NULL,
        !           273:        ai_stand2, 0, NULL,
        !           274:        ai_stand2, 0, NULL,
        !           275:        ai_stand2, 0, NULL,
        !           276:        
        !           277:        ai_stand2, 0, gekk_check_underwater,
        !           278: };
        !           279: mmove_t gekk_move_stand = {FRAME_stand_01, FRAME_stand_39, gekk_frames_stand, NULL};
        !           280: 
        !           281: mframe_t gekk_frames_standunderwater[] =
        !           282: {
        !           283:        ai_stand2, 0, NULL,     
        !           284:        ai_stand2, 0, NULL,
        !           285:        ai_stand2, 0, NULL,
        !           286:        
        !           287:        ai_stand2, 0, gekk_check_underwater
        !           288: };
        !           289: 
        !           290: mmove_t gekk_move_standunderwater = {FRAME_amb_01, FRAME_amb_04, gekk_frames_standunderwater, NULL};
        !           291: 
        !           292: 
        !           293: void gekk_swim_loop (edict_t *self)
        !           294: {
        !           295:        self->flags |= FL_SWIM; 
        !           296:        self->monsterinfo.currentmove = &gekk_move_swim_loop;
        !           297: }
        !           298: 
        !           299: mframe_t gekk_frames_swim [] =
        !           300: {
        !           301:        ai_run, 16, NULL,       
        !           302:        ai_run, 16, NULL,
        !           303:        ai_run, 16, NULL,
        !           304:        
        !           305:        ai_run, 16, gekk_swim
        !           306: };
        !           307: mmove_t gekk_move_swim_loop = {FRAME_amb_01, FRAME_amb_04, gekk_frames_swim, gekk_swim_loop};
        !           308: 
        !           309: mframe_t gekk_frames_swim_start [] =
        !           310: {
        !           311:        ai_run, 14, NULL,
        !           312:        ai_run, 14, NULL,
        !           313:        ai_run, 14, NULL,
        !           314:        ai_run, 14, NULL,
        !           315:        ai_run, 16, NULL,
        !           316:        ai_run, 16, NULL,
        !           317:        ai_run, 16, NULL,
        !           318:        ai_run, 18, NULL,
        !           319:        ai_run, 18, gekk_hit_left,
        !           320:        ai_run, 18, NULL,
        !           321:        
        !           322:        ai_run, 20, NULL,
        !           323:        ai_run, 20, NULL,
        !           324:        ai_run, 22, NULL,
        !           325:        ai_run, 22, NULL,
        !           326:        ai_run, 24, gekk_hit_right,
        !           327:        ai_run, 24, NULL,
        !           328:        ai_run, 26, NULL,
        !           329:        ai_run, 26, NULL,
        !           330:        ai_run, 24, NULL,
        !           331:        ai_run, 24, NULL,
        !           332:        
        !           333:        ai_run, 22, gekk_bite,
        !           334:        ai_run, 22, NULL,
        !           335:        ai_run, 22, NULL,
        !           336:        ai_run, 22, NULL,
        !           337:        ai_run, 22, NULL,
        !           338:        ai_run, 22, NULL,
        !           339:        ai_run, 22, NULL,
        !           340:        ai_run, 22, NULL,
        !           341:        ai_run, 18, NULL,
        !           342:        ai_run, 18, NULL,
        !           343: 
        !           344:        ai_run, 18, NULL,
        !           345:        ai_run, 18, NULL
        !           346: };
        !           347: mmove_t gekk_move_swim_start = {FRAME_swim_01, FRAME_swim_32, gekk_frames_swim_start, gekk_swim_loop};
        !           348: 
        !           349: void gekk_swim (edict_t *self)
        !           350: {
        !           351:        
        !           352:        if (gekk_checkattack)
        !           353:                if (!self->enemy->waterlevel && random() > 0.7)
        !           354:                        water_to_land (self);
        !           355:        else
        !           356:                self->monsterinfo.currentmove = &gekk_move_swim_start;
        !           357: }
        !           358: 
        !           359: 
        !           360: void gekk_stand (edict_t *self)
        !           361: {
        !           362:        if (self->waterlevel)
        !           363:                self->monsterinfo.currentmove = &gekk_move_standunderwater;
        !           364:        else
        !           365:                self->monsterinfo.currentmove = &gekk_move_stand;
        !           366: }
        !           367: 
        !           368: void gekk_chant (edict_t *self)
        !           369: {
        !           370:        self->monsterinfo.currentmove = &gekk_move_chant;
        !           371: }
        !           372: 
        !           373: //
        !           374: // IDLE
        !           375: //
        !           376: 
        !           377: void gekk_idle_loop (edict_t *self)
        !           378: {
        !           379:        if (random() > 0.75 && self->health < self->max_health)
        !           380:                self->monsterinfo.nextframe = FRAME_idle_01;
        !           381: }
        !           382: 
        !           383: mframe_t gekk_frames_idle [] =
        !           384: {
        !           385:        ai_stand2, 0, gekk_search,
        !           386:        ai_stand2, 0, NULL,
        !           387:        ai_stand2, 0, NULL,
        !           388:        ai_stand2, 0, NULL,             
        !           389:        ai_stand2, 0, NULL,
        !           390:        ai_stand2, 0, NULL,
        !           391:        ai_stand2, 0, NULL,             
        !           392:        ai_stand2, 0, NULL,
        !           393:        ai_stand2, 0, NULL,
        !           394:        ai_stand2, 0, NULL,
        !           395:        
        !           396:        ai_stand2, 0, NULL,
        !           397:        ai_stand2, 0, NULL,
        !           398:        ai_stand2, 0, NULL,
        !           399:        ai_stand2, 0, NULL,             
        !           400:        ai_stand2, 0, NULL,
        !           401:        ai_stand2, 0, NULL,
        !           402:        ai_stand2, 0, NULL,             
        !           403:        ai_stand2, 0, NULL,
        !           404:        ai_stand2, 0, NULL,
        !           405:        ai_stand2, 0, NULL,
        !           406:        
        !           407:        ai_stand2, 0, NULL,
        !           408:        ai_stand2, 0, NULL,
        !           409:        ai_stand2, 0, NULL,
        !           410:        ai_stand2, 0, NULL,             
        !           411:        ai_stand2, 0, NULL,
        !           412:        ai_stand2, 0, NULL,
        !           413:        ai_stand2, 0, NULL,             
        !           414:        ai_stand2, 0, NULL,
        !           415:        ai_stand2, 0, NULL,
        !           416:        ai_stand2, 0, NULL,
        !           417:        
        !           418:        ai_stand2, 0, NULL,
        !           419:        ai_stand2, 0, gekk_idle_loop
        !           420: };
        !           421: mmove_t gekk_move_idle = {FRAME_idle_01, FRAME_idle_32, gekk_frames_idle, gekk_stand};
        !           422: mmove_t gekk_move_idle2 = {FRAME_idle_01, FRAME_idle_32, gekk_frames_idle, gekk_face};
        !           423: 
        !           424: mframe_t gekk_frames_idle2 [] =
        !           425: {
        !           426:        ai_move, 0, gekk_search,
        !           427:        ai_move, 0, NULL,
        !           428:        ai_move, 0, NULL,
        !           429:        ai_move, 0, NULL,               
        !           430:        ai_move, 0, NULL,
        !           431:        ai_move, 0, NULL,
        !           432:        ai_move, 0, NULL,               
        !           433:        ai_move, 0, NULL,
        !           434:        ai_move, 0, NULL,
        !           435:        ai_move, 0, NULL,
        !           436:        
        !           437:        ai_move, 0, NULL,
        !           438:        ai_move, 0, NULL,
        !           439:        ai_move, 0, NULL,
        !           440:        ai_move, 0, NULL,               
        !           441:        ai_move, 0, NULL,
        !           442:        ai_move, 0, NULL,
        !           443:        ai_move, 0, NULL,               
        !           444:        ai_move, 0, NULL,
        !           445:        ai_move, 0, NULL,
        !           446:        ai_move, 0, NULL,
        !           447:        
        !           448:        ai_move, 0, NULL,
        !           449:        ai_move, 0, NULL,
        !           450:        ai_move, 0, NULL,
        !           451:        ai_move, 0, NULL,               
        !           452:        ai_move, 0, NULL,
        !           453:        ai_move, 0, NULL,
        !           454:        ai_move, 0, NULL,               
        !           455:        ai_move, 0, NULL,
        !           456:        ai_move, 0, NULL,
        !           457:        ai_move, 0, NULL,
        !           458:        
        !           459:        ai_move, 0, NULL,
        !           460:        ai_move, 0, gekk_idle_loop
        !           461: };
        !           462: mmove_t gekk_move_chant = {FRAME_idle_01, FRAME_idle_32, gekk_frames_idle2, gekk_chant};
        !           463: 
        !           464: 
        !           465: void gekk_idle (edict_t *self)
        !           466: {
        !           467:        if (!self->waterlevel)
        !           468:                self->monsterinfo.currentmove = &gekk_move_idle;
        !           469:        else
        !           470:                self->monsterinfo.currentmove = &gekk_move_swim_start;
        !           471:        // gi.sound (self, CHAN_VOICE, sound_idle, 1, ATTN_IDLE, 0);
        !           472: }
        !           473: 
        !           474: 
        !           475: //
        !           476: // WALK
        !           477: //
        !           478: 
        !           479: void gekk_walk (edict_t *self);
        !           480: mframe_t gekk_frames_walk[] = 
        !           481: {
        !           482:  ai_walk,   3.849, gekk_check_underwater, // frame 0
        !           483:  ai_walk,  19.606, NULL, // frame 1
        !           484:  ai_walk,  25.583, NULL, // frame 2
        !           485:  ai_walk,  34.625, gekk_step, // frame 3
        !           486:  ai_walk,  27.365, NULL, // frame 4
        !           487:  ai_walk,  28.480, NULL, // frame 5
        !           488: };
        !           489: 
        !           490: mmove_t gekk_move_walk = {FRAME_run_01, FRAME_run_06, gekk_frames_walk, NULL};
        !           491: 
        !           492: void gekk_walk (edict_t *self)
        !           493: {
        !           494:        self->monsterinfo.currentmove = &gekk_move_walk;
        !           495: }
        !           496: 
        !           497: 
        !           498: //
        !           499: // RUN
        !           500: //
        !           501: 
        !           502: void gekk_run_start (edict_t *self)
        !           503: {
        !           504:        if (self->waterlevel)
        !           505:        {
        !           506:                self->monsterinfo.currentmove = &gekk_move_swim_start;
        !           507:        }       
        !           508:        else
        !           509:        {
        !           510:                self->monsterinfo.currentmove = &gekk_move_run_start;
        !           511:        }
        !           512: }
        !           513: 
        !           514: void gekk_run (edict_t *self)
        !           515: {
        !           516:        
        !           517:        if (self->waterlevel)
        !           518:        {
        !           519:                self->monsterinfo.currentmove = &gekk_move_swim_start;
        !           520:                return;
        !           521:        }
        !           522:        else
        !           523:        {
        !           524:                if (self->monsterinfo.aiflags & AI_STAND_GROUND)
        !           525:                        self->monsterinfo.currentmove = &gekk_move_stand;
        !           526:                else
        !           527:                        self->monsterinfo.currentmove = &gekk_move_run;
        !           528:        }
        !           529: 
        !           530: }
        !           531: mframe_t gekk_frames_run[] = 
        !           532: {
        !           533:  ai_run,   3.849, gekk_check_underwater, // frame 0
        !           534:  ai_run,  19.606, NULL, // frame 1
        !           535:  ai_run,  25.583, NULL, // frame 2
        !           536:  ai_run,  34.625, gekk_step, // frame 3
        !           537:  ai_run,  27.365, NULL, // frame 4
        !           538:  ai_run,  28.480, NULL, // frame 5
        !           539: };
        !           540: mmove_t gekk_move_run = {FRAME_run_01, FRAME_run_06, gekk_frames_run, NULL};
        !           541: 
        !           542: mframe_t gekk_frames_run_st[] = 
        !           543: {
        !           544:  ai_run,   0.212, NULL, // frame 0
        !           545:  ai_run,  19.753, NULL, // frame 1
        !           546: };
        !           547: mmove_t gekk_move_run_start = {FRAME_stand_01, FRAME_stand_02, gekk_frames_run_st, gekk_run};
        !           548: 
        !           549: //
        !           550: // MELEE
        !           551: //
        !           552: 
        !           553: void gekk_hit_left (edict_t *self)
        !           554: {
        !           555:        vec3_t  aim;
        !           556: 
        !           557:        VectorSet (aim, MELEE_DISTANCE, self->mins[0], 8);
        !           558:        if (fire_hit (self, aim, (15 + (rand() %5)), 100))
        !           559:                gi.sound (self, CHAN_WEAPON, sound_hit, 1, ATTN_NORM, 0);
        !           560:        else
        !           561:                gi.sound (self, CHAN_WEAPON, sound_swing, 1, ATTN_NORM, 0);
        !           562: }
        !           563: 
        !           564: void gekk_hit_right (edict_t *self)
        !           565: {
        !           566:        vec3_t  aim;
        !           567: 
        !           568:        VectorSet (aim, MELEE_DISTANCE, self->maxs[0], 8);
        !           569:        if (fire_hit (self, aim, (15 + (rand() %5)), 100))
        !           570:                gi.sound (self, CHAN_WEAPON, sound_hit2, 1, ATTN_NORM, 0);
        !           571:        else
        !           572:                gi.sound (self, CHAN_WEAPON, sound_swing, 1, ATTN_NORM, 0);
        !           573: }
        !           574: 
        !           575: void gekk_check_refire (edict_t *self)
        !           576: {
        !           577:        if (!self->enemy || !self->enemy->inuse || self->enemy->health <= 0)
        !           578:                return;
        !           579:        
        !           580:        if (random() < (skill->value * 0.1))
        !           581:        {
        !           582:                if (range (self, self->enemy) == RANGE_MELEE)
        !           583:                {
        !           584:                        if (self->s.frame == FRAME_clawatk3_09)
        !           585:                                self->monsterinfo.currentmove = &gekk_move_attack2;
        !           586:                        else if (self->s.frame == FRAME_clawatk5_09)
        !           587:                                self->monsterinfo.currentmove = &gekk_move_attack1;
        !           588:                }
        !           589:        }
        !           590:        
        !           591: }
        !           592: 
        !           593: 
        !           594: void loogie_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
        !           595: {
        !           596: 
        !           597:        if (other == self->owner)
        !           598:                return;
        !           599: 
        !           600:        if (surf && (surf->flags & SURF_SKY))
        !           601:        {
        !           602:                G_FreeEdict (self);
        !           603:                return;
        !           604:        }
        !           605: 
        !           606:        if (self->owner->client)
        !           607:                PlayerNoise(self->owner, self->s.origin, PNOISE_IMPACT);
        !           608: 
        !           609:        if (other->takedamage)
        !           610:                T_Damage (other, self, self->owner, self->velocity, self->s.origin, plane->normal, self->dmg, 1, DAMAGE_ENERGY, MOD_GEKK);
        !           611:        
        !           612:        G_FreeEdict (self);
        !           613: };
        !           614:        
        !           615: 
        !           616: 
        !           617: void fire_loogie (edict_t *self, vec3_t start, vec3_t dir, int damage, int speed)
        !           618: {
        !           619:        edict_t *loogie;
        !           620:        trace_t tr;
        !           621: 
        !           622:        VectorNormalize (dir);
        !           623: 
        !           624:        loogie = G_Spawn();
        !           625:        VectorCopy (start, loogie->s.origin);
        !           626:        VectorCopy (start, loogie->s.old_origin);
        !           627:        vectoangles (dir, loogie->s.angles);
        !           628:        VectorScale (dir, speed, loogie->velocity);
        !           629:        loogie->movetype = MOVETYPE_FLYMISSILE;
        !           630:        loogie->clipmask = MASK_SHOT;
        !           631:        loogie->solid = SOLID_BBOX;
        !           632:        loogie->s.effects |= RF_FULLBRIGHT;
        !           633:        VectorClear (loogie->mins);
        !           634:        VectorClear (loogie->maxs);
        !           635:        
        !           636:        loogie->s.modelindex = gi.modelindex ("models/objects/loogy/tris.md2");
        !           637:        loogie->owner = self;
        !           638:        loogie->touch = loogie_touch;
        !           639:        loogie->nextthink = level.time + 2;
        !           640:        loogie->think = G_FreeEdict;
        !           641:        loogie->dmg = damage;
        !           642:        gi.linkentity (loogie);
        !           643: 
        !           644:        tr = gi.trace (self->s.origin, NULL, NULL, loogie->s.origin, loogie, MASK_SHOT);
        !           645:        if (tr.fraction < 1.0)
        !           646:        {
        !           647:                VectorMA (loogie->s.origin, -10, dir, loogie->s.origin);
        !           648:                loogie->touch (loogie, tr.ent, NULL, NULL);
        !           649:        }
        !           650: 
        !           651: }      
        !           652: 
        !           653: void loogie (edict_t *self)
        !           654: {
        !           655:        vec3_t  start;
        !           656:        vec3_t  forward, right, up;
        !           657:        vec3_t  end;
        !           658:        vec3_t  dir;
        !           659:        vec3_t  gekkoffset;
        !           660: 
        !           661:        VectorSet (gekkoffset, -18, -0.8, 24);
        !           662: 
        !           663:        if (!self->enemy || self->enemy->health <= 0)
        !           664:                return;
        !           665:        
        !           666:        AngleVectors (self->s.angles, forward, right, up);
        !           667:        G_ProjectSource (self->s.origin, gekkoffset, forward, right, start);
        !           668: 
        !           669:        VectorMA (start, 2, up, start);
        !           670:        
        !           671:        VectorCopy (self->enemy->s.origin, end);
        !           672:        end[2] += self->enemy->viewheight;
        !           673:        VectorSubtract (end, start, dir);
        !           674: 
        !           675:        fire_loogie (self, start, dir, 5, 550);
        !           676:        
        !           677: }
        !           678: 
        !           679: void reloogie (edict_t *self)
        !           680: {
        !           681:        if (random() > 0.8 && self->health < self->max_health)
        !           682:        {
        !           683:                self->monsterinfo.currentmove = &gekk_move_idle2;
        !           684:                return;
        !           685:        }
        !           686:                
        !           687:        if (self->enemy->health >= 0)
        !           688:                if (random() > 0.7 && (range(self, self->enemy) == RANGE_NEAR))
        !           689:                        self->monsterinfo.currentmove = &gekk_move_spit;
        !           690: }
        !           691: 
        !           692: 
        !           693: mframe_t gekk_frames_spit [] =
        !           694: {
        !           695:  ai_charge,   0.000, NULL, 
        !           696:  ai_charge,   0.000, NULL, 
        !           697:  ai_charge,   0.000, NULL, 
        !           698:  ai_charge,   0.000, NULL, 
        !           699:  ai_charge,   0.000, NULL, 
        !           700:  
        !           701:  ai_charge,   0.000, loogie, 
        !           702:  ai_charge,   0.000, reloogie 
        !           703: };
        !           704: mmove_t gekk_move_spit = {FRAME_spit_01, FRAME_spit_07, gekk_frames_spit, gekk_run_start};
        !           705: 
        !           706: 
        !           707: mframe_t gekk_frames_attack1 [] =
        !           708: {
        !           709:        ai_charge,   0, NULL, 
        !           710:        ai_charge,   0, NULL, 
        !           711:        ai_charge,   0, NULL, 
        !           712:        
        !           713:        ai_charge,   0, gekk_hit_left, 
        !           714:        ai_charge,   0, NULL, 
        !           715:        ai_charge,   0, NULL, 
        !           716:        
        !           717:        ai_charge,   0, NULL, 
        !           718:        ai_charge,   0, NULL, 
        !           719:        ai_charge,   0, gekk_check_refire 
        !           720:                
        !           721: };
        !           722: mmove_t gekk_move_attack1 = {FRAME_clawatk3_01, FRAME_clawatk3_09, gekk_frames_attack1, gekk_run_start};
        !           723: 
        !           724: mframe_t gekk_frames_attack2[] = 
        !           725: {
        !           726:  ai_charge,   0.000, NULL, 
        !           727:  ai_charge,   0.000, NULL, 
        !           728:  ai_charge,   0.000, gekk_hit_left, 
        !           729:  
        !           730:  ai_charge,   0.000, NULL, 
        !           731:  ai_charge,   0.000, NULL, 
        !           732:  ai_charge,   0.000, gekk_hit_right, 
        !           733:  
        !           734:  ai_charge,   0.000, NULL, 
        !           735:  ai_charge,   0.000, NULL, 
        !           736:  ai_charge,   0.000, gekk_check_refire 
        !           737:  
        !           738: };
        !           739: mmove_t gekk_move_attack2 = {FRAME_clawatk5_01, FRAME_clawatk5_09, gekk_frames_attack2, gekk_run_start};
        !           740: 
        !           741: void gekk_check_underwater (edict_t *self)
        !           742: {
        !           743:        if (self->waterlevel)
        !           744:        {
        !           745:                land_to_water (self);
        !           746:        }
        !           747: }
        !           748: 
        !           749: mframe_t gekk_frames_leapatk[] = 
        !           750: {
        !           751:  ai_charge,   0.000, NULL, // frame 0
        !           752:  ai_charge,  -0.387, NULL, // frame 1
        !           753:  ai_charge,  -1.113, NULL, // frame 2
        !           754:  ai_charge,  -0.237, NULL, // frame 3
        !           755:  ai_charge,   6.720, gekk_jump_takeoff, // frame 4  last frame on ground
        !           756:  ai_charge,   6.414, NULL, // frame 5  leaves ground
        !           757:  ai_charge,   0.163, NULL, // frame 6
        !           758:  ai_charge,  28.316, NULL, // frame 7
        !           759:  ai_charge,  24.198, NULL, // frame 8
        !           760:  ai_charge,  31.742, NULL, // frame 9
        !           761:  ai_charge,  35.977, gekk_check_landing, // frame 10  last frame in air
        !           762:  ai_charge,  12.303, gekk_stop_skid, // frame 11  feet back on ground
        !           763:  ai_charge,  20.122, gekk_stop_skid, // frame 12
        !           764:  ai_charge,  -1.042, gekk_stop_skid, // frame 13
        !           765:  ai_charge,   2.556, gekk_stop_skid, // frame 14
        !           766:  ai_charge,   0.544, gekk_stop_skid, // frame 15
        !           767:  ai_charge,   1.862, gekk_stop_skid, // frame 16
        !           768:  ai_charge,   1.224, gekk_stop_skid, // frame 17
        !           769: 
        !           770:  ai_charge,  -0.457, gekk_check_underwater, // frame 18
        !           771: };
        !           772: mmove_t gekk_move_leapatk = {FRAME_leapatk_01, FRAME_leapatk_19, gekk_frames_leapatk, gekk_run_start};
        !           773: 
        !           774: 
        !           775: mframe_t gekk_frames_leapatk2[] = 
        !           776: {
        !           777:  ai_charge,   0.000, NULL, // frame 0
        !           778:  ai_charge,  -0.387, NULL, // frame 1
        !           779:  ai_charge,  -1.113, NULL, // frame 2
        !           780:  ai_charge,  -0.237, NULL, // frame 3
        !           781:  ai_charge,   6.720, gekk_jump_takeoff2, // frame 4  last frame on ground
        !           782:  ai_charge,   6.414, NULL, // frame 5  leaves ground
        !           783:  ai_charge,   0.163, NULL, // frame 6
        !           784:  ai_charge,  28.316, NULL, // frame 7
        !           785:  ai_charge,  24.198, NULL, // frame 8
        !           786:  ai_charge,  31.742, NULL, // frame 9
        !           787:  ai_charge,  35.977, gekk_check_landing, // frame 10  last frame in air
        !           788:  ai_charge,  12.303, gekk_stop_skid, // frame 11  feet back on ground
        !           789:  ai_charge,  20.122, gekk_stop_skid, // frame 12
        !           790:  ai_charge,  -1.042, gekk_stop_skid, // frame 13
        !           791:  ai_charge,   2.556, gekk_stop_skid, // frame 14
        !           792:  ai_charge,   0.544, gekk_stop_skid, // frame 15
        !           793:  ai_charge,   1.862, gekk_stop_skid, // frame 16
        !           794:  ai_charge,   1.224, gekk_stop_skid, // frame 17
        !           795:  
        !           796:  ai_charge,  -0.457, gekk_check_underwater, // frame 18
        !           797: };
        !           798: mmove_t gekk_move_leapatk2 = {FRAME_leapatk_01, FRAME_leapatk_19, gekk_frames_leapatk2, gekk_run_start};
        !           799: 
        !           800: 
        !           801: void gekk_bite (edict_t *self)
        !           802: {
        !           803:        vec3_t  aim;
        !           804: 
        !           805:        VectorSet (aim, MELEE_DISTANCE, 0, 0);
        !           806:        fire_hit (self, aim, 5, 0);
        !           807: }
        !           808: 
        !           809: void gekk_preattack (edict_t *self)
        !           810: {
        !           811:        // underwater attack sound
        !           812:        // gi.sound (self, CHAN_WEAPON, something something underwater sound, 1, ATTN_NORM, 0);
        !           813:        return;
        !           814: }
        !           815: 
        !           816: 
        !           817: mframe_t gekk_frames_attack [] =
        !           818: {
        !           819:        ai_charge, 16,  gekk_preattack,
        !           820:        ai_charge, 16,  NULL,
        !           821:        ai_charge, 16,  NULL,
        !           822:        ai_charge, 16,  NULL,
        !           823:        ai_charge, 16,  gekk_bite,
        !           824:        ai_charge, 16,  NULL,
        !           825:        ai_charge, 16,  NULL,
        !           826:        ai_charge, 16,  NULL,
        !           827:        ai_charge, 16,  NULL,
        !           828:        ai_charge, 16,  gekk_bite,
        !           829:        
        !           830:        ai_charge, 16,  NULL,
        !           831:        ai_charge, 16,  NULL,
        !           832:        ai_charge, 16,  NULL,
        !           833:        ai_charge, 16,  gekk_hit_left,
        !           834:        ai_charge, 16,  NULL,
        !           835:        ai_charge, 16,  NULL,
        !           836:        ai_charge, 16,  NULL,
        !           837:        ai_charge, 16,  NULL,
        !           838:        ai_charge, 16,  gekk_hit_right,
        !           839:        ai_charge, 16,  NULL,
        !           840: 
        !           841:        ai_charge, 16,  NULL
        !           842:                
        !           843: };
        !           844: mmove_t gekk_move_attack = {FRAME_attack_01, FRAME_attack_21, gekk_frames_attack, gekk_run_start};
        !           845: 
        !           846: void gekk_melee (edict_t *self)
        !           847: {
        !           848:        
        !           849:        float r;
        !           850:        
        !           851:        if (self->waterlevel)
        !           852:        {
        !           853:                self->monsterinfo.currentmove = &gekk_move_attack;      
        !           854:        }
        !           855:        else
        !           856:        {
        !           857:                r = random();
        !           858: 
        !           859:                if (r > 0.66)
        !           860:                        self->monsterinfo.currentmove = &gekk_move_attack1;
        !           861:                else 
        !           862:                        self->monsterinfo.currentmove = &gekk_move_attack2;
        !           863:                
        !           864:        }
        !           865: 
        !           866: }
        !           867: 
        !           868: 
        !           869: //
        !           870: // ATTACK
        !           871: //
        !           872: 
        !           873: void gekk_jump_touch (edict_t *self, edict_t *other, cplane_t *plane, csurface_t *surf)
        !           874: {
        !           875:        if (self->health <= 0)
        !           876:        {
        !           877:                self->touch = NULL;
        !           878:                return;
        !           879:        }
        !           880: 
        !           881:        if (other->takedamage)
        !           882:        {
        !           883:                if (VectorLength(self->velocity) > 200)
        !           884:                {
        !           885:                        vec3_t  point;
        !           886:                        vec3_t  normal;
        !           887:                        int             damage;
        !           888: 
        !           889:                        VectorCopy (self->velocity, normal);
        !           890:                        VectorNormalize(normal);
        !           891:                        VectorMA (self->s.origin, self->maxs[0], normal, point);
        !           892:                        damage = 10 + 10 * random();
        !           893:                        T_Damage (other, self, self, self->velocity, point, normal, damage, damage, 0, MOD_GEKK);
        !           894:                }
        !           895:        }
        !           896: 
        !           897:        if (!M_CheckBottom (self))
        !           898:        {
        !           899:                if (self->groundentity)
        !           900:                {
        !           901:                        self->monsterinfo.nextframe = FRAME_leapatk_11;
        !           902:                        self->touch = NULL;
        !           903:                }
        !           904:                return;
        !           905:        }
        !           906: 
        !           907:        self->touch = NULL;
        !           908: }
        !           909: 
        !           910: void gekk_jump_takeoff (edict_t *self)
        !           911: {
        !           912:        vec3_t  forward;
        !           913: 
        !           914:        gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
        !           915:        AngleVectors (self->s.angles, forward, NULL, NULL);
        !           916:        self->s.origin[2] += 1;
        !           917:        
        !           918:        // high jump
        !           919:        if (gekk_check_jump (self))
        !           920:        {
        !           921:                VectorScale (forward, 700, self->velocity);
        !           922:                self->velocity[2] = 250;
        !           923:        }
        !           924:        else
        !           925:        {
        !           926:                VectorScale (forward, 250, self->velocity);
        !           927:                self->velocity[2] = 400;
        !           928:        }
        !           929: 
        !           930:        
        !           931:        self->groundentity = NULL;
        !           932:        self->monsterinfo.aiflags |= AI_DUCKED;
        !           933:        self->monsterinfo.attack_finished = level.time + 3;
        !           934:        self->touch = gekk_jump_touch;
        !           935: }
        !           936: 
        !           937: void gekk_jump_takeoff2 (edict_t *self)
        !           938: {
        !           939:        vec3_t  forward;
        !           940: 
        !           941:        gi.sound (self, CHAN_VOICE, sound_sight, 1, ATTN_NORM, 0);
        !           942:        AngleVectors (self->s.angles, forward, NULL, NULL);
        !           943:        self->s.origin[2] = self->enemy->s.origin[2];
        !           944:        
        !           945:        if (gekk_check_jump (self))
        !           946:        {
        !           947:                VectorScale (forward, 300, self->velocity);
        !           948:                self->velocity[2] = 250;
        !           949:        }
        !           950:        else 
        !           951:        {
        !           952:                VectorScale (forward, 150, self->velocity);
        !           953:                self->velocity[2] = 300;
        !           954:        }
        !           955: 
        !           956:        self->groundentity = NULL;
        !           957:        self->monsterinfo.aiflags |= AI_DUCKED;
        !           958:        self->monsterinfo.attack_finished = level.time + 3;
        !           959:        self->touch = gekk_jump_touch;
        !           960:        
        !           961: }
        !           962: 
        !           963: void gekk_stop_skid (edict_t *self)
        !           964: {
        !           965:        if (self->groundentity)
        !           966:        {
        !           967:                VectorClear (self->velocity);
        !           968:        }
        !           969: }
        !           970: 
        !           971: void gekk_check_landing (edict_t *self)
        !           972: {
        !           973:        if (self->groundentity)
        !           974:        {
        !           975:                gi.sound (self, CHAN_WEAPON, sound_thud, 1, ATTN_NORM, 0);
        !           976:                self->monsterinfo.attack_finished = 0;
        !           977:                self->monsterinfo.aiflags &= ~AI_DUCKED;
        !           978: 
        !           979:                VectorClear (self->velocity);
        !           980: 
        !           981:                return;
        !           982:        }
        !           983: 
        !           984:        // note to self
        !           985:        // causing skid
        !           986:        if (level.time > self->monsterinfo.attack_finished)
        !           987:                self->monsterinfo.nextframe = FRAME_leapatk_11;
        !           988:        else
        !           989:        {
        !           990:                self->monsterinfo.nextframe = FRAME_leapatk_12;
        !           991:        }
        !           992: }
        !           993: 
        !           994: void gekk_jump (edict_t *self)
        !           995: {
        !           996:        
        !           997:        if (self->flags & FL_SWIM || self->waterlevel)
        !           998:        {
        !           999:                return;
        !          1000:        }
        !          1001:        else
        !          1002:        {
        !          1003:                //if (random() > 0.8 && self->health < self->max_health)
        !          1004:                //      self->monsterinfo.currentmove = &gekk_move_idle2;
        !          1005:                //else
        !          1006:                {
        !          1007:                        if (random() > 0.5 && (range (self, self->enemy) >= RANGE_NEAR))
        !          1008:                                self->monsterinfo.currentmove = &gekk_move_spit;
        !          1009:                        else if (random() > 0.8)
        !          1010:                                self->monsterinfo.currentmove = &gekk_move_spit;
        !          1011:                        else
        !          1012:                                self->monsterinfo.currentmove = &gekk_move_leapatk;
        !          1013:                        
        !          1014:                }
        !          1015:        }
        !          1016: }
        !          1017: 
        !          1018: //
        !          1019: // PAIN
        !          1020: //
        !          1021: 
        !          1022: mframe_t gekk_frames_pain[] = 
        !          1023: {
        !          1024:        ai_move,   0.000, NULL, // frame 0
        !          1025:        ai_move,   0.000, NULL, // frame 1
        !          1026:        ai_move,   0.000, NULL, // frame 2
        !          1027:        ai_move,   0.000, NULL, // frame 3
        !          1028:        ai_move,   0.000, NULL, // frame 4
        !          1029:        ai_move,   0.000, NULL, // frame 5
        !          1030: };
        !          1031: mmove_t gekk_move_pain = {FRAME_pain_01, FRAME_pain_06, gekk_frames_pain, gekk_run_start};
        !          1032: 
        !          1033: mframe_t gekk_frames_pain1[] = 
        !          1034: {
        !          1035:  ai_move,   0.000, NULL, // frame 0
        !          1036:  ai_move,   0.000, NULL, // frame 1
        !          1037:  ai_move,   0.000, NULL, // frame 2
        !          1038:  ai_move,   0.000, NULL, // frame 3
        !          1039:  ai_move,   0.000, NULL, // frame 4
        !          1040:  ai_move,   0.000, NULL, // frame 5
        !          1041:  ai_move,   0.000, NULL, // frame 6
        !          1042:  ai_move,   0.000, NULL, // frame 7
        !          1043:  ai_move,   0.000, NULL, // frame 8
        !          1044:  ai_move,   0.000, NULL, // frame 9
        !          1045:  
        !          1046:  ai_move,   0.000, gekk_check_underwater 
        !          1047: };
        !          1048: mmove_t gekk_move_pain1 = {FRAME_pain3_01, FRAME_pain3_11, gekk_frames_pain1, gekk_run_start};
        !          1049: 
        !          1050: mframe_t gekk_frames_pain2[] = 
        !          1051: {
        !          1052:  ai_move,   0.000, NULL, // frame 0
        !          1053:  ai_move,   0.000, NULL, // frame 1
        !          1054:  ai_move,   0.000, NULL, // frame 2
        !          1055:  ai_move,   0.000, NULL, // frame 3
        !          1056:  ai_move,   0.000, NULL, // frame 4
        !          1057:  ai_move,   0.000, NULL, // frame 5
        !          1058:  ai_move,   0.000, NULL, // frame 6
        !          1059:  ai_move,   0.000, NULL, // frame 7
        !          1060:  ai_move,   0.000, NULL, // frame 8
        !          1061:  ai_move,   0.000, NULL, // frame 9
        !          1062:  
        !          1063:  ai_move,   0.000, NULL, // frame 10
        !          1064:  ai_move,   0.000, NULL, // frame 11
        !          1065:  ai_move,   0.000, gekk_check_underwater, 
        !          1066: };
        !          1067: mmove_t gekk_move_pain2 = {FRAME_pain4_01, FRAME_pain4_13, gekk_frames_pain2, gekk_run_start};
        !          1068: 
        !          1069: void gekk_pain (edict_t *self, edict_t *other, float kick, int damage)
        !          1070: {
        !          1071:        float   r;
        !          1072: 
        !          1073:        if (self->spawnflags & 8)
        !          1074:        {
        !          1075:                self->spawnflags &= ~8;
        !          1076:                return;
        !          1077:        }
        !          1078:        
        !          1079:        if (self->health < (self->max_health /4))
        !          1080:                self->s.skinnum = 2;
        !          1081:        else if (self->health < (self->max_health / 2))
        !          1082:                self->s.skinnum = 1;
        !          1083: 
        !          1084:        if (level.time < self->pain_debounce_time)
        !          1085:                return;
        !          1086: 
        !          1087:        self->pain_debounce_time = level.time + 3;
        !          1088: 
        !          1089:        gi.sound (self, CHAN_VOICE, sound_pain1, 1, ATTN_NORM, 0);
        !          1090:                
        !          1091:        if (self->waterlevel)
        !          1092:        {
        !          1093:                if (!self->flags & FL_SWIM)
        !          1094:                        self->flags |= FL_SWIM;
        !          1095:                
        !          1096:                self->monsterinfo.currentmove = &gekk_move_pain;
        !          1097:        }
        !          1098:        else
        !          1099:        {
        !          1100:                r = random();
        !          1101: 
        !          1102:                if (r > 0.5)
        !          1103:                        self->monsterinfo.currentmove = &gekk_move_pain1;
        !          1104:                else
        !          1105:                        self->monsterinfo.currentmove = &gekk_move_pain2;
        !          1106:        }
        !          1107: }
        !          1108: 
        !          1109: 
        !          1110: //
        !          1111: // DEATH
        !          1112: //
        !          1113: 
        !          1114: void gekk_dead (edict_t *self)
        !          1115: {
        !          1116:        // fix this because of no blocking problem
        !          1117:        if (self->waterlevel)
        !          1118:        {
        !          1119:                return;
        !          1120:        }
        !          1121:        else
        !          1122:        {
        !          1123:                VectorSet (self->mins, -16, -16, -24);
        !          1124:                VectorSet (self->maxs, 16, 16, -8);
        !          1125:                self->movetype = MOVETYPE_TOSS;
        !          1126:                self->svflags |= SVF_DEADMONSTER;
        !          1127:                self->nextthink = 0;
        !          1128:                gi.linkentity (self);
        !          1129:        }
        !          1130: 
        !          1131:        
        !          1132: }
        !          1133: 
        !          1134: void gekk_gibfest (edict_t *self)
        !          1135: {
        !          1136: 
        !          1137:        int damage = 20;
        !          1138:        
        !          1139:        gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
        !          1140:        
        !          1141:        ThrowGibACID (self, "models/objects/gekkgib/pelvis/tris.md2", damage, GIB_ORGANIC);
        !          1142:        ThrowGibACID (self, "models/objects/gekkgib/arm/tris.md2", damage, GIB_ORGANIC);
        !          1143:        ThrowGibACID (self, "models/objects/gekkgib/arm/tris.md2", damage, GIB_ORGANIC);
        !          1144:        ThrowGibACID (self, "models/objects/gekkgib/torso/tris.md2", damage, GIB_ORGANIC);
        !          1145:        ThrowGibACID (self, "models/objects/gekkgib/claw/tris.md2", damage, GIB_ORGANIC);
        !          1146:        ThrowGibACID (self, "models/objects/gekkgib/leg/tris.md2", damage, GIB_ORGANIC);
        !          1147:        ThrowGibACID (self, "models/objects/gekkgib/leg/tris.md2", damage, GIB_ORGANIC);
        !          1148:        
        !          1149:        ThrowHeadACID (self, "models/objects/gekkgib/head/tris.md2", damage, GIB_ORGANIC);
        !          1150:        
        !          1151: 
        !          1152:        self->deadflag = DEAD_DEAD;
        !          1153:        
        !          1154: }
        !          1155: 
        !          1156: void isgibfest (edict_t *self)
        !          1157: {
        !          1158:        if (random() > 0.9)
        !          1159:                gekk_gibfest (self);
        !          1160: }
        !          1161: 
        !          1162: mframe_t gekk_frames_death1[] =
        !          1163: {
        !          1164: 
        !          1165:        ai_move,  -5.151, NULL, // frame 0
        !          1166:        ai_move, -12.223, NULL, // frame 1
        !          1167:        ai_move, -11.484, NULL, // frame 2
        !          1168:        ai_move, -17.952, NULL, // frame 3
        !          1169:        ai_move,  -6.953, NULL, // frame 4
        !          1170:        ai_move,  -7.393, NULL, // frame 5
        !          1171:        ai_move, -10.713, NULL, // frame 6
        !          1172:        ai_move, -17.464, NULL, // frame 7
        !          1173:        ai_move, -11.678, NULL, // frame 8
        !          1174:        ai_move, -11.678, NULL  // frame 9
        !          1175: };
        !          1176: mmove_t gekk_move_death1 = {FRAME_death1_01, FRAME_death1_10, gekk_frames_death1, gekk_dead};
        !          1177: 
        !          1178: mframe_t gekk_frames_death3[] =
        !          1179: {
        !          1180:        ai_move,   0.000, NULL, // frame 0
        !          1181:        ai_move,   0.022, NULL, // frame 1
        !          1182:        ai_move,   0.169, NULL, // frame 2
        !          1183:        ai_move,  -0.710, NULL, // frame 3
        !          1184:        ai_move, -13.446, NULL, // frame 4
        !          1185:        ai_move,  -7.654, isgibfest, // frame 5
        !          1186:        ai_move, -31.951, NULL, // frame 6
        !          1187:        
        !          1188: };
        !          1189: mmove_t gekk_move_death3 = {FRAME_death3_01, FRAME_death3_07, gekk_frames_death3, gekk_dead};
        !          1190: 
        !          1191: mframe_t gekk_frames_death4[] = 
        !          1192: {
        !          1193:  ai_move,   5.103, NULL, // frame 0
        !          1194:  ai_move,  -4.808, NULL, // frame 1
        !          1195:  ai_move, -10.509, NULL, // frame 2
        !          1196:  ai_move,  -9.899, NULL, // frame 3
        !          1197:  ai_move,   4.033, isgibfest, // frame 4
        !          1198:  ai_move,  -5.197, NULL, // frame 5
        !          1199:  ai_move,  -0.919, NULL, // frame 6
        !          1200:  ai_move,  -8.821, NULL, // frame 7
        !          1201:  ai_move,  -5.626, NULL, // frame 8
        !          1202:  ai_move,  -8.865, isgibfest, // frame 9
        !          1203:  ai_move,  -0.845, NULL, // frame 10
        !          1204:  ai_move,   1.986, NULL, // frame 11
        !          1205:  ai_move,   0.170, NULL, // frame 12
        !          1206:  ai_move,   1.339, isgibfest, // frame 13
        !          1207:  ai_move,  -0.922, NULL, // frame 14
        !          1208:  ai_move,   0.818, NULL, // frame 15
        !          1209:  ai_move,  -1.288, NULL, // frame 16
        !          1210:  ai_move,  -1.408, isgibfest, // frame 17
        !          1211:  ai_move,  -7.787, NULL, // frame 18
        !          1212:  ai_move,  -3.995, NULL, // frame 19
        !          1213:  ai_move,  -4.604, NULL, // frame 20
        !          1214:  ai_move,  -1.715, isgibfest, // frame 21
        !          1215:  ai_move,  -0.564, NULL, // frame 22
        !          1216:  ai_move,  -0.597, NULL, // frame 23
        !          1217:  ai_move,   0.074, NULL, // frame 24
        !          1218:  ai_move,  -0.309, isgibfest, // frame 25
        !          1219:  ai_move,  -0.395, NULL, // frame 26
        !          1220:  ai_move,  -0.501, NULL, // frame 27
        !          1221:  ai_move,  -0.325, NULL, // frame 28
        !          1222:  ai_move,  -0.931, isgibfest, // frame 29
        !          1223:  ai_move,  -1.433, NULL, // frame 30
        !          1224:  ai_move,  -1.626, NULL, // frame 31
        !          1225:  ai_move,   4.680, NULL, // frame 32
        !          1226:  ai_move,   0.560, NULL, // frame 33
        !          1227:  ai_move,  -0.549, gekk_gibfest // frame 34
        !          1228: };
        !          1229: mmove_t gekk_move_death4 = {FRAME_death4_01, FRAME_death4_35, gekk_frames_death4, gekk_dead};
        !          1230: 
        !          1231: mframe_t gekk_frames_wdeath[] = 
        !          1232: {
        !          1233:         ai_move,   0.000, NULL, // frame 0
        !          1234:         ai_move,   0.000, NULL, // frame 1
        !          1235:         ai_move,   0.000, NULL, // frame 2
        !          1236:         ai_move,   0.000, NULL, // frame 3
        !          1237:         ai_move,   0.000, NULL, // frame 4
        !          1238:         ai_move,   0.000, NULL, // frame 5
        !          1239:         ai_move,   0.000, NULL, // frame 6
        !          1240:         ai_move,   0.000, NULL, // frame 7
        !          1241:         ai_move,   0.000, NULL, // frame 8
        !          1242:         ai_move,   0.000, NULL, // frame 9
        !          1243:         ai_move,   0.000, NULL, // frame 10
        !          1244:         ai_move,   0.000, NULL, // frame 11
        !          1245:         ai_move,   0.000, NULL, // frame 12
        !          1246:         ai_move,   0.000, NULL, // frame 13
        !          1247:         ai_move,   0.000, NULL, // frame 14
        !          1248:         ai_move,   0.000, NULL, // frame 15
        !          1249:         ai_move,   0.000, NULL, // frame 16
        !          1250:         ai_move,   0.000, NULL, // frame 17
        !          1251:         ai_move,   0.000, NULL, // frame 18
        !          1252:         ai_move,   0.000, NULL, // frame 19
        !          1253:         ai_move,   0.000, NULL, // frame 20
        !          1254:         ai_move,   0.000, NULL, // frame 21
        !          1255:         ai_move,   0.000, NULL, // frame 22
        !          1256:         ai_move,   0.000, NULL, // frame 23
        !          1257:         ai_move,   0.000, NULL, // frame 24
        !          1258:         ai_move,   0.000, NULL, // frame 25
        !          1259:         ai_move,   0.000, NULL, // frame 26
        !          1260:         ai_move,   0.000, NULL, // frame 27
        !          1261:         ai_move,   0.000, NULL, // frame 28
        !          1262:         ai_move,   0.000, NULL, // frame 29
        !          1263:         ai_move,   0.000, NULL, // frame 30
        !          1264:         ai_move,   0.000, NULL, // frame 31
        !          1265:         ai_move,   0.000, NULL, // frame 32
        !          1266:         ai_move,   0.000, NULL, // frame 33
        !          1267:         ai_move,   0.000, NULL, // frame 34
        !          1268:         ai_move,   0.000, NULL, // frame 35
        !          1269:         ai_move,   0.000, NULL, // frame 36
        !          1270:         ai_move,   0.000, NULL, // frame 37
        !          1271:         ai_move,   0.000, NULL, // frame 38
        !          1272:         ai_move,   0.000, NULL, // frame 39
        !          1273:         ai_move,   0.000, NULL, // frame 40
        !          1274:         ai_move,   0.000, NULL, // frame 41
        !          1275:         ai_move,   0.000, NULL, // frame 42
        !          1276:         ai_move,   0.000, NULL, // frame 43
        !          1277:         ai_move,   0.000, NULL  // frame 44
        !          1278: };
        !          1279: mmove_t gekk_move_wdeath = {FRAME_wdeath_01, FRAME_wdeath_45, gekk_frames_wdeath, gekk_dead};
        !          1280: 
        !          1281: void gekk_die (edict_t *self, edict_t *inflictor, edict_t *attacker, int damage, vec3_t point)
        !          1282: {
        !          1283:        
        !          1284:        float   r;
        !          1285: 
        !          1286:        if (self->health <= self->gib_health)
        !          1287:        {
        !          1288:                gi.sound (self, CHAN_VOICE, gi.soundindex ("misc/udeath.wav"), 1, ATTN_NORM, 0);
        !          1289: 
        !          1290:                ThrowGibACID (self, "models/objects/gekkgib/pelvis/tris.md2", damage, GIB_ORGANIC);
        !          1291:                ThrowGibACID (self, "models/objects/gekkgib/arm/tris.md2", damage, GIB_ORGANIC);
        !          1292:                ThrowGibACID (self, "models/objects/gekkgib/arm/tris.md2", damage, GIB_ORGANIC);
        !          1293:                ThrowGibACID (self, "models/objects/gekkgib/torso/tris.md2", damage, GIB_ORGANIC);
        !          1294:                ThrowGibACID (self, "models/objects/gekkgib/claw/tris.md2", damage, GIB_ORGANIC);
        !          1295:                ThrowGibACID (self, "models/objects/gekkgib/leg/tris.md2", damage, GIB_ORGANIC);
        !          1296:                ThrowGibACID (self, "models/objects/gekkgib/leg/tris.md2", damage, GIB_ORGANIC);
        !          1297:        
        !          1298:                ThrowHeadACID (self, "models/objects/gekkgib/head/tris.md2", damage, GIB_ORGANIC);
        !          1299: 
        !          1300:                self->deadflag = DEAD_DEAD;
        !          1301:                return;
        !          1302:        }
        !          1303: 
        !          1304:        if (self->deadflag == DEAD_DEAD)
        !          1305:                return;
        !          1306: 
        !          1307:        gi.sound (self, CHAN_VOICE, sound_death, 1, ATTN_NORM, 0);
        !          1308:        self->deadflag = DEAD_DEAD;
        !          1309:        self->takedamage = DAMAGE_YES;
        !          1310:        self->s.skinnum = 2;
        !          1311: 
        !          1312:        if (self->waterlevel)
        !          1313:                self->monsterinfo.currentmove = &gekk_move_wdeath;
        !          1314:        else
        !          1315:        {
        !          1316:                r = random();
        !          1317:                if (r > 0.66)
        !          1318:                        self->monsterinfo.currentmove = &gekk_move_death1;
        !          1319:                else if (r > 0.33)
        !          1320:                        self->monsterinfo.currentmove = &gekk_move_death3;
        !          1321:                else
        !          1322:                        self->monsterinfo.currentmove = &gekk_move_death4;
        !          1323: 
        !          1324:        }
        !          1325:        
        !          1326: }
        !          1327: 
        !          1328: 
        !          1329: /*
        !          1330:        duck
        !          1331: */
        !          1332: void gekk_duck_down (edict_t *self)
        !          1333: {
        !          1334:        if (self->monsterinfo.aiflags & AI_DUCKED)
        !          1335:                return;
        !          1336:        self->monsterinfo.aiflags |= AI_DUCKED;
        !          1337:        self->maxs[2] -= 32;
        !          1338:        self->takedamage = DAMAGE_YES;
        !          1339:        self->monsterinfo.pausetime = level.time + 1;
        !          1340:        gi.linkentity (self);
        !          1341: }
        !          1342: 
        !          1343: void gekk_duck_up (edict_t *self)
        !          1344: {
        !          1345:        self->monsterinfo.aiflags &= ~AI_DUCKED;
        !          1346:        self->maxs[2] += 32;
        !          1347:        self->takedamage = DAMAGE_AIM;
        !          1348:        gi.linkentity (self);
        !          1349: }
        !          1350: 
        !          1351: 
        !          1352: void gekk_duck_hold (edict_t *self)
        !          1353: {
        !          1354:        if (level.time >= self->monsterinfo.pausetime)
        !          1355:                self->monsterinfo.aiflags &= ~AI_HOLD_FRAME;
        !          1356:        else
        !          1357:                self->monsterinfo.aiflags |= AI_HOLD_FRAME;
        !          1358: }
        !          1359: 
        !          1360: mframe_t gekk_frames_lduck[] = 
        !          1361: {
        !          1362:  ai_move,   0.000, NULL, // frame 0
        !          1363:  ai_move,   0.000, NULL, // frame 1
        !          1364:  ai_move,   0.000, NULL, // frame 2
        !          1365:  ai_move,   0.000, NULL, // frame 3
        !          1366:  ai_move,   0.000, NULL, // frame 4
        !          1367:  ai_move,   0.000, NULL, // frame 5
        !          1368:  ai_move,   0.000, NULL, // frame 6
        !          1369:  ai_move,   0.000, NULL, // frame 7
        !          1370:  ai_move,   0.000, NULL, // frame 8
        !          1371:  ai_move,   0.000, NULL, // frame 9
        !          1372:  
        !          1373:  ai_move,   0.000, NULL, // frame 10
        !          1374:  ai_move,   0.000, NULL, // frame 11
        !          1375:  ai_move,   0.000, NULL  // frame 12
        !          1376:  
        !          1377: };
        !          1378: mmove_t gekk_move_lduck = {FRAME_lduck_01, FRAME_lduck_13, gekk_frames_lduck, gekk_run_start};
        !          1379: 
        !          1380: mframe_t gekk_frames_rduck[] = 
        !          1381: {
        !          1382:  ai_move,   0.000, NULL, // frame 0
        !          1383:  ai_move,   0.000, NULL, // frame 1
        !          1384:  ai_move,   0.000, NULL, // frame 2
        !          1385:  ai_move,   0.000, NULL, // frame 3
        !          1386:  ai_move,   0.000, NULL, // frame 4
        !          1387:  ai_move,   0.000, NULL, // frame 5
        !          1388:  ai_move,   0.000, NULL, // frame 6
        !          1389:  ai_move,   0.000, NULL, // frame 7
        !          1390:  ai_move,   0.000, NULL, // frame 8
        !          1391:  ai_move,   0.000, NULL, // frame 9
        !          1392:  ai_move,   0.000, NULL, // frame 10
        !          1393:  ai_move,   0.000, NULL, // frame 11
        !          1394:  ai_move,   0.000, NULL // frame 12
        !          1395:  
        !          1396: };
        !          1397: mmove_t gekk_move_rduck = {FRAME_rduck_01, FRAME_rduck_13, gekk_frames_rduck, gekk_run_start};
        !          1398: 
        !          1399: 
        !          1400: void gekk_dodge (edict_t *self, edict_t *attacker, float eta)
        !          1401: {
        !          1402:        float   r;
        !          1403: 
        !          1404:        r = random();
        !          1405:        if (r > 0.25)
        !          1406:                return;
        !          1407: 
        !          1408:        if (!self->enemy)
        !          1409:                self->enemy = attacker;
        !          1410: 
        !          1411:        if (self->waterlevel)
        !          1412:        {
        !          1413:                self->monsterinfo.currentmove = &gekk_move_attack;
        !          1414:                return;
        !          1415:        }
        !          1416:        
        !          1417:        if (skill->value == 0)
        !          1418:        {
        !          1419:                r = random();
        !          1420:                if (r > 0.5)
        !          1421:                        self->monsterinfo.currentmove = &gekk_move_lduck;
        !          1422:                else 
        !          1423:                        self->monsterinfo.currentmove = &gekk_move_rduck;
        !          1424:                return;
        !          1425:        }
        !          1426: 
        !          1427:        self->monsterinfo.pausetime = level.time + eta + 0.3;
        !          1428:        r = random();
        !          1429: 
        !          1430:        if (skill->value == 1)
        !          1431:        {
        !          1432:                if (r > 0.33)
        !          1433:                {
        !          1434:                        r = random();
        !          1435:                        if (r > 0.5)
        !          1436:                                self->monsterinfo.currentmove = &gekk_move_lduck;
        !          1437:                        else 
        !          1438:                                self->monsterinfo.currentmove = &gekk_move_rduck;
        !          1439:                }
        !          1440:                else
        !          1441:                {
        !          1442:                        r = random();
        !          1443:                        if (r > 0.66)
        !          1444:                                self->monsterinfo.currentmove = &gekk_move_attack1;
        !          1445:                        else 
        !          1446:                                self->monsterinfo.currentmove = &gekk_move_attack2;
        !          1447:                        
        !          1448:                }
        !          1449:                return;
        !          1450:        }
        !          1451: 
        !          1452:        if (skill->value == 2)
        !          1453:        {
        !          1454:                if (r > 0.66)
        !          1455:                {
        !          1456:                        r = random();
        !          1457:                        if (r > 0.5)
        !          1458:                                self->monsterinfo.currentmove = &gekk_move_lduck;
        !          1459:                        else 
        !          1460:                                self->monsterinfo.currentmove = &gekk_move_rduck;
        !          1461:                }
        !          1462:                else
        !          1463:                {
        !          1464:                        r = random();
        !          1465:                        if (r > 0.66)
        !          1466:                                self->monsterinfo.currentmove = &gekk_move_attack1;
        !          1467:                        else 
        !          1468:                                self->monsterinfo.currentmove = &gekk_move_attack2;
        !          1469:                }
        !          1470:                return;
        !          1471:        }
        !          1472: 
        !          1473:        r = random();
        !          1474:        if (r > 0.66)
        !          1475:                self->monsterinfo.currentmove = &gekk_move_attack1;
        !          1476:        else 
        !          1477:                self->monsterinfo.currentmove = &gekk_move_attack2;
        !          1478:        
        !          1479:        
        !          1480: }
        !          1481: 
        !          1482: //
        !          1483: // SPAWN
        !          1484: //
        !          1485: 
        !          1486: /*QUAKED monster_gekk (1 .5 0) (-24 -24 -24) (24 24 24) Ambush Trigger_Spawn Sight Chant
        !          1487: */
        !          1488: void SP_monster_gekk (edict_t *self)
        !          1489: {
        !          1490:        if (deathmatch->value)
        !          1491:        {
        !          1492:                G_FreeEdict (self);
        !          1493:                return;
        !          1494:        }
        !          1495: 
        !          1496:        sound_swing = gi.soundindex ("gek/gk_atck1.wav");
        !          1497:        sound_hit = gi.soundindex ("gek/gk_atck2.wav");
        !          1498:        sound_hit2 = gi.soundindex ("gek/gk_atck3.wav");
        !          1499:        sound_death = gi.soundindex ("gek/gk_deth1.wav");
        !          1500:        sound_pain1 = gi.soundindex ("gek/gk_pain1.wav");
        !          1501:        sound_sight = gi.soundindex ("gek/gk_sght1.wav");
        !          1502:        sound_search = gi.soundindex ("gek/gk_idle1.wav");
        !          1503:        sound_step1 = gi.soundindex ("gek/gk_step1.wav");
        !          1504:        sound_step2 = gi.soundindex ("gek/gk_step2.wav");
        !          1505:        sound_step3 = gi.soundindex ("gek/gk_step3.wav");
        !          1506:        sound_thud = gi.soundindex ("mutant/thud1.wav");
        !          1507:        
        !          1508:        sound_chantlow = gi.soundindex ("gek/gek_low.wav");
        !          1509:        sound_chantmid = gi.soundindex ("gek/gek_mid.wav");
        !          1510:        sound_chanthigh = gi.soundindex ("gek/gek_high.wav");
        !          1511:        
        !          1512:        self->movetype = MOVETYPE_STEP;
        !          1513:        self->solid = SOLID_BBOX;
        !          1514:        self->s.modelindex = gi.modelindex ("models/monsters/gekk/tris.md2");
        !          1515:        VectorSet (self->mins, -24, -24, -24);
        !          1516:        VectorSet (self->maxs, 24, 24, 24);
        !          1517: 
        !          1518:        gi.modelindex ("models/objects/gekkgib/pelvis/tris.md2");
        !          1519:        gi.modelindex ("models/objects/gekkgib/arm/tris.md2");
        !          1520:        gi.modelindex ("models/objects/gekkgib/torso/tris.md2");
        !          1521:        gi.modelindex ("models/objects/gekkgib/claw/tris.md2");
        !          1522:        gi.modelindex ("models/objects/gekkgib/leg/tris.md2");
        !          1523:        gi.modelindex ("models/objects/gekkgib/head/tris.md2");
        !          1524:                
        !          1525:        self->health = 125;
        !          1526:        self->gib_health = -30;
        !          1527:        self->mass = 300;
        !          1528: 
        !          1529:        self->pain = gekk_pain;
        !          1530:        self->die = gekk_die;
        !          1531: 
        !          1532:        self->monsterinfo.stand = gekk_stand;
        !          1533: 
        !          1534:        self->monsterinfo.walk = gekk_walk;
        !          1535:        self->monsterinfo.run = gekk_run_start;
        !          1536:        self->monsterinfo.dodge = gekk_dodge;
        !          1537:        self->monsterinfo.attack = gekk_jump;
        !          1538:        self->monsterinfo.melee = gekk_melee;
        !          1539:        self->monsterinfo.sight = gekk_sight;
        !          1540:        
        !          1541:        self->monsterinfo.search = gekk_search;
        !          1542:        self->monsterinfo.idle = gekk_idle;
        !          1543:        self->monsterinfo.checkattack = gekk_checkattack;
        !          1544: 
        !          1545:        gi.linkentity (self);
        !          1546:        
        !          1547:        self->monsterinfo.currentmove = &gekk_move_stand;
        !          1548: 
        !          1549:        self->monsterinfo.scale = MODEL_SCALE;
        !          1550:        walkmonster_start (self);
        !          1551: 
        !          1552:        if (self->spawnflags & 8)
        !          1553:                self->monsterinfo.currentmove = &gekk_move_chant;
        !          1554:        
        !          1555: }
        !          1556: 
        !          1557: 
        !          1558: void water_to_land (edict_t *self)
        !          1559: {
        !          1560:        self->flags &= ~FL_SWIM;
        !          1561:        self->yaw_speed = 20;
        !          1562:        self->viewheight = 25;
        !          1563:        
        !          1564:        self->monsterinfo.currentmove = &gekk_move_leapatk2;
        !          1565:        
        !          1566:        VectorSet (self->mins, -24, -24, -24);
        !          1567:        VectorSet (self->maxs, 24, 24, 24);
        !          1568: }
        !          1569: 
        !          1570: void land_to_water (edict_t *self)
        !          1571: {
        !          1572:        self->flags |= FL_SWIM;
        !          1573:        self->yaw_speed = 10;
        !          1574:        self->viewheight = 10;
        !          1575:        
        !          1576:        self->monsterinfo.currentmove = &gekk_move_swim_start;
        !          1577:        
        !          1578:        VectorSet (self->mins, -24, -24, -24);
        !          1579:        VectorSet (self->maxs, 24, 24, 16);
        !          1580: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.