Annotation of quake2/xatrix/m_gekk.c, revision 1.1.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.