Beispiel #1
0
/* sand falls down and applies pressure to water */
void move_sand(void) {
	int x, y;
	for(x = map.w - 1; x >= 0 ; x--) {
		for(y = map.h - 1; y >= 0; y--) {
			if((y + 1 <= map.h) && (x + 1 <= map.w)) {
				if(sand_tile(x, y) && air_tile(x, y+1)) {
					map.tiles[x][y] = AIR;
					map.tiles[x][y+1] = SAND;
				}

				/* current is sand and below is water*/
				if(sand_tile(x, y) && water_tile(x, y+1)) {

					/* left of bottom tile is water or air, flow left*/
					if((x > 0) && (water_tile(x-1, y+1) || air_tile(x-1, y+1))) {
						map.new_water_mass[x-1][y+1] += map.new_water_mass[x][y+1];
						map.new_water_mass[x][y+1] = 0;
						map.tiles[x][y] = AIR;
						map.new_water_mass[x][y] = 0;
						map.tiles[x][y+1] = SAND;
					}

					/* right of bottom tile is water or air, flow rightt*/
					else if(water_tile(x+1, y+1) || air_tile(x+1, y+1)) {
						map.new_water_mass[x+1][y+1] += map.new_water_mass[x][y+1];
						map.new_water_mass[x][y+1] = 0;
						map.tiles[x][y] = AIR;
						map.new_water_mass[x][y] = 0;
						map.tiles[x][y+1] = SAND;
					}

					/* can't flow left or right, move to top of tile */
					else {
						map.tiles[x][y] = map.tiles[x][y+1];		// move below tile one up
						map.new_water_mass[x][y] = map.new_water_mass[x][y+1];	// set mass to mass of below tile
						map.tiles[x][y+1] = SAND;					// move sand tile one down
						map.new_water_mass[x][y+1] = 0;					// reset sand mass
					}
				}
			}
		}
	}
}
Beispiel #2
0
void simulate_water(void) {
	float flow = 0;
	float remaining_mass;
	int x, y;

	for(x = 0; x < map.w; x++) {
		for(y = 0; y < map.h; y++) {
			/* skip non water blocks */
			if(!air_tile(x, y) && !water_tile(x, y)) {
				continue;
			}

			flow = 0;
			remaining_mass = map.water_mass[x][y];
			if(remaining_mass <= 0) {
				continue;
			}

			/* the block below this one */
			if(y+1 < map.h) {
				if(air_tile(x, y+1) || water_tile(x, y+1)) {
					flow = get_stable_state_below(remaining_mass + map.water_mass[x][y+1]) - map.water_mass[x][y+1];
					if(flow > MIN_FLOW) {
						flow *= 0.5; /* leads to smoother flow */
					}
					flow = constrain(flow, 0, min(MAX_SPEED, remaining_mass));

					map.new_water_mass[x][y] -= flow;
					map.new_water_mass[x][y+1] += flow;
					remaining_mass -= flow;
				}
			}

			if(remaining_mass <= 0) {
				continue;
			}

			/* block left of this one */
			if(x-1 >= 0) {
				if(air_tile(x-1, y) || water_tile(x-1, y)) {
					/* equalize the amount of water in this block and it's neighbour */
					flow = (map.water_mass[x][y] - map.water_mass[x-1][y]) / 4;
					if(flow > MIN_FLOW) {
						flow *= 0.5;
					}
					flow = constrain(flow, 0, remaining_mass);

					map.new_water_mass[x][y] -= flow;
					map.new_water_mass[x-1][y] += flow;
					remaining_mass -= flow;
				}
			}

			if(remaining_mass <= 0) {
				continue;
			}

			/* block right of this one */
			if(x + 1 < map.w) {
				if(air_tile(x+1, y) || water_tile(x+1, y)) {
					/* equalize the amount of water in this block and it's neighbour */
					flow = (map.water_mass[x][y] - map.water_mass[x+1][y]) / 4;
					if(flow > MIN_FLOW) {
						flow *= 0.5;
					}
					flow = constrain(flow, 0, remaining_mass);

					map.new_water_mass[x][y] -= flow;
					map.new_water_mass[x+1][y] += flow;
					remaining_mass -= flow;
				}
			}

			if(remaining_mass <= 0) {
				continue;
			}

			/* up. only compressed water flows upwards */
			if(y-1 >= 0) {
				if(air_tile(x, y-1) || water_tile(x, y-1)) {
					flow = remaining_mass - get_stable_state_below(remaining_mass + map.water_mass[x][y-1]);
					if(flow > MIN_FLOW) {
						flow *= 0.5;
					}
					flow = constrain(flow, 0, min(MAX_SPEED, remaining_mass));

					map.new_water_mass[x][y] -= flow;
					map.new_water_mass[x][y-1] += flow;
					remaining_mass -= flow;
				}
			}
		}
	}
	/* copy the new mass values to the mass array */
	for(x = 0; x < map.w; x++) {
		for(y = 0; y < map.h; y++) {
			map.water_mass[x][y] = map.new_water_mass[x][y];
		}
	}

	for(x = 0; x < map.w; x++) {
		for(y = 0; y < map.h; y++) {
			/* skip ground blocks */
			if(!air_tile(x, y) && !water_tile(x, y)) {
				continue;
			}
			/* Flag/unflag water blocks */
			if ((map.water_mass[x][y] >= MIN_MASS) && (map.water_mass[x][y] < water2_mass)) {
				map.tiles[x][y] = WATER1;
			}
			else if ((map.water_mass[x][y] >= water2_mass) && (map.water_mass[x][y] < water3_mass)) {
				map.tiles[x][y] = WATER2;
			}
			else if ((map.water_mass[x][y] >= water3_mass) && (map.water_mass[x][y] < water4_mass)) {
				map.tiles[x][y] = WATER3;
			}
			else if ((map.water_mass[x][y] >= water4_mass) && (map.water_mass[x][y] < water5_mass)) {
				map.tiles[x][y] = WATER4;
			}
			else if (map.water_mass[x][y] >= water5_mass) {
				map.tiles[x][y] = WATER5;
			}
			else {
				map.tiles[x][y] = AIR;
			}
		}
	}
}
Beispiel #3
0
int liquid_tile(int x, int y) {
	return (water_tile(x, y) || oil_tile(x, y));
}
Beispiel #4
0
void player_act()
{
    switch(get_last_action()) {
        case ACTION_TILL:
            till(x, y, current_map);
            break;
        case ACTION_PICKUP: {
            item* it = get_item(items_at(x, y, current_map), item_count_at(x, y, current_map), PURPOSE_PICKUP, true);
            if(!it)
                break;
            printf_message(COLOR_DEFAULT, "Picked up %d %s", it->count, it->name);
            callback("picked_up", it->script_state);
            take_item(x, y, it, current_map);
            add_item(it);
        } break;
        case ACTION_DROP: {
            item* it = get_item(inventory, item_count, PURPOSE_DROP, false);
            if(!it)
                break;
            if(it->can_equip && equipment[it->slot] == it) {
                equipment[it->slot] = 0;
                printf_message(COLOR_DEFAULT, "You unequip the %s, and drop it on the ground.", it->name);
                callback("removed", it->script_state);
            }
            item* clone = clone_item(it);
            callback("dropped", clone->script_state);
            place_item(x, y, clone, current_map);
            remove_item(it, -1);
        } break;
        case ACTION_APPLY: {
            item* it = get_item(inventory, item_count, PURPOSE_APPLY, false);
            if(!it)
                break;
            callback("apply", it->script_state);
            remove_item(it, 1);
        } break;
        case ACTION_EQUIP: {
            item* it = get_item(inventory, item_count, PURPOSE_EQUIP, false);
            if(!it || it->slot == SLOT_INVALID)
                break;
            callback("equip", it->script_state);
            printf_message(COLOR_DEFAULT, "You equip the %s.", it->name);
            equipment[it->slot] = it;
        break; }
        case ACTION_REMOVE: {
            item* it = get_item(equipment, 3, PURPOSE_REMOVE, false);
            if(!it)
                break;
            callback("remove", it->script_state);
            equipment[it->slot] = 0;
            printf_message(COLOR_DEFAULT, "You unequip the %s.", it->name);
        break; }
        case ACTION_PLANT: {
            if(!can_plant(x, y, current_map, true))
                break;
            item* it = get_item(inventory, item_count, PURPOSE_PLANT, false);
            if(!it)
                break;
            if(spawn_plant(x, y, it->plant_id, current_map)) {
                printf_message(COLOR_DEFAULT, "You plant the %s in the tilled soil.", it->name);
                remove_item(it, 1);
            }
        break; }
        case ACTION_HARVEST: {
            add_item(harvest_plant(x, y, current_map));
        break; }
        case ACTION_HELP:
            show_controls();
            break;
        case ACTION_INVENTORY:
            get_item(inventory, item_count, PURPOSE_NONE, false);
            break;
        case ACTION_WATER:
            water_tile(x, y, current_map);
            break;
        case ACTION_EXAMINE: {
            int mx, my;
            get_last_mouse_position(&mx, &my);
            int xdiff = mx - pres_x;
            int ydiff = my - pres_y;
            if(mx < 1 || my < 1 || mx > 78 || my > 78)
                break;
            examine(x + xdiff, y +ydiff, current_map);
        } break;
    }
    if(ep_current <= 0)
        add_message(COLOR_EP_CRIT, "Out of energy, you fall to the ground.");
}