// check the training message que to see if we should play a new message yet or not. // Goober5000: removed stipulation of instructor being present void message_training_que_check() { int i, j, iship_num; // get the instructor's ship. iship_num = ship_name_lookup(NOX("instructor")); // if ( iship_num == -1 ) // commented out by Goober5000 // return; // if the instructor is dying or departing, do nothing if ( iship_num != -1 ) // added by Goober5000 if (Ships[iship_num].flags & (SF_DYING | SF_DEPARTING)) return; if (Training_failure) return; for (i=0; i<Training_msg_que_count; i++) { if (timestamp_elapsed(Training_msg_que[i].timestamp)) { message_training_setup(Training_msg_que[i].num, Training_msg_que[i].length); // remove this message from the que now. for (j=i+1; j<Training_msg_que_count; j++) Training_msg_que[j - 1] = Training_msg_que[j]; i--; Training_msg_que_count--; } } }
/** * Check the training message queue to see if we should play a new message yet or not. */ void message_training_queue_check() { int i, iship_num; // get the instructor's ship. iship_num = ship_name_lookup(NOX("instructor")); // if the instructor is dying or departing, do nothing if ( iship_num != -1 ) // added by Goober5000 if (Ships[iship_num].flags & (SF_DYING | SF_DEPARTING)) return; if (Training_failure) return; for (i=0; i<Training_message_queue_count; i++) { if (timestamp_elapsed(Training_message_queue[i].timestamp)) { message_training_setup(Training_message_queue[i].num, Training_message_queue[i].length, Training_message_queue[i].special_message); // remove this message from the queue now. message_training_remove_from_queue(i); i--; } } }
// function to maybe restore some hotkeys during the first N seconds of the mission void mission_hotkey_maybe_restore() { int i, index; for ( i = 0; i < Num_hotkeys_saved; i++ ) { // don't process something that has no set if ( Hotkey_saved_info[i].setnum == -1 ) continue; // the ship is present, add it to the given set. index = ship_name_lookup(Hotkey_saved_info[i].name); if ( index != -1 ) { hud_target_hotkey_add_remove( Hotkey_saved_info[i].setnum, &Objects[Ships[index].objnum], HOTKEY_USER_ADDED ); Hotkey_saved_info[i].setnum = -1; } } }
// function to detect whether or not we have AI ships to respawn this frame void multi_respawn_check_ai() { int i; for (i = 0; i < MAX_AI_RESPAWNS; i++ ) { if ( Ai_respawns[i].pobjp != NULL ) { if ( timestamp_elapsed(Ai_respawns[i].timestamp) ) { // be sure that ship is actually gone before respawning it. if ( ship_name_lookup(Ai_respawns[i].pobjp->name) != -1 ) { Ai_respawns[i].timestamp = timestamp(1000); } else { multi_respawn_ai( Ai_respawns[i].pobjp ); multi_respawn_send_ai_respawn( Ai_respawns[i].pobjp->net_signature ); Ai_respawns[i].pobjp = NULL; Ai_respawns[i].timestamp = timestamp(-1); } } } } }
void emp_hud_jitter(int *x, int *y) { // if the emp effect is not active, don't jitter anything if(!emp_active_local()){ return; } // some movement *x += (int)frand_range(-8.0f * Emp_intensity, 8.0f * Emp_intensity); *y += (int)frand_range(-8.0f * Emp_intensity, 8.0f * Emp_intensity); } // current intensity of the EMP effect (0.0 - 1.0) float emp_current_intensity() { return Emp_intensity; } DCF(zap, "zap a ship with an EMP effect") { int shipnum; SCP_string ship_str; dc_stuff_string_white(ship_str); shipnum = ship_name_lookup(ship_str.c_str(), 1); if(shipnum >= 0){ emp_start_ship(&Objects[Ships[shipnum].objnum], 500.0f, 10.0f); } }
// perform one-time initialization of data from the goals struct. void ShipGoalsDlg::initialize(ai_goal *goals, int ship) { int i, item, num, inst, flag, mode; object *ptr; // note that the flag variable is a bitfield: // 1 = ships // 2 = wings // 4 = waypoint paths // 8 = individual waypoints // 16 = ship classes goalp = goals; for (item=0; item<ED_MAX_GOALS; item++) { flag = 1; m_data[item] = 0; m_priority[item] = 0; mode = AI_GOAL_NONE; if (item < MAX_AI_GOALS) { m_priority[item] = goalp[item].priority; mode = goalp[item].ai_mode; } if (m_priority[item] < 0 || m_priority[item] > MAX_EDITOR_GOAL_PRIORITY){ m_priority[item] = 50; } m_behavior[item] = 0; if (mode != AI_GOAL_NONE) { i = m_behavior_box[item] -> GetCount(); while (i-- > 0){ if (mode & (m_behavior_box[item]->GetItemData(i))) { m_behavior[item] = i; break; } } } switch (mode) { case AI_GOAL_NONE: case AI_GOAL_CHASE_ANY: case AI_GOAL_UNDOCK: case AI_GOAL_KEEP_SAFE_DISTANCE: case AI_GOAL_PLAY_DEAD: case AI_GOAL_PLAY_DEAD_PERSISTENT: case AI_GOAL_WARP: continue; case AI_GOAL_CHASE_SHIP_CLASS: flag = 16; // target is a ship class break; case AI_GOAL_STAY_STILL: flag = 9; // target is a ship or a waypoint break; case AI_GOAL_CHASE: case AI_GOAL_GUARD: case AI_GOAL_DISABLE_SHIP: case AI_GOAL_DISARM_SHIP: case AI_GOAL_IGNORE: case AI_GOAL_IGNORE_NEW: case AI_GOAL_EVADE_SHIP: case AI_GOAL_STAY_NEAR_SHIP: break; case AI_GOAL_WAYPOINTS: case AI_GOAL_WAYPOINTS_ONCE: flag = 4; // target is a waypoint break; case AI_GOAL_DESTROY_SUBSYSTEM: num = ship_name_lookup(goalp[item].target_name, 1); if (num != -1) m_subsys[item] = ship_get_subsys_index(&Ships[num], goalp[item].docker.name); break; case AI_GOAL_DOCK: m_subsys[item] = -1; num = get_docking_list(Ship_info[Ships[ship].ship_info_index].model_num); for (i=0; i<num; i++) { Assert(Docking_bay_list[i]); if (!stricmp(goalp[item].docker.name, Docking_bay_list[i])) { m_subsys[item] = i; break; } } break; case AI_GOAL_CHASE_WING: case AI_GOAL_GUARD_WING: flag = 2; // target is a wing break; default: Error(LOCATION, "Unhandled AI_GOAL_X #define %d in ship goals dialog box", mode); } if (flag & 0x1) { ptr = GET_FIRST(&obj_used_list); while (ptr != END_OF_LIST(&obj_used_list)) { if ((ptr->type == OBJ_SHIP) || (ptr->type == OBJ_START)) { inst = ptr->instance; if (ptr->type == OBJ_SHIP) { Assert(inst >= 0 && inst < MAX_SHIPS); if (!stricmp(goalp[item].target_name, Ships[inst].ship_name)) { m_data[item] = inst | TYPE_SHIP; break; } } else { Assert(inst >= 0 && inst < MAX_SHIPS); if (!stricmp(goalp[item].target_name, Ships[inst].ship_name)) { m_data[item] = inst | TYPE_PLAYER; break; } } } ptr = GET_NEXT(ptr); } } if (flag & 0x2) { for (i=0; i<MAX_WINGS; i++) if (Wings[i].wave_count) { if (!stricmp(goalp[item].target_name, Wings[i].name)) { m_data[item] = i | TYPE_WING; break; } } } if (flag & 0x4) { // data is a waypoint path name SCP_list<waypoint_list>::iterator ii; for (i = 0, ii = Waypoint_lists.begin(); ii != Waypoint_lists.end(); ++i, ++ii) { if (!stricmp(goalp[item].target_name, ii->get_name())) { m_data[item] = i | TYPE_PATH; break; } } } if (flag & 0x8) { // data is a waypoint name waypoint *wpt = find_matching_waypoint(goalp[item].target_name); if (wpt != NULL) m_data[item] = wpt->get_objnum() | TYPE_WAYPOINT; } if (flag & 0x10) { // data is a ship class for (i = 0; i < static_cast<int>(Ship_info.size()); i++) { if (!stricmp(goalp[item].target_name, Ship_info[i].name)) { m_data[item] = i | TYPE_SHIP_CLASS; break; } } } switch (mode) { case AI_GOAL_DOCK: m_dock2[item] = -1; if (m_data[item]) { num = get_docking_list(Ship_info[Ships[m_data[item] & DATA_MASK].ship_info_index].model_num); for (i=0; i<num; i++) { Assert(Docking_bay_list[i]); Assert(goalp[item].dockee.name); Assert(goalp[item].dockee.index != -1); if (!stricmp(goalp[item].dockee.name, Docking_bay_list[i])) { m_dock2[item] = i; break; } } } break; } // Assert(m_data[item]); } }
void VOICEREC_execute_command(ISpPhrase *pPhrase, HWND hWnd) { SPPHRASE *pElements; // Get the phrase elements, one of which is the rule id we specified in // the grammar. Switch on it to figure out which command was recognized. if (SUCCEEDED(pPhrase->GetPhrase(&pElements))) { #ifndef NDEBUG if(DEBUG_ON) { WCHAR *pwszText; char szText[255]; int i; pPhrase->GetText(static_cast<ULONG>(SP_GETWHOLEPHRASE), static_cast<ULONG>(SP_GETWHOLEPHRASE), TRUE, &pwszText, NULL); memset(szText, 0, 255); for (i=0;i<254;i++) { if (*(pwszText + i) == 0) { break; } szText[i] = (char)(*(pwszText + i)); szText[i+1] = 0; } mprintf(( "recognized speech : %s \n", szText )); mprintf(( "speech Rule.ulId : %d \n", pElements->Rule.ulId )); mprintf(( "confidence: %f \n", pElements->pProperties->SREngineConfidence)); ::CoTaskMemFree(pwszText); } #endif int part1, part2, part3; part1 = part2 = part3 = -1; switch ( pElements->Rule.ulId ) { case VID_WingName: { part1 = pElements->pProperties->vValue.ulVal; if (pElements->pProperties->pNextSibling) { part2 = pElements->pProperties->pNextSibling->vValue.ulVal; if (pElements->pProperties->pNextSibling->pNextSibling) { part3 = pElements->pProperties->pNextSibling->pNextSibling->vValue.ulVal; } } if (part2 == -1) break; // no ship number or wing const wchar_t* valstr = pElements->pProperties->pszValue; char* wing_name = new char[wcslen(valstr)+1]; size_t j = 0; for (size_t i = 0; i < wcslen(valstr); i++) { int c = wctob(valstr[i]); if (c != EOF) { wing_name[j++] = static_cast<char>(c); } } wing_name[j] = '\0'; if (part2 == 0) { Msg_instance = wing_lookup(wing_name); delete[] wing_name; if (Msg_instance < 0) break; if(!(Player->flags & PLAYER_FLAGS_MSG_MODE)) { hud_squadmsg_toggle(); } if (hud_squadmsg_wing_valid(&Wings[Msg_instance])) hud_squadmsg_do_mode(SM_MODE_WING_COMMAND); } else { char shipName[NAME_LENGTH]; wing_bash_ship_name(shipName, wing_name, part2); delete[] wing_name; Msg_instance = ship_name_lookup(shipName); // Can't issue commands to yourself or to nobody if (Msg_instance < 0 || Msg_instance == Player_obj->instance) { break; } if(!(Player->flags & PLAYER_FLAGS_MSG_MODE)) { hud_squadmsg_toggle(); } if (hud_squadmsg_ship_valid(&Ships[Msg_instance])) hud_squadmsg_do_mode(SM_MODE_SHIP_COMMAND); } if (part3 == -1) break; } case VID_Action: { int action; if (part3 == -1) { action = pElements->pProperties->vValue.ulVal; } else { action = part3; } doVid_Action(action); break; } // These commands run no matter what, and will even bring up the menu case VID_TopMenu: { int action = pElements->pProperties->vValue.ulVal; bool msgWindow = false; if (Player->flags & PLAYER_FLAGS_MSG_MODE) { msgWindow = true; } // If the command window is not up, or it is and its a cancel request toggle if((msgWindow && action == VID_Cancel) || (!msgWindow && action != VID_Cancel)) { hud_squadmsg_toggle(); } switch(action) { case VID_Ships: hud_squadmsg_do_mode( SM_MODE_SHIP_SELECT ); break; case VID_Wings: hud_squadmsg_do_mode( SM_MODE_WING_SELECT ); break; case VID_AllFighters: case VID_AllWings: hud_squadmsg_msg_all_fighters(); // can have the action to perform spoken directly afterwards if (pElements->pProperties->pFirstChild) { doVid_Action(pElements->pProperties->pFirstChild->vValue.ulVal); } break; case VID_Reinforcements: hud_squadmsg_do_mode( SM_MODE_REINFORCEMENTS ); break; case VID_SupportShip: hud_squadmsg_do_mode( SM_MODE_REPAIR_REARM ); break; case VID_AbortSupport: hud_squadmsg_do_mode( SM_MODE_REPAIR_REARM_ABORT ); break; case VID_More: break; } break; } // phrases for transferring shield energy to different locations case VID_shields: { int action = pElements->pProperties->vValue.ulVal; switch(action) { case 0: button_function( SHIELD_XFER_TOP ); break; case 1: button_function( SHIELD_XFER_LEFT ); break; case 2: button_function( SHIELD_XFER_RIGHT ); break; case 3: button_function( SHIELD_XFER_BOTTOM ); break; case 4: button_function( SHIELD_EQUALIZE ); break; } break; } // basic cheat, phrase as a value equivalent to the defines in ControlConfig/ControlsConfig.h // it just calls the button_function with this value case VID_speed: case VID_targeting: case VID_other: { int action = pElements->pProperties->vValue.ulVal; if (action > -1) { button_function( action ); } break; } // nearly the same as the previous except it has some extra entries for // maximising/minimising energy case VID_power: { int action = pElements->pProperties->vValue.ulVal; if (action >= INCREASE_WEAPON && action <= ETS_EQUALIZE) { button_function( action ); } else { // this is for the max engines etc. for (int i=1; i<7; i++) { button_function( action - 132 ); } } break; } } // Free the pElements memory which was allocated for us ::CoTaskMemFree(pElements); } }
void multi_respawn_place(object *new_obj, int team) { ship_obj *moveup; ship *s_check; ship *pri = NULL; object *pri_obj = NULL; object *hit_check; int collided, idx, lookup; // first determine if there are any appropriate priority ships to use pri = NULL; pri_obj = NULL; for(idx=0; idx<Multi_respawn_priority_count; idx++){ // all relevant ships if((Multi_respawn_priority_ships[idx].team == team) || !(Netgame.type_flags & NG_TYPE_TEAM)){ lookup = ship_name_lookup(Multi_respawn_priority_ships[idx].ship_name); if( (lookup >= 0) && ((pri == NULL) || (Ships[lookup].respawn_priority > pri->respawn_priority)) && (Ships[lookup].objnum >= 0) && (Ships[lookup].objnum < MAX_OBJECTS)){ pri = &Ships[lookup]; pri_obj = &Objects[Ships[lookup].objnum]; } } } // if we have a relevant respawn ship if((pri != NULL) && (pri_obj != NULL)){ // pick a point just outside his bounding box polymodel *pm = model_get(pri->modelnum); // hmm, ugly. Pick a point 2000 meters to the y direction if(pm == NULL){ vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.rvec, 2000.0f); } else { // pick a random direction int d = (int)frand_range(0.0f, 5.9f); switch(d){ case 0: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.rvec, (pm->maxs.xyz.x - pm->mins.xyz.x)); break; case 1: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.rvec, -(pm->maxs.xyz.x - pm->mins.xyz.x)); break; case 2: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.uvec, (pm->maxs.xyz.y - pm->mins.xyz.y)); break; case 3: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.uvec, -(pm->maxs.xyz.y - pm->mins.xyz.y)); break; case 4: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.fvec, (pm->maxs.xyz.z - pm->mins.xyz.z)); break; case 5: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.fvec, -(pm->maxs.xyz.z - pm->mins.xyz.z)); break; default: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.v.uvec, -(pm->maxs.xyz.y - pm->mins.xyz.y)); break; } } } // otherwise, resort to plain respawn points else { Assert(Multi_respawn_point_count > 0); // get the next appropriate respawn point by team lookup = 0; int count = 0; while(!lookup && (count < 13)){ if((team == TEAM_TRAITOR) || (team == Multi_respawn_points[Multi_next_respawn_point].team)){ lookup = 1; } // next item if(!lookup){ if(Multi_next_respawn_point >= (Multi_respawn_point_count-1)){ Multi_next_respawn_point = 0; } else { Multi_next_respawn_point++; } } count++; } // set respawn info new_obj->pos = Multi_respawn_points[Multi_next_respawn_point].pos; } // now make sure we're not colliding with anyone do { collided = 0; moveup = GET_FIRST(&Ship_obj_list); while(moveup!=END_OF_LIST(&Ship_obj_list)){ // don't check the new_obj itself!! if(Objects[moveup->objnum].net_signature != new_obj->net_signature){ hit_check = &Objects[moveup->objnum]; Assert(hit_check->type == OBJ_SHIP); Assert(hit_check->instance >= 0); if((hit_check->type != OBJ_SHIP) || (hit_check->instance < 0)){ continue; } s_check = &Ships[hit_check->instance]; // just to make sure we don't get any strange magnitude errors if(vm_vec_same(&hit_check->pos, &new_obj->pos)){ new_obj->pos.xyz.x += 1.0f; } WITHIN_BBOX(); if(collided){ MOVE_AWAY_BBOX(); break; } collided = 0; } moveup = GET_NEXT(moveup); } } while(collided); }
void VoiceActingManager::OnGenerateScript() { int i; char pathname[256]; // stuff data to variables UpdateData(TRUE); // prompt to save script CFileDialog dlg(FALSE, "txt", NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, "Text files (*.txt)|*.txt||"); if (dlg.DoModal() != IDOK) return; CString dlgPathName = dlg.GetPathName( ); string_copy(pathname, dlgPathName, 256); fp = cfopen(pathname, "wt", CFILE_NORMAL); if (!fp) { MessageBox("Can't open file to save.", "Error!"); return; } fout("%s\n", Mission_filename); fout("%s\n\n", The_mission.name); if (m_export_everything || m_export_command_briefings) { fout("\n\nCommand Briefings\n-----------------\n\n"); for (i = 0; i < Cmd_briefs[0].num_stages; i++) { CString entry = m_script_entry_format; entry.Replace("\r\n", "\n"); cmd_brief_stage *stage = &Cmd_briefs[0].stage[i]; entry.Replace("$filename", stage->wave_filename); entry.Replace("$message", stage->text); entry.Replace("$persona", "<no persona specified>"); entry.Replace("$sender", "<no sender specified>"); fout("%s\n\n\n", (char *) (LPCTSTR) entry); } } if (m_export_everything || m_export_briefings) { fout("\n\nBriefings\n---------\n\n"); for (i = 0; i < Briefings[0].num_stages; i++) { CString entry = m_script_entry_format; entry.Replace("\r\n", "\n"); brief_stage *stage = &Briefings[0].stages[i]; entry.Replace("$filename", stage->voice); entry.Replace("$message", stage->new_text); entry.Replace("$persona", "<no persona specified>"); entry.Replace("$sender", "<no sender specified>"); fout("%s\n\n\n", (char *) (LPCTSTR) entry); } } if (m_export_everything || m_export_debriefings) { fout("\n\nDebriefings\n-----------\n\n"); for (i = 0; i < Debriefings[0].num_stages; i++) { CString entry = m_script_entry_format; entry.Replace("\r\n", "\n"); debrief_stage *stage = &Debriefings[0].stages[i]; entry.Replace("$filename", stage->voice); entry.Replace("$message", stage->new_text); entry.Replace("$persona", "<no persona specified>"); entry.Replace("$sender", "<no sender specified>"); fout("%s\n\n\n", (char *) (LPCTSTR) entry); } } if (m_export_everything || m_export_messages) { fout("\n\nMessages\n--------\n\n"); for (i = 0; i < Num_messages - Num_builtin_messages; i++) { CString entry = m_script_entry_format; entry.Replace("\r\n", "\n"); MMessage *message = &Messages[i + Num_builtin_messages]; // replace file name entry.Replace("$filename", message->wave_info.name); // determine and replace persona entry.Replace("$message", message->message); if (message->persona_index >= 0) entry.Replace("$persona", Personas[message->persona_index].name); else entry.Replace("$persona", "<none>"); // determine sender char sender[NAME_LENGTH+1]; strcpy_s(sender, get_message_sender(message->name)); int shipnum = ship_name_lookup(sender); if (shipnum >= 0) { ship *shipp = &Ships[shipnum]; // we may have to use the callsign if (*Fred_callsigns[shipnum]) { hud_stuff_ship_callsign(sender, shipp); } // account for hidden ship names else if ( ((Iff_info[shipp->team].flags & IFFF_WING_NAME_HIDDEN) && (shipp->wingnum != -1)) || (shipp->flags2 & SF2_HIDE_SHIP_NAME) ) { hud_stuff_ship_class(sender, shipp); } // use the regular sender text else { end_string_at_first_hash_symbol(sender); } } // replace sender (but print #Command as Command) if (*sender == '#') entry.Replace("$sender", &sender[1]); else entry.Replace("$sender", sender); fout("%s\n\n\n", (char *) (LPCTSTR) entry); } } cfclose(fp); // notify MessageBox("Script generation complete.", "Woohoo!"); }
void multi_respawn_place(object *new_obj, int team) { ship *pri = NULL; object *pri_obj = NULL; int idx, lookup; // first determine if there are any appropriate priority ships to use pri = NULL; pri_obj = NULL; for(idx=0; idx<Multi_respawn_priority_count; idx++){ // all relevant ships if((Multi_respawn_priority_ships[idx].team == team) || !(Netgame.type_flags & NG_TYPE_TEAM)){ lookup = ship_name_lookup(Multi_respawn_priority_ships[idx].ship_name); if( (lookup >= 0) && ((pri == NULL) || (Ships[lookup].respawn_priority > pri->respawn_priority)) && (Ships[lookup].objnum >= 0) && (Ships[lookup].objnum < MAX_OBJECTS)){ pri = &Ships[lookup]; pri_obj = &Objects[Ships[lookup].objnum]; } } } // if we have a relevant respawn ship if((pri != NULL) && (pri_obj != NULL)){ // pick a point just outside his bounding box polymodel *pm = model_get(Ship_info[pri->ship_info_index].model_num); // hmm, ugly. Pick a point 2000 meters to the y direction if(pm == NULL){ vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.vec.rvec, 2000.0f); } else { // pick a random direction int d = (int)frand_range(0.0f, 5.9f); switch(d){ case 0: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.vec.rvec, (pm->maxs.xyz.x - pm->mins.xyz.x)); break; case 1: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.vec.rvec, -(pm->maxs.xyz.x - pm->mins.xyz.x)); break; case 2: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.vec.uvec, (pm->maxs.xyz.y - pm->mins.xyz.y)); break; case 3: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.vec.uvec, -(pm->maxs.xyz.y - pm->mins.xyz.y)); break; case 4: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.vec.fvec, (pm->maxs.xyz.z - pm->mins.xyz.z)); break; case 5: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.vec.fvec, -(pm->maxs.xyz.z - pm->mins.xyz.z)); break; default: vm_vec_scale_add(&new_obj->pos, &pri_obj->pos, &pri_obj->orient.vec.uvec, -(pm->maxs.xyz.y - pm->mins.xyz.y)); break; } } } // otherwise, resort to plain respawn points else { Assert(Multi_respawn_point_count > 0); // get the next appropriate respawn point by team lookup = 0; int count = 0; while(!lookup && (count < 13)){ if((team == Iff_traitor) || (team == Multi_respawn_points[Multi_next_respawn_point].team)){ lookup = 1; } // next item if(!lookup){ if(Multi_next_respawn_point >= (Multi_respawn_point_count-1)){ Multi_next_respawn_point = 0; } else { Multi_next_respawn_point++; } } count++; } // set respawn info new_obj->pos = Multi_respawn_points[Multi_next_respawn_point].pos; } // now make sure we're not colliding with anyone prevent_spawning_collision(new_obj); }