void thresholding(PALLET* pal, /* I - pallet consist with many colors */ RGB *base, /* I - base color */ double variation) /* I - fault tolerant */ { RGB *other; size_t points = pal->info->bmiHeader.biSizeImage / sizeof(RGB); for (size_t i = 0; i < points; ++i) { other = &pal->colors[i]; color_cmp(base, other, variation) == 1 ? other->blue = other->green = other->red = 0 : other->blue = other->green = other->red = 255; } }
/* * Find an existing trigger and which slot it is in */ int level_trigger2slot (levelp level, color c) { if (color_none(c)) { c = default_trigger; } int i; /* * See if the trigger exists */ for (i = 0; i < ARRAY_SIZE(level->trigger); i++) { if (color_none(level->trigger[i].c)) { break; } if (color_cmp(c, level->trigger[i].c)) { return (i); } } return (-1); }
void thing_reached_teleport (levelp level, thingp t, thingp teleport) { int tx[MAP_WIDTH*MAP_HEIGHT]; int ty[MAP_WIDTH*MAP_HEIGHT]; int poss = 0; int x, y; int delay = 20; if (!thing_is_player(t)) { /* * Only move other things sometimes. */ if ((myrand() % 100) < 95) { return; } } if (!time_have_x_tenths_passed_since(delay, t->timestamp_last_teleport)) { return; } for (x = 0; x < MAP_WIDTH; x++) { for (y = 0; y < MAP_HEIGHT; y++) { level_map_tile *tile = &level->map_grid.tile[x][y][MAP_DEPTH_EXPLOSION]; tpp it = tile->tp; if (!it) { continue; } if (!tp_is_teleport(it)) { continue; } if (DISTANCE(t->x, t->y, x, y) < 2.0) { continue; } color tcol; color col; tcol = teleport->data.col; col = tile->data.col; if (color_none(col) || color_none(tcol)) { tx[poss] = x; ty[poss] = y; poss++; continue; } if (color_cmp(col, tcol)) { tx[poss] = x; ty[poss] = y; poss++; continue; } } } if (!poss) { return; } t->timestamp_last_teleport = time_get_time_ms(); poss = myrand() % poss; double nx = tx[poss]; double ny = ty[poss]; /* * Don't let lava spawn continually on top of itself. */ if (thing_is_lava(t) && map_is_lava_at(level, nx, ny)) { return; } /* * Don't let water spawn continually on top of itself. */ if (thing_is_water(t) && map_is_water_at(level, nx, ny)) { return; } /* * Don't let acid spawn continually on top of itself. */ if (thing_is_acid(t) && map_is_acid_at(level, nx, ny)) { return; } /* * Don't let water spawn continually on top of itself. */ if (thing_is_water(t) && map_is_water_at(level, nx, ny)) { return; } /* * Don't let monsters spawn continually on top of themselves. */ if (thing_is_monst(t) && map_is_monst_at(level, nx, ny)) { return; } THING_LOG(t, "Teleport"); wid_move_end(t->wid); thing_wid_update(level, t, nx, ny, false /* smooth */, true /* is_new */); /* * Make sure the client sees the jump */ thing_handle_collisions(level, t); MSG_SHOUT_AT(SOUND, t, t->x, t->y, "teleport"); }
void level_trigger_activate (levelp level, color c) { int x, y, z; int spawned = false; int zapped = false; if (level_trigger_is_activated(level, c)) { return; } LEVEL_LOG(level, "Activate trigger, %u.%u.%u.%u", c.a, c.r, c.g, c.a); level_trigger_mark_activate(level, c); /* * Look for any items to be spawned. * * We don't need to activate movement tiles as they will be activated by * the move tiles themselves during collision testing. */ for (x = 0; x < MAP_WIDTH; x++) { for (y = 0; y < MAP_HEIGHT; y++) { level_map_tile *tile = &level->map_grid.tile[x][y][MAP_DEPTH_ACTIONS]; tpp tile_tp = tile->tp; if (!tile_tp) { continue; } color it_trigger = tile->data.col; if (color_none(it_trigger)) { it_trigger = default_trigger; } if (!color_cmp(it_trigger, c)) { continue; } /* * Look for the original thing that it looks like we wanted to * destroy. Then try and find it on the map. */ tpp triggerd_tp = 0; for (z = MAP_DEPTH_ACTIONS - 1; z >= 0; z--) { triggerd_tp = level->map_grid.tile[x][y][z].tp; if (triggerd_tp) { break; } } if (!triggerd_tp) { continue; } /* * Any sleeping things that need to be awoken? Actually they don't * exist yet, so we need to create them. It's best not to waste * resources with sleeping things until they are needed. */ if (tp_is_action_sleep(tile_tp)) { LEVEL_LOG(level, "Spawn %s via movement trigger %u.%u.%u.%u", tp_name(triggerd_tp), c.a, c.r, c.g, c.a); widp w = wid_game_map_replace_tile(level, x, y, 0, /* thing */ triggerd_tp, 0 /* tpp data */ ); /* * For things like bombs and the like, make them active. */ thingp t = wid_get_thing(w); if (t) { thing_wake(level, t); } spawned = 1; } /* * Any things that need to be zapped? */ if (tp_is_action_zap(tile_tp)) { thingp t = map_is_tp_at(level, x, y, triggerd_tp); if (t) { LEVEL_LOG(level, "Kill %s via movement trigger %u.%u.%u.%u", thing_logname(t), c.a, c.r, c.g, c.a); thing_dead(level, t, 0, "killed by zap trigger"); zapped = true; } } /* * Activate any blocks sitting on movement actions. This will * allow them to do collision testing with the action block and * then move. */ if (tp_is_action_left(tile_tp) || tp_is_action_right(tile_tp) || tp_is_action_up(tile_tp) || tp_is_action_down(tile_tp)) { thingp t = map_is_tp_at(level, x, y, triggerd_tp); if (t) { LEVEL_LOG(level, "Active %s via movement trigger %u.%u.%u.%u", thing_logname(t), c.a, c.r, c.g, c.a); level_trigger_move_thing(level, tile_tp, t); } } } } if (spawned) { sound_play_slime(); } }