bool todd_getchar(unsigned char *c) { zmq_pollitem_t items [4]; items[0].socket = chat_socket; items[0].events = ZMQ_POLLIN; items[1].socket = NULL; items[1].fd = fileno(stdin); items[1].events = ZMQ_POLLIN; items[2].socket = party_socket; items[2].events = ZMQ_POLLIN; items[3].socket = ctrl_socket; items[3].events = ZMQ_POLLIN; /* Poll for events indefinitely */ do { int rc = zmq_poll (items, 4, -1); if (rc < 0) { return false; } if (items[0].revents & ZMQ_POLLIN) { char *msg = try_recv_msg(chat_socket); parse_and_print_chatmsg(msg); free(msg); } if (items[2].revents & ZMQ_POLLIN) { char *msg = try_recv_msg(party_socket); // TODO real prefix parsing. avoid buffer overrun parse_partymsg(msg); free(msg); } if (items[3].revents & ZMQ_POLLIN) { char *msg = try_recv_msg(ctrl_socket); parse_ctrlmsg(msg); free(msg); } } while (!(items[1].revents & ZMQ_POLLIN)); unsigned char dummy; if (c == NULL) c = &dummy; /* if no events from network, return a local getch */ int rc = read(fileno(stdin), c, sizeof(char)); /* toggle chat window */ if (rc == 1) { if (*c == '\t') { // this is a dirty hack; input_win is only NULL when logging in // when logging in, don't toggle chat_typing (would cause random *** to appear when writing your username if (input_win != NULL) { if (chat_typing == 0) /* if not typing yet, goto chat toggle */ { ncurs_chat(player); } else { chat_typing = 0; /* if typing already, cancel it */ ncurs_chat(player); } } } if (*c == 'v') // v for View Stats { if (chat_typing == 0) // don't view stats when in line input mode { ac_view_stats(); wclear(command_win); wrefresh(command_win); // empty commands and wait for a getch ncurs_modal_msg(""); // only "continue" and getch set_player_location(player.location); } } // no special keys pressed, input as normal return true; } else { return false; } }
void combat_seeifready() { // loop through all the players in combat int allready = 1; //if (is_online(partymember1.id) || is_online(partymember2.id)) // it's multiplayer combat if (combat_ismulti()) // it's multiplayer combat { // loop through all the effects of all party members taking part in the fight for (int i = 0; i <= 2; i++) if (player_party.characters[i]->incombat) { if (player_party.characters[i]->turnready < 0) { ncurs_log_sysmsg("still waiting for: %s",player_party.characters[i]->name); allready = 0; // still waiting for a keypress } } } else // it's single player combat { allready = 1; } // COMBAT EFFECTS START HERE if (allready) // if everyone is ready, do combat stuff { ncurs_log_sysmsg(_("all players have committed turns, calculating effects")); ncurs_log_sysmsg(_("Combat resolution============================")); // combat stuff begins here // players attack enemies for (int i = 0; i <= 2; i++) if (player_party.characters[i]->incombat) skill_effect(player_party.characters[i], enemy_party.characters[player_party.characters[i]->combattarget],player_party.characters[i]->skill[player_party.characters[i]->turnready]); // enemies attack players // choose which player to attack int dest = 0; int players = 0; for (int i = 0; i <= 2; i++) if (player_party.characters[i]->incombat) players++; // players now holds the number of players in combat, randomize one of them int i = 0; // enemies attack here for (int j = 0; j <= 2; j++) { if (enemy_party.characters[j]->incombat) // only enemies who are in combat attack { while (i == 0) // loop until you find an acceptable target, then attack { dest = rand() % players; // dest holds a number from 0..players in combat if (player_party.characters[dest]->incombat) // this player is in combat -> acceptable target i = 1; } // TODO: random enemy skill (enemies should have more than one skill.. skill_effect(enemy_party.characters[j], player_party.characters[dest], enemy_party.characters[j]->skill[0]); } } ncurs_log_sysmsg(_("=============================================")); // combat stuff ends here // reset turnready for (int i = 0; i <= 2; i++) if (player_party.characters[i]->incombat) player_party.characters[i]->turnready = -1; /* 3. check for dead player/enemy */ int all_enemies_dead = fight_check_dead(); /* 4. update stats and display them IF THE ENEMY DIDN'T DIE */ if (!all_enemies_dead) ac_update_fightscreen(); else { ncurs_clear_fightwindows(); ncurs_modal_msg(_("All enemies are slain! The battle is over")); // ac_dungeons makes the player go up a dungeon level // -> to stay at the same level, decrease the level here player.dungeon_lvl--; ac_dungeons(); } } }
int fight_check_dead() { /* TODO: figure out the order of checking deaths: attacks are simultaneous. Iniative? */ // TODO enemy and player codes are almost identical, refactor into a function // bool check_chr_dead(Character *chr); or something /* check if enemy dies */ bool enemy_dead = false; bool enemy_dead_elements = false; for (size_t i = 0; i < ELEM_COUNT; i++) { if (enemy.elements[i] <= 0) { enemy_dead = true; enemy_dead_elements = true; } } if (enemy.health <= 0) enemy_dead = true; if (enemy_dead) { int money = 7; int exp = 10; player.money += money; player.experience += exp; werase(game_win); if (enemy_dead_elements) ncurs_log_sysmsg(_("%s has caused an elemental imbalance in %s"), player.name, enemy.name); ncurs_log_sysmsg(_("%s has killed %s!"), player.name, enemy.name); ncurs_log_sysmsg(_("%s received %d coins and %d XP"), player.name, money, exp); ncurs_modal_msg( _("%s is slain!\n\nYou find %d coins on the corpse, and gain %d experience\n"), enemy.name, money, exp); ac_dungeons(); } /* check if player dies as well */ bool player_dead = false; bool player_dead_elements = false; for (size_t i = 0; i < 5; i++) { if (player.elements[i] <= 0) { player_dead = true; player_dead_elements = true; } } if (player.health <= 0) player_dead = true; if (player_dead) { wclear (game_win); if (player_dead_elements) // elements below 0, don't die but faint only { db_player_location(LOC_FAINTED); ncurs_log_sysmsg(_("%s has caused an elemental imbalance in %s"), enemy.name, player.name); mvwprintw(game_win, 6, 0, _("The world around you starts to spin.\nYou sense a great imbalance inside you.")); wattron(game_win, A_BOLD); wattron(game_win, A_UNDERLINE); mvwprintw(game_win, 8, 0, _("You faint. TODO: \"come back in 8 hours??\"")); wattroff(game_win, A_BOLD); wattroff(game_win, A_UNDERLINE); } else // PERMADEATH { /* first, set the player location to "DEAD" */ db_player_location(LOC_DEAD); ncurs_log_sysmsg(_("%s has killed %s!"), enemy.name, player.name); mvwprintw(game_win, 6, 0, _("The world fades around you as you fall to the ground, \nbleeding.")); wattron(game_win, A_BOLD); wattron(game_win, A_UNDERLINE); mvwprintw(game_win, 8, 0, _("You are dead.")); wattroff(game_win, A_BOLD); wattroff(game_win, A_UNDERLINE); } // common stuff to death // elemental imbalance wrefresh(game_win); todd_getchar(NULL); playing = false; } if (enemy_dead || player_dead) return 1; /* if enemy / player is dead, don't redraw combat stuff anymore */ else return 0; // redraw combat stuff }