void WeaponFire( Weapon *w, const direction_e d, const Vec2i pos, const int flags, const int player, const int uid) { if (w->state != GUNSTATE_FIRING && w->state != GUNSTATE_RECOIL) { WeaponSetState(w, GUNSTATE_FIRING); } if (!w->Gun->CanShoot) { return; } const double radians = dir2radians[d]; const Vec2i muzzleOffset = GunGetMuzzleOffset(w->Gun, d); const Vec2i muzzlePosition = Vec2iAdd(pos, muzzleOffset); const bool playSound = w->soundLock <= 0; GunAddBullets( w->Gun, muzzlePosition, w->Gun->MuzzleHeight, radians, flags, player, uid, playSound); if (playSound) { w->soundLock = w->Gun->SoundLockLength; } // Brass shells // If we have a reload lead, defer the creation of shells until then if (w->Gun->Brass && w->Gun->ReloadLead == 0) { AddBrass(w->Gun, d, pos); } w->lock = w->Gun->Lock; }
static void DamageObject( const int power, const int flags, const int player, const int uid, TTileItem *target) { TObject *object = CArrayGet(&gObjs, target->id); // Don't bother if object already destroyed if (object->structure <= 0) { return; } object->structure -= power; const Vec2i pos = Vec2iNew(target->x, target->y); // Destroying objects and all the wonderful things that happen if (object->structure <= 0) { object->structure = 0; UpdateMissionObjective( &gMission, object->tileItem.flags, OBJECTIVE_DESTROY, player, pos); if (object->flags & OBJFLAG_QUAKE) { GameEvent shake; shake.Type = GAME_EVENT_SCREEN_SHAKE; shake.u.ShakeAmount = SHAKE_BIG_AMOUNT; GameEventsEnqueue(&gGameEvents, shake); } const Vec2i fullPos = Vec2iReal2Full( Vec2iNew(object->tileItem.x, object->tileItem.y)); if (object->flags & OBJFLAG_EXPLOSIVE) { GunAddBullets( StrGunDescription("explosion1"), fullPos, 0, 0, flags, player, uid, true); GunAddBullets( StrGunDescription("explosion2"), fullPos, 0, 0, flags, player, uid, true); GunAddBullets( StrGunDescription("explosion3"), fullPos, 0, 0, flags, player, uid, true); } else if (object->flags & OBJFLAG_FLAMMABLE) { GunAddBullets( StrGunDescription("fire_explosion"), fullPos, 0, 0, flags, player, uid, true); } else if (object->flags & OBJFLAG_POISONOUS) { GunAddBullets( StrGunDescription("gas_poison_explosion"), fullPos, 0, 0, flags, player, uid, true); } else if (object->flags & OBJFLAG_CONFUSING) { GunAddBullets( StrGunDescription("gas_confuse_explosion"), fullPos, 0, 0, flags, player, uid, true); } else { // A wreck left after the destruction of this object GameEvent e; memset(&e, 0, sizeof e); e.Type = GAME_EVENT_ADD_BULLET; e.u.AddBullet.BulletClass = StrBulletClass("fireball_wreck"); e.u.AddBullet.MuzzlePos = fullPos; e.u.AddBullet.MuzzleHeight = 0; e.u.AddBullet.Angle = 0; e.u.AddBullet.Elevation = 0; e.u.AddBullet.Flags = 0; e.u.AddBullet.PlayerIndex = -1; e.u.AddBullet.UID = -1; GameEventsEnqueue(&gGameEvents, e); SoundPlayAt( &gSoundDevice, gSoundDevice.wreckSound, Vec2iNew(object->tileItem.x, object->tileItem.y)); } if (object->wreckedPic) { object->tileItem.flags = TILEITEM_IS_WRECK; object->pic = object->wreckedPic; object->picName = ""; } else { ObjDestroy(object->tileItem.id); } } }