/* Copyright (C) 2006 Parallel Realities This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sentryGuns.h" void sentryGunDead() { if (self->custom == 0) { addSmokeParticle(self->position); self->thinkTime = rand() % 10; } self->health -= engine->getTimeDifference(TD_LOGIC); if (self->health <= -350) { generalMechLargeExplosion(); } } void drawSentryGun(bool transparent, bool reflected) { if (transparent) { return; } Unit *unit = (Unit*)self; glDisable(GL_BLEND); glEnable(GL_TEXTURE_2D); glEnable(GL_LIGHTING); glColor3f(1.0, 1.0, 1.0); glPushMatrix(); { glTranslatef(unit->position.x, unit->position.y, unit->position.z); glScalef(unit->scale, unit->scale, unit->scale); glBindTexture(GL_TEXTURE_2D, unit->definition->texture[0]->data); glCallList(unit->definition->model[0]->data); } glPopMatrix(); if (self->action == sentryGunDead) { return; } float z = unit->rotation.z; glPushMatrix(); { glTranslatef(unit->position.x, unit->position.y, unit->position.z + 9); glRotatef(unit->rotation.x, 0.0, 0.0, 1.0); glRotatef(unit->rotation.y, 0.0, 1.0, 0.0); glRotatef(z, 1.0, 0.0, 0.0); glScalef(unit->scale, unit->scale, unit->scale); glBindTexture(GL_TEXTURE_2D, unit->definition->texture[1]->data); glCallList(unit->definition->model[1]->data); } glPopMatrix(); } void sentryGunDie2() { Vector v; v = self->position; v.x += Math::rrand(-3, 3); v.y += Math::rrand(-3, 3); addSmokeParticle(v); self->custom -= engine->getTimeDifference(TD_LOGIC); if ((int)self->rotation.z != 15) { if (self->rotation.z > 15) { self->rotation.z -= engine->getTimeDifference(TD_LOGIC) * 0.25; } else { self->rotation.z += engine->getTimeDifference(TD_LOGIC) * 0.25; } } if (self->custom <= 0) { generalMechLargeExplosion(); self->flags &= ~EF_DYING; self->flags &= ~EF_DEAD; self->walk = &sentryGunDead; self->attack = &sentryGunDead; self->die = &sentryGunDead; self->action = &sentryGunDead; self->boundingBox.boxType = BOX_HOLLOW; if ((rand() % 2) == 0) { Vector velocity; velocity.x = Math::rrand(-10, 10); velocity.y = Math::rrand(-10, 10); velocity.z = Math::rrand(15, 25); velocity.x *= 0.1; velocity.y *= 0.1; velocity.z *= 0.1; Vector position = self->position; position.z += 9; Properties props; props.setProperty("classname", "NME_DEAD_SENTRYGUN"); props.setProperty("position", position); props.setProperty("velocity", velocity); props.setProperty("helpless", 9999); addEnemy(&props); } switch (rand() % 3) { case 0: self->custom = 0; break; case 1: self->flags |= EF_ONFIRE; break; } } } void sentryGunDie1() { Vector v; v = self->position; v.x += Math::rrand((int)self->boundingBox.mins.x, (int)self->boundingBox.maxs.x); v.y += Math::rrand((int)self->boundingBox.mins.y, (int)self->boundingBox.maxs.y); v.z += Math::rrand((int)self->boundingBox.mins.z, (int)self->boundingBox.maxs.z); doExplosion(v, 10, self); self->thinkTime = Math::rrand(15, 30); if (--self->custom == 0) { self->action = &sentryGunDie2; self->custom = 200; } } void sentryGunPostDie() { self->health = 0; self->thinkTime = 0; self->action = sentryGunDie1; self->custom = Math::rrand(3, 5); self->flags |= EF_DYING; } void sentryGunSearch() { Unit *unit = (Unit*)self; if (unit->flags & EF_NOTARGET) { return; } if (unit->target != NULL) { faceTarget(unit); } if (enemySightTarget(unit, 650)) { self->action = self->attack; } if (unit->health <= 0) { unit->action = &sentryGunDead; } self->thinkTime = Math::rrand(25, 75); } // ==================== Uzi sentry gun ================= void uziSentryGunAttack() { Unit *unit = (Unit*)self; faceTarget(unit); if (unit->reload > 0) { return; } self->thinkTime = 0; self->action = &uziSentryGunAttack; attackTarget(unit); if (--self->custom == 0) { self->action = &sentryGunSearch; self->thinkTime = Math::rrand(50, 100); } } void uziSentryGunPreAttack() { self->custom = Math::rrand(10, 20); self->thinkTime = 0; self->action = &uziSentryGunAttack; } void uziSentryGunInit(Unit *unit) { unit->walk = &sentryGunSearch; unit->attack = &uziSentryGunPreAttack; unit->die = &sentryGunPostDie; unit->thinkTime = Math::rrand(0, 50); unit->action = unit->walk; unit->draw = &drawSentryGun; } // ==================== Plasma sentry gun ================= void plasmaSentryGunAttack() { Unit *unit = (Unit*)self; faceTarget(unit); if (unit->reload > 0) { return; } self->thinkTime = 0; self->action = &plasmaSentryGunAttack; attackTarget(unit); if (--self->custom == 0) { self->action = &sentryGunSearch; self->thinkTime = Math::rrand(50, 100); } } void plasmaSentryGunPreAttack() { self->custom = Math::rrand(5, 20); self->thinkTime = 0; self->action = &plasmaSentryGunAttack; } void plasmaSentryGunInit(Unit *unit) { unit->walk = &sentryGunSearch; unit->attack = &plasmaSentryGunPreAttack; unit->die = &sentryGunPostDie; unit->thinkTime = Math::rrand(0, 50); unit->action = unit->walk; unit->draw = &drawSentryGun; } // ==================== Rocket sentry gun ================= void rocketSentryGunAttack() { Unit *unit = (Unit*)self; faceTarget(unit); if (unit->reload > 0) { return; } self->thinkTime = 0; self->action = &rocketSentryGunAttack; attackTarget(unit); if (--self->custom == 0) { self->action = &sentryGunSearch; self->thinkTime = Math::rrand(300, 500); } } void rocketSentryGunPreAttack() { self->custom = Math::rrand(1, 2); self->thinkTime = 0; self->action = &rocketSentryGunAttack; } void rocketSentryGunInit(Unit *unit) { unit->walk = &sentryGunSearch; unit->attack = &rocketSentryGunPreAttack; unit->die = &sentryGunPostDie; unit->thinkTime = Math::rrand(0, 50); unit->action = unit->walk; unit->draw = &drawSentryGun; } // ==================== Mortor sentry gun ================= void mortorSentryGunAttack() { Unit *unit = (Unit*)self; faceTarget(unit); if (unit->reload > 0) { return; } self->thinkTime = 0; self->action = &mortorSentryGunAttack; attackTarget(unit); if (--self->custom == 0) { self->action = &sentryGunSearch; self->thinkTime = Math::rrand(50, 100); } } void mortorSentryGunPreAttack() { self->custom = Math::rrand(1, 3); self->thinkTime = 0; self->action = &mortorSentryGunAttack; } void mortorSentryGunInit(Unit *unit) { unit->walk = &sentryGunSearch; unit->attack = &mortorSentryGunPreAttack; unit->die = &sentryGunPostDie; unit->thinkTime = Math::rrand(0, 50); unit->action = unit->walk; unit->draw = &drawSentryGun; } // ============= Dead Sentry Gun ============ void deadSentryGunTouch(Entity *other) { if (other == self->owner) { return; } generalMechLargeExplosion(); self->touch = NULL; } void deadSentryGunInit(Unit *unit) { unit->walk = &sentryGunDead; unit->attack = &sentryGunDead; unit->die = &sentryGunDead; unit->touch = &deadSentryGunTouch; unit->boundingBox.boxType = BOX_HOLLOW; unit->owner = self; }