void RepairShop::load() { shop_id = SDL::load_texture("./assets/repair_shop.png"); status_message_id = SDL::texture_from_string(status_message, 200, 200, 40, 255); /* reserve the blocks underneath of the repair shop */ for (int i = 0; i < 4; ++i) World::blocks[(Y_POS + 192) / 64][X_POS / 64 + i].reserve(); /* set up the repair shop interface */ interface = std::make_unique<MouseInterface>(540, 400, 50, 40, SDL::load_texture("./assets/repair_shop_interface.png"), [&](){ status_message = "Repair Shop"; }); size_t button_bg = SDL::load_texture("./assets/button_bg.png"); /* add all of the necessary buttons to the interface */ interface->add_button(128, 92, 94, 154, button_bg, SDL::load_texture("./assets/wrench.png"), [&]() { status_message = "Repair Hull"; }, []() { repair_hull(); close_interface(); }); interface->add_button(128, 92, 316, 154, button_bg, SDL::small_texture_from_string("Exit", 0, 0, 0, 255), nullptr, []() { close_interface(); }); }
void FuelStation::key_down(SDL_Keycode k) { /* the interface is necessarily open if this is called */ /* the point of handling keys is to allow the user to close the fuel * interface by simply pressing the arrow keys. this makes the interface * less annoying when you don't mean to use it */ /* don't handle key presses unless the interface has been open for * at least 30 frames. This avoids accidental closing of the interface */ if (frames_interface_open < 30) return; if (k == SDLK_RIGHT) { Digger::vx = 1.0; close_interface(); } else if (k == SDLK_LEFT) { Digger::vx = -1.0; close_interface(); } else if (k == SDLK_UP) { Digger::y -= 10; Digger::vy = 1.0; close_interface(); } }
static void attempt_purchase(int amount) { if (amount) { if (Digger::money >= amount) { int spent = std::min(amount, (int) (Digger::max_fuel - Digger::fuel)); if (spent) { Digger::money -= spent; status_message = "Purchased: " + std::to_string(spent) + " liters"; Digger::fuel = (float) ((int)Digger::fuel + spent); SDL::play_sound(fuel_sound_id); } else { status_message = "Tank is already full"; } } else { status_message = "Insufficient funds"; } } else { /* 0 was passed, so we attempt to fill the tank */ int spent = std::min(Digger::money, (int) (Digger::max_fuel - Digger::fuel)); if (spent) { Digger::money -= spent; Digger::fuel = (float) ((int)Digger::fuel + spent); status_message = "Purchased: " + std::to_string(spent) + " liters"; SDL::play_sound(fuel_sound_id); } close_interface(); } }
/** * Start the interface and main client loop */ int interface(struct config* config){ CONFIG = config; init_interface(); fd_set master; fd_set readset; FD_ZERO(&readset); FD_ZERO(&master); FD_SET(config->self.socket, &master); FD_SET(STDIN, &master); int max_sock = config->self.socket; struct timeval tv; while(EXIT == 0){ readset = master; tv.tv_sec = 0; tv.tv_usec = 100; select(max_sock+1, &readset, NULL, NULL, &tv); if(tv.tv_sec == 0 && tv.tv_usec == 0){ if(handle_user() != 0){ perror("BAD THINGS HAPPENED!"); EXIT = 1; } continue; } for(int i = 0; i < max_sock+1; ++i){ if (FD_ISSET(i, &readset)){ if(i == config->self.socket){ if(handle_server(config->self.socket) < 0){ close_interface(); perror("Connection closed to server"); return -1; } }else if(i == STDIN){ handle_user(); } } } refresh(); } return 0; }
void FuelStation::click(int x, int y) { /* the caller of this function has already checked * that the fuel interface is open */ if (x > X_OFF + 30 && x < X_OFF + 160 && y > Y_OFF + 90 && y < Y_OFF + 220) attempt_purchase(5); else if (x > X_OFF + 202 && x < X_OFF + 332 && y > Y_OFF + 90 && y < Y_OFF + 220) attempt_purchase(10); else if (x > X_OFF + 374 && x < X_OFF + 504 && y > Y_OFF + 90 && y < Y_OFF + 220) attempt_purchase(25); else if (x > X_OFF + 116 && x < X_OFF + 246 && y > Y_OFF + 236 && y < Y_OFF + 366) attempt_purchase(50); else if (x > X_OFF + 296 && x < X_OFF + 426 && y > Y_OFF + 236 && y < Y_OFF + 366) attempt_purchase(0); /* 0 means fill the tank */ else if ((x - (496 + X_OFF)) * (x - (496 + X_OFF)) + (y - (40 + Y_OFF)) * (y - (40 + Y_OFF)) <= 18 * 18) close_interface(); }
/** * Process the user input * It handles building commands to the server as well as just sending messages */ int process_user(){ int buffer_len = strlen(buffer); int command = 0; unsigned char* next_arg = buffer; print_prompt(windows[INPUT_WIN]); if(buffer_len == 0){ return 0; } // TODO: add command processing if(buffer[0] == '/'){ next_arg = strchr(buffer,' '); if(next_arg){ *next_arg = 0; // null terminate the command next_arg++; } if(strcmp(buffer+1,"who") == 0){ command = USER_LIST; } else if(strcmp(buffer+1,"pm") == 0){ command = PM; } else if(strcmp(buffer+1,"whois") == 0){ command = WHOIS; } else if(strcmp(buffer+1,"q") == 0){ command = -1; } else if(strcmp(buffer+1,"quit") == 0){ command = -1; } else if(strcmp(buffer+1,"help") == 0){ command = HELP; } } switch(command){ case -1: close_interface(); return -1; break; case 0: { struct message message; memset(&message,0,sizeof(struct message)); strcpy(message.message,buffer); message.length = strlen(message.message); message.user_id = CONFIG->self.id; send_message(CONFIG->self.socket,&message); } break; case PM: { unsigned char* to = next_arg; next_arg = strchr(next_arg,' '); if(next_arg){ *next_arg = 0; // null terminate the command next_arg++; }else{ return 0; } struct private_message message; memset(&message,0,sizeof(struct private_message)); strcpy(message.to, to); strcpy(message.message.message,next_arg); message.message.length = strlen(message.message.message); message.message.user_id = CONFIG->self.id; message.from = CONFIG->self.id; send_pm(CONFIG->self.socket,&message); } break; case WHOIS: { send_whois_request(CONFIG->self.socket, next_arg); } break; case USER_LIST: send_user_list_request(CONFIG->self.socket); break; case HELP: { struct message msg; msg.user_id = 65535; memset(msg.message,0,sizeof(msg.message)); strcpy(msg.message,"[Commands: ]"); msg.length = strlen(msg.message); add_message(&msg); strcpy(msg.message,"[who Show who is on the server]"); msg.length = strlen(msg.message); add_message(&msg); strcpy(msg.message,"[whois <user> <msg> Get details about a user]"); msg.length = strlen(msg.message); add_message(&msg); strcpy(msg.message,"[pm <username> Send a private message to a user]"); msg.length = strlen(msg.message); add_message(&msg); /*strcpy(msg.message,"[Commands: ]"); msg.length = strlen(msg.message); add_message(&msg); strcpy(msg.message,"[Commands: ]"); msg.length = strlen(msg.message); add_message(&msg); */ show_messages(windows[CHAT_WIN]); wrefresh(windows[CHAT_WIN]); } break; } memset(buffer,0,sizeof(buffer)); return 0; }
void signal_handler(int sig){ signal(SIGINT, signal_handler); printf("You pressed ^C\n"); close_interface(); EXIT = 1; }
/** * Process user input * This function only looks at a single character typed at a time. * Once it sees a newline character it will then call process_user * to process the user input */ int handle_user(){ refresh(); int c = getch(); if(c == ERR){ return 0; } switch(c){ case '\n': if(process_user(buffer) != 0){ return 1; } buffer_pos = 0; break; case KEY_F(4): close_interface(); exit(0); case KEY_F(1): case KEY_F(2): case KEY_F(3): case KEY_F(5): case KEY_F(6): case KEY_F(7): case KEY_F(8): case KEY_F(9): case KEY_F(10): case KEY_F(11): case KEY_F(12): break; case KEY_UP: case KEY_DOWN: break; case KEY_LEFT: break; case KEY_RIGHT: break; case KEY_BACKSPACE: case KEY_DC: // delete the current character buffer[buffer_pos] = 0; buffer_pos --; // sanity check if(buffer_pos < 0){ buffer_pos = 0; } buffer[buffer_pos] = 0; // ugly hack to clear the line, we rebuild the window >.< destroy_win(windows[INPUT_WIN]); windows[INPUT_WIN] = create_newwin(4, COLS, LINES-4, 0); print_prompt(windows[INPUT_WIN]); wprintw(windows[INPUT_WIN],"%s",buffer); wrefresh(windows[INPUT_WIN]); break; default: buffer[buffer_pos++] = (char)c; wprintw(windows[INPUT_WIN],"%c",c); wrefresh(windows[INPUT_WIN]); } return 0; }