static bool Particle_CollideHor(Vector3* nextPos, BlockID block) { Vector3 horPos = Vector3_Create3((Real32)Math_Floor(nextPos->X), 0.0f, (Real32)Math_Floor(nextPos->Z)); Vector3 min, max; Vector3_Add(&min, &Block_MinBB[block], &horPos); Vector3_Add(&max, &Block_MaxBB[block], &horPos); return nextPos->X >= min.X && nextPos->Z >= min.Z && nextPos->X < max.X && nextPos->Z < max.Z; }
Vector3 Respawn_FindSpawnPosition(float x, float z, Vector3 modelSize) { Vector3 spawn = Vector3_Create3(x, 0.0f, z); struct AABB bb; float highestY; int y; spawn.Y = World.Height + ENTITY_ADJUSTMENT; AABB_Make(&bb, &spawn, &modelSize); spawn.Y = 0.0f; for (y = World.Height; y >= 0; y--) { highestY = Respawn_HighestSolidY(&bb); if (highestY != RESPAWN_NOT_FOUND) { spawn.Y = highestY; break; } bb.Min.Y -= 1.0f; bb.Max.Y -= 1.0f; } return spawn; }
void Particles_RainSnowEffect(Vector3 pos) { Vector3 startPos = pos; Int32 i; for (i = 0; i < 2; i++) { Real32 velX = Random_Float(&rnd) * 0.8f - 0.4f; /* [-0.4, 0.4] */ Real32 velZ = Random_Float(&rnd) * 0.8f - 0.4f; Real32 velY = Random_Float(&rnd) + 0.4f; Vector3 velocity = Vector3_Create3(velX, velY, velZ); Vector3 offset; offset.X = Random_Float(&rnd); /* [0.0, 1.0] */ offset.Y = Random_Float(&rnd) * 0.1f + 0.01f; offset.Z = Random_Float(&rnd); if (Rain_Count == PARTICLES_MAX) Rain_RemoveAt(0); RainParticle* p = &Rain_Particles[Rain_Count++]; Vector3_Add(&pos, &startPos, &offset); Particle_Reset(&p->Base, pos, velocity, 40.0f); Int32 type = Random_Range(&rnd, 0, 30); p->Base.Size = (UInt8)(type >= 28 ? 2 : (type >= 25 ? 4 : 3)); } }
void Particles_BreakBlockEffect(Vector3I coords, BlockID oldBlock, BlockID block) { if (block != BLOCK_AIR || Block_Draw[oldBlock] == DRAW_GAS) return; block = oldBlock; Vector3 worldPos; Vector3I_ToVector3(&worldPos, &coords); TextureLoc texLoc = Block_GetTexLoc(block, FACE_XMIN); Int32 texIndex; TextureRec baseRec = Atlas1D_TexRec(texLoc, 1, &texIndex); Real32 uScale = (1.0f / 16.0f), vScale = (1.0f / 16.0f) * Atlas1D_InvTileSize; Vector3 minBB = Block_MinBB[block]; Vector3 maxBB = Block_MaxBB[block]; Int32 minX = (Int32)(minBB.X * 16), minZ = (Int32)(minBB.Z * 16); Int32 maxX = (Int32)(maxBB.X * 16), maxZ = (Int32)(maxBB.Z * 16); Int32 minU = min(minX, minZ), maxU = min(maxX, maxZ); Int32 minV = (Int32)(16 - maxBB.Y * 16), maxV = (Int32)(16 - minBB.Y * 16); Int32 maxUsedU = maxU, maxUsedV = maxV; /* This way we can avoid creating particles which outside the bounds and need to be clamped */ if (minU < 12 && maxU > 12) maxUsedU = 12; if (minV < 12 && maxV > 12) maxUsedV = 12; #define GRID_SIZE 4 /* gridOffset gives the centre of the cell on a grid */ #define CELL_CENTRE ((1.0f / GRID_SIZE) * 0.5f) Int32 x, y, z; Real32 maxU2 = baseRec.U1 + maxU * uScale; Real32 maxV2 = baseRec.V1 + maxV * vScale; for (x = 0; x < GRID_SIZE; x++) { for (y = 0; y < GRID_SIZE; y++) { for (z = 0; z < GRID_SIZE; z++) { Real32 cellX = (Real32)x / GRID_SIZE, cellY = (Real32)y / GRID_SIZE, cellZ = (Real32)z / GRID_SIZE; Vector3 cell = Vector3_Create3(CELL_CENTRE + cellX, CELL_CENTRE / 2 + cellY, CELL_CENTRE + cellZ); if (cell.X < minBB.X || cell.X > maxBB.X || cell.Y < minBB.Y || cell.Y > maxBB.Y || cell.Z < minBB.Z || cell.Z > maxBB.Z) continue; Vector3 velocity; /* centre random offset around [-0.2, 0.2] */ velocity.X = CELL_CENTRE + (cellX - 0.5f) + (Random_Float(&rnd) * 0.4f - 0.2f); velocity.Y = CELL_CENTRE + (cellY - 0.0f) + (Random_Float(&rnd) * 0.4f - 0.2f); velocity.Z = CELL_CENTRE + (cellZ - 0.5f) + (Random_Float(&rnd) * 0.4f - 0.2f); TextureRec rec = baseRec; rec.U1 = baseRec.U1 + Random_Range(&rnd, minU, maxUsedU) * uScale; rec.V1 = baseRec.V1 + Random_Range(&rnd, minV, maxUsedV) * vScale; rec.U2 = rec.U1 + 4 * uScale; rec.V2 = rec.V1 + 4 * vScale; rec.U2 = min(rec.U2, maxU2) - 0.01f * uScale; rec.V2 = min(rec.V2, maxV2) - 0.01f * vScale; if (Terrain_Count == PARTICLES_MAX) Terrain_RemoveAt(0); TerrainParticle* p = &Terrain_Particles[Terrain_Count++]; Real32 life = 0.3f + Random_Float(&rnd) * 1.2f; Vector3 pos; Vector3_Add(&pos, &worldPos, &cell); Particle_Reset(&p->Base, pos, velocity, life); p->Rec = rec; p->TexLoc = (TextureLoc)texLoc; p->Block = block; Int32 type = Random_Range(&rnd, 0, 30); p->Base.Size = (UInt8)(type >= 28 ? 12 : (type >= 25 ? 10 : 8)); } } } }