static int
flit(object *monster)
{
	short i, row, col;

	if (!rand_percent(FLIT_PERCENT + ((monster->m_flags & FLIES) ? 20 : 0))) {
		return(0);
	}
	if (rand_percent(10)) {
		return(1);
	}
	row = monster->row;
	col = monster->col;

	for (i = 0; i < 9; i++) {
		rand_around(i, &row, &col);
		if ((row == rogue.row) && (col == rogue.col)) {
			continue;
		}
		if (mtry(monster, row, col)) {
			return(1);
		}
	}
	return(1);
}
Ejemplo n.º 2
0
void
freeze(object *monster)
{
    short freeze_percent = 99;
    short i, n;

    if (rand_percent(12)) {
	return;
    }
    freeze_percent -= (rogue.str_current + (rogue.str_current / 2));
    freeze_percent -= ((rogue.exp + ring_exp) * 4);
    freeze_percent -= (get_armor_class(rogue.armor) * 5);
    freeze_percent -= (rogue.hp_max / 3);

    if (freeze_percent > 10) {
	monster->m_flags |= FREEZING_ROGUE;
	message(mesg[203], 1);
	n = get_rand(4, 8);
	for (i = 0; i < n; i++) {
	    mv_mons();
	}
	if (rand_percent(freeze_percent)) {
	    for (i = 0; i < 50; i++) {
		mv_mons();
	    }
	    killed_by((object *) 0, HYPOTHERMIA);
	}
	message(you_can_move_again, 1);
	monster->m_flags &= (~FREEZING_ROGUE);
    }
}
Ejemplo n.º 3
0
void
plStepParticleSystem(PLparticles *ps, float dt)
{
  assert(ps != NULL);
  if (ps->enabled == false) return;

  size_t activeParticles = 0;
  for (size_t i = 0 ; i < ps->particleCount ; ++i) {
    if (ps->particles[i].active) {
      ps->particles[i].p += vf3_s_mul(ps->particles[i].v, dt) + vf3_s_mul(ps->obj->v, dt);
      ps->particles[i].age += dt;
      activeParticles++;

      if (ps->particles[i].age > ps->particles[i].lifeTime) {
        ps->particles[i].active = false;
        int_array_push(&ps->freeParticles, i);
        activeParticles --;
      }
    }
  }

  // Auto disable
  if (ps->autoDisable) {
    if (activeParticles == 0) {
      ps->enabled = false;
    }

    return;
  }

  // Not off or disabled, emitt new particles
  float newPartCount = ps->emissionRate * dt * (1.0 + rand_percent(10));
  float intPart;
  float frac = modff(newPartCount, &intPart);
  unsigned newParticles = (unsigned) intPart;

  // The fraction is handled with randomisation
  int rval = random() % 128;
  if ((float)rval/128.0f < frac) newParticles ++;

  for (unsigned i = 0 ; i < newParticles ; ++i) {
    if (ps->freeParticles.length > 0) {
      int i = int_array_remove(&ps->freeParticles, 0);
      ps->particles[i].active = true;
      ps->particles[i].age = 0.0;
      // Adjust lifetime by +-20 %
      ps->particles[i].lifeTime = ps->lifeTime + ps->lifeTime * rand_percent(20);
      ps->particles[i].p = v_q_rot(ps->p, ps->obj->q);
      ps->particles[i].v = v_q_rot(ps->v * vf3_set(rand_percent(10), rand_percent(10), rand_percent(10)), ps->obj->q);
      ps->particles[i].rgb = ps->rgb;
    } else {
      break;
    }
  }
}
Ejemplo n.º 4
0
void
trap_player(short row, short col)
{
    short t;

    if ((t = trap_at(row, col)) == NO_TRAP) {
	return;
    }
    dungeon[row][col] &= (~HIDDEN);
    if (rand_percent(rogue.exp + ring_exp)) {
	message(mesg[228], 1);
	return;
    }
    switch (t) {
    case TRAP_DOOR:
	trap_door = 1;
	new_level_message = trap_strings[(t * 2) + 1];
	break;
    case BEAR_TRAP:
	message(trap_strings[(t * 2) + 1], 1);
	bear_trap = get_rand(4, 7);
	break;
    case TELE_TRAP:
	mvaddch_rogue(rogue.row, rogue.col, '^');
	tele();
	break;
    case DART_TRAP:
	message(trap_strings[(t * 2) + 1], 1);
	rogue.hp_current -= get_damage("1d6", 1);
	if (rogue.hp_current <= 0) {
	    rogue.hp_current = 0;
	}
	if ((!sustain_strength) && rand_percent(40) &&
	    (rogue.str_current >= 3)) {
	    rogue.str_current--;
	}
	print_stats(STAT_HP | STAT_STRENGTH);
	if (rogue.hp_current <= 0) {
	    killed_by((object *) 0, POISON_DART);
	}
	break;
    case SLEEPING_GAS_TRAP:
	message(trap_strings[(t * 2) + 1], 1);
	take_a_nap();
	break;
    case RUST_TRAP:
	message(trap_strings[(t * 2) + 1], 1);
	rust((object *) 0);
	break;
    }
}
Ejemplo n.º 5
0
void
drain_life(void)
{
    short n;

    if (rand_percent(60) || (rogue.hp_max <= 30) || (rogue.hp_current < 10)) {
	return;
    }
    n = get_rand(1, 3);		/* 1 Hp, 2 Str, 3 both */

    if ((n != 2) || (!sustain_strength)) {
	message(mesg[208], 0);
    }
    if (n != 2) {
	rogue.hp_max--;
	rogue.hp_current--;
	less_hp++;
    }
    if (n != 1) {
	if ((rogue.str_current > 3) && (!sustain_strength)) {
	    rogue.str_current--;
	    if (coin_toss()) {
		rogue.str_max--;
	    }
	}
    }
    print_stats((STAT_STRENGTH | STAT_HP));
}
Ejemplo n.º 6
0
void
mon_hit(object *monster)
{
	short damage, hit_chance;
	const char *mn;
	float minus;

	if (fight_monster && (monster != fight_monster)) {
		fight_monster = NULL;
	}
	monster->trow = NO_ROOM;
	if (cur_level >= (AMULET_LEVEL * 2)) {
		hit_chance = 100;
	} else {
		hit_chance = monster->m_hit_chance;
		hit_chance -= (((2 * rogue.exp) + (2 * ring_exp)) - r_rings);
	}
	if (wizard) {
		hit_chance /= 2;
	}
	if (!fight_monster) {
		interrupted = 1;
	}
	mn = mon_name(monster);

	if (!rand_percent(hit_chance)) {
		if (!fight_monster) {
			sprintf(hit_message + strlen(hit_message), "the %s misses", mn);
			message(hit_message, 1);
			hit_message[0] = 0;
		}
		return;
	}
	if (!fight_monster) {
		sprintf(hit_message + strlen(hit_message), "the %s hit", mn);
		message(hit_message, 1);
		hit_message[0] = 0;
	}
	if (!(monster->m_flags & STATIONARY)) {
		damage = get_damage(monster->m_damage, 1);
		if (cur_level >= (AMULET_LEVEL * 2)) {
			minus = (float)((AMULET_LEVEL * 2) - cur_level);
		} else {
			minus = (float)get_armor_class(rogue.armor) * 3.00;
			minus = minus / 100.00 * (float)damage;
		}
		damage -= (short)minus;
	} else {
		damage = monster->stationary_damage++;
	}
	if (wizard) {
		damage /= 3;
	}
	if (damage > 0) {
		rogue_damage(damage, monster, 0);
	}
	if (monster->m_flags & SPECIAL_HIT) {
		special_hit(monster);
	}
}
Ejemplo n.º 7
0
static void
put_door(room *rm, short dir, short *row, short *col)
{
    short wall_width;

    wall_width = (rm->is_room & R_MAZE) ? 0 : 1;

    switch(dir) {
    case UPWARD:
    case DOWN:
        *row = ((dir == UPWARD) ? rm->top_row : rm->bottom_row);
        do {
            *col = get_rand(rm->left_col+wall_width,
                            rm->right_col-wall_width);
        } while (!(dungeon[*row][*col] & (HORWALL | TUNNEL)));
        break;
    case RIGHT:
    case LEFT:
        *col = (dir == LEFT) ? rm->left_col : rm->right_col;
        do {
            *row = get_rand(rm->top_row+wall_width,
                            rm->bottom_row-wall_width);
        } while (!(dungeon[*row][*col] & (VERTWALL | TUNNEL)));
        break;
    }
    if (rm->is_room & R_ROOM) {
        dungeon[*row][*col] = DOOR;
    }
    if ((cur_level > 2) && rand_percent(HIDE_PERCENT)) {
        dungeon[*row][*col] |= HIDDEN;
    }
    rm->doors[dir/2].door_row = *row;
    rm->doors[dir/2].door_col = *col;
}
static int
move_confused(object *monster)
{
	short i, row, col;

	if (!(monster->m_flags & ASLEEP)) {
		if (--monster->moves_confused <= 0) {
			monster->m_flags &= (~CONFUSED);
		}
		if (monster->m_flags & STATIONARY) {
			return(coin_toss() ? 1 : 0);
		} else if (rand_percent(15)) {
			return(1);
		}
		row = monster->row;
		col = monster->col;

		for (i = 0; i < 9; i++) {
			rand_around(i, &row, &col);
			if ((row == rogue.row) && (col == rogue.col)) {
				return(0);
			}
			if (mtry(monster, row, col)) {
				return(1);
			}
		}
	}
	return(0);
}
void
wake_room(short rn, boolean entering, short row, short col)
{
	object *monster;
	short wake_percent;
	boolean in_room;

	wake_percent = (rn == party_room) ? PARTY_WAKE_PERCENT : WAKE_PERCENT;
	if (stealthy > 0) {
		wake_percent /= (STEALTH_FACTOR + stealthy);
	}

	monster = level_monsters.next_monster;

	while (monster) {
		in_room = (rn == get_room_number(monster->row, monster->col));
		if (in_room) {
			if (entering) {
				monster->trow = NO_ROOM;
			} else {
				monster->trow = row;
				monster->tcol = col;
			}
		}
		if ((monster->m_flags & WAKENS) &&
			(rn == get_room_number(monster->row, monster->col))) {
			if (rand_percent(wake_percent)) {
				wake_up(monster);
			}
		}
		monster = monster->next_monster;
	}
}
Ejemplo n.º 10
0
put_gold()
{
	short i, j;
	short row,col;
	boolean is_maze, is_room;

	for (i = 0; i < MAXROOMS; i++) {
		is_maze = (rooms[i].is_room & R_MAZE) ? 1 : 0;
		is_room = (rooms[i].is_room & R_ROOM) ? 1 : 0;

		if (!(is_room || is_maze)) {
			continue;
		}
		if (is_maze || rand_percent(GOLD_PERCENT)) {
			for (j = 0; j < 50; j++) {
				row = get_rand(rooms[i].top_row+1,
				rooms[i].bottom_row-1);
				col = get_rand(rooms[i].left_col+1,
				rooms[i].right_col-1);
				if ((dungeon[row][col] == FLOOR) ||
					(dungeon[row][col] == TUNNEL)) {
					plant_gold(row, col, is_maze);
					break;
				}
			}
		}
	}
}
Ejemplo n.º 11
0
static void
add_mazes(void)
{
    short i, j;
    short start;
    short maze_percent;

    if (cur_level > 1) {
        start = get_rand(0, (MAXROOMS-1));
        maze_percent = (cur_level * 5) / 4;

        if (cur_level > 15) {
            maze_percent += cur_level;
        }
        for (i = 0; i < MAXROOMS; i++) {
            j = ((start + i) % MAXROOMS);
            if (rooms[j].is_room & R_NOTHING) {
                if (rand_percent(maze_percent)) {
                    rooms[j].is_room = R_MAZE;
                    make_maze(get_rand(rooms[j].top_row+1, rooms[j].bottom_row-1),
                              get_rand(rooms[j].left_col+1, rooms[j].right_col-1),
                              rooms[j].top_row, rooms[j].bottom_row,
                              rooms[j].left_col, rooms[j].right_col);
                    hide_boxed_passage(rooms[j].top_row, rooms[j].left_col,
                                       rooms[j].bottom_row, rooms[j].right_col,
                                       get_rand(0, 2));
                }
            }
        }
    }
}
Ejemplo n.º 12
0
void
special_hit(object *monster)
{
    if ((monster->m_flags & CONFUSED) && rand_percent(66)) {
	return;
    }
    if (monster->m_flags & RUSTS) {
	rust(monster);
    }
    if ((monster->m_flags & HOLDS) && !levitate) {
	being_held = 1;
    }
    if (monster->m_flags & FREEZES) {
	freeze(monster);
    }
    if (monster->m_flags & STINGS) {
	sting(monster);
    }
    if (monster->m_flags & DRAINS_LIFE) {
	drain_life();
    }
    if (monster->m_flags & DROPS_LEVEL) {
	drop_level();
    }
    if (monster->m_flags & STEALS_GOLD) {
	steal_gold(monster);
    } else if (monster->m_flags & STEALS_ITEM) {
	steal_item(monster);
    }
}
Ejemplo n.º 13
0
void
search(short n, boolean is_auto)
{
    short s, i, j, row, col, t;
    short shown = 0, found = 0;
    static boolean reg_search;

    for (i = -1; i <= 1; i++) {
	for (j = -1; j <= 1; j++) {
	    row = rogue.row + i;
	    col = rogue.col + j;
	    if ((row < MIN_ROW) || (row >= (ROGUE_LINES - 1)) ||
		(col < 0) || (col >= ROGUE_COLUMNS)) {
		continue;
	    }
	    if (dungeon[row][col] & HIDDEN) {
		found++;
	    }
	}
    }
    for (s = 0; s < n; s++) {
	for (i = -1; i <= 1; i++) {
	    for (j = -1; j <= 1; j++) {
		row = rogue.row + i;
		col = rogue.col + j;
		if ((row < MIN_ROW) || (row >= (ROGUE_LINES - 1)) ||
		    (col < 0) || (col >= ROGUE_COLUMNS)) {
		    continue;
		}
		if (dungeon[row][col] & HIDDEN) {
		    if (rand_percent(17 + (rogue.exp + ring_exp))) {
			dungeon[row][col] &= (~HIDDEN);
			if ((!blind) && ((row != rogue.row) ||
					 (col != rogue.col))) {
			    mvaddch_rogue(row, col,
					  get_dungeon_char(row, col));
			}
			shown++;
			if (dungeon[row][col] & TRAP) {
			    t = trap_at(row, col);
			    message(trap_strings[t * 2], 1);
			}
		    }
		}
		if (((shown == found) && (found > 0)) || interrupted) {
		    return;
		}
	    }
	}
	if ((!is_auto) && (reg_search = !reg_search)) {
	    (void) reg_move();
	}
    }
}
Ejemplo n.º 14
0
int
m_confuse(object *monster)
{
    char msg[80];

    if (!rogue_can_see(monster->row, monster->col)) {
	return 0;
    }
    if (rand_percent(45)) {
	monster->m_flags &= (~CONFUSES);	/* will not confuse the rogue */
	return 0;
    }
    if (rand_percent(55)) {
	monster->m_flags &= (~CONFUSES);
	sprintf(msg, mesg[209], mon_name(monster));
	message(msg, 1);
	confuse();
	return 1;
    }
    return 0;
}
Ejemplo n.º 15
0
void eat(void)
{
	short ch;
	short moves;
	object *obj;
	char buf[70];

	ch = pack_letter("Eat what?", FOOD);

	if (ch == ROGUE_KEY_CANCEL)
	{
		return;
	}
	if (!(obj = get_letter_object(ch)))
	{
		message("No such item.", 0);
		return;
	}
	if (obj->what_is != FOOD)
	{
		message("You can't eat that!", 0);
		return;
	}
	if ((obj->which_kind == FRUIT) || rand_percent(60))
	{
		moves = get_rand(900, 1100);
		if (obj->which_kind == RATION)
		{
			message("Yum, that tasted good.", 0);
		}
		else
		{
			sprintf(buf, "My, that was a yummy %s\b.", fruit);
			message(buf, 0);
		}
	}
	else
	{
		moves = get_rand(700, 900);
		message("Yuk, that food tasted awful.", 0);
		add_exp(2, 1);
	}
	rogue.moves_left /= 3;
	rogue.moves_left += moves;
	hunger_str[0] = 0;
	print_stats(STAT_HUNGER);

	vanish(obj, 1, &rogue.pack);
}
Ejemplo n.º 16
0
static int
connect_rooms(short room1, short room2)
{
    short row1, col1, row2, col2, dir;

    if ((!(rooms[room1].is_room & (R_ROOM | R_MAZE))) ||
            (!(rooms[room2].is_room & (R_ROOM | R_MAZE)))) {
        return(0);
    }
    if (same_row(room1, room2) &&
            (rooms[room1].left_col > rooms[room2].right_col)) {
        put_door(&rooms[room1], LEFT, &row1, &col1);
        put_door(&rooms[room2], RIGHT, &row2, &col2);
        dir = LEFT;
    } else if (same_row(room1, room2) &&
               (rooms[room2].left_col > rooms[room1].right_col)) {
        put_door(&rooms[room1], RIGHT, &row1, &col1);
        put_door(&rooms[room2], LEFT, &row2, &col2);
        dir = RIGHT;
    } else if (same_col(room1, room2) &&
               (rooms[room1].top_row > rooms[room2].bottom_row)) {
        put_door(&rooms[room1], UPWARD, &row1, &col1);
        put_door(&rooms[room2], DOWN, &row2, &col2);
        dir = UPWARD;
    } else if (same_col(room1, room2) &&
               (rooms[room2].top_row > rooms[room1].bottom_row)) {
        put_door(&rooms[room1], DOWN, &row1, &col1);
        put_door(&rooms[room2], UPWARD, &row2, &col2);
        dir = DOWN;
    } else {
        return(0);
    }

    do {
        draw_simple_passage(row1, col1, row2, col2, dir);
    } while (rand_percent(4));

    rooms[room1].doors[dir/2].oth_room = room2;
    rooms[room1].doors[dir/2].oth_row = row2;
    rooms[room1].doors[dir/2].oth_col = col2;

    rooms[room2].doors[(((dir+4)%DIRS)/2)].oth_room = room1;
    rooms[room2].doors[(((dir+4)%DIRS)/2)].oth_row = row1;
    rooms[room2].doors[(((dir+4)%DIRS)/2)].oth_col = col1;
    return(1);
}
Ejemplo n.º 17
0
void
steal_gold(object *monster)
{
    int amount;

    if ((rogue.gold <= 0) || rand_percent(10)) {
	return;
    }

    amount = get_rand((cur_level * 10), (cur_level * 30));

    if (amount > rogue.gold) {
	amount = rogue.gold;
    }
    rogue.gold -= amount;
    message(mesg[204], 0);
    print_stats(STAT_GOLD);
    disappear(monster);
}
Ejemplo n.º 18
0
void
cough_up(object *monster)
{
    object *obj;
    short row, col, i, n;

    if (cur_level < max_level) {
	return;
    }

    if (monster->m_flags & STEALS_GOLD) {
	obj = alloc_object();
	obj->what_is = GOLD;
	obj->quantity = get_rand((cur_level * 15), (cur_level * 30));
    } else {
	if (!rand_percent((int) monster->drop_percent)) {
	    return;
	}
	obj = gr_object();
    }
    row = monster->row;
    col = monster->col;

    for (n = 0; n <= 5; n++) {
	for (i = -n; i <= n; i++) {
	    if (try_to_cough(row + n, col + i, obj)) {
		return;
	    }
	    if (try_to_cough(row - n, col + i, obj)) {
		return;
	    }
	}
	for (i = -n; i <= n; i++) {
	    if (try_to_cough(row + i, col - n, obj)) {
		return;
	    }
	    if (try_to_cough(row + i, col + n, obj)) {
		return;
	    }
	}
    }
    free_object(obj);
}
Ejemplo n.º 19
0
void
drop_level(void)
{
    int hp;

    if (rand_percent(80) || (rogue.exp <= 5)) {
	return;
    }
    rogue.exp_points = level_points[rogue.exp - 2] - get_rand(9, 29);
    rogue.exp -= 2;
    hp = hp_raise();
    if ((rogue.hp_current -= hp) <= 0) {
	rogue.hp_current = 1;
    }
    if ((rogue.hp_max -= hp) <= 0) {
	rogue.hp_max = 1;
    }
    add_exp(1, 0);
}
Ejemplo n.º 20
0
void
eat(void)
{
    short ch;
    short moves;
    object *obj;
    char buf[70];

    ch = pack_letter(mesg[262], FOOD);
    if (ch == CANCEL) {
	return;
    }
    if (!(obj = get_letter_object(ch))) {
	message(mesg[263], 0);
	return;
    }
    if (obj->what_is != FOOD) {
	message(mesg[264], 0);
	return;
    }
    if ((obj->which_kind == FRUIT) || rand_percent(60)) {
	moves = get_rand(900, 1100);
	if (obj->which_kind == RATION) {
	    if (get_rand(1, 10) == 1) {
		message(mesg[265], 0);
	    } else
		message(mesg[266], 0);
	} else {
	    sprintf(buf, mesg[267], fruit);
	    message(buf, 0);
	}
    } else {
	moves = get_rand(700, 900);
	message(mesg[268], 0);
	add_exp(2, 1);
    }
    rogue.moves_left /= 3;
    rogue.moves_left += moves;
    hunger_str[0] = 0;
    print_stats(STAT_HUNGER);

    vanish(obj, 1, &rogue.pack);
}
Ejemplo n.º 21
0
put_objects()
{
	short i, n;
	object *obj;

	if (cur_level < max_level) {
		return;
	}
	n = coin_toss() ? get_rand(2, 4) : get_rand(3, 5);
	while (rand_percent(33)) {
		n++;
	}
	if (party_room != NO_ROOM) {
		make_party();
	}
	for (i = 0; i < n; i++) {
		obj = gr_object();
		rand_place(obj);
	}
	put_gold();
}
Ejemplo n.º 22
0
void
sting(object *monster)
{
    short sting_chance = 35;
    char msg[80];

    if ((rogue.str_current <= 3) || sustain_strength) {
	return;
    }
    sting_chance += (6 * (6 - get_armor_class(rogue.armor)));

    if ((rogue.exp + ring_exp) > 8) {
	sting_chance -= (6 * ((rogue.exp + ring_exp) - 8));
    }
    if (rand_percent(sting_chance)) {
	sprintf(msg, mesg[207], mon_name(monster));
	message(msg, 0);
	rogue.str_current--;
	print_stats(STAT_STRENGTH);
    }
}
Ejemplo n.º 23
0
static void
draw_simple_passage(short row1, short col1, short row2, short col2, short dir)
{
    short i, middle, t;

    if ((dir == LEFT) || (dir == RIGHT)) {
        if (col1 > col2) {
            SWAP(row1, row2);
            SWAP(col1, col2);
        }
        middle = get_rand(col1+1, col2-1);
        for (i = col1+1; i != middle; i++) {
            dungeon[row1][i] = TUNNEL;
        }
        for (i = row1; i != row2; i += (row1 > row2) ? -1 : 1) {
            dungeon[i][middle] = TUNNEL;
        }
        for (i = middle; i != col2; i++) {
            dungeon[row2][i] = TUNNEL;
        }
    } else {
        if (row1 > row2) {
            SWAP(row1, row2);
            SWAP(col1, col2);
        }
        middle = get_rand(row1+1, row2-1);
        for (i = row1+1; i != middle; i++) {
            dungeon[i][col1] = TUNNEL;
        }
        for (i = col1; i != col2; i += (col1 > col2) ? -1 : 1) {
            dungeon[middle][i] = TUNNEL;
        }
        for (i = middle; i != row2; i++) {
            dungeon[i][col2] = TUNNEL;
        }
    }
    if (rand_percent(HIDE_PERCENT)) {
        hide_boxed_passage(row1, col1, row2, col2, 1);
    }
}
Ejemplo n.º 24
0
void
rogue_hit(object *monster, boolean force_hit)
{
	short damage, hit_chance;

	if (monster) {
		if (check_imitator(monster)) {
			return;
		}
		hit_chance = force_hit ? 100 : get_hit_chance(rogue.weapon);

		if (wizard) {
			hit_chance *= 2;
		}
		if (!rand_percent(hit_chance)) {
			if (!fight_monster) {
				strcpy(hit_message, "you miss  ");
			}
			goto RET;
		}
		damage = get_weapon_damage(rogue.weapon);
		if (wizard) {
			damage *= 3;
		}
		if (con_mon) {
			s_con_mon(monster);
		}
		if (mon_damage(monster, damage)) {	/* still alive? */
			if (!fight_monster) {
				strcpy(hit_message, "you hit  ");
			}
		}
RET:	check_gold_seeker(monster);
		wake_up(monster);
	}
}
Ejemplo n.º 25
0
/**
 * Sends a cTCP segment to a destination associated with the provided
 * connection object.
 *
 * conn: Connection object.
 * segment: Pointer to cTCP segment to send.
 * len: Length of the segment (including the cTCP header and data).
 *
 * returns: The number of bytes actually sent, 0 if nothing was sent, -1 if
 *          there in an error.
 */
