2 * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton)
4 * ShapeFusion is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * ShapeFusion is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with ShapeFusion; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "wx/wxprec.h"
25 #include "wx/clipbrd.h"
29 #include "PhysicsView.h"
30 #include "PhysicsTreeItemData.h"
31 #include "../ShapeFusionMenus.h"
33 BEGIN_EVENT_TABLE(PhysicsView, wxView)
34 EVT_MENU(EDIT_MENU_COPY, PhysicsView::MenuEditCopy)
35 EVT_MENU(EDIT_MENU_PASTE, PhysicsView::MenuEditPaste)
36 EVT_TREE_SEL_CHANGED(-1, PhysicsView::OnTreeSelect)
37 EVT_COMMAND_RANGE(FIELD_ALIEN_COLLECTION, FIELD_ALIEN_RANGED_ATTACK_SHAPE, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditAlienFields)
38 EVT_TEXT(FIELD_ALIEN_RANDOM_SOUND_MASK, PhysicsView::EditAlienFields)
39 EVT_TEXT(FIELD_ALIEN_SOUND_PITCH, PhysicsView::EditAlienDoubles)
40 EVT_COMMAND_RANGE(MENU_ALIEN_ACTIVATION, MENU_ALIEN_RANDOM, wxEVT_COMMAND_CHOICE_SELECTED, PhysicsView::EditAlienMenus)
41 EVT_TEXT(FIELD_ALIEN_ATTACK_FREQUENCY, PhysicsView::EditAlienFields)
42 EVT_CHOICE(MENU_ALIEN_ATTACK_TYPE, PhysicsView::EditAlienMenus)
43 EVT_COMMAND_RANGE(FIELD_ALIEN_ATTACK_REPETITIONS, FIELD_ALIEN_ATTACK_DZ, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditAlienFields)
44 EVT_CHOICE(MENU_ALIEN_ATTACK_TYPE + NUM_ALIEN_ATTACK_CONTROLS, PhysicsView::EditAlienMenus)
45 EVT_COMMAND_RANGE(FIELD_ALIEN_ATTACK_REPETITIONS + NUM_ALIEN_ATTACK_CONTROLS, FIELD_ALIEN_ATTACK_DZ + NUM_ALIEN_ATTACK_CONTROLS, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditAlienFields)
46 EVT_TEXT(FIELD_ALIEN_SHRAPNEL_RADIUS, PhysicsView::EditAlienFields)
47 EVT_CHOICE(MENU_ALIEN_SHRAPNEL_DAMAGE_TYPE, PhysicsView::EditAlienMenus)
48 EVT_COMMAND_RANGE(FIELD_ALIEN_SHRAPNEL_BASE_DAMAGE, FIELD_ALIEN_SHRAPNEL_RANDOM_DAMAGE, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditAlienFields)
49 EVT_TEXT(FIELD_ALIEN_SHRAPNEL_DAMAGE_SCALE, PhysicsView::EditAlienDoubles)
50 EVT_CHECKBOX(CB_ALIEN_SHRAPNEL_ALIEN_DAMAGE, PhysicsView::EditAlienCheckboxes)
51 EVT_CHOICE(MENU_ALIEN_RANGED_IMPACT_EFFECT, PhysicsView::EditAlienMenus)
52 EVT_CHOICE(MENU_ALIEN_MELEE_IMPACT_EFFECT, PhysicsView::EditAlienMenus)
53 EVT_COMMAND_RANGE(FIELD_ALIEN_VITALITY, FIELD_ALIEN_MAX_LEDGE_JUMP, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditAlienFields)
54 EVT_TEXT(FIELD_ALIEN_EXT_VELOCITY_SCALE, PhysicsView::EditAlienDoubles)
55 EVT_COMMAND_RANGE(FIELD_ALIEN_HOVER_HEIGHT, FIELD_ALIEN_INTELLIGENCE, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditAlienFields)
56 EVT_COMMAND_RANGE(MENU_ALIEN_CARRYING_ITEM, MENU_ALIEN_CLASS, wxEVT_COMMAND_CHOICE_SELECTED, PhysicsView::EditAlienMenus)
57 EVT_COMMAND_RANGE(CB_ALIEN_FRIENDS, CB_ALIEN_WEAKNESSES + 23, wxEVT_COMMAND_CHECKBOX_CLICKED, PhysicsView::EditAlienCheckboxes)
59 EVT_COMMAND_RANGE(FIELD_EFFECT_COLLECTION, FIELD_EFFECT_SEQUENCE, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditEffectFields)
60 EVT_TEXT(FIELD_EFFECT_PITCH, PhysicsView::EditEffectDoubles)
61 EVT_CHOICE(MENU_EFFECT_DELAY_SOUND, PhysicsView::EditEffectMenus)
62 EVT_COMMAND_RANGE(CB_EFFECT_END_WHEN_ANIMATION_LOOPS, CB_EFFECT_MEDIA_EFFECT, wxEVT_COMMAND_CHECKBOX_CLICKED, PhysicsView::EditEffectCheckboxes)
64 EVT_COMMAND_RANGE(CB_SHOT_FLAGS, CB_SHOT_ALIEN_DAMAGE, wxEVT_COMMAND_CHECKBOX_CLICKED, PhysicsView::EditShotCheckboxes)
65 EVT_COMMAND_RANGE(FIELD_SHOT_COLLECTION, FIELD_SHOT_MAXIMUM_CONTRAILS, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditShotFields)
66 EVT_COMMAND_RANGE(FIELD_SHOT_DAMAGE_SCALE, FIELD_SHOT_SOUND_PITCH, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditShotDoubles)
67 EVT_COMMAND_RANGE(MENU_SHOT_DAMAGE_TYPE, MENU_SHOT_MEDIA_IMPACT, wxEVT_COMMAND_CHOICE_SELECTED, PhysicsView::EditShotMenus)
69 EVT_COMMAND_RANGE(FIELD_MAX_FORWARD_VELOCITY, FIELD_HALF_CAMERA_SEPARATION, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditPhysicsConstants)
71 EVT_COMMAND_RANGE(CB_WEAPON_FLAGS, CB_WEAPON_FLAGS + 9, wxEVT_COMMAND_CHECKBOX_CLICKED, PhysicsView::EditWeaponCheckboxes)
72 EVT_COMMAND_RANGE(FIELD_WEAPON_COLLECTION, FIELD_WEAPON_FLASH_DECAY, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditWeaponFields)
73 EVT_COMMAND_RANGE(FIELD_WEAPON_FLASH_INTENSITY, FIELD_WEAPON_IDLE_WIDTH, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditWeaponDoubles)
74 EVT_COMMAND_RANGE(MENU_WEAPON_ITEM_TYPE, MENU_WEAPON_CLASS, wxEVT_COMMAND_CHOICE_SELECTED, PhysicsView::EditWeaponMenus)
75 EVT_COMMAND_RANGE(FIELD_TRIGGER_ROUNDS, FIELD_TRIGGER_BURST_COUNT, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditTriggerFields)
76 EVT_COMMAND_RANGE(FIELD_TRIGGER_ROUNDS + NUM_TRIGGER_IDS, FIELD_TRIGGER_BURST_COUNT + NUM_TRIGGER_IDS, wxEVT_COMMAND_TEXT_UPDATED, PhysicsView::EditTriggerFields)
77 EVT_COMMAND_RANGE(MENU_TRIGGER_PROJECTILE, MENU_TRIGGER_SHELL_CASING_TYPE, wxEVT_COMMAND_CHOICE_SELECTED, PhysicsView::EditTriggerMenus)
78 EVT_COMMAND_RANGE(MENU_TRIGGER_PROJECTILE + NUM_TRIGGER_IDS, MENU_TRIGGER_SHELL_CASING_TYPE + NUM_TRIGGER_IDS, wxEVT_COMMAND_CHOICE_SELECTED, PhysicsView::EditTriggerMenus)
81 IMPLEMENT_DYNAMIC_CLASS(PhysicsView, wxView)
84 static inline wxString Format(double f) {
85 return wxString::Format(wxT("%0.4f"), f);
88 static inline wxString Format(unsigned short u) {
89 return wxString::Format(wxT("%hu"), u);
92 static inline wxString Format(short i) {
93 return wxString::Format(wxT("%hi"), i);
96 void PhysicsView::OnSelectPhysicsConstants(int index)
98 PhysicsConstants* constants = static_cast<PhysicsDocument*>(GetDocument())->GetPhysicsConstants(index);
100 max_forward_velocity_field->ChangeValue(Format(constants->GetMaximumForwardVelocity()));
101 max_backward_velocity_field->ChangeValue(Format(constants->GetMaximumBackwardVelocity()));
102 max_perpendicular_velocity_field->ChangeValue(Format(constants->GetMaximumPerpendicularVelocity()));
104 acceleration_field->ChangeValue(Format(constants->GetAcceleration()));
105 deceleration_field->ChangeValue(Format(constants->GetDeceleration()));
106 airborne_deceleration_field->ChangeValue(Format(constants->GetAirborneDeceleration()));
107 gravitational_acceleration_field->ChangeValue(Format(constants->GetGravitationalAcceleration()));
108 climbing_acceleration_field->ChangeValue(Format(constants->GetClimbingAcceleration()));
109 terminal_velocity_field->ChangeValue(Format(constants->GetTerminalVelocity()));
110 external_deceleration_field->ChangeValue(Format(constants->GetExternalDeceleration()));
112 step_delta_field->ChangeValue(Format(constants->GetStepDelta()));
113 step_amplitude_field->ChangeValue(Format(constants->GetStepAmplitude()));
115 radius_field->ChangeValue(Format(constants->GetRadius()));
116 height_field->ChangeValue(Format(constants->GetHeight()));
118 angular_acceleration_field->ChangeValue(Format(constants->GetAngularAcceleration()));
119 angular_deceleration_field->ChangeValue(Format(constants->GetAngularDeceleration()));
120 maximum_angular_velocity_field->ChangeValue(Format(constants->GetMaximumAngularVelocity()));
121 angular_recentering_velocity_field->ChangeValue(Format(constants->GetAngularRecenteringVelocity()));
122 head_angular_velocity_field->ChangeValue(Format(constants->GetFastAngularVelocity()));
123 head_angular_maximum_field->ChangeValue(Format(constants->GetFastAngularMaximum()));
124 maximum_elevation_field->ChangeValue(Format(constants->GetMaximumElevation()));
125 external_angular_deceleration_field->ChangeValue(Format(constants->GetExternalAngularDeceleration()));
127 dead_height_field->ChangeValue(Format(constants->GetDeadHeight()));
128 camera_height_field->ChangeValue(Format(constants->GetCameraHeight()));
129 splash_height_field->ChangeValue(Format(constants->GetSplashHeight()));
130 half_camera_separation_field->ChangeValue(Format(constants->GetHalfCameraSeparation()));
132 mainbox->Show(physics_sizer, true);
135 void PhysicsView::OnSelectAlienAppearance(int index)
137 MonsterDefinition* monster = static_cast<PhysicsDocument*>(GetDocument())->GetMonsterDefinition(index);
139 alien_collection_field->ChangeValue(Format(monster->GetCollection()));
140 alien_color_table_field->ChangeValue(Format(monster->GetColorTable()));
142 alien_hit_field->ChangeValue(Format(monster->GetHitShapes()));
143 alien_hard_dying_field->ChangeValue(Format(monster->GetHardDyingShape()));
144 alien_soft_dying_field->ChangeValue(Format(monster->GetSoftDyingShape()));
145 alien_hard_dead_field->ChangeValue(Format(monster->GetHardDeadShapes()));
146 alien_soft_dead_field->ChangeValue(Format(monster->GetSoftDeadShapes()));
147 alien_stationary_field->ChangeValue(Format(monster->GetStationaryShape()));
148 alien_moving_field->ChangeValue(Format(monster->GetMovingShape()));
149 alien_teleport_in_field->ChangeValue(Format(monster->GetTeleportInShape()));
150 alien_teleport_out_field->ChangeValue(Format(monster->GetTeleportOutShape()));
151 alien_melee_attack_shape_field->ChangeValue(Format(monster->GetMeleeAttack()->GetShape()));
152 alien_ranged_attack_shape_field->ChangeValue(Format(monster->GetRangedAttack()->GetShape()));
154 alien_activation_choice->SetSelection(monster->GetActivationSound() + 1);
155 alien_friendly_activation_choice->SetSelection(monster->GetFriendlyActivationSound() + 1);
156 alien_clear_choice->SetSelection(monster->GetClearSound() + 1);
157 alien_kill_choice->SetSelection(monster->GetKillSound() + 1);
158 alien_apology_choice->SetSelection(monster->GetApologySound() + 1);
159 alien_friendly_fire_choice->SetSelection(monster->GetFriendlyFireSound() + 1);
160 alien_flaming_choice->SetSelection(monster->GetFlamingSound() + 1);
161 alien_random_choice->SetSelection(monster->GetRandomSound() + 1);
163 alien_random_sound_mask_field->ChangeValue(Format(monster->GetRandomSoundMask()));
164 alien_sound_pitch_field->ChangeValue(Format(monster->GetSoundPitch()));
166 mainbox->Show(aliens_appearance_sizer, true);
169 void PhysicsView::OnSelectAlienCombat(int index)
171 MonsterDefinition* monster = static_cast<PhysicsDocument*>(GetDocument())->GetMonsterDefinition(index);
173 alien_attack_frequency_field->ChangeValue(Format(monster->GetAttackFrequency()));
175 for (int i = 0; i < 2; ++i) {
176 AttackDefinition* attack = (i == 0) ? monster->GetMeleeAttack() : monster->GetRangedAttack();
177 alien_attack_type_choices[i]->SetSelection(attack->GetType() + 1);
178 alien_attack_repetitions_fields[i]->ChangeValue(Format(attack->GetRepetitions()));
179 // Anvil displays the raw angle units here...
180 alien_attack_error_fields[i]->ChangeValue(Format(static_cast<short>(std::floor(attack->GetError() * 512.0 / 360.0 + 0.5))));
181 alien_attack_range_fields[i]->ChangeValue(Format(attack->GetRange()));
182 alien_attack_sequence_fields[i]->ChangeValue(Format(attack->GetShape()));
183 alien_attack_dx_fields[i]->ChangeValue(Format(attack->GetDx()));
184 alien_attack_dy_fields[i]->ChangeValue(Format(attack->GetDy()));
185 alien_attack_dz_fields[i]->ChangeValue(Format(attack->GetDz()));
188 alien_shrapnel_radius_field->ChangeValue(Format(monster->GetShrapnelRadius()));
190 DamageDefinition* shrapnel = monster->GetShrapnelDamage();
191 alien_shrapnel_damage_type_choice->SetSelection(shrapnel->GetType() + 1);
192 alien_shrapnel_base_damage_field->ChangeValue(Format(shrapnel->GetBase()));
193 alien_shrapnel_random_damage_field->ChangeValue(Format(shrapnel->GetRandom()));
194 alien_shrapnel_damage_scale_field->ChangeValue(Format(shrapnel->GetScale()));
195 alien_shrapnel_alien_damage_checkbox->SetValue(shrapnel->GetAlien());
197 alien_ranged_impact_effect_choice->SetSelection(monster->GetImpactEffect() + 1);
198 alien_melee_impact_effect_choice->SetSelection(monster->GetMeleeImpactEffect() + 1);
200 mainbox->Show(aliens_combat_sizer, true);
203 void PhysicsView::OnSelectAlienConstants(int index)
205 MonsterDefinition* monster = static_cast<PhysicsDocument*>(GetDocument())->GetMonsterDefinition(index);
207 alien_vitality_field->ChangeValue(Format(monster->GetVitality()));
209 alien_radius_field->ChangeValue(Format(monster->GetRadius()));
210 alien_height_field->ChangeValue(Format(monster->GetHeight()));
212 alien_speed_field->ChangeValue(Format(monster->GetSpeed()));
214 alien_terminal_velocity_field->ChangeValue(Format(monster->GetTerminalVelocity()));
215 alien_gravity_field->ChangeValue(Format(monster->GetGravity()));
217 alien_min_ledge_jump_field->ChangeValue(Format(monster->GetMinimumLedgeDelta()));
218 alien_max_ledge_jump_field->ChangeValue(Format(monster->GetMaximumLedgeDelta()));
219 alien_ext_velocity_scale_field->ChangeValue(Format(monster->GetExternalVelocityScale()));
220 alien_hover_height_field->ChangeValue(Format(monster->GetPreferredHoverHeight()));
222 alien_door_retry_mask_field->ChangeValue(Format(monster->GetDoorRetryMask()));
224 alien_visual_range_field->ChangeValue(Format(monster->GetVisualRange()));
225 alien_dark_visual_range_field->ChangeValue(Format(monster->GetDarkVisualRange()));
226 alien_intelligence_field->ChangeValue(Format(monster->GetIntelligence()));
228 alien_carrying_item_choice->SetSelection(monster->GetCarryingItemType() + 1);
229 alien_contrail_effect_choice->SetSelection(monster->GetContrailEffect() + 1);
231 mainbox->Show(aliens_constants_sizer, true);
234 void PhysicsView::OnSelectAlienBehavior(int index)
236 MonsterDefinition* monster = static_cast<PhysicsDocument*>(GetDocument())->GetMonsterDefinition(index);
238 int monster_class_index = 0;
239 long monster_class = monster->GetClass();
240 while (monster_class >>= 1) {
241 monster_class_index++;
243 alien_class_choice->SetSelection(monster_class_index);
245 for (int i = 0; i < 16; ++i) {
246 alien_friends_checkboxes[i]->SetValue(monster->GetFriend(i));
247 alien_enemies_checkboxes[i]->SetValue(monster->GetEnemy(i));
250 for (int i = 0; i < 27; ++i) {
251 alien_flags_checkboxes[i]->SetValue(monster->GetFlag(i + 1));
254 mainbox->Show(aliens_behavior_sizer, true);
257 void PhysicsView::OnSelectAlienImmunities(int index)
259 MonsterDefinition* monster = static_cast<PhysicsDocument*>(GetDocument())->GetMonsterDefinition(index);
261 for (int i = 0; i < 24; ++i) {
262 alien_immunities_checkboxes[i]->SetValue(monster->GetImmunity(i));
263 alien_weaknesses_checkboxes[i]->SetValue(monster->GetWeakness(i));
266 mainbox->Show(aliens_immunities_sizer, true);
269 void PhysicsView::OnSelectEffect(int index)
271 EffectDefinition* effect = static_cast<PhysicsDocument*>(GetDocument())->GetEffectDefinition(index);
273 eff_collection_field->ChangeValue(Format(effect->GetCollection()));
274 eff_color_table_field->ChangeValue(Format(effect->GetColorTable()));
275 eff_sequence_field->ChangeValue(Format(effect->GetShape()));
277 eff_delay_field->ChangeValue(Format(effect->GetDelay()));
278 eff_pitch_field->ChangeValue(Format(effect->GetSoundPitch()));
280 eff_delay_sound_choice->SetSelection(effect->GetDelaySound() + 1);
282 eff_end_when_animation_loops_checkbox->SetValue(effect->GetEndWhenAnimationLoops());
283 eff_end_when_transfer_animation_loops_checkbox->SetValue(effect->GetEndWhenTransferAnimationLoops());
284 eff_sound_only_checkbox->SetValue(effect->GetSoundOnly());
285 eff_media_effect_checkbox->SetValue(effect->GetMediaEffect());
287 mainbox->Show(effects_sizer, true);
290 void PhysicsView::OnSelectShot(int index)
292 ProjectileDefinition* projectile = static_cast<PhysicsDocument*>(GetDocument())->GetProjectileDefinition(index);
294 shots_collection_field->ChangeValue(Format(projectile->GetCollection()));
295 shots_color_table_field->ChangeValue(Format(projectile->GetColorTable()));
296 shots_sequence_field->ChangeValue(Format(projectile->GetShape()));
298 DamageDefinition* damage = projectile->GetDamage();
300 shots_damage_type_choice->SetSelection(damage->GetType() + 1);
301 shots_damage_base_field->ChangeValue(Format(damage->GetBase()));
302 shots_damage_random_field->ChangeValue(Format(damage->GetRandom()));
303 shots_damage_scale_field->ChangeValue(Format(damage->GetScale()));
304 shots_alien_damage_checkbox->SetValue(damage->GetAlien());
306 shots_flyby_sound_choice->SetSelection(projectile->GetFlybySound() + 1);
307 shots_rebound_sound_choice->SetSelection(projectile->GetReboundSound() + 1);
308 shots_sound_pitch_field->ChangeValue(Format(projectile->GetSoundPitch()));
310 shots_radius_field->ChangeValue(Format(projectile->GetRadius()));
311 shots_area_of_effect_field->ChangeValue(Format(projectile->GetAreaOfEffect()));
312 shots_speed_field->ChangeValue(Format(projectile->GetSpeed()));
313 shots_range_field->ChangeValue(Format(projectile->GetMaximumRange()));
315 shots_detonation_effect_choice->SetSelection(projectile->GetDetonationEffect() + 1);
316 shots_media_detonation_effect_choice->SetSelection(projectile->GetMediaDetonationEffect() + 1);
317 shots_contrail_choice->SetSelection(projectile->GetContrailEffect() + 1);
318 shots_contrail_ticks_field->ChangeValue(Format(projectile->GetTicksBetweenContrails()));
319 shots_maximum_contrails_field->ChangeValue(Format(projectile->GetMaximumContrails()));
321 for (int i = 0; i < 22; ++i) {
322 shots_flags_checkboxes[i]->SetValue(projectile->GetFlag(i));
325 shots_media_impact_choice->SetSelection(projectile->GetMediaProjectilePromotion() + 1);
327 mainbox->Show(shots_sizer, true);
330 void PhysicsView::OnSelectWeaponDefinition(int index)
332 WeaponDefinition* weapon = static_cast<PhysicsDocument*>(GetDocument())->GetWeaponDefinition(index);
334 weapon_item_type_choice->SetSelection(weapon->GetItemType() + 1);
336 weapon_collection_field->ChangeValue(Format(weapon->GetCollection()));
337 weapon_color_table_field->ChangeValue(Format(weapon->GetColorTable()));
338 weapon_idle_field->ChangeValue(Format(weapon->GetIdleShape()));
339 weapon_firing_field->ChangeValue(Format(weapon->GetFiringShape()));
340 weapon_reloading_field->ChangeValue(Format(weapon->GetReloadingShape()));
341 weapon_charging_field->ChangeValue(Format(weapon->GetChargingShape()));
342 weapon_charged_field->ChangeValue(Format(weapon->GetChargedShape()));
343 weapon_flash_intensity_field->ChangeValue(Format(weapon->GetFiringLightIntensity()));
345 weapon_ready_field->ChangeValue(Format(weapon->GetReadyTicks()));
346 weapon_await_reload_field->ChangeValue(Format(weapon->GetAwaitReloadTicks()));
347 weapon_loading_field->ChangeValue(Format(weapon->GetLoadingTicks()));
348 weapon_finish_loading_field->ChangeValue(Format(weapon->GetFinishLoadingTicks()));
349 weapon_flash_decay_field->ChangeValue(Format(weapon->GetFiringIntensityDecayTicks()));
351 weapon_class_choice->SetSelection(weapon->GetWeaponClass() + 1);
353 weapon_idle_height_field->ChangeValue(Format(weapon->GetIdleHeight()));
354 weapon_bob_amplitude_field->ChangeValue(Format(weapon->GetBobAmplitude()));
355 weapon_kick_height_field->ChangeValue(Format(weapon->GetKickHeight()));
356 weapon_reload_height_field->ChangeValue(Format(weapon->GetReloadHeight()));
357 weapon_idle_width_field->ChangeValue(Format(weapon->GetIdleWidth()));
359 for (int i = 0; i < 10; ++i) {
360 weapon_flags_checkboxes[i]->SetValue(weapon->GetFlag(i >= 5 ? i + 1 : i));
363 mainbox->Show(weapons_definitions_sizer, true);
366 void PhysicsView::OnSelectWeaponTriggers(int index)
368 WeaponDefinition* weapon = static_cast<PhysicsDocument*>(GetDocument())->GetWeaponDefinition(index);
370 for (int i = 0; i < 2; ++i) {
371 TriggerDefinition* trigger = (i == 0) ? weapon->GetPrimaryTrigger() : weapon->GetSecondaryTrigger();
373 trigger_projectile_choices[i]->SetSelection(trigger->GetProjectileType() + 1);
374 trigger_rounds_fields[i]->ChangeValue(Format(trigger->GetRoundsPerMagazine()));
375 trigger_ammo_type_choices[i]->SetSelection(trigger->GetAmmunitionType() + 1);
377 trigger_firing_choices[i]->SetSelection(trigger->GetFiringSound() + 1);
378 trigger_click_choices[i]->SetSelection(trigger->GetClickSound() + 1);
379 trigger_charging_choices[i]->SetSelection(trigger->GetChargingSound() + 1);
380 trigger_shell_casing_choices[i]->SetSelection(trigger->GetShellCasingSound() + 1);
381 trigger_reloading_choices[i]->SetSelection(trigger->GetReloadingSound() + 1);
382 trigger_charged_choices[i]->SetSelection(trigger->GetChargedSound() + 1);
384 trigger_ticks_fields[i]->ChangeValue(Format(trigger->GetTicksPerRound()));
385 trigger_recovery_fields[i]->ChangeValue(Format(trigger->GetRecoveryTicks()));
386 trigger_charging_fields[i]->ChangeValue(Format(trigger->GetChargingTicks()));
387 trigger_recoil_fields[i]->ChangeValue(Format(trigger->GetRecoilMagnitude()));
388 trigger_theta_fields[i]->ChangeValue(Format(trigger->GetThetaError()));
389 trigger_dx_fields[i]->ChangeValue(Format(trigger->GetDx()));
390 trigger_dz_fields[i]->ChangeValue(Format(trigger->GetDz()));
391 trigger_burst_count_fields[i]->ChangeValue(Format(trigger->GetBurstCount()));
393 trigger_shell_casing_type_choices[i]->SetSelection(trigger->GetShellCasingType() + 1);
397 mainbox->Show(weapons_triggers_sizer, true);
400 void PhysicsView::OnTreeSelect(wxTreeEvent& e)
402 PhysicsTreeItemData* data = dynamic_cast<PhysicsTreeItemData*>(tree->GetItemData(e.GetItem()));
404 mainbox->Show(aliens_appearance_sizer, false);
405 mainbox->Show(aliens_behavior_sizer, false);
406 mainbox->Show(aliens_combat_sizer, false);
407 mainbox->Show(aliens_constants_sizer, false);
408 mainbox->Show(aliens_immunities_sizer, false);
409 mainbox->Show(dummy_sizer, false);
410 mainbox->Show(effects_sizer, false);
411 mainbox->Show(shots_sizer, false);
412 mainbox->Show(physics_sizer, false);
413 mainbox->Show(weapons_definitions_sizer, false);
414 mainbox->Show(weapons_triggers_sizer, false);
416 int new_section = data->Section();
417 switch (new_section) {
418 case TREESECTION_PHYSICS:
419 OnSelectPhysicsConstants(data->ID());
421 case TREESECTION_EFFECTS:
422 OnSelectEffect(data->ID());
424 case TREESECTION_PROJECTILES:
425 OnSelectShot(data->ID());
427 case TREESECTION_MONSTERS_APPEARANCE:
428 OnSelectAlienAppearance(data->ID());
430 case TREESECTION_MONSTERS_COMBAT:
431 OnSelectAlienCombat(data->ID());
433 case TREESECTION_MONSTERS_CONSTANTS:
434 OnSelectAlienConstants(data->ID());
436 case TREESECTION_MONSTERS_BEHAVIOR:
437 OnSelectAlienBehavior(data->ID());
439 case TREESECTION_MONSTERS_IMMUNITIES:
440 OnSelectAlienImmunities(data->ID());
442 case TREESECTION_WEAPONS_SETTINGS:
443 OnSelectWeaponDefinition(data->ID());
445 case TREESECTION_WEAPONS_TRIGGERS:
446 OnSelectWeaponTriggers(data->ID());
449 mainbox->Show(dummy_sizer, true);
453 switch (new_section) {
454 case TREESECTION_MONSTERS:
455 case TREESECTION_EFFECTS:
456 case TREESECTION_PROJECTILES:
457 case TREESECTION_PHYSICS:
458 case TREESECTION_WEAPONS:
459 menubar->Enable(EDIT_MENU_COPY, true);
460 menubar->Enable(EDIT_MENU_PASTE, true);
463 menubar->Enable(EDIT_MENU_COPY, false);
464 menubar->Enable(EDIT_MENU_PASTE, false);
472 short PhysicsView::GetSelection() {
473 return static_cast<PhysicsTreeItemData*>(tree->GetItemData(tree->GetSelection()))->ID();
477 inline unsigned char* Serialize(T* element, size_t& size)
480 unsigned char* data = new unsigned char[size];
481 BigEndianBuffer buffer(data, size);
482 element->SaveObject(buffer);
486 void PhysicsView::MenuEditCopy(wxCommandEvent&) {
487 if (wxTheClipboard->Open()) {
489 PhysicsTreeItemData* data = static_cast<PhysicsTreeItemData*>(tree->GetItemData(tree->GetSelection()));
490 PhysicsDocument* document = static_cast<PhysicsDocument*>(GetDocument());
494 unsigned char* buf = 0;
497 switch (data->Section()) {
498 case TREESECTION_MONSTERS:
499 buf = Serialize(document->GetMonsterDefinition(data->ID()), size);
500 format.SetId(wxT("application/vnd.shapefusion.monster"));
502 case TREESECTION_EFFECTS:
503 buf = Serialize(document->GetEffectDefinition(data->ID()), size);
504 format.SetId(wxT("application/vnd.shapefusion.effect"));
506 case TREESECTION_PROJECTILES:
507 buf = Serialize(document->GetProjectileDefinition(data->ID()), size);
508 format.SetId(wxT("application/vnd.shapefusion.projectile"));
510 case TREESECTION_PHYSICS:
511 buf = Serialize(document->GetPhysicsConstants(data->ID()), size);
512 format.SetId(wxT("application/vnd.shapefusion.physics"));
514 case TREESECTION_WEAPONS:
515 buf = Serialize(document->GetWeaponDefinition(data->ID()), size);
516 format.SetId(wxT("application/vnd.shapefusion.weapon"));
520 wxCustomDataObject* dataObject = new wxCustomDataObject(format);
521 dataObject->TakeData(size, buf);
522 wxTheClipboard->SetData(dataObject);
524 wxTheClipboard->Close();
529 void PhysicsView::MenuEditPaste(wxCommandEvent&) {
530 if (wxTheClipboard->Open()) {
531 PhysicsTreeItemData* data = static_cast<PhysicsTreeItemData*>(tree->GetItemData(tree->GetSelection()));
532 PhysicsDocument* document = static_cast<PhysicsDocument*>(GetDocument());
537 switch (data->Section()) {
538 case TREESECTION_MONSTERS:
539 format.SetId(wxT("application/vnd.shapefusion.monster"));
541 case TREESECTION_EFFECTS:
542 format.SetId(wxT("application/vnd.shapefusion.effect"));
544 case TREESECTION_PROJECTILES:
545 format.SetId(wxT("application/vnd.shapefusion.projectile"));
547 case TREESECTION_PHYSICS:
548 format.SetId(wxT("application/vnd.shapefusion.physics"));
550 case TREESECTION_WEAPONS:
551 format.SetId(wxT("application/vnd.shapefusion.weapon"));
556 wxCustomDataObject dataObject(format);
557 if (wxTheClipboard->GetData(dataObject)) {
558 BigEndianBuffer buffer(reinterpret_cast<unsigned char *>(dataObject.GetData()), dataObject.GetSize());
560 switch (data->Section()) {
561 case TREESECTION_MONSTERS:
562 document->GetMonsterDefinition(data->ID())->LoadObject(buffer);
564 case TREESECTION_EFFECTS:
565 document->GetEffectDefinition(data->ID())->LoadObject(buffer);
566 OnSelectEffect(data->ID());
568 case TREESECTION_PROJECTILES:
569 document->GetProjectileDefinition(data->ID())->LoadObject(buffer);
570 OnSelectShot(data->ID());
572 case TREESECTION_PHYSICS:
573 document->GetPhysicsConstants(data->ID())->LoadObject(buffer);
574 OnSelectPhysicsConstants(data->ID());
576 case TREESECTION_WEAPONS:
577 document->GetWeaponDefinition(data->ID())->LoadObject(buffer);
581 document->Modify(true);
585 wxTheClipboard->Close();
589 void PhysicsView::EditAlienCheckboxes(wxCommandEvent& e)
591 MonsterDefinition* monster = static_cast<PhysicsDocument*>(GetDocument())->GetMonsterDefinition(GetSelection());
595 if (id == CB_ALIEN_SHRAPNEL_ALIEN_DAMAGE) {
596 monster->GetShrapnelDamage()->SetAlien(e.IsChecked());
597 } else if (id >= CB_ALIEN_FRIENDS && id < CB_ALIEN_ENEMIES) {
598 monster->SetFriend(id - CB_ALIEN_FRIENDS, e.IsChecked());
599 } else if (id >= CB_ALIEN_ENEMIES && id < CB_ALIEN_FLAGS) {
600 monster->SetEnemy(id - CB_ALIEN_ENEMIES, e.IsChecked());
601 } else if (id >= CB_ALIEN_FLAGS && id < CB_ALIEN_IMMUNITIES) {
602 monster->SetFlag(id - CB_ALIEN_FLAGS + 1, e.IsChecked());
603 } else if (id >= CB_ALIEN_IMMUNITIES && id < CB_ALIEN_WEAKNESSES) {
604 monster->SetImmunity(id - CB_ALIEN_IMMUNITIES, e.IsChecked());
605 } else if (id >= CB_ALIEN_WEAKNESSES && id <= CB_ALIEN_WEAKNESSES + 24) {
606 monster->SetWeakness(id - CB_ALIEN_WEAKNESSES, e.IsChecked());
609 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
612 void PhysicsView::EditAlienDoubles(wxCommandEvent& e)
614 MonsterDefinition* monster = static_cast<PhysicsDocument*>(GetDocument())->GetMonsterDefinition(GetSelection());
617 if (e.GetString().ToDouble(&d)) {
619 case FIELD_ALIEN_SOUND_PITCH:
620 monster->SetSoundPitch(d);
622 case FIELD_ALIEN_SHRAPNEL_DAMAGE_SCALE:
623 monster->GetShrapnelDamage()->SetScale(d);
625 case FIELD_ALIEN_EXT_VELOCITY_SCALE:
626 monster->SetExternalVelocityScale(d);
631 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
634 void PhysicsView::EditAlienFields(wxCommandEvent& e)
636 MonsterDefinition* monster = static_cast<PhysicsDocument*>(GetDocument())->GetMonsterDefinition(GetSelection());
639 if (e.GetString().ToLong(&v)) {
641 AttackDefinition* attack = monster->GetMeleeAttack();
643 if (id >= MENU_ALIEN_ATTACK_TYPE + NUM_ALIEN_ATTACK_CONTROLS && id <= FIELD_ALIEN_ATTACK_DZ + NUM_ALIEN_ATTACK_CONTROLS)
645 id -= NUM_ALIEN_ATTACK_CONTROLS;
646 attack = monster->GetRangedAttack();
650 case FIELD_ALIEN_COLLECTION:
652 monster->SetCollection(31);
653 monster->SetColorTable(7);
654 alien_collection_field->ChangeValue(wxT("31"));
655 alien_color_table_field->ChangeValue(wxT("7"));
657 monster->SetCollection(v);
660 case FIELD_ALIEN_COLOR_TABLE:
662 monster->SetCollection(31);
663 monster->SetColorTable(7);
664 alien_collection_field->ChangeValue(wxT("31"));
665 alien_color_table_field->ChangeValue(wxT("7"));
667 monster->SetColorTable(v);
670 case FIELD_ALIEN_HIT:
671 monster->SetHitShapes(v);
673 case FIELD_ALIEN_HARD_DYING:
674 monster->SetHardDyingShape(v);
676 case FIELD_ALIEN_SOFT_DYING:
677 monster->SetSoftDyingShape(v);
679 case FIELD_ALIEN_HARD_DEAD:
680 monster->SetHardDeadShapes(v);
682 case FIELD_ALIEN_SOFT_DEAD:
683 monster->SetSoftDeadShapes(v);
685 case FIELD_ALIEN_STATIONARY:
686 monster->SetStationaryShape(v);
688 case FIELD_ALIEN_MOVING:
689 monster->SetMovingShape(v);
691 case FIELD_ALIEN_TELEPORT_IN:
692 monster->SetTeleportInShape(v);
694 case FIELD_ALIEN_TELEPORT_OUT:
695 monster->SetTeleportOutShape(v);
697 case FIELD_ALIEN_MELEE_ATTACK_SHAPE:
698 monster->GetMeleeAttack()->SetShape(v);
700 case FIELD_ALIEN_RANGED_ATTACK_SHAPE:
701 monster->GetRangedAttack()->SetShape(v);
703 case FIELD_ALIEN_RANDOM_SOUND_MASK:
704 monster->SetRandomSoundMask(v);
706 case FIELD_ALIEN_ATTACK_FREQUENCY:
707 monster->SetAttackFrequency(v);
709 case FIELD_ALIEN_ATTACK_REPETITIONS:
710 attack->SetRepetitions(v);
712 case FIELD_ALIEN_ATTACK_ERROR:
713 attack->SetError(v / 512.0 * 360.0);
715 case FIELD_ALIEN_ATTACK_RANGE:
718 case FIELD_ALIEN_ATTACK_SEQUENCE:
721 case FIELD_ALIEN_ATTACK_DX:
724 case FIELD_ALIEN_ATTACK_DY:
727 case FIELD_ALIEN_ATTACK_DZ:
730 case FIELD_ALIEN_SHRAPNEL_RADIUS:
731 monster->SetShrapnelRadius(v);
733 case FIELD_ALIEN_SHRAPNEL_BASE_DAMAGE:
734 monster->GetShrapnelDamage()->SetBase(v);
736 case FIELD_ALIEN_SHRAPNEL_RANDOM_DAMAGE:
737 monster->GetShrapnelDamage()->SetRandom(v);
739 case FIELD_ALIEN_VITALITY:
740 monster->SetVitality(v);
742 case FIELD_ALIEN_RADIUS:
743 monster->SetRadius(v);
745 case FIELD_ALIEN_HEIGHT:
746 monster->SetHeight(v);
748 case FIELD_ALIEN_SPEED:
749 monster->SetSpeed(v);
751 case FIELD_ALIEN_TERMINAL_VELOCITY:
752 monster->SetTerminalVelocity(v);
754 case FIELD_ALIEN_GRAVITY:
755 monster->SetGravity(v);
757 case FIELD_ALIEN_MIN_LEDGE_JUMP:
758 monster->SetMinimumLedgeDelta(v);
760 case FIELD_ALIEN_MAX_LEDGE_JUMP:
761 monster->SetMaximumLedgeDelta(v);
763 case FIELD_ALIEN_HOVER_HEIGHT:
764 monster->SetPreferredHoverHeight(v);
766 case FIELD_ALIEN_DOOR_RETRY_MASK:
767 monster->SetDoorRetryMask(v);
769 case FIELD_ALIEN_VISUAL_RANGE:
770 monster->SetVisualRange(v);
772 case FIELD_ALIEN_DARK_VISUAL_RANGE:
773 monster->SetDarkVisualRange(v);
775 case FIELD_ALIEN_INTELLIGENCE:
776 monster->SetIntelligence(v);
781 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
784 void PhysicsView::EditAlienMenus(wxCommandEvent& e)
786 MonsterDefinition* monster = static_cast<PhysicsDocument*>(GetDocument())->GetMonsterDefinition(GetSelection());
789 case MENU_ALIEN_ACTIVATION:
790 monster->SetActivationSound(e.GetSelection() - 1);
792 case MENU_ALIEN_FRIENDLY_ACTIVATION:
793 monster->SetFriendlyActivationSound(e.GetSelection() - 1);
795 case MENU_ALIEN_CLEAR:
796 monster->SetClearSound(e.GetSelection() - 1);
798 case MENU_ALIEN_KILL:
799 monster->SetKillSound(e.GetSelection() - 1);
801 case MENU_ALIEN_APOLOGY:
802 monster->SetApologySound(e.GetSelection() - 1);
804 case MENU_ALIEN_FRIENDLY_FIRE:
805 monster->SetFriendlyFireSound(e.GetSelection() - 1);
807 case MENU_ALIEN_FLAMING:
808 monster->SetFlamingSound(e.GetSelection() - 1);
810 case MENU_ALIEN_RANDOM:
811 monster->SetRandomSound(e.GetSelection() - 1);
813 case MENU_ALIEN_ATTACK_TYPE:
814 monster->GetMeleeAttack()->SetType(e.GetSelection() - 1);
816 case MENU_ALIEN_ATTACK_TYPE + NUM_ALIEN_ATTACK_CONTROLS:
817 monster->GetRangedAttack()->SetType(e.GetSelection() - 1);
819 case MENU_ALIEN_SHRAPNEL_DAMAGE_TYPE:
820 monster->GetShrapnelDamage()->SetType(e.GetSelection() - 1);
822 case MENU_ALIEN_RANGED_IMPACT_EFFECT:
823 monster->SetImpactEffect(e.GetSelection() - 1);
825 case MENU_ALIEN_MELEE_IMPACT_EFFECT:
826 monster->SetMeleeImpactEffect(e.GetSelection() - 1);
828 case MENU_ALIEN_CARRYING_ITEM:
829 monster->SetCarryingItemType(e.GetSelection() - 1);
831 case MENU_ALIEN_CONTRAIL_EFFECT:
832 monster->SetContrailEffect(e.GetSelection() - 1);
834 case MENU_ALIEN_CLASS:
835 monster->SetClass(1 << e.GetSelection());
839 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
842 void PhysicsView::EditEffectCheckboxes(wxCommandEvent& e)
844 EffectDefinition* effect = static_cast<PhysicsDocument*>(GetDocument())->GetEffectDefinition(GetSelection());
847 case CB_EFFECT_END_WHEN_ANIMATION_LOOPS:
848 effect->SetEndWhenAnimationLoops(e.IsChecked());
850 case CB_EFFECT_END_WHEN_TRANSFER_ANIMATION_LOOPS:
851 effect->SetEndWhenTransferAnimationLoops(e.IsChecked());
853 case CB_EFFECT_SOUND_ONLY:
854 effect->SetSoundOnly(e.IsChecked());
856 case CB_EFFECT_MEDIA_EFFECT:
857 effect->SetMediaEffect(e.IsChecked());
861 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
864 void PhysicsView::EditEffectDoubles(wxCommandEvent& e)
866 EffectDefinition* effect = static_cast<PhysicsDocument*>(GetDocument())->GetEffectDefinition(GetSelection());
869 if (e.GetString().ToDouble(&d)) {
871 case FIELD_EFFECT_PITCH:
872 effect->SetSoundPitch(d);
877 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
880 void PhysicsView::EditEffectFields(wxCommandEvent& e)
882 EffectDefinition* effect = static_cast<PhysicsDocument*>(GetDocument())->GetEffectDefinition(GetSelection());
885 if (e.GetString().ToLong(&v)) {
887 case FIELD_EFFECT_COLLECTION:
889 effect->SetCollection(31);
890 effect->SetColorTable(7);
891 eff_collection_field->ChangeValue(wxT("31"));
892 eff_color_table_field->ChangeValue(wxT("7"));
894 effect->SetCollection(v);
897 case FIELD_EFFECT_COLOR_TABLE:
899 effect->SetCollection(31);
900 effect->SetColorTable(7);
901 eff_collection_field->ChangeValue(wxT("31"));
902 eff_color_table_field->ChangeValue(wxT("7"));
904 effect->SetColorTable(v);
907 case FIELD_EFFECT_SEQUENCE:
913 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
916 void PhysicsView::EditEffectMenus(wxCommandEvent& e)
918 EffectDefinition* effect = static_cast<PhysicsDocument*>(GetDocument())->GetEffectDefinition(GetSelection());
921 case MENU_EFFECT_DELAY_SOUND:
922 effect->SetDelaySound(e.GetSelection() - 1);
926 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
929 void PhysicsView::EditShotCheckboxes(wxCommandEvent& e)
931 ProjectileDefinition* projectile = static_cast<PhysicsDocument*>(GetDocument())->GetProjectileDefinition(GetSelection());
933 if (e.GetId() == CB_SHOT_ALIEN_DAMAGE) {
934 projectile->GetDamage()->SetAlien(e.IsChecked());
935 } else if (e.GetId() >= CB_SHOT_FLAGS && e.GetId() < CB_SHOT_FLAGS + 22) {
936 projectile->SetFlag(e.GetId() - CB_SHOT_FLAGS, e.IsChecked());
939 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
942 void PhysicsView::EditShotFields(wxCommandEvent& e)
944 ProjectileDefinition* projectile = static_cast<PhysicsDocument*>(GetDocument())->GetProjectileDefinition(GetSelection());
947 if (e.GetString().ToLong(&v)) {
949 case FIELD_SHOT_COLLECTION:
951 projectile->SetCollection(31);
952 projectile->SetColorTable(7);
953 shots_collection_field->ChangeValue(wxT("31"));
954 shots_color_table_field->ChangeValue(wxT("7"));
956 projectile->SetCollection(v);
959 case FIELD_SHOT_COLOR_TABLE:
961 projectile->SetCollection(31);
962 projectile->SetColorTable(7);
963 shots_collection_field->ChangeValue(wxT("31"));
964 shots_color_table_field->ChangeValue(wxT("7"));
966 projectile->SetColorTable(v);
969 case FIELD_SHOT_SEQUENCE:
970 projectile->SetShape(v);
972 case FIELD_SHOT_DAMAGE_BASE:
973 projectile->GetDamage()->SetBase(v);
975 case FIELD_SHOT_DAMAGE_RANDOM:
976 projectile->GetDamage()->SetRandom(v);
978 case FIELD_SHOT_RADIUS:
979 projectile->SetRadius(v);
981 case FIELD_SHOT_AREA_OF_EFFECT:
982 projectile->SetAreaOfEffect(v);
984 case FIELD_SHOT_SPEED:
985 projectile->SetSpeed(v);
987 case FIELD_SHOT_RANGE:
988 projectile->SetMaximumRange(v);
990 case FIELD_SHOT_CONTRAIL_TICKS:
991 projectile->SetTicksBetweenContrails(v);
993 case FIELD_SHOT_MAXIMUM_CONTRAILS:
994 projectile->SetMaximumContrails(v);
998 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
1001 void PhysicsView::EditShotDoubles(wxCommandEvent& e)
1003 ProjectileDefinition* projectile = static_cast<PhysicsDocument*>(GetDocument())->GetProjectileDefinition(GetSelection());
1007 if (e.GetString().ToDouble(&d)) {
1008 switch (e.GetId()) {
1009 case FIELD_SHOT_DAMAGE_SCALE:
1010 projectile->GetDamage()->SetScale(d);
1012 case FIELD_SHOT_SOUND_PITCH:
1013 projectile->SetSoundPitch(d);
1018 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
1021 void PhysicsView::EditShotMenus(wxCommandEvent& e)
1023 ProjectileDefinition* projectile = static_cast<PhysicsDocument*>(GetDocument())->GetProjectileDefinition(GetSelection());
1025 switch (e.GetId()) {
1026 case MENU_SHOT_DAMAGE_TYPE:
1027 projectile->GetDamage()->SetType(e.GetSelection() - 1);
1029 case MENU_SHOT_FLYBY_SOUND:
1030 projectile->SetFlybySound(e.GetSelection() - 1);
1032 case MENU_SHOT_REBOUND_SOUND:
1033 projectile->SetReboundSound(e.GetSelection() - 1);
1035 case MENU_SHOT_DETONATION_EFFECT:
1036 projectile->SetDetonationEffect(e.GetSelection() - 1);
1038 case MENU_SHOT_MEDIA_DETONATION_EFFECT:
1039 projectile->SetMediaDetonationEffect(e.GetSelection() - 1);
1041 case MENU_SHOT_CONTRAIL:
1042 projectile->SetContrailEffect(e.GetSelection() - 1);
1044 case MENU_SHOT_MEDIA_IMPACT:
1045 projectile->SetMediaProjectilePromotion(e.GetSelection() - 1);
1049 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
1052 void PhysicsView::EditPhysicsConstants(wxCommandEvent& e)
1054 PhysicsConstants* constants = static_cast<PhysicsDocument*>(GetDocument())->GetPhysicsConstants(GetSelection());
1057 if (e.GetString().ToDouble(&d)) {
1058 switch (e.GetId()) {
1059 case FIELD_MAX_FORWARD_VELOCITY:
1060 constants->SetMaximumForwardVelocity(d);
1062 case FIELD_MAX_BACKWARD_VELOCITY:
1063 constants->SetMaximumBackwardVelocity(d);
1065 case FIELD_MAX_PERPENDICULAR_VELOCITY:
1066 constants->SetMaximumPerpendicularVelocity(d);
1069 case FIELD_ACCELERATION:
1070 constants->SetAcceleration(d);
1072 case FIELD_DECELERATION:
1073 constants->SetDeceleration(d);
1075 case FIELD_AIRBORNE_DECELERATION:
1076 constants->SetAirborneDeceleration(d);
1078 case FIELD_GRAVITATIONAL_ACCELERATION:
1079 constants->SetGravitationalAcceleration(d);
1081 case FIELD_CLIMBING_ACCELERATION:
1082 constants->SetClimbingAcceleration(d);
1084 case FIELD_TERMINAL_VELOCITY:
1085 constants->SetTerminalVelocity(d);
1087 case FIELD_EXTERNAL_DECELERATION:
1088 constants->SetExternalDeceleration(d);
1091 case FIELD_STEP_DELTA:
1092 constants->SetStepDelta(d);
1094 case FIELD_STEP_AMPLITUDE:
1095 constants->SetStepAmplitude(d);
1099 constants->SetRadius(d);
1102 constants->SetHeight(d);
1105 case FIELD_ANGULAR_ACCELERATION:
1106 constants->SetAngularAcceleration(d);
1108 case FIELD_ANGULAR_DECELERATION:
1109 constants->SetAngularDeceleration(d);
1111 case FIELD_MAXIMUM_ANGULAR_VELOCITY:
1112 constants->SetMaximumAngularVelocity(d);
1114 case FIELD_ANGULAR_RECENTERING_VELOCITY:
1115 constants->SetAngularRecenteringVelocity(d);
1117 case FIELD_HEAD_ANGULAR_VELOCITY:
1118 constants->SetFastAngularVelocity(d);
1120 case FIELD_HEAD_ANGULAR_MAXIMUM:
1121 constants->SetFastAngularMaximum(d);
1123 case FIELD_MAXIMUM_ELEVATION:
1124 constants->SetMaximumElevation(d);
1126 case FIELD_EXTERNAL_ANGULAR_DECELERATION:
1127 constants->SetExternalAngularDeceleration(d);
1130 case FIELD_DEAD_HEIGHT:
1131 constants->SetDeadHeight(d);
1133 case FIELD_CAMERA_HEIGHT:
1134 constants->SetCameraHeight(d);
1136 case FIELD_SPLASH_HEIGHT:
1137 constants->SetSplashHeight(d);
1139 case FIELD_HALF_CAMERA_SEPARATION:
1140 constants->SetHalfCameraSeparation(d);
1145 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
1148 void PhysicsView::EditWeaponCheckboxes(wxCommandEvent& e)
1150 WeaponDefinition* weapon = static_cast<PhysicsDocument*>(GetDocument())->GetWeaponDefinition(GetSelection());
1152 int flag = e.GetId() - CB_WEAPON_FLAGS;
1154 weapon->SetFlag(flag >= 5 ? flag + 1: flag, e.IsChecked());
1156 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
1159 void PhysicsView::EditWeaponFields(wxCommandEvent& e)
1161 WeaponDefinition* weapon = static_cast<PhysicsDocument*>(GetDocument())->GetWeaponDefinition(GetSelection());
1164 if (e.GetString().ToLong(&v)) {
1165 switch (e.GetId()) {
1166 case FIELD_WEAPON_COLLECTION:
1168 weapon->SetCollection(31);
1169 weapon->SetColorTable(7);
1170 weapon_collection_field->ChangeValue(wxT("31"));
1171 weapon_color_table_field->ChangeValue(wxT("7"));
1173 weapon->SetCollection(v);
1176 case FIELD_WEAPON_COLOR_TABLE:
1178 weapon->SetCollection(31);
1179 weapon->SetColorTable(7);
1180 weapon_collection_field->ChangeValue(wxT("31"));
1181 weapon_color_table_field->ChangeValue(wxT("7"));
1183 weapon->SetColorTable(v);
1186 case FIELD_WEAPON_IDLE:
1187 weapon->SetIdleShape(v);
1189 case FIELD_WEAPON_FIRING:
1190 weapon->SetFiringShape(v);
1192 case FIELD_WEAPON_RELOADING:
1193 weapon->SetReloadingShape(v);
1195 case FIELD_WEAPON_CHARGING:
1196 weapon->SetChargingShape(v);
1198 case FIELD_WEAPON_CHARGED:
1199 weapon->SetChargedShape(v);
1201 case FIELD_WEAPON_READY:
1202 weapon->SetReadyTicks(v);
1204 case FIELD_WEAPON_AWAIT_RELOAD:
1205 weapon->SetAwaitReloadTicks(v);
1207 case FIELD_WEAPON_LOADING:
1208 weapon->SetLoadingTicks(v);
1210 case FIELD_WEAPON_FINISH_LOADING:
1211 weapon->SetFinishLoadingTicks(v);
1213 case FIELD_WEAPON_FLASH_DECAY:
1214 weapon->SetFiringIntensityDecayTicks(v);
1219 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
1223 void PhysicsView::EditWeaponDoubles(wxCommandEvent& e)
1225 WeaponDefinition* weapon = static_cast<PhysicsDocument*>(GetDocument())->GetWeaponDefinition(GetSelection());
1228 if (e.GetString().ToDouble(&d)) {
1229 switch (e.GetId()) {
1230 case FIELD_WEAPON_FLASH_INTENSITY:
1231 weapon->SetFiringLightIntensity(d);
1233 case FIELD_WEAPON_IDLE_HEIGHT:
1234 weapon->SetIdleHeight(d);
1236 case FIELD_WEAPON_BOB_AMPLITUDE:
1237 weapon->SetBobAmplitude(d);
1239 case FIELD_WEAPON_KICK_HEIGHT:
1240 weapon->SetKickHeight(d);
1242 case FIELD_WEAPON_RELOAD_HEIGHT:
1243 weapon->SetReloadHeight(d);
1245 case FIELD_WEAPON_IDLE_WIDTH:
1246 weapon->SetIdleWidth(d);
1251 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
1254 void PhysicsView::EditWeaponMenus(wxCommandEvent& e)
1256 WeaponDefinition* weapon = static_cast<PhysicsDocument*>(GetDocument())->GetWeaponDefinition(GetSelection());
1258 switch (e.GetId()) {
1259 case MENU_WEAPON_ITEM_TYPE:
1260 weapon->SetItemType(e.GetSelection() - 1);
1262 case MENU_WEAPON_CLASS:
1263 weapon->SetWeaponClass(e.GetSelection() - 1);
1267 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
1270 void PhysicsView::EditTriggerFields(wxCommandEvent& e)
1272 WeaponDefinition* weapon = static_cast<PhysicsDocument*>(GetDocument())->GetWeaponDefinition(GetSelection());
1275 if (e.GetString().ToLong(&v)) {
1277 TriggerDefinition* trigger = weapon->GetPrimaryTrigger();
1279 if (id >= FIELD_TRIGGER_ROUNDS + NUM_TRIGGER_IDS) {
1280 id -= NUM_TRIGGER_IDS;
1281 trigger = weapon->GetSecondaryTrigger();
1285 case FIELD_TRIGGER_ROUNDS:
1286 trigger->SetRoundsPerMagazine(v);
1288 case FIELD_TRIGGER_TICKS:
1289 trigger->SetTicksPerRound(v);
1291 case FIELD_TRIGGER_RECOVERY:
1292 trigger->SetRecoveryTicks(v);
1294 case FIELD_TRIGGER_CHARGING:
1295 trigger->SetChargingTicks(v);
1297 case FIELD_TRIGGER_RECOIL:
1298 trigger->SetRecoilMagnitude(v);
1300 case FIELD_TRIGGER_THETA:
1301 trigger->SetThetaError(v);
1303 case FIELD_TRIGGER_DX:
1306 case FIELD_TRIGGER_DZ:
1309 case FIELD_TRIGGER_BURST_COUNT:
1310 trigger->SetBurstCount(v);
1315 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);
1318 void PhysicsView::EditTriggerMenus(wxCommandEvent& e)
1320 WeaponDefinition* weapon = static_cast<PhysicsDocument*>(GetDocument())->GetWeaponDefinition(GetSelection());
1323 TriggerDefinition* trigger = weapon->GetPrimaryTrigger();
1325 if (id >= FIELD_TRIGGER_ROUNDS + NUM_TRIGGER_IDS) {
1326 id -= NUM_TRIGGER_IDS;
1327 trigger = weapon->GetSecondaryTrigger();
1331 case MENU_TRIGGER_PROJECTILE:
1332 trigger->SetProjectileType(e.GetSelection() - 1);
1334 case MENU_TRIGGER_AMMO_TYPE:
1335 trigger->SetAmmunitionType(e.GetSelection() - 1);
1337 case MENU_TRIGGER_FIRING:
1338 trigger->SetFiringSound(e.GetSelection() - 1);
1340 case MENU_TRIGGER_CLICK:
1341 trigger->SetClickSound(e.GetSelection() - 1);
1343 case MENU_TRIGGER_CHARGING:
1344 trigger->SetChargingSound(e.GetSelection() - 1);
1346 case MENU_TRIGGER_SHELL_CASING:
1347 trigger->SetShellCasingSound(e.GetSelection() - 1);
1349 case MENU_TRIGGER_RELOADING:
1350 trigger->SetReloadingSound(e.GetSelection() - 1);
1352 case MENU_TRIGGER_CHARGED:
1353 trigger->SetChargedSound(e.GetSelection() - 1);
1355 case MENU_TRIGGER_SHELL_CASING_TYPE:
1356 trigger->SetShellCasingType(e.GetSelection() - 1);
1360 static_cast<PhysicsDocument*>(GetDocument())->Modify(true);