Wolf3D-Mac/Missiles.c

1 line
4.9 KiB
C
Raw Normal View History

#include "wolfdef.h" /********************************** Returns a pointer to an empty missile record **********************************/ missile_t *GetNewMissile(void) { Word Count; Count = nummissiles; if (Count < MAXMISSILES) { /* Already full? */ ++Count; /* Next entry */ nummissiles = Count; /* Save the new missile count */ } return &missiles[Count-1]; /* Get pointer to empty missile */ } /********************************** Explode a missile **********************************/ void ExplodeMissile(missile_t *MissilePtr) { MissilePtr->flags = 0; /* Can't harm anyone! */ if (MissilePtr->type == MI_PMISSILE) { MissilePtr->pic = S_MISSBOOM; /* Rocket explosion */ MissilePtr->type = 16; /* Tics to stay in explosion*/ } else { MissilePtr->pic = S_FIREBOOM; /* Fire explosion */ MissilePtr->type = 8; /* Tics to stay in explosion*/ } PlaySound(SND_BOOM|0x8000); /* BOOM! */ MissilePtr->x -= MissilePtr->xspeed; /* Undo the last motion */ MissilePtr->y -= MissilePtr->yspeed; MissilePtr->xspeed = 0; /* Don't move anymore */ MissilePtr->yspeed = 0; } /********************************** Take damage from the player Damage is 8,16...64, pass the x,y for a kill x,y **********************************/ void MissileHitPlayer(missile_t *MissilePtr) { TakeDamage((w_rnd()&0x38)+8,MissilePtr->x,MissilePtr->y); /* Inflict damage */ } /********************************** Take damage from the enemy Detonate if not killed (return True) **********************************/ Boolean MissileHitEnemy(missile_t *MissilePtr, actor_t *ActorPtr) { Word Damage; if (MissilePtr->type == MI_PMISSILE) { /* Rocket? */ Damage = (w_rnd()&0x30)+16; /* Hit'm hard! */ } else { Damage = (w_rnd()&0x0f)+1; /* Burn a little */ } DamageActor(Damage,ActorPtr); /* Hit'em! */ return !(ActorPtr->flags & FL_DEAD); /* Not dead? */ } /********************************** Did the missile impact on an actor **********************************/ Boolean CheckMissileActorHits(missile_t *MissilePtr) { Word xl,xh,yh; Word x,y; Word Bang; Word tile; actor_t *ActorPtr; Bang = 0; /* Assume the missile is OK */ xl = (MissilePtr->x>>FRACBITS)-1; /* Create the kill rect */ xh = xl+3; y = (MissilePtr->y>>FRACBITS)-1; yh = y+3; if (xl>=MAPSIZE) { /* Clip the attack rect to STAY on the map! */ xl = 0; } if (y>=MAPSIZE) { y = 0; } if (xh>=MAPSIZE) { xh = MAPSIZE; } if (yh>=MAPSIZE) { yh = MAPSIZE; } do { x = xl; /* Begin the X scan */ do { tile = tilemap[y][x]; /* Actor here? */ if (tile&TI_ACTOR) { ActorPtr = &actors[MapPtr->tilemap[y][x]]; /* Check for impact */ if ( (w_abs(ActorPtr->x - MissilePtr->x) < MISSILEHITDIST) && (w_abs(ActorPtr->y - MissilePtr->y) < MISSILEHITDIST)) { Bang |= MissileHitEnemy(MissilePtr,ActorPtr); /* Detonate? */ } } } while (++x<xh); /* Scan the x's */ } while (++y<yh); /* Scan the y's */ return Bang; /* Return detonation value */ } /********************************** Move the missiles each game frame **********************************/ void MoveMissiles(void) { Word Count; /* Current missile # */ missile_t *MissilePtr; /* Pointer to missile record */ Word i,x,y,tile; /* Tile position */ Count = nummissiles; /* How many active missiles? */ if (!Count || !TicCount) { /* No missiles? (Or elapsed time?) */ return; /* Exit now */ } MissilePtr = &missiles[0]; /* Init pointer to the first missile */ do { if (!MissilePtr->flags) { /* inert explosion*/ if (MissilePtr->type>TicCount) { /* Time up? */ MissilePtr->type-=TicCount; /* Remove some time */ ++MissilePtr; /* Go to the next entry */ } else { --nummissiles; /* Remove this missile */ MissilePtr[0] = missiles[nummissiles]; /* Copy the FINAL record here */ } continue; /* Next! */ } /* move position*/ i = TicCount; /* How many times to try this? */ do { MissilePtr->x += MissilePtr->xspeed; MissilePtr->y += MissilePtr->yspeed; /* check for contact with player*/ if (MissilePtr->flag