int conn_send(conn_t *conn, ctcp_segment_t *segment, size_t len) { ASSERT_CONN;
  /* Check parameters. */
  if (conn == NULL || segment == NULL) {
    fprintf(stderr, "[ERROR] NULL parameters in conn_send\n");
    return -1;
  }

  /* Make a copy of the segment first. */
  ctcp_segment_t *segment_copy = calloc(len, 1);
  memcpy(segment_copy, segment, len);

  /* Fork process off in order to do unreliability. Keep track of whether we
     are forked or not. */
  int fork_level = 0;
  bool am_i_forked = 0;

  /* Segment drop. Don't send the segment. */
  if ((test_debug_on && !tester_did_unreliable && opt_drop) ||
      (!test_debug_on && rand_percent(fork_level) < opt_drop)) {
    tester_did_unreliable = true;

    if (DEBUG) {
      fprintf(stderr, "[DEBUG] Dropping segment\n");
      print_hdr_ctcp(segment_copy);
    }
    free(segment_copy);
    return len;
  }

  /* Segment duplication. Fork another process to send the other segment. */
  if ((test_debug_on && !tester_did_unreliable && opt_duplicate) ||
      (!test_debug_on && rand_percent(fork_level) < opt_duplicate)) {
    tester_did_unreliable = true;

    if (DEBUG) {
      fprintf(stderr, "[DEBUG] Duplicating segment\n");
      print_hdr_ctcp(segment_copy);
    }
    if (fork() == 0) {
      am_i_forked = 1;
      fork_level++;
    }
  }

  /* Segment delay. Fork another process to delay the segment, and kill the
     current one. */
  if ((test_debug_on && !tester_did_unreliable && opt_delay) ||
       (!test_debug_on && rand_percent(fork_level) < opt_delay)) {
    tester_did_unreliable = true;

    if (DEBUG) {
      fprintf(stderr, "[DEBUG] Delaying segment\n");
      print_hdr_ctcp(segment_copy);
    }
    /* Forked process. Sleep for a bit. */
    if (fork() == 0) {
      am_i_forked = 1;
      fork_level++;
      sleep(rand() % 5);
    }
    /* Original process. */
    else {
      free(segment_copy);
      return len;
    }
  }

  /* Segment corruption. Flip bits in the segment after the TCP flags (to avoid
     corrupting the flags, which may cause problems). */
  bool do_corrupt = rand_percent(fork_level) < opt_corrupt;
  uint16_t data_length = len - sizeof(ctcp_segment_t) + sizeof(uint32_t);
  uint16_t rand_bit = rand() % (data_length * 8 - 1) +
                      (sizeof(ctcp_segment_t) - sizeof(uint32_t)) * 8;

  if ((test_debug_on && !tester_did_unreliable && opt_corrupt) ||
      (!test_debug_on && do_corrupt)) {
    tester_did_unreliable = true;

    if (DEBUG) {
      fprintf(stderr, "[DEBUG] Corrupting segment\n");
      print_hdr_ctcp(segment_copy);
    }
    flipbit(segment_copy, rand_bit);
  }

  uint16_t data_len = len - sizeof(ctcp_segment_t);
  uint16_t total_len = FULL_HDR_SIZE + data_len;

  if (log_file != -1 || test_debug_on) {
    log_segment(log_file, config->ip_addr, config->port, conn, segment_copy,
                len, true, unix_socket);
  }

  /* Convert from a cTCP segment to a real one and finally send the segment. */
  char *pkt = convert_to_datagram(conn, segment_copy, len);
  int n = send_pkt(conn, config->socket, pkt, total_len, 0);
  if (DEBUG) {
    fprintf(stderr, "[DEBUG] Sent segment\n");
    print_hdr_ctcp(segment_copy);
  }
  free(pkt);
  free(segment_copy);

  /* Kill forked process. */
  if (am_i_forked)
    exit(0);

  /* Return number of bytes sent. Need to subtract some because the return value
     is actually the size of the TCP segment instead of the cTCP segment. */
  if (n >= (long int)TCP_HDR_SIZE)
    return n - (TCP_HDR_SIZE + IP_HDR_SIZE - sizeof(ctcp_segment_t));
  return n;
}
Ejemplo n.º 26
0
static void
make_maze(short r, short c, short tr, short br, short lc, short rc)
{
    char dirs[4];
    short i, t;

    dirs[0] = UPWARD;
    dirs[1] = DOWN;
    dirs[2] = LEFT;
    dirs[3] = RIGHT;

    dungeon[r][c] = TUNNEL;

    if (rand_percent(20)) {
        for (i = 0; i < 10; i++) {
            short t1, t2;

            t1 = get_rand(0, 3);
            t2 = get_rand(0, 3);

            SWAP(dirs[t1], dirs[t2]);
        }
    }
    for (i = 0; i < 4; i++) {
        switch(dirs[i]) {
        case UPWARD:
            if (((r-1) >= tr) &&
                    (dungeon[r-1][c] != TUNNEL) &&
                    (dungeon[r-1][c-1] != TUNNEL) &&
                    (dungeon[r-1][c+1] != TUNNEL) &&
                    (dungeon[r-2][c] != TUNNEL)) {
                make_maze((r-1), c, tr, br, lc, rc);
            }
            break;
        case DOWN:
            if (((r+1) <= br) &&
                    (dungeon[r+1][c] != TUNNEL) &&
                    (dungeon[r+1][c-1] != TUNNEL) &&
                    (dungeon[r+1][c+1] != TUNNEL) &&
                    (dungeon[r+2][c] != TUNNEL)) {
                make_maze((r+1), c, tr, br, lc, rc);
            }
            break;
        case LEFT:
            if (((c-1) >= lc) &&
                    (dungeon[r][c-1] != TUNNEL) &&
                    (dungeon[r-1][c-1] != TUNNEL) &&
                    (dungeon[r+1][c-1] != TUNNEL) &&
                    (dungeon[r][c-2] != TUNNEL)) {
                make_maze(r, (c-1), tr, br, lc, rc);
            }
            break;
        case RIGHT:
            if (((c+1) <= rc) &&
                    (dungeon[r][c+1] != TUNNEL) &&
                    (dungeon[r-1][c+1] != TUNNEL) &&
                    (dungeon[r+1][c+1] != TUNNEL) &&
                    (dungeon[r][c+2] != TUNNEL)) {
                make_maze(r, (c+1), tr, br, lc, rc);
            }
            break;
        }
    }
}
Ejemplo n.º 27
0
static void
make_room(short rn, short r1, short r2, short r3)
{
    short left_col, right_col, top_row, bottom_row;
    short width, height;
    short row_offset, col_offset;
    short i, j, ch;

    left_col = right_col = top_row = bottom_row = 0;
    switch(rn) {
    case 0:
        left_col = 0;
        right_col = COL1-1;
        top_row = MIN_ROW;
        bottom_row = ROW1-1;
        break;
    case 1:
        left_col = COL1+1;
        right_col = COL2-1;
        top_row = MIN_ROW;
        bottom_row = ROW1-1;
        break;
    case 2:
        left_col = COL2+1;
        right_col = DCOLS-1;
        top_row = MIN_ROW;
        bottom_row = ROW1-1;
        break;
    case 3:
        left_col = 0;
        right_col = COL1-1;
        top_row = ROW1+1;
        bottom_row = ROW2-1;
        break;
    case 4:
        left_col = COL1+1;
        right_col = COL2-1;
        top_row = ROW1+1;
        bottom_row = ROW2-1;
        break;
    case 5:
        left_col = COL2+1;
        right_col = DCOLS-1;
        top_row = ROW1+1;
        bottom_row = ROW2-1;
        break;
    case 6:
        left_col = 0;
        right_col = COL1-1;
        top_row = ROW2+1;
        bottom_row = DROWS - 2;
        break;
    case 7:
        left_col = COL1+1;
        right_col = COL2-1;
        top_row = ROW2+1;
        bottom_row = DROWS - 2;
        break;
    case 8:
        left_col = COL2+1;
        right_col = DCOLS-1;
        top_row = ROW2+1;
        bottom_row = DROWS - 2;
        break;
    case BIG_ROOM:
        top_row = get_rand(MIN_ROW, MIN_ROW+5);
        bottom_row = get_rand(DROWS-7, DROWS-2);
        left_col = get_rand(0, 10);
        right_col = get_rand(DCOLS-11, DCOLS-1);
        rn = 0;
        goto B;
    }
    height = get_rand(4, (bottom_row - top_row + 1));
    width = get_rand(7, (right_col - left_col - 2));

    row_offset = get_rand(0, ((bottom_row - top_row) - height + 1));
    col_offset = get_rand(0, ((right_col - left_col) - width + 1));

    top_row += row_offset;
    bottom_row = top_row + height - 1;

    left_col += col_offset;
    right_col = left_col + width - 1;

    if ((rn != r1) && (rn != r2) && (rn != r3) && rand_percent(40)) {
        goto END;
    }
B:
    rooms[rn].is_room = R_ROOM;

    for (i = top_row; i <= bottom_row; i++) {
        for (j = left_col; j <= right_col; j++) {
            if ((i == top_row) || (i == bottom_row)) {
                ch = HORWALL;
            } else if (	((i != top_row) && (i != bottom_row)) &&
                        ((j == left_col) || (j == right_col))) {
                ch = VERTWALL;
            } else {
                ch = FLOOR;
            }
            dungeon[i][j] = ch;
        }
    }
END:
    rooms[rn].top_row = top_row;
    rooms[rn].bottom_row = bottom_row;
    rooms[rn].left_col = left_col;
    rooms[rn].right_col = right_col;
}
Ejemplo n.º 28
0
void
make_level(void)
{
    short i, j;
    short must_1, must_2, must_3;
    boolean big_room;

    must_2 = must_3 = 0;
    if (cur_level < LAST_DUNGEON) {
        cur_level++;
    }
    if (cur_level > max_level) {
        max_level = cur_level;
    }
    must_1 = get_rand(0, 5);

    switch(must_1) {
    case 0:
        must_1 = 0;
        must_2 = 1;
        must_3 = 2;
        break;
    case 1:
        must_1 = 3;
        must_2 = 4;
        must_3 = 5;
        break;
    case 2:
        must_1 = 6;
        must_2 = 7;
        must_3 = 8;
        break;
    case 3:
        must_1 = 0;
        must_2 = 3;
        must_3 = 6;
        break;
    case 4:
        must_1 = 1;
        must_2 = 4;
        must_3 = 7;
        break;
    case 5:
        must_1 = 2;
        must_2 = 5;
        must_3 = 8;
        break;
    }
    if (rand_percent(8)) {
        party_room = 0;
    }
    big_room = ((party_room != NO_ROOM) && rand_percent(1));
    if (big_room) {
        make_room(BIG_ROOM, 0, 0, 0);
    } else {
        for (i = 0; i < MAXROOMS; i++) {
            make_room(i, must_1, must_2, must_3);
        }
    }
    if (!big_room) {
        add_mazes();

        mix_random_rooms();

        for (j = 0; j < MAXROOMS; j++) {

            i = random_rooms[j];

            if (i < (MAXROOMS-1)) {
                (void)connect_rooms(i, i+1);
            }
            if (i < (MAXROOMS-3)) {
                (void)connect_rooms(i, i+3);
            }
            if (i < (MAXROOMS-2)) {
                if (rooms[i+1].is_room & R_NOTHING) {
                    if (connect_rooms(i, i+2)) {
                        rooms[i+1].is_room = R_CROSS;
                    }
                }
            }
            if (i < (MAXROOMS-6)) {
                if (rooms[i+3].is_room & R_NOTHING) {
                    if (connect_rooms(i, i+6)) {
                        rooms[i+3].is_room = R_CROSS;
                    }
                }
            }
            if (is_all_connected()) {
                break;
            }
        }
        fill_out_level();
    }
    if (!has_amulet() && (cur_level >= AMULET_LEVEL)) {
        put_amulet();
    }
}
Ejemplo n.º 29
0
void
steal_item(object *monster)
{
    object *obj;
    short i, n, t = 0;		/* 未初期化変数の使用の警告のための初期化。 0 を代入 */
    char desc[80];
    boolean has_something = 0;

    if (rand_percent(15)) {
	return;
    }
    obj = rogue.pack.next_object;

    if (!obj) {
	goto DSPR;
    }
#if !defined( ORIGINAL )
    while (obj) {
	if ((obj->what_is == RING) &&
	    (obj->which_kind == ADORNMENT) &&
	    (obj->in_use_flags & ON_EITHER_HAND) && (obj->is_cursed == 0)) {
	    un_put_on(obj);
	    goto adornment;
	}
	obj = obj->next_object;
    }
    obj = rogue.pack.next_object;
#endif /* ORIGINAL */
    while (obj) {
	if (!(obj->in_use_flags & BEING_USED)) {
	    has_something = 1;
	    break;
	}
	obj = obj->next_object;
    }
    if (!has_something) {
	goto DSPR;
    }
    n = get_rand(0, MAX_PACK_COUNT);
    obj = rogue.pack.next_object;

    for (i = 0; i <= n; i++) {
	obj = obj->next_object;
	while ((!obj) || (obj->in_use_flags & BEING_USED)) {
	    if (!obj) {
		obj = rogue.pack.next_object;
	    } else {
		obj = obj->next_object;
	    }
	}
    }
#if !defined( ORIGINAL )
adornment:
#endif /* not ORIGINAL */
#if !defined( JAPAN )
    (void) strcpy(desc, mesg[205]);
#endif /* JAPAN */
    if (obj->what_is != WEAPON) {
	t = obj->quantity;
	obj->quantity = 1;
    }
#if defined( JAPAN )
    get_desc(obj, desc, 0);
    (void) strcat(desc, mesg[205]);
#else /* not JAPAN */
    get_desc(obj, desc + 10, 0);
#endif /* not JAPAN */
    message(desc, 0);

    obj->quantity = ((obj->what_is != WEAPON) ? t : 1);

    vanish(obj, 0, &rogue.pack);
DSPR:
    disappear(monster);
}
Ejemplo n.º 30
0
// Loads up **grid with the results of a cellular automata simulation.
void createBlobOnGrid(short **grid,
                      short *retMinX, short *retMinY, short *retWidth, short *retHeight,
                      short roundCount,
                      short minBlobWidth, short minBlobHeight,
					  short maxBlobWidth, short maxBlobHeight, short percentSeeded,
					  char birthParameters[9], char survivalParameters[9]) {
    
	short i, j, k;
	short blobNumber, blobSize, topBlobNumber, topBlobSize;
    
    short topBlobMinX, topBlobMinY, topBlobMaxX, topBlobMaxY, blobWidth, blobHeight;
	//short buffer2[maxBlobWidth][maxBlobHeight]; // buffer[][] is already a global short array
	boolean foundACellThisLine;
	
	// Generate blobs until they satisfy the minBlobWidth and minBlobHeight restraints
	do {
		// Clear buffer.
        fillGrid(grid, 0);
		
		// Fill relevant portion with noise based on the percentSeeded argument.
		for(i=0; i<maxBlobWidth; i++) {
			for(j=0; j<maxBlobHeight; j++) {
				grid[i][j] = (rand_percent(percentSeeded) ? 1 : 0);
			}
		}
		
//        colorOverDungeon(&darkGray);
//        hiliteGrid(grid, &white, 100);
//        temporaryMessage("Random starting noise:", true);
		
		// Some iterations of cellular automata
		for (k=0; k<roundCount; k++) {
			cellularAutomataRound(grid, birthParameters, survivalParameters);
            
//            colorOverDungeon(&darkGray);
//            hiliteGrid(grid, &white, 100);
//            temporaryMessage("Cellular automata progress:", true);
		}
        
//        colorOverDungeon(&darkGray);
//        hiliteGrid(grid, &white, 100);
//        temporaryMessage("Cellular automata result:", true);
        
		// Now to measure the result. These are best-of variables; start them out at worst-case values.
		topBlobSize =   0;
		topBlobNumber = 0;
		topBlobMinX =   maxBlobWidth;
		topBlobMaxX =   0;
		topBlobMinY =   maxBlobHeight;
		topBlobMaxY =   0;
        
		// Fill each blob with its own number, starting with 2 (since 1 means floor), and keeping track of the biggest:
		blobNumber = 2;
		
		for(i=0; i<DCOLS; i++) {
			for(j=0; j<DROWS; j++) {
				if (grid[i][j] == 1) { // an unmarked blob
					// Mark all the cells and returns the total size:
					blobSize = fillContiguousRegion(grid, i, j, blobNumber);
					if (blobSize > topBlobSize) { // if this blob is a new record
						topBlobSize = blobSize;
						topBlobNumber = blobNumber;
					}
					blobNumber++;
				}
			}
		}
		
		// Figure out the top blob's height and width:
		// First find the max & min x:
		for(i=0; i<DCOLS; i++) {
			foundACellThisLine = false;
			for(j=0; j<DROWS; j++) {
				if (grid[i][j] == topBlobNumber) {
					foundACellThisLine = true;
					break;
				}
			}
			if (foundACellThisLine) {
				if (i < topBlobMinX) {
					topBlobMinX = i;
				}
				if (i > topBlobMaxX) {
					topBlobMaxX = i;
				}
			}
		}
		
		// Then the max & min y:
		for(j=0; j<DROWS; j++) {
			foundACellThisLine = false;
			for(i=0; i<DCOLS; i++) {
				if (grid[i][j] == topBlobNumber) {
					foundACellThisLine = true;
					break;
				}
			}
			if (foundACellThisLine) {
				if (j < topBlobMinY) {
					topBlobMinY = j;
				}
				if (j > topBlobMaxY) {
					topBlobMaxY = j;
				}
			}
		}
        
		blobWidth =		(topBlobMaxX - topBlobMinX) + 1;
		blobHeight =	(topBlobMaxY - topBlobMinY) + 1;
        
	} while (blobWidth < minBlobWidth
             || blobHeight < minBlobHeight
             || topBlobNumber == 0);
	
	// Replace the winning blob with 1's, and everything else with 0's:
    for(i=0; i<DCOLS; i++) {
        for(j=0; j<DROWS; j++) {
			if (grid[i][j] == topBlobNumber) {
				grid[i][j] = 1;
			} else {
				grid[i][j] = 0;
			}
		}
	}
    
    // Populate the returned variables.
    *retMinX = topBlobMinX;
    *retMinY = topBlobMinY;
    *retWidth = blobWidth;
    *retHeight = blobHeight;
}