OpenGothic
Open source reimplementation of Gothic I and II
Loading...
Searching...
No Matches
visualfx.cpp
Go to the documentation of this file.
1#include "visualfx.h"
2
3#include <Tempest/Log>
4#include <cctype>
5
6#include "utils/string_frm.h"
7#include "world/world.h"
8#include "utils/parser.h"
9#include "gothic.h"
10
11using namespace Tempest;
12
13VisualFx::Key::Key(const zenkit::IParticleEffectEmitKey& k) {
14 visName = Gothic::inst().loadParticleFx(k.vis_name_s);
15 visSizeScale = k.vis_size_scale;
16 scaleDuration = k.scale_duration; // time to reach full scale at this key for relevant vars (size, alpha, etc.)
17
18 pfx_ppsValue = k.pfx_pps_value;
19 pfx_ppsIsSmoothChg = k.pfx_pps_is_smooth_chg!=0;
20 pfx_ppsIsLoopingChg = k.pfx_pps_is_looping_chg!=0;
21 pfx_scTime = 0.f;
22 if(!k.pfx_fly_gravity_s.empty())
23 pfx_flyGravity = Parser::loadVec3(k.pfx_fly_gravity_s);
24
25 if(!k.pfx_shp_dim_s.empty())
26 pfx_shpDim = Parser::loadVec3(k.pfx_shp_dim_s);
27 pfx_shpIsVolumeChg = k.pfx_shp_is_volume_chg; // changes volume rendering of pfx if set to 1
28 pfx_shpScaleFPS = k.pfx_shp_scale_fps;
29 pfx_shpDistribWalkSpeed = k.pfx_shp_distrib_walks_peed;
30 if(!k.pfx_shp_offset_vec_s.empty())
31 pfx_shpOffsetVec = Parser::loadVec3(k.pfx_shp_offset_vec_s);
32 pfx_shpDistribType_S = k.pfx_shp_distrib_type_s;
33 pfx_dirMode_S = k.pfx_dir_mode_s;
34 pfx_dirFOR_S = k.pfx_dir_for_s;
35 pfx_dirModeTargetFOR_S = k.pfx_dir_mode_target_for_s;
36 pfx_dirModeTargetPos_S = k.pfx_dir_mode_target_pos_s;
37 pfx_velAvg = k.pfx_vel_avg;
38 pfx_lspPartAvg = k.pfx_lsp_part_avg;
39 pfx_visAlphaStart = k.pfx_vis_alpha_start;
40
41 lightPresetName = k.light_preset_name;
42 lightRange = k.light_range;
43 sfxID = k.sfx_id;
44 sfxIsAmbient = k.sfx_is_ambient;
45 emCreateFXID = Gothic::inst().loadVisualFx(k.em_create_fx_id);
46
47 emFlyGravity = k.em_fly_gravity;
48 if(!k.em_self_rot_vel_s.empty())
49 emSelfRotVel = Parser::loadVec3(k.em_self_rot_vel_s);
50 if(!k.em_trj_mode_s.empty())
51 emTrjMode = VisualFx::loadTrajectory(k.em_trj_mode_s);
52 emTrjEaseVel = k.em_trj_ease_vel;
53 emCheckCollision = k.em_check_collision!=0;
54 emFXLifeSpan = k.em_fx_lifespan<0 ? 0 : uint64_t(k.em_fx_lifespan*1000.f);
55 }
56
57VisualFx::VisualFx(const zenkit::IEffectBase& fx, zenkit::DaedalusVm& vm, std::string_view name) {
58 visName_S = fx.vis_name_s;
59 visSize = Parser::loadVec2(fx.vis_size_s);
60 visAlpha = fx.vis_alpha;
61 visAlphaBlendFunc = Parser::loadAlpha(fx.vis_alpha_blend_func_s);
62 visTexAniFPS = 0.f;
63 visTexAniIsLooping = false;
64
65 emTrjMode = loadTrajectory(fx.em_trj_mode_s);
66 emTrjOriginNode = fx.em_trj_origin_node;
67 emTrjTargetNode = fx.em_trj_target_node;
68 emTrjTargetRange = fx.em_trj_target_range;
69 emTrjTargetAzi = fx.em_trj_target_azi;
70 emTrjTargetElev = fx.em_trj_target_elev;
71 emTrjNumKeys = fx.em_trj_num_keys;
72 emTrjNumKeysVar = fx.em_trj_num_keys_var;
73 emTrjAngleElevVar = fx.em_trj_angle_elev_var;
74 emTrjAngleHeadVar = fx.em_trj_angle_head_var;
75 emTrjKeyDistVar = fx.em_trj_key_dist_var;
76 emTrjLoopMode = loadLoopmode(fx.em_trj_loop_mode_s);
77 emTrjEaseFunc = loadEaseFunc(fx.em_trj_ease_func_s);
78 emTrjEaseVel = fx.em_trj_ease_vel;
79 emTrjDynUpdateDelay = fx.em_trj_dyn_update_delay;
80 emTrjDynUpdateTargetOnly = fx.em_trj_dyn_update_target_only!=0;
81
82 emFXCreate = Gothic::inst().loadVisualFx(fx.em_fx_create_s);
83 emFXInvestOrigin = fx.em_fx_invest_origin_s;
84 emFXInvestTarget = fx.em_fx_invest_target_s;
85 emFXTriggerDelay = fx.em_fx_trigger_delay<0 ? 0 : uint64_t(fx.em_fx_trigger_delay*1000.f);
86 emFXCreatedOwnTrj = fx.em_fx_create_down_trj!=0;
87 emActionCollDyn = strToColision(fx.em_action_coll_dyn_s); // CREATE, BOUNCE, CREATEONCE, NORESP, COLLIDE
88 emActionCollStat = strToColision(fx.em_action_coll_stat_s); // CREATE, BOUNCE, CREATEONCE, NORESP, COLLIDE, CREATEQUAD
89 emFXCollStat = Gothic::inst().loadVisualFx(fx.em_fx_coll_stat_s);
90 emFXCollDyn = Gothic::inst().loadVisualFx(fx.em_fx_coll_dyn_s);
91 emFXCollDynPerc = Gothic::inst().loadVisualFx(fx.em_fx_coll_dyn_perc_s);
92 emFXCollStatAlign = loadCollisionAlign(fx.em_fx_coll_stat_align_s);
93 emFXCollDynAlign = loadCollisionAlign(fx.em_fx_coll_dyn_align_s);
94 emFXLifeSpan = fx.em_fx_lifespan<0 ? 0 : uint64_t(fx.em_fx_lifespan*1000.f);
95
96 emCheckCollision = fx.em_check_collision;
97 emAdjustShpToOrigin = fx.em_adjust_shp_to_origin;
98 emInvestNextKeyDuration = fx.em_invest_next_key_duration<0 ? 0 : uint64_t(fx.em_invest_next_key_duration*1000.f);
99 emFlyGravity = fx.em_fly_gravity;
100 emSelfRotVel = Parser::loadVec3(fx.em_self_rot_vel_s);
101 for(size_t i=0; i<zenkit::IEffectBase::user_string_count; ++i)
102 userString[i] = fx.user_string[i];
103 lightPresetName = fx.light_preset_name;
104 sfxID = fx.sfx_id;
105 sfxIsAmbient = fx.sfx_is_ambient;
106 sendAssessMagic = fx.send_assess_magic;
107 secsPerDamage = fx.secs_per_damage;
108
109 for(auto& c:emTrjOriginNode)
110 c = char(std::toupper(c));
111
112 static std::string_view keyName[int(SpellFxKey::Count)] = {
113 "OPEN",
114 "INIT",
115 "CAST",
116 "INVEST",
117 "COLLIDE"
118 };
119
120 for(int i=0; i<int(SpellFxKey::Count); ++i) {
121 string_frm kname(name,"_KEY_",keyName[i]);
122 auto id = vm.find_symbol_by_name(kname);
123 if(id==nullptr)
124 continue;
125 auto key = vm.init_instance<zenkit::IParticleEffectEmitKey>(id);
126 keys [i] = Key(*key);
127 hasKey[i] = true;
128 }
129
130 for(int i=1; ; ++i) {
131 string_frm kname(name,"_KEY_INVEST_",i);
132 auto id = vm.find_symbol_by_name(kname);
133 if(id==nullptr)
134 break;
135 auto key = vm.init_instance<zenkit::IParticleEffectEmitKey>(id);
136 // keys[int(SpellFxKey::Invest)] = key;
137 investKeys.emplace_back(*key);
138 }
139 }
140
142 return emFXLifeSpan;
143 }
144
146 return PfxEmitter(owner,visName_S);
147 }
148
149const VisualFx::Key* VisualFx::key(SpellFxKey type, int32_t keyLvl) const {
150 if(type==SpellFxKey::Count)
151 return nullptr;
152
153 if(type==SpellFxKey::Invest && keyLvl>0) {
154 keyLvl--;
155 if(size_t(keyLvl)<investKeys.size())
156 return &investKeys[size_t(keyLvl)];
157 return nullptr;
158 }
159
160 if(!hasKey[int(type)])
161 return nullptr;
162 return &keys[int(type)];
163 }
164
165VisualFx::Trajectory VisualFx::loadTrajectory(std::string_view str) {
166 uint8_t bits = 0;
167 while(str.size()>0) {
168 auto sp = str.find(' ');
169 auto word = str.substr(0,sp);
170 if(word=="NONE") {
171 bits |= 0; // no effect
172 }
173 else if(word=="TARGET") {
174 bits |= Trajectory::Target;
175 }
176 else if(word=="LINE") {
177 bits |= Trajectory::Line;
178 }
179 else if(word=="SPLINE") {
180 bits |= Trajectory::Spline;
181 }
182 else if(word=="RANDOM") {
183 bits |= Trajectory::Random;
184 }
185 else if(word=="FIXED") {
186 bits |= Trajectory::Fixed;
187 }
188 else if(word=="FOLLOW") {
189 bits |= Trajectory::Follow;
190 }
191 else {
192 Log::d("unknown trajectory flag: \"",word,"\"");
193 }
194 if(sp==std::string_view::npos)
195 break;
196 str = str.substr(sp+1);
197 }
198 return Trajectory(bits);
199 }
200
201VisualFx::LoopMode VisualFx::loadLoopmode(std::string_view str) {
202 if(str=="NONE")
204 if(str=="PINGPONG")
205 return LoopMode::PinPong;
206 if(str=="PINGPONG_ONCE")
208 if(str=="HALT")
209 return LoopMode::Halt;
211 }
212
213VisualFx::EaseFunc VisualFx::loadEaseFunc(std::string_view str) {
214 if(str=="LINEAR")
215 return EaseFunc::Linear;
216 return EaseFunc::Linear;
217 }
218
219VisualFx::CollisionAlign VisualFx::loadCollisionAlign(std::string_view str) {
220 if(str=="COLLISIONNORMAL")
222 if(str=="TRAJECTORY")
225 }
226
227VisualFx::Collision VisualFx::strToColision(std::string_view sv) {
228 uint8_t bits = 0;
229 while(sv.size()>0) {
230 auto sp = sv.find(' ');
231 auto word = sv.substr(0,sp);
232 if(word=="COLLIDE") {
233 bits |= Collision::Collide;
234 }
235 else if(word=="CREATE") {
236 bits |= Collision::Create;
237 }
238 else if(word=="CREATEONCE") {
239 bits |= Collision::CreateOnce;
240 }
241 else if(word=="NORESP") {
242 bits |= Collision::NoResp;
243 }
244 else if(word=="NORESP") {
245 bits |= Collision::NoResp;
246 }
247 else if(word=="CREATEQUAD") {
248 bits |= Collision::CreateQuad;
249 }
250 else {
251 Log::d("unknown collision flag: \"",word,"\"");
252 }
253 if(sp==std::string_view::npos)
254 break;
255 sv = sv.substr(sp+1);
256 }
257 return Collision(bits);
258 }
auto loadParticleFx(std::string_view name, bool relaxed=false) -> const ParticleFx *
Definition gothic.cpp:387
static Gothic & inst()
Definition gothic.cpp:249
auto loadVisualFx(std::string_view name) -> const VisualFx *
Definition gothic.cpp:383
std::string sfxID
Definition visualfx.h:90
OptTrajectory emTrjMode
Definition visualfx.h:96
std::string lightPresetName
Definition visualfx.h:88
float emFlyGravity
Definition visualfx.h:94
float visSizeScale
Definition visualfx.h:64
float pfx_velAvg
Definition visualfx.h:84
OptVec3 pfx_shpOffsetVec
Definition visualfx.h:78
std::string pfx_shpDistribType_S
Definition visualfx.h:79
std::string pfx_dirModeTargetFOR_S
Definition visualfx.h:82
std::string pfx_dirFOR_S
Definition visualfx.h:81
float scaleDuration
Definition visualfx.h:65
int sfxIsAmbient
Definition visualfx.h:91
float pfx_lspPartAvg
Definition visualfx.h:85
float pfx_ppsValue
Definition visualfx.h:67
float lightRange
Definition visualfx.h:89
float emTrjEaseVel
Definition visualfx.h:97
bool emCheckCollision
Definition visualfx.h:98
const VisualFx * emCreateFXID
Definition visualfx.h:92
OptVec3 pfx_shpDim
Definition visualfx.h:74
bool pfx_shpIsVolumeChg
Definition visualfx.h:75
Key()=default
float pfx_shpScaleFPS
Definition visualfx.h:76
bool pfx_ppsIsSmoothChg
Definition visualfx.h:68
OptVec3 pfx_flyGravity
Definition visualfx.h:71
std::string pfx_dirModeTargetPos_S
Definition visualfx.h:83
float pfx_shpDistribWalkSpeed
Definition visualfx.h:77
uint64_t emFXLifeSpan
Definition visualfx.h:99
float pfx_visAlphaStart
Definition visualfx.h:86
const ParticleFx * visName
Definition visualfx.h:63
bool pfx_ppsIsLoopingChg
Definition visualfx.h:69
OptVec3 emSelfRotVel
Definition visualfx.h:95
std::string pfx_dirMode_S
Definition visualfx.h:80
float pfx_scTime
Definition visualfx.h:70
float visTexAniFPS
Definition visualfx.h:108
Trajectory emTrjMode
Definition visualfx.h:111
uint64_t emFXLifeSpan
Definition visualfx.h:140
std::string userString[zenkit::IEffectBase::user_string_count]
Definition visualfx.h:147
EaseFunc emTrjEaseFunc
Definition visualfx.h:123
CollisionAlign
Definition visualfx.h:27
const VisualFx * emFXCollDynPerc
Definition visualfx.h:137
VisualFx(const zenkit::IEffectBase &src, zenkit::DaedalusVm &tmpVm, std::string_view name)
Definition visualfx.cpp:57
Material::AlphaFunc visAlphaBlendFunc
Definition visualfx.h:107
PfxEmitter visual(World &owner) const
Definition visualfx.cpp:145
bool visTexAniIsLooping
Definition visualfx.h:109
int32_t emTrjNumKeys
Definition visualfx.h:117
Tempest::Vec3 emSelfRotVel
Definition visualfx.h:146
std::string sfxID
Definition visualfx.h:149
CollisionAlign emFXCollDynAlign
Definition visualfx.h:139
bool emAdjustShpToOrigin
Definition visualfx.h:143
std::string lightPresetName
Definition visualfx.h:148
float emTrjEaseVel
Definition visualfx.h:124
const VisualFx * emFXCreate
Definition visualfx.h:128
Tempest::Vec2 visSize
Definition visualfx.h:105
Collision emActionCollDyn
Definition visualfx.h:133
LoopMode emTrjLoopMode
Definition visualfx.h:122
const VisualFx * emFXCollStat
Definition visualfx.h:135
std::string visName_S
Definition visualfx.h:104
float emTrjTargetRange
Definition visualfx.h:114
bool emFXCreatedOwnTrj
Definition visualfx.h:132
float emTrjAngleElevVar
Definition visualfx.h:119
bool emTrjDynUpdateTargetOnly
Definition visualfx.h:126
float emTrjKeyDistVar
Definition visualfx.h:121
float secsPerDamage
Definition visualfx.h:152
std::string emTrjTargetNode
Definition visualfx.h:113
std::string emTrjOriginNode
Definition visualfx.h:112
float emTrjTargetAzi
Definition visualfx.h:115
CollisionAlign emFXCollStatAlign
Definition visualfx.h:138
uint64_t emFXTriggerDelay
Definition visualfx.h:131
uint64_t emInvestNextKeyDuration
Definition visualfx.h:144
@ Collide
Definition visualfx.h:20
@ CreateQuad
Definition visualfx.h:24
@ CreateOnce
Definition visualfx.h:22
float emTrjTargetElev
Definition visualfx.h:116
bool emCheckCollision
Definition visualfx.h:142
uint64_t effectPrefferedTime() const
Definition visualfx.cpp:141
bool sendAssessMagic
Definition visualfx.h:151
std::string emFXInvestOrigin
Definition visualfx.h:129
float emFlyGravity
Definition visualfx.h:145
bool sfxIsAmbient
Definition visualfx.h:150
int32_t emTrjNumKeysVar
Definition visualfx.h:118
float emTrjDynUpdateDelay
Definition visualfx.h:125
float emTrjAngleHeadVar
Definition visualfx.h:120
Collision emActionCollStat
Definition visualfx.h:134
const VisualFx * emFXCollDyn
Definition visualfx.h:136
const Key * key(SpellFxKey type, int32_t keyLvl=0) const
Definition visualfx.cpp:149
float visAlpha
Definition visualfx.h:106
std::string emFXInvestTarget
Definition visualfx.h:130
Definition world.h:31
SpellFxKey
Definition constants.h:268
Tempest::Vec3 loadVec3(std::string_view src)
Definition parser.cpp:24
Tempest::Vec2 loadVec2(std::string_view src)
Definition parser.cpp:6
Material::AlphaFunc loadAlpha(std::string_view src)
Definition parser.cpp:44