/* * Copyright (C) 1999 Peter Amstutz * * 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 #include #include "../log.h" #include "../ballistics.h" #include "../terrain.h" #include "../aiexterns.h" #include "basic.h" #include "blackhole.h" Shellstat_bal wepBlackHoleInit(struct Projectilepos_bal *prjpos, void** guide, Shellstat_bal (*initexplosion)(struct Projectilepos_bal *prjpos, void** explosioninfo), void** explosioninfo) { Player_pl *plhit = NULL; int ix, iy; /*Shellstat_bal res;*/ /*res=balEnvironmentAdjustProjPos(prjpos);*/ *guide=NULL; if(balCheckIntersect(prjpos->ox, prjpos->oy, prjpos->x, prjpos->y, &plhit, &ix, &iy)) { prjpos->x=ix; prjpos->y=iy; aihExplosionHook(prjpos); aihExplosionHook(prjpos); return initexplosion(prjpos, explosioninfo); } else { prjpos->rox = prjpos->ox = prjpos->x; prjpos->roy = prjpos->oy = prjpos->y; return FLYING; } } Shellstat_bal wepBlackHoleGuidance(void* info, struct Projectilepos_bal *prjpos, Shellstat_bal (*initexplosion)(struct Projectilepos_bal *prjpos, void** explosioninfo), void **explosioninfo) { Shellstat_bal res; Player_pl *plhit = NULL; struct Projectilelist_bal *prj; int ix, iy; double dist, angle; double pull, dvx, dvy; prjpos->rox = prjpos->ox = prjpos->x; prjpos->roy = prjpos->oy = prjpos->y; prjpos->x+=prjpos->vx; prjpos->y+=prjpos->vy; prjpos->vy-=bal_grav/bal_lerp_tweak; if((res=balEnvironmentAdjustProjPos(prjpos))!=FLYING || balCheckIntersect(prjpos->ox, prjpos->oy, prjpos->x, prjpos->y, &plhit, &ix, &iy)) { if(plLookupPlayer(prjpos->id)) { logPrintf(DEBUG, "Intersection at (%i, %i) of %s's shot\n", ix, iy, plLookupPlayer(prjpos->id)->name); } else { logPrintf(DEBUG, "Intersection at (%i, %i) of null's shot\n", ix, iy); } if(plhit != NULL) logPrintf(DEBUG, "and hit %s\n", plhit->name); switch(res) { case HOLDING: /* wtf ??? */ break; case FLYING: prjpos->x=ix; prjpos->y=iy; /* fall through */ case EXPLODING: return initexplosion(prjpos, explosioninfo); break; case FREEING: return FREEING; break; } } /* Start messing with other shells */ if(bal_Projectiles) { for(prj=bal_Projectiles; prj; prj=prj->next) { if((prj->stat == FLYING) && (prj->prjpos.id!=prjpos->id)) /* Only mess with shells in the air that aren't us */ { /* get distance from us */ dist=sqrt((pow(prj->prjpos.x-prjpos->x, 2))+(pow(prj->prjpos.y-prjpos->y, 2))); /* get angle from us */ angle=acos((prj->prjpos.x-prjpos->x)/dist); /* correct for angles over 180 degrees */ if(prj->prjpos.y-prjpos->y < 0) { angle=-angle; } /* get pull */ pull=BH_MASS/dist+1; /* get change in x,y velocities */ dvx=pull*(cos(angle)); dvy=pull*(sin(angle)); /* modify the flight path */ prj->prjpos.vx-=dvx; prj->prjpos.vy-=dvy; logPrintf(DEBUG, "d:%06.2f a:%06.2f p:%06.2f, dvx:%06.2f dvy:%06.2f\n", dist, angle, pull, dvx, dvy); /* No destruction for now */ /* Lets destroy the shell if it gets close */ /* if(dist <= BH_DESTRUCT) { logPrintf(DEBUG, "Destroying shell\n"); if(prj->wpn->initexplosion) { prj->stat=prj->wpn->initexplosion(&(prj->prjpos), &(prj->explosioninfo)); } else { prj->stat=FREEING; } } */ } } } return FLYING; } Shellstat_bal wepBlackHoleExplosionInit(struct Projectilepos_bal *prjpos, void** explosioninfo) { struct DurationExplosion_wep *e = (struct DurationExplosion_wep*)malloc(sizeof(struct DurationExplosion_wep)); e->x = prjpos->x; e->y = prjpos->y; e->width = 10; e->id = prjpos->id; e->duration = 20; e->wid = prjpos->wid; *((struct DurationExplosion_wep**)explosioninfo)=e; return EXPLODING; } Shellstat_bal wepBlackHoleExplosion(void* info) { struct DurationExplosion_wep *prj = (struct DurationExplosion_wep *)info; /*Player_pl *pcur; */ struct Projectilelist_bal *prjlist; double dist, angle; double pull, dvx, dvy; prj->duration--; if(prj->duration < 0) { return FREEING; } else { /* Lets affect those shells a little longer */ if(bal_Projectiles) { for(prjlist=bal_Projectiles; prjlist; prjlist=prjlist->next) { if((prjlist->stat == FLYING) && (prjlist->prjpos.id!=prj->id)) /* Only mess with shells in the air that aren't us */ { /* get distance from us */ dist=sqrt((pow(prjlist->prjpos.x-prj->x, 2))+(pow(prjlist->prjpos.y-prj->y, 2))); /* get angle from us */ angle=acos((prjlist->prjpos.x-prj->x)/dist); /* correct for angles over 180 degrees */ if(prjlist->prjpos.y-prj->y < 0) { angle=-angle; } /* get pull */ pull=BH_MASS/dist+1; /* get change in x,y velocities */ dvx=pull*(cos(angle)); dvy=pull*(sin(angle)); /* modify the flight path */ prjlist->prjpos.vx-=dvx; prjlist->prjpos.vy-=dvy; logPrintf(DEBUG, "d:%06.2f a:%06.2f p:%06.2f, dvx:%06.2f dvy:%06.2f\n", dist, angle, pull, dvx, dvy); /* No destruction for now */ /* Lets destroy the shell if it gets close */ /* if(dist <= BH_DESTRUCT) { logPrintf(DEBUG, "Destroying shell\n"); if(prjlist->wpn->initexplosion) { prjlist->stat=prjlist->wpn->initexplosion(&(prjlist->prjpos), &(prjlist->explosioninfo)); } else { prjlist->stat=FREEING; } } */ } } } return EXPLODING; } }