Wolf3D-Mac/EnThink.c

1 line
13 KiB
C
Raw Normal View History

#include "wolfdef.h" /********************************** Drops a bonus item at the x,y of the actor If there are no free item spots, nothing is done. **********************************/ void PlaceItemType(Word shape,actor_t *ActorPtr) { Word tile; Word x,y; static_t *StaticPtr; if (numstatics>=MAXSTATICS) { /* Already full? */ return; /* Get out! */ } StaticPtr = &statics[numstatics]; /* Get pointer to the record */ /* drop bonus items on closest tile, rather than goal tile (unless it is a closing door) */ x = ActorPtr->x >> FRACBITS; y = ActorPtr->y >> FRACBITS; tile = tilemap[y][x]; if ( (tile&TI_BLOCKMOVE) && !(tile &TI_ACTOR) ) { x = ActorPtr->goalx; y = ActorPtr->goaly; } StaticPtr->pic = shape; StaticPtr->x = (x<<FRACBITS)|0x80; StaticPtr->y = (y<<FRACBITS)|0x80; StaticPtr->areanumber = ActorPtr->areanumber; tilemap[y][x] |= TI_GETABLE; /* Mark as getable */ ++numstatics; /* A new static */ } /********************************** Kill an actor Also drop off any items you can get from a dead guy. **********************************/ void KillActor(actor_t *ActorPtr) { Word x,y; GivePoints(classinfo[ActorPtr->class].points); /* Award the score */ switch(ActorPtr->class) { /* Drop anything special? */ case CL_SS: PlaceItemType(S_MACHINEGUN,ActorPtr); /* Give a gun */ break; case CL_OFFICER: case CL_MUTANT: case CL_GUARD: PlaceItemType(S_AMMO,ActorPtr); /* Drop some ammo */ break; case CL_HANS: case CL_SCHABBS: case CL_TRANS: case CL_UBER: case CL_DKNIGHT: PlaceItemType(S_G_KEY,ActorPtr); /* Drop a key */ break; } ++gamestate.killcount; /* I killed someone! */ ActorPtr->flags = FL_DEAD; /* remove old actor marker*/ tilemap[ActorPtr->goaly][ActorPtr->goalx] &= ~TI_ACTOR; x = ActorPtr->x >> FRACBITS; y = ActorPtr->y >> FRACBITS; tilemap[y][x] |= TI_BODY; /* body flag on most apparant, no matter what */ NewState(ActorPtr,classinfo[ActorPtr->class].deathstate); /* start the death animation */ } /********************************** Does damage points to enemy actor, either putting it into a stun frame or killing it. Called when an enemy is hit. **********************************/ static Word PainTick; void DamageActor(Word damage,actor_t *ActorPtr) { stateindex_t pain; madenoise = TRUE; /* You made some noise! */ /* do double damage if shooting a non attack mode actor*/ if ( !(ActorPtr->flags & FL_ACTIVE) ) { if (difficulty<3) { /* Death incarnate? */ damage <<= 1; } FirstSighting(ActorPtr); /* Put into combat mode*/ } if (damage >= ActorPtr->hitpoints) { /* Did I kill it? */ KillActor(ActorPtr); /* Die!! */ return; } ActorPtr->hitpoints -= damage; /* Remove the damage */ if (ActorPtr->class == CL_MECHAHITLER && ActorPtr->hitpoints <= 250 && ActorPtr->hitpoints+damage > 250) { /* hitler losing armor */ PlaySound(SND_SHIT); /* Remove armor */ pain = ST_MHITLER_DIE1; } else { if ((ReadTick() - PainTick) >= 30) { PainTick = ReadTick(); PlaySound(SND_PAIN); /* Ow!! */ } pain = classinfo[ActorPtr->class].painstate; /* Do pain */ } if (pain) { /* some classes don't have pain frames */ if (ActorPtr->state != pain) { /* Already in pain? */ NewState(ActorPtr,pain); } } } /********************************** Throw a Missile at the player **********************************/ void A_Throw(actor_t *ActorPtr) { Word angle; int speed; missile_t *MissilePtr; PlaySound(SND_ROCKET|0x8000); MissilePtr = GetNewMissile(); /* Create a missile */ MissilePtr->x = ActorPtr->x; MissilePtr->y = ActorPtr->y; MissilePtr->areanumber = ActorPtr->areanumber; /* get direction from enemy to player */ angle = PointToAngle(ActorPtr->x,ActorPtr->y); angle >>= SHORTTOANGLESHIFT; speed = costable[angle]; speed = speed/5; MissilePtr->xspeed = -speed; speed = sintable[angle]; speed = speed/5; MissilePtr->yspeed = speed; MissilePtr->pic = S_NEEDLE; /* Hurl a needle */ MissilePtr->flags = MF_HITPLAYER | MF_HITSTATICS; /* Can hit the player */ MissilePtr->type = MI_NEEDLE; /* Needle mis