void ship_select::OnOK() { object *ptr; unmark_all(); update_status(); ptr = GET_FIRST(&obj_used_list); while (ptr != END_OF_LIST(&obj_used_list)) { if (ptr->flags & OF_TEMP_MARKED) mark_object(OBJ_INDEX(ptr)); ptr = GET_NEXT(ptr); } if (query_valid_object() && (Marked == 1) && (Objects[cur_object_index].type == OBJ_POINT)) { Assert(Briefing_dialog); Briefing_dialog->icon_select(Objects[cur_object_index].instance); } else { if (Briefing_dialog) Briefing_dialog->icon_select(-1); } filter_ships = m_filter_ships; filter_starts = m_filter_starts; filter_waypoints = m_filter_waypoints; filter_friendly = m_filter_friendly; filter_hostile = m_filter_hostile; filter_neutral = m_filter_neutral; filter_unknown = m_filter_unknown; CDialog::OnOK(); }
bool cockpit_display_h::isValid() { if (obj_num < 0 || obj_num > MAX_OBJECTS) { return false; } if (m_objp == NULL || OBJ_INDEX(m_objp) != obj_num) { return false; } // Only player has cockpit displays if (m_objp != Player_obj) { return false; } if (m_display_num == INVALID_ID) { return false; } if (m_display_num >= Player_displays.size()) { return false; } return true; }
// called when a shield quadrant is struct, so we can update the timer that will draw the quadrant // as flashing // // input: // objp => object pointer for ship that has been hit // quadrant => quadrant of shield getting hit (-1 if no shield is present) void hud_shield_quadrant_hit(object* objp, int quadrant) { shield_hit_info* shi; int num; if (objp->type != OBJ_SHIP) return; hud_escort_ship_hit(objp, quadrant); hud_gauge_popup_start(HUD_TARGET_MINI_ICON); if (OBJ_INDEX(objp) == Player_ai->target_objnum) { shi = &Shield_hit_data[SHIELD_HIT_TARGET]; } else if (objp == Player_obj) { shi = &Shield_hit_data[SHIELD_HIT_PLAYER]; } else { return; } if (quadrant >= 0) { num = Quadrant_xlate[quadrant]; shi->shield_hit_timers[num] = timestamp(300); } else { shi->shield_hit_timers[HULL_HIT_OFFSET] = timestamp(SHIELD_HIT_DURATION_SHORT); hud_targetbox_start_flash(TBOX_FLASH_HULL); } }
particle *particle_create( vec3d *pos, vec3d *vel, float lifetime, float rad, int type, int optional_data, float tracer_length, object *objp, bool reverse ) { particle_info pinfo; if ( (type < 0) || (type >= NUM_PARTICLE_TYPES) ) { Int3(); return NULL; } // setup old data pinfo.pos = *pos; pinfo.vel = *vel; pinfo.lifetime = lifetime; pinfo.rad = rad; pinfo.type = type; pinfo.optional_data = optional_data; // setup new data pinfo.tracer_length = -1.0f; if(objp == NULL) { pinfo.attached_objnum = -1; pinfo.attached_sig = -1; } else { pinfo.attached_objnum = OBJ_INDEX(objp); pinfo.attached_sig = objp->signature; } pinfo.reverse = reverse? 1 : 0; // lower level function return particle_create(&pinfo); }
void ship_select::OnOK() { int i; object *ptr; unmark_all(); update_status(); ptr = GET_FIRST(&obj_used_list); while (ptr != END_OF_LIST(&obj_used_list)) { if (ptr->flags & OF_TEMP_MARKED) mark_object(OBJ_INDEX(ptr)); ptr = GET_NEXT(ptr); } if (query_valid_object() && (Marked == 1) && (Objects[cur_object_index].type == OBJ_POINT)) { Assert(Briefing_dialog); Briefing_dialog->icon_select(Objects[cur_object_index].instance); } else { if (Briefing_dialog) Briefing_dialog->icon_select(-1); } filter_ships = m_filter_ships; filter_starts = m_filter_starts; filter_waypoints = m_filter_waypoints; for (i = 0; i < MAX_IFFS; i++) filter_iff[i] = m_filter_iff[i]; CDialog::OnOK(); }
// respawn myself as an observer void multi_respawn_as_observer() { // configure the hud to be in "observer" mode hud_config_as_observer(Player_ship,Player_ai); // blow away my old player object Player_obj->flags |= OF_SHOULD_BE_DEAD; obj_delete(OBJ_INDEX(Player_obj)); // create a new shiny observer object for me multi_obs_create_observer(Net_player); // set my object to be the observer object Player_obj = &Objects[Net_player->player->objnum]; Player_ship = &Hud_obs_ship; Player_ai = &Hud_obs_ai; // set some flags for myself Net_player->flags |= NETINFO_FLAG_OBSERVER; Net_player->flags |= NETINFO_FLAG_OBS_PLAYER; Net_player->flags &= ~(NETINFO_FLAG_LIMBO); // clear my auto-match speed flag Net_player->player->flags &= ~(PLAYER_FLAGS_AUTO_MATCH_SPEED | PLAYER_FLAGS_MATCH_TARGET); // reset the control info structure memset(&Player->ci,0,sizeof(control_info)); }
// Called whenever a ship is hit to determine if that ship is in the escort list. If it // is, then start timers to flash the name hull/shield icon for that ship. void hud_escort_ship_hit(object* objp, int quadrant) { int num, i; shield_hit_info* shi; // no ships on the escort list in multiplayer dogfight if ((Game_mode & GM_MULTIPLAYER) && (Netgame.type_flags & NG_TYPE_DOGFIGHT)) { return; } for (i = 0; i < Num_escort_ships; i++) { if (Escort_ships[i].objnum == OBJ_INDEX(objp)) { shi = &Escort_ships[i].hit_info; num = Quadrant_xlate[quadrant]; hud_gauge_popup_start(HUD_ESCORT_VIEW); if (quadrant >= 0) { shi->shield_hit_timers[num] = timestamp(SHIELD_HIT_DURATION); } else { shi->shield_hit_timers[HULL_HIT_OFFSET] = timestamp(SHIELD_HIT_DURATION); } } } }
void convert_arg(lua_State* L, luacpp::LuaValueList& out, object* objp) { LuaValue val; ade_set_object_with_breed(L, OBJ_INDEX(objp)); convert::popValue(L, val); out.push_back(val); }
void initial_status::undock(object *objp1, object *objp2) { vec3d v; int ship_num, other_ship_num; if (objp1 == NULL || objp2 == NULL) return; vm_vec_sub(&v, &objp2->pos, &objp1->pos); vm_vec_normalize(&v); ship_num = get_ship_from_obj(OBJ_INDEX(objp1)); other_ship_num = get_ship_from_obj(OBJ_INDEX(objp2)); if (ship_class_compare(Ships[ship_num].ship_info_index, Ships[other_ship_num].ship_info_index) <= 0) vm_vec_scale_add2(&objp2->pos, &v, objp2->radius * 2.0f); else vm_vec_scale_add2(&objp1->pos, &v, objp1->radius * -2.0f); ai_do_objects_undocked_stuff(objp1, objp2); // check to see if one of these ships has an arrival cue of false. If so, then // reset it back to default value of true. be sure to correctly update before // and after setting data. // Goober5000 - but don't reset it if it's part of a wing! Ship_editor_dialog.update_data(1); if ( Ships[ship_num].arrival_cue == Locked_sexp_false && Ships[ship_num].wingnum < 0 ) { Ships[ship_num].arrival_cue = Locked_sexp_true; } else if ( Ships[other_ship_num].arrival_cue == Locked_sexp_false && Ships[other_ship_num].wingnum < 0 ) { Ships[other_ship_num].arrival_cue = Locked_sexp_true; } // if this ship is no longer docked, ensure its dock leader flag is clear if (!object_is_docked(&Objects[Ships[ship_num].objnum])) Ships[ship_num].flags.remove(Ship::Ship_Flags::Dock_leader); // same for the other ship if (!object_is_docked(&Objects[Ships[other_ship_num].objnum])) Ships[other_ship_num].flags.remove(Ship::Ship_Flags::Dock_leader); Ship_editor_dialog.initialize_data(1); }
void ship_select::OnSelchangeShipList() { int i, j, k, count; if (activity) return; activity = ACTIVITY_SHIP; for (i=0; i<wlist_size; i++) { count = 0; for (j=0; j<Wings[wing_index[i]].wave_count; j++) for (k=0; k<list_size; k++) if (OBJ_INDEX(obj_index[k]) == wing_objects[wing_index[i]][j]) { if (m_ship_list.GetSel(k)) count++; break; } if (count == Wings[wing_index[i]].wave_count) wing_sel_last[i] = 1; else wing_sel_last[i] = 0; m_wing_list.SetSel(i, wing_sel_last[i] ? TRUE : FALSE); } for (i=wlist_size; i<wplist_size; i++) { waypoint_list *wp_list = find_waypoint_list_at_index(wing_index[i]); Assert(wp_list != NULL); SCP_list<waypoint>::iterator jj; count = 0; for (j = 0, jj = wp_list->get_waypoints().begin(); jj != wp_list->get_waypoints().end(); ++j, ++jj) { for (k=0; k<list_size; k++) { if ((obj_index[k]->type == OBJ_WAYPOINT) && (obj_index[k]->instance == calc_waypoint_instance(wing_index[i], j))) { if (m_ship_list.GetSel(k)) count++; break; } } } if ((uint) count == wp_list->get_waypoints().size()) wing_sel_last[i] = 1; else wing_sel_last[i] = 0; m_wing_list.SetSel(i, wing_sel_last[i] ? TRUE : FALSE); } activity = 0; }
void observer_delete(object *obj) { int num; num = obj->instance; Assert( Observers[num].objnum == OBJ_INDEX(obj)); Observers[num].objnum = -1; Observers[num].target_objnum = -1; Observers[num].flags = 0; // mark it as being free }
void dock_evaluate_tree(object *objp, dock_function_info *infop, void (*function)(object *, dock_function_info *), ubyte *visited_bitstring) { // make sure we haven't visited this object already if (get_bit(visited_bitstring, OBJ_INDEX(objp))) return; // mark as visited set_bit(visited_bitstring, OBJ_INDEX(objp)); // call the function for this object, and return if instructed function(objp, infop); if (infop->early_return_condition) return; // iterate through all docked objects for (dock_instance *ptr = objp->dock_list; ptr != NULL; ptr = ptr->next) { // start another tree with the docked object as the root, and return if instructed dock_evaluate_tree(ptr->docked_objp, infop, function, visited_bitstring); if (infop->early_return_condition) return; } }
/* * Called with a signal message id that is reporting a property value or metadata change. Finds out * which widget is involved and if the signal is reporting a value change or a metadata change. */ static void* SignalInvolvesWidget(uint32_t identifier, uint8_t* isProperty) { const char* member; AJ_MemberType mt = AJ_GetMemberType(identifier, &member, NULL); if (mt == AJ_SIGNAL_MEMBER) { *isProperty = (member[0] == 'V'); return objectList[OBJ_INDEX(identifier)].context; } else { return NULL; } }
/** * If weapon_obj is likely to hit ship_obj sooner than current aip->danger_weapon_objnum, * then update danger_weapon_objnum. */ void update_danger_weapon(object *pship_obj, object *weapon_obj) { ai_info *aip; Assert(pship_obj->type == OBJ_SHIP); aip = &Ai_info[Ships[pship_obj->instance].ai_index]; if (aip->danger_weapon_objnum == -1) { aip->danger_weapon_objnum = OBJ_INDEX(weapon_obj); aip->danger_weapon_signature = weapon_obj->signature; } else if (aip->danger_weapon_signature == Objects[aip->danger_weapon_objnum].signature) { float danger_old_time, danger_new_time; danger_old_time = ai_endangered_time(pship_obj, &Objects[aip->danger_weapon_objnum]); danger_new_time = ai_endangered_time(pship_obj, weapon_obj); if (danger_new_time < danger_old_time) { aip->danger_weapon_objnum = OBJ_INDEX(weapon_obj); aip->danger_weapon_signature = weapon_obj->signature; } } }
/** * Called whenever a ship is hit to determine if that ship is in the escort list. If it * is, then start timers to flash the name hull/shield icon for that ship. * * @param objp The object hit * @param quadrant Shield quadrant on the object that was hit, alternatively -1 if no shield */ void hud_escort_ship_hit(object *objp, int quadrant) { // no ships on the escort list in multiplayer dogfight if(MULTI_DOGFIGHT){ return; } for ( int i = 0; i < Num_escort_ships; i++ ) { if ( Escort_ships[i].objnum == OBJ_INDEX(objp) ) { hud_gauge_popup_start(HUD_ESCORT_VIEW); Escort_ships[i].escort_hit_timer = timestamp(SHIELD_HIT_DURATION); Escort_ships[i].escort_hit_next_flash = timestamp(SHIELD_FLASH_INTERVAL); } } }
void ship_select::OnSelchangeShipList() { int i, j, k, count; if (activity) return; activity = ACTIVITY_SHIP; for (i=0; i<wlist_size; i++) { count = 0; for (j=0; j<Wings[wing_index[i]].wave_count; j++) for (k=0; k<list_size; k++) if (OBJ_INDEX(obj_index[k]) == wing_objects[wing_index[i]][j]) { if (m_ship_list.GetSel(k)) count++; break; } if (count == Wings[wing_index[i]].wave_count) wing_sel_last[i] = 1; else wing_sel_last[i] = 0; m_wing_list.SetSel(i, wing_sel_last[i] ? TRUE : FALSE); } for (i=wlist_size; i<wplist_size; i++) { count = 0; for (j=0; j<Waypoint_lists[wing_index[i]].count; j++) for (k=0; k<list_size; k++) if ((obj_index[k]->type == OBJ_WAYPOINT) && (obj_index[k]->instance == wing_index[i] * 65536 + j)) { if (m_ship_list.GetSel(k)) count++; break; } if (count == Waypoint_lists[wing_index[i]].count) wing_sel_last[i] = 1; else wing_sel_last[i] = 0; m_wing_list.SetSel(i, wing_sel_last[i] ? TRUE : FALSE); } activity = 0; }
void cmeasure_maybe_alert_success(object *objp) { //Is this a countermeasure, and does it have a parent if ( objp->type != OBJ_WEAPON || objp->parent < 0) { return; } Assert(Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags[Weapon::Info_Flags::Cmeasure]); if ( objp->parent == OBJ_INDEX(Player_obj) ) { hud_start_text_flash(XSTR("Evaded", 1430), 800); snd_play(gamesnd_get_game_sound(ship_get_sound(Player_obj, SND_MISSILE_EVADED_POPUP))); } else if ( Objects[objp->parent].flags[Object::Object_Flags::Player_ship] ) { send_countermeasure_success_packet( objp->parent ); } }
void ship_select::OnSelchangeWingList() { int i, j, k, z; if (activity) return; activity = ACTIVITY_WING; for (i=0; i<wlist_size; i++) { z = (m_wing_list.GetSel(i) > 0) ? 1 : 0; if (z != wing_sel_last[i]) { for (j=0; j<Wings[wing_index[i]].wave_count; j++) for (k=0; k<list_size; k++) if (OBJ_INDEX(obj_index[k]) == wing_objects[wing_index[i]][j]) { m_ship_list.SetSel(k, z ? TRUE : FALSE); break; } wing_sel_last[i] = z; } } for (i=wlist_size; i<wplist_size; i++) { z = (m_wing_list.GetSel(i) > 0) ? 1 : 0; if (z != wing_sel_last[i]) { waypoint_list *wp_list = find_waypoint_list_at_index(wing_index[i]); Assert(wp_list != NULL); SCP_list<waypoint>::iterator jj; for (j = 0, jj = wp_list->get_waypoints().begin(); jj != wp_list->get_waypoints().end(); ++j, ++jj) { for (k=0; k<list_size; k++) { if ((obj_index[k]->type == OBJ_WAYPOINT) && (obj_index[k]->instance == calc_waypoint_instance(wing_index[i], j))) { m_ship_list.SetSel(k, z ? TRUE : FALSE); break; } } } wing_sel_last[i] = z; } } activity = 0; }
/** * Delete the debris object. * This is only ever called via obj_delete(). Do not call directly. * Use debris_start_death_roll() if you want to force a debris piece to die. */ void debris_delete( object * obj ) { int num; debris *db; num = obj->instance; Assert( Debris[num].objnum == OBJ_INDEX(obj)); db = &Debris[num]; Assert( Num_debris_pieces >= 0 ); if ( db->is_hull && (db->flags & DEBRIS_EXPIRE) ) { debris_clear_expired_flag(db); } db->flags = 0; db->objnum = -1; Num_debris_pieces--; }
// If this is a player countermeasure, let the player know he evaded a missile void cmeasure_maybe_alert_success(object* objp) { //Is this a countermeasure, and does it have a parent if (objp->type != OBJ_WEAPON || objp->parent < 0) { return; } Assert(Weapon_info[Weapons[objp->instance].weapon_info_index].wi_flags & WIF_CMEASURE); if (objp->parent == OBJ_INDEX(Player_obj)) { hud_start_text_flash(XSTR("Evaded", 1430), 800); snd_play(&Snds[SND_MISSILE_EVADED_POPUP]); } else if (Objects[objp->parent].flags & OF_PLAYER_SHIP) { send_countermeasure_success_packet(objp->parent); } }
// called when a shield quadrant is struct, so we can update the timer that will draw the quadrant // as flashing // // input: // objp => object pointer for ship that has been hit // quadrant => quadrant of shield getting hit (-1 if no shield is present) void hud_shield_quadrant_hit(object *objp, int quadrant) { shield_hit_info *shi; int num; if (Game_mode & GM_STANDALONE_SERVER) return; Assertion(objp != NULL, "hud_shield_quadrant_hit() called with a NULL objp; get a coder!\n"); if ( objp->type != OBJ_SHIP ) return; hud_escort_ship_hit(objp, quadrant); hud_gauge_popup_start(HUD_TARGET_MINI_ICON); if ( OBJ_INDEX(objp) == Player_ai->target_objnum ) { shi = &Shield_hit_data[SHIELD_HIT_TARGET]; } else if ( objp == Player_obj ) { shi = &Shield_hit_data[SHIELD_HIT_PLAYER]; } else { return; } Assertion(!shi->shield_hit_timers.empty(), "Shield hit info object for object '%s' has a size " SIZE_T_ARG " shield_hit_timers; get a coder!\n", Ships[objp->instance].ship_name, shi->shield_hit_timers.size()); Assertion(shi->hull_hit_index < (int) shi->shield_hit_timers.size(), "Shield hit info object for object '%s' has a hull_hit_index of %d (should be between 0 and " SIZE_T_ARG "); get a coder!\n", Ships[objp->instance].ship_name, shi->hull_hit_index, shi->shield_hit_timers.size() - 1); if ( quadrant >= 0 ) { if ( !(Ship_info[Ships[objp->instance].ship_info_index].flags[Ship::Info_Flags::Model_point_shields]) ) num = Quadrant_xlate[quadrant]; else num = quadrant; Assertion(num < shi->hull_hit_index, "Shield hit info object for object '%s' hit on quadrant #%d, despite having a hull_hit_index of %d; get a coder!\n", Ships[objp->instance].ship_name, num, shi->hull_hit_index); shi->shield_hit_timers[num] = timestamp(SHIELD_HIT_DURATION_SHORT); } else { shi->shield_hit_timers[shi->hull_hit_index] = timestamp(SHIELD_HIT_DURATION_SHORT); hud_targetbox_start_flash(TBOX_FLASH_HULL); } }
void prevent_spawning_collision(object *new_obj) { int collided; ship_obj *moveup; object *hit_check; ship *s_check; do { collided = 0; for (moveup = GET_FIRST(&Ship_obj_list); moveup != END_OF_LIST(&Ship_obj_list); moveup = GET_NEXT(moveup)) { // don't check the new object itself!! if (moveup->objnum == OBJ_INDEX(new_obj)) continue; 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; polymodel *pm = model_get(Ship_info[s_check->ship_info_index].model_num); WITHIN_BBOX(); if (collided) { MOVE_AWAY_BBOX(); break; } } } while (collided); }
/** * Start the sequence of a piece of debris writhing in unholy agony!!! */ static void debris_start_death_roll(object *debris_obj, debris *debris_p) { if (debris_p->is_hull) { // tell everyone else to blow up the piece of debris if( MULTIPLAYER_MASTER ) send_debris_update_packet(debris_obj,DEBRIS_UPDATE_NUKE); int fireball_type = fireball_ship_explosion_type(&Ship_info[debris_p->ship_info_index]); if(fireball_type < 0) { fireball_type = FIREBALL_EXPLOSION_LARGE1 + rand()%FIREBALL_NUM_LARGE_EXPLOSIONS; } fireball_create( &debris_obj->pos, fireball_type, FIREBALL_LARGE_EXPLOSION, OBJ_INDEX(debris_obj), debris_obj->radius*1.75f); // only play debris destroy sound if hull piece and it has been around for at least 2 seconds if ( Missiontime > debris_p->time_started + 2*F1_0 ) { snd_play_3d( gamesnd_get_game_sound(SND_MISSILE_IMPACT1), &debris_obj->pos, &View_position, debris_obj->radius ); } } debris_obj->flags.set(Object::Object_Flags::Should_be_dead); }
void ship_select::OnSelchangeWingList() { int i, j, k, z; if (activity) return; activity = ACTIVITY_WING; for (i=0; i<wlist_size; i++) { z = (m_wing_list.GetSel(i) > 0) ? 1 : 0; if (z != wing_sel_last[i]) { for (j=0; j<Wings[wing_index[i]].wave_count; j++) for (k=0; k<list_size; k++) if (OBJ_INDEX(obj_index[k]) == wing_objects[wing_index[i]][j]) { m_ship_list.SetSel(k, z ? TRUE : FALSE); break; } wing_sel_last[i] = z; } } for (i=wlist_size; i<wplist_size; i++) { z = (m_wing_list.GetSel(i) > 0) ? 1 : 0; if (z != wing_sel_last[i]) { for (j=0; j<Waypoint_lists[wing_index[i]].count; j++) for (k=0; k<list_size; k++) if ((obj_index[k]->type == OBJ_WAYPOINT) && (obj_index[k]->instance == wing_index[i] * 65536 + j)) { m_ship_list.SetSel(k, z ? TRUE : FALSE); break; } wing_sel_last[i] = z; } } activity = 0; }
void script_state::SetHookObjects(int num, ...) { va_list vl; va_start(vl, num); if (this->OpenHookVarTable()) { int amt_ldx = lua_gettop(LuaState); for (int i = 0; i < num; i++) { char *name = va_arg(vl, char*); object *objp = va_arg(vl, object*); ade_set_object_with_breed(LuaState, OBJ_INDEX(objp)); int data_ldx = lua_gettop(LuaState); lua_pushstring(LuaState, name); lua_pushvalue(LuaState, data_ldx); lua_rawset(LuaState, amt_ldx); lua_pop(LuaState, 1); //data_ldx } this->CloseHookVarTable(); }
/* * Called with an identifier for a method call or property access message. Finds the widget that is * involved and determine what property value type if any is affected. */ static void* CallInvolvesWidget(uint32_t identifier, uint16_t* widgetType, uint16_t* propType, uint16_t* language) { AJS_Widget* widget = (AJS_Widget*)objectList[OBJ_INDEX(identifier)].context; const char* member; AJ_MemberType mt = AJ_GetMemberType(identifier, &member, NULL); if (mt == AJ_INVALID_MEMBER) { return NULL; } *widgetType = widget->type; if (mt == AJ_PROPERTY_MEMBER) { /* * We have to do string comparisons here because the properties appears at different offsets * in the different widget interfaces, but we only need to check the first few characters. */ if (strncmp(member, PROPERTY_TYPE_VERSION_NAME, UNIQUE_PREFIX_LEN) == 0) { *propType = PROPERTY_TYPE_VERSION; } else if (strncmp(member, PROPERTY_TYPE_STATES_NAME, UNIQUE_PREFIX_LEN) == 0) { *propType = PROPERTY_TYPE_STATES; } else if (strncmp(member, PROPERTY_TYPE_OPTPARAMS_NAME, UNIQUE_PREFIX_LEN) == 0) { *propType = PROPERTY_TYPE_OPTPARAMS; } else if (strncmp(member, PROPERTY_TYPE_VALUE_NAME, UNIQUE_PREFIX_LEN) == 0) { *propType = PROPERTY_TYPE_VALUE; } else if (strncmp(member, PROPERTY_TYPE_MESSAGE_NAME, UNIQUE_PREFIX_LEN) == 0) { *propType = PROPERTY_TYPE_MESSAGE; } else if (strncmp(member, PROPERTY_TYPE_NUM_ACTIONS_NAME, UNIQUE_PREFIX_LEN) == 0) { *propType = PROPERTY_TYPE_NUM_ACTIONS; } else if (strncmp(member, PROPERTY_TYPE_LABEL_NAME, UNIQUE_PREFIX_LEN) == 0) { *propType = PROPERTY_TYPE_LABEL; } } else { *propType = 0; } *language = 0; return (void*)widget; }
static AJ_Status ExecuteAction(AJ_Message* msg, uint8_t action, void* context) { AJS_Widget* widget = (AJS_Widget*)objectList[OBJ_INDEX(msg->msgId)].context; AJ_Status status; AJ_Message reply; /* * Need to make a clone of the message and close the original */ msg = AJS_CloneAndCloseMessage(widget->dukCtx, msg); if (!msg) { return AJ_ERR_RESOURCES; } /* * Call into JavaScript object to perform action */ status = AJS_CP_ExecuteAction(widget, action); if (status == AJ_OK) { AJ_MarshalReplyMsg(msg, &reply); } else { AJ_MarshalStatusMsg(msg, &reply, status); } return AJ_DeliverMsg(&reply); }
static AJ_Status SetWidgetProp(AJ_Message* msg) { AJS_Widget* widget = NULL; AJ_Message reply; AJ_Status status; uint32_t propId; const char* vsig; AJ_InfoPrintf(("SetWidgetProp %s\n", msg->objPath)); status = AJ_UnmarshalPropertyArgs(msg, &propId, &vsig); /* * Two levels of variant because Set always uses a variant and the property type for the widget * is not known until runtime so is specified as a variant type in the property widget interface. */ if (status == AJ_OK) { status = AJ_UnmarshalVariant(msg, &vsig); } if (status == AJ_OK) { status = AJ_UnmarshalVariant(msg, &vsig); } if (status == AJ_OK) { widget = (AJS_Widget*)objectList[OBJ_INDEX(propId)].context; /* * Value is the only property that is writeable. Figure out how to unmarshal it. */ switch (widget->property.wdt.signature[0]) { case 'i': status = AJ_UnmarshalArgs(msg, "i", &widget->property.val.i); break; case 'q': status = AJ_UnmarshalArgs(msg, "q", &widget->property.val.q); break; case 'b': status = AJ_UnmarshalArgs(msg, "b", &widget->property.val.b); break; case 'd': status = AJ_UnmarshalArgs(msg, "d", &widget->property.val.d); break; case 's': status = AJ_UnmarshalArgs(msg, "s", &widget->property.val.s); break; default: { AJ_Arg st; uint16_t propertyType; status = AJ_UnmarshalContainer(msg, &st, AJ_ARG_STRUCT); if (status != AJ_OK) { break; } status = AJ_UnmarshalArgs(msg, "q", &propertyType); if (status != AJ_OK) { break; } /* * For some reason the implementors of the control panel service used 0/1 to * distingsuish between date/time rather than 1/2. Incrementing the property type * fixes this oversight. */ if (++propertyType != widget->property.wdt.propertyType) { status = AJ_ERR_INVALID; break; } if (propertyType == TIME_VALUE_PROPERTY) { status = AJ_UnmarshalArgs(msg, "(qqq)", &widget->property.val.time.hour, &widget->property.val.time.minute, &widget->property.val.time.second); } else { status = AJ_UnmarshalArgs(msg, "(qqq)", &widget->property.val.date.mDay, &widget->property.val.date.month, &widget->property.val.date.fullYear); } /* * Signal that the value has been changed */ AJS_CPS_SignalValueChanged(AJS_GetBusAttachment(), widget); if (status == AJ_OK) { status = AJ_UnmarshalCloseContainer(msg, &st); } } break; } } else { return AJ_ERR_RESOURCES; } /* * Need to make a clone of the message and close the original */ msg = AJS_CloneAndCloseMessage(widget->dukCtx, msg); if (!msg) { return AJ_ERR_RESOURCES; } if (status == AJ_OK) { /* * Call JavaScript to report the value change */ status = AJS_CPS_OnValueChanged(widget); } else { AJ_ErrPrintf(("SetWidgetProp %s\n", AJ_StatusText(status))); } if (status == AJ_OK) { AJ_MarshalReplyMsg(msg, &reply); } else { AJ_MarshalStatusMsg(msg, &reply, status); } AJ_DeliverMsg(&reply); return status; }
static uint8_t InvolvesRootWidget(uint32_t identifier) { return OBJ_INDEX(identifier) == 0; }
// ------------------------------------------------------------------ // swarm_update_direction() // // Check if we want to update the direction of a swarm missile. // void swarm_update_direction(object *objp, float frametime) { weapon_info *wip; weapon *wp; object *hobjp; swarm_info *swarmp; vec3d obj_to_target; float vel, target_dist, radius, missile_speed, missile_dist; physics_info *pi; Assert(objp->instance >= 0 && objp->instance < MAX_WEAPONS); wp = &Weapons[objp->instance]; if (wp->swarm_index == -1) { return; } wip = &Weapon_info[wp->weapon_info_index]; hobjp = wp->homing_object; pi = &Objects[wp->objnum].phys_info; swarmp = &Swarm_missiles[wp->swarm_index]; // check if homing is lost.. if it is then get a new path to move swarm missile along if ( swarmp->homing_objnum != -1 && hobjp == &obj_used_list ) { swarmp->change_timestamp = 1; swarmp->path_num = -1; swarmp->homing_objnum = -1; } if ( hobjp != &obj_used_list ) { swarmp->homing_objnum = OBJ_INDEX(hobjp); } if ( timestamp_elapsed(swarmp->change_timestamp) ) { if ( swarmp->path_num == -1 ) { if ( Objects[objp->parent].type != OBJ_SHIP ) { //AL: parent ship died... so just pick some random paths swarmp->path_num = myrand()%4; } else { ship *parent_shipp; parent_shipp = &Ships[Objects[objp->parent].instance]; swarmp->path_num = (parent_shipp->next_swarm_path++)%4; if ( parent_shipp->next_swarm_path%4 == 0 ) { swarmp->flags ^= SWARM_POSITIVE_PATH; } } vm_vec_scale_add(&swarmp->original_target, &objp->pos, &objp->orient.vec.fvec, SWARM_CONE_LENGTH); swarmp->circle_rvec = objp->orient.vec.rvec; swarmp->circle_uvec = objp->orient.vec.uvec; swarmp->change_count = 1; swarmp->change_time = fl2i(SWARM_CHANGE_DIR_TIME + SWARM_TIME_VARIANCE*(frand() - 0.5f) * 2); vm_vec_zero(&swarmp->last_offset); missile_speed = pi->speed; missile_dist = missile_speed * swarmp->change_time/1000.0f; if ( missile_dist < SWARM_DIST_OFFSET ) { missile_dist=i2fl(SWARM_DIST_OFFSET); } swarmp->angle_offset = (float)(asin(SWARM_DIST_OFFSET / missile_dist)); Assert(!_isnan(swarmp->angle_offset) ); } swarmp->change_timestamp = timestamp(swarmp->change_time); // check if swarm missile is homing, if so need to calculate a new target pos to turn towards if ( hobjp != &obj_used_list && f2fl(Missiontime - wp->creation_time) > 0.5f && ( f2fl(Missiontime - wp->creation_time) > wip->free_flight_time ) ) { swarmp->original_target = wp->homing_pos; // Calculate a rvec and uvec that will determine the displacement from the // intended target. Use crossprod to generate a right vector, from the missile // up vector and the vector connecting missile to the homing object. swarmp->circle_uvec = objp->orient.vec.uvec; swarmp->circle_rvec = objp->orient.vec.rvec; missile_speed = pi->speed; missile_dist = missile_speed * swarmp->change_time/1000.0f; if ( missile_dist < SWARM_DIST_OFFSET ) { missile_dist = i2fl(SWARM_DIST_OFFSET); } swarmp->angle_offset = (float)(asin(SWARM_DIST_OFFSET / missile_dist)); Assert(!_isnan(swarmp->angle_offset) ); } vm_vec_sub(&obj_to_target, &swarmp->original_target, &objp->pos); target_dist = vm_vec_mag_quick(&obj_to_target); swarmp->last_dist = target_dist; // If homing swarm missile is close to target, let missile home in on original target if ( target_dist < SWARM_DIST_STOP_SWARMING ) { swarmp->new_target = swarmp->original_target; goto swarm_new_target_calced; } radius = (float)tan(swarmp->angle_offset) * target_dist; vec3d rvec_component, uvec_component; swarmp->change_count++; if ( swarmp->change_count > 2 ) { swarmp->flags ^= SWARM_POSITIVE_PATH; swarmp->change_count = 0; } // pick a new path number to follow once at center if ( swarmp->change_count == 1 ) { swarmp->path_num = swarmp->path_num + myrand()%3; if ( swarmp->path_num > 3 ) { swarmp->path_num = 0; } } vm_vec_zero(&rvec_component); vm_vec_zero(&uvec_component); switch ( swarmp->path_num ) { case 0: // straight up and down if ( swarmp->flags & SWARM_POSITIVE_PATH ) vm_vec_copy_scale( &uvec_component, &swarmp->circle_uvec, radius); else vm_vec_copy_scale( &uvec_component, &swarmp->circle_uvec, -radius); break; case 1: // left/right if ( swarmp->flags & SWARM_POSITIVE_PATH ) vm_vec_copy_scale( &rvec_component, &swarmp->circle_rvec, radius); else vm_vec_copy_scale( &rvec_component, &swarmp->circle_rvec, -radius); break; case 2: // top/right - bottom/left if ( swarmp->flags & SWARM_POSITIVE_PATH ) { vm_vec_copy_scale( &rvec_component, &swarmp->circle_rvec, radius); vm_vec_copy_scale( &uvec_component, &swarmp->circle_uvec, radius); } else { vm_vec_copy_scale( &rvec_component, &swarmp->circle_rvec, -radius); vm_vec_copy_scale( &uvec_component, &swarmp->circle_uvec, -radius); } break; case 3: // top-left - bottom/right if ( swarmp->flags & SWARM_POSITIVE_PATH ) { vm_vec_copy_scale( &rvec_component, &swarmp->circle_rvec, -radius); vm_vec_copy_scale( &uvec_component, &swarmp->circle_uvec, radius); } else { vm_vec_copy_scale( &rvec_component, &swarmp->circle_rvec, radius); vm_vec_copy_scale( &uvec_component, &swarmp->circle_uvec, -radius); } break; default: Int3(); break; } swarmp->new_target = swarmp->original_target; vm_vec_zero(&swarmp->last_offset); vm_vec_add(&swarmp->last_offset, &uvec_component, &rvec_component); vm_vec_add2(&swarmp->new_target, &swarmp->last_offset); } else { if ( hobjp != &obj_used_list && f2fl(Missiontime - wp->creation_time) > 0.5f ) { swarmp->new_target = swarmp->original_target; if ( swarmp->last_dist < SWARM_DIST_STOP_SWARMING ) { swarmp->new_target = wp->homing_pos; goto swarm_new_target_calced; } vm_vec_add2(&swarmp->new_target, &swarmp->last_offset); } } swarm_new_target_calced: ai_turn_towards_vector(&swarmp->new_target, objp, frametime, wip->turn_time, NULL, NULL, 0.0f, 0); vel = vm_vec_mag(&objp->phys_info.desired_vel); vm_vec_copy_scale(&objp->phys_info.desired_vel, &objp->orient.vec.fvec, vel); }