Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <onidev/math/vec2.h>
- #include <tuple>
- #include <fstream>
- #include <iostream>
- #include <typeinfo>
- // index sequence only
- template <std::size_t ...>
- struct indexSequence { };
- template <std::size_t N, std::size_t ... Next>
- struct indexSequenceHelper : public indexSequenceHelper<N-1U, N-1U, Next...> { };
- template <std::size_t ... Next>
- struct indexSequenceHelper<0U, Next ... >
- { using type = indexSequence<Next ... >; };
- template <std::size_t N>
- using makeIndexSequence = typename indexSequenceHelper<N>::type;
- namespace centauri
- {
- template<int frames, unsigned... states>
- struct MonsterMountState
- {
- std::array<od::Vec2, frames> offsets;
- };
- template<typename Monster, typename... States>
- struct MonsterMount
- {
- std::tuple<States...> states;
- bool offsets_loaded = false;
- MonsterMount() {}
- od::Vec2 offset(unsigned state, int frame) const {
- return offset(state, frame, makeIndexSequence<sizeof...(States)>{});
- }
- template<std::size_t N>
- void loadOffsets(const std::string& root, const std::array<std::string, N>& t) {
- if(!offsets_loaded) {
- setOffsets(root, t, makeIndexSequence<sizeof...(States)>{});
- offsets_loaded = true;
- }
- }
- private:
- using expand = int[];
- template <std::size_t... StateIdx>
- od::Vec2 offset(unsigned state, int frame, indexSequence<StateIdx...>) const
- {
- od::Vec2 offset{};
- (void) expand {0, offsetFromState(
- std::get<StateIdx>(states), state, frame, offset)... };
- return offset;
- }
- template <int frames, unsigned... states>
- int offsetFromState(
- MonsterMountState<frames, states...> const &mms,
- unsigned state, int frame, od::Vec2 &offset) const
- {
- (void) expand { 0, (state == states ?
- offset = mms.offsets[frame % mms.offsets.size()], 0 : 0)... };
- return 0;
- }
- // load offsets from txt files
- template <std::size_t N, std::size_t... StateIdx>
- void setOffsets(
- const std::string& root,
- const std::array<std::string, N>& t,
- indexSequence<StateIdx...>)
- {
- (void) expand {0, loadOffsetsImpl(
- std::get<StateIdx>(states).offsets, root + t.at(StateIdx))... };
- }
- template<std::size_t N>
- int loadOffsetsImpl(
- std::array<od::Vec2,N>& t, const std::string& fname)
- {
- //std::cout << fname << std::endl;
- std::ifstream f(fname);
- if(!f.is_open()) {
- return 0;
- }
- // read global offset
- od::Vec2 w; {
- char sep;
- float x(0), y(0);
- f >> x >> sep >> y;
- w = od::Vec2(x, y);
- }
- for(std::size_t i=0; i<N; ++i) {
- char sep;
- float x(0), y(0);
- f >> x >> sep >> y;
- t[i] = w + od::Vec2(x, y);
- }
- return 0;
- }
- };
- }
- using centauri::MonsterMount;
- using centauri::MonsterMountState;
Advertisement
Add Comment
Please, Sign In to add comment