static void AddBrass( const GunDescription *g, const direction_e d, const Vec2i pos) { CASSERT(g->Brass, "Cannot create brass for no-brass weapon"); GameEvent e = GameEventNew(GAME_EVENT_ADD_PARTICLE); e.u.AddParticle.Class = g->Brass; double x, y; const double radians = dir2radians[d]; GetVectorsForRadians(radians, &x, &y); const Vec2i ejectionPortOffset = Vec2iReal2Full(Vec2iScale(Vec2iNew( (int)round(x), (int)round(y)), 7)); const Vec2i muzzleOffset = GunGetMuzzleOffset(g, d); const Vec2i muzzlePosition = Vec2iAdd(pos, muzzleOffset); e.u.AddParticle.FullPos = Vec2iMinus(muzzlePosition, ejectionPortOffset); e.u.AddParticle.Z = g->MuzzleHeight; e.u.AddParticle.Vel = Vec2iScaleDiv( GetFullVectorsForRadians(radians + PI / 2), 3); e.u.AddParticle.Vel.x += (rand() % 128) - 64; e.u.AddParticle.Vel.y += (rand() % 128) - 64; e.u.AddParticle.Angle = RAND_DOUBLE(0, PI * 2); e.u.AddParticle.DZ = (rand() % 6) + 6; e.u.AddParticle.Spin = RAND_DOUBLE(-0.1, 0.1); GameEventsEnqueue(&gGameEvents, e); }
void BulletAdd(const NAddBullet add) { const Vec2i pos = Net2Vec2i(add.MuzzlePos); // Find an empty slot in mobobj list TMobileObject *obj = NULL; int i; for (i = 0; i < (int)gMobObjs.size; i++) { TMobileObject *m = CArrayGet(&gMobObjs, i); if (!m->isInUse) { obj = m; break; } } if (obj == NULL) { TMobileObject m; memset(&m, 0, sizeof m); CArrayPushBack(&gMobObjs, &m); i = (int)gMobObjs.size - 1; obj = CArrayGet(&gMobObjs, i); } memset(obj, 0, sizeof *obj); obj->UID = add.UID; obj->bulletClass = StrBulletClass(add.BulletClass); obj->x = pos.x; obj->y = pos.y; obj->z = add.MuzzleHeight; obj->dz = add.Elevation; obj->vel = Vec2iFull2Real(Vec2iScale( GetFullVectorsForRadians(add.Angle), RAND_INT(obj->bulletClass->SpeedLow, obj->bulletClass->SpeedHigh))); if (obj->bulletClass->SpeedScale) { obj->vel.y = obj->vel.y * TILE_WIDTH / TILE_HEIGHT; } obj->PlayerUID = add.PlayerUID; obj->ActorUID = add.ActorUID; obj->range = RAND_INT( obj->bulletClass->RangeLow, obj->bulletClass->RangeHigh); obj->flags = add.Flags; if (obj->bulletClass->HurtAlways) { obj->flags |= FLAGS_HURTALWAYS; } obj->tileItem.kind = KIND_MOBILEOBJECT; obj->tileItem.id = i; obj->isInUse = true; obj->tileItem.x = obj->tileItem.y = -1; obj->tileItem.getPicFunc = NULL; obj->tileItem.getActorPicsFunc = NULL; obj->tileItem.drawFunc = NULL; obj->tileItem.drawData.MobObjId = i; obj->tileItem.CPic = obj->bulletClass->CPic; obj->tileItem.CPicFunc = GetBulletDrawContext; obj->tileItem.size = obj->bulletClass->Size; obj->tileItem.ShadowSize = obj->bulletClass->ShadowSize; obj->updateFunc = UpdateBullet; MapTryMoveTileItem(&gMap, &obj->tileItem, Vec2iFull2Real(pos)); }