Pol  Revision:cb584c9
bowsalut.cpp
Go to the documentation of this file.
1 
9 #include <string.h>
10 #include <string>
11 
12 #include "../clib/cfgelem.h"
13 #include "../clib/cfgfile.h"
14 #include "../clib/clib.h"
15 #include "../clib/fileutil.h"
16 #include "../clib/logfacility.h"
17 #include "../clib/rawtypes.h"
18 #include "../clib/stlutil.h"
19 #include "action.h"
20 #include "globals/uvars.h"
21 #include "mobile/charactr.h"
22 #include "network/client.h"
23 #include "network/packetdefs.h"
24 #include "pktin.h"
25 #include "uworld.h"
26 
27 namespace Pol
28 {
29 namespace Core
30 {
32  : valid( false ),
33  action( 0 ),
34  framecount( 0 ),
35  repeatcount( 0 ),
36  backward( 0 ),
37  repeatflag( 0 ),
38  delay( 0 )
39 {
40 }
41 MobileTranslate::NewAnimDef::NewAnimDef() : valid( false ), anim( 0 ), action( 0 ), subaction( 0 )
42 {
43 }
45 {
46  memset( &old_anim, 0, sizeof( old_anim ) );
47  memset( &new_anim, 0, sizeof( new_anim ) );
48 }
49 bool MobileTranslate::has_graphic( u16 graphic ) const
50 {
51  return std::find( graphics.begin(), graphics.end(), graphic ) != graphics.end();
52 }
53 
55 {
56  return sizeof( MobileTranslate ) + 3 * sizeof( u16* ) + graphics.capacity() * sizeof( u16 );
57 }
58 
59 
60 UACTION str_to_action( Clib::ConfigElem& elem, const std::string& str )
61 {
62  unsigned short tmp = static_cast<unsigned short>( strtoul( str.c_str(), nullptr, 0 ) );
63 
64  if ( UACTION_IS_VALID( tmp ) )
65  {
66  return static_cast<UACTION>( tmp );
67  }
68  else
69  {
70  elem.throw_error( "Animation value of " + str + " is out of range" );
71  }
72 }
73 
74 void load_anim_xlate_cfg( bool /*reload*/ )
75 {
76  memset( &Core::gamestate.mount_action_xlate, 0, sizeof( Core::gamestate.mount_action_xlate ) );
78 
79  if ( Clib::FileExists( "config/animxlate.cfg" ) )
80  {
81  Clib::ConfigFile cf( "config/animxlate.cfg", "OnMount MobileType" );
82  Clib::ConfigElem elem;
83  while ( cf.read( elem ) )
84  {
85  if ( elem.type_is( "OnMount" ) )
86  {
87  std::string from_str, to_str;
88  while ( elem.remove_first_prop( &from_str, &to_str ) )
89  {
90  UACTION from = str_to_action( elem, from_str );
91  UACTION to = str_to_action( elem, to_str );
93  }
94  }
95  else if ( elem.type_is( "MobileType" ) )
96  {
97  MobileTranslate mobiletype;
98  std::string key, value;
99  while ( elem.has_prop( "Graphic" ) )
100  {
101  mobiletype.graphics.push_back( elem.remove_ushort( "Graphic" ) );
102  }
103  std::sort( mobiletype.graphics.begin(), mobiletype.graphics.end() );
104  mobiletype.supports_mount = elem.remove_bool( "MountTranslation", false );
105 
106  auto split_str = []( const std::string& source ) -> std::vector<std::string> {
107  ISTRINGSTREAM is( source );
108  std::string tmp;
109  std::vector<std::string> result;
110  while ( is >> tmp )
111  {
112  if ( tmp.empty() )
113  continue;
114  if ( tmp.at( 0 ) == '#' )
115  break;
116  result.push_back( tmp );
117  tmp.clear();
118  }
119  return result;
120  };
121  for ( int id = 0; id <= ACTION__HIGHEST; ++id )
122  {
123  std::string entry( "OldAnim" + std::to_string( id ) );
124  if ( elem.has_prop( entry.c_str() ) )
125  {
126  std::vector<std::string> values = split_str( elem.remove_string( entry.c_str() ) );
127  if ( !values.empty() )
128  {
129  mobiletype.old_anim[id].action =
130  static_cast<u16>( strtoul( values[0].c_str(), nullptr, 0 ) );
131  mobiletype.old_anim[id].valid = true;
132  mobiletype.old_anim[id].framecount = 5;
133  mobiletype.old_anim[id].repeatcount = 1;
134  mobiletype.old_anim[id].backward = 0;
135  mobiletype.old_anim[id].repeatflag = 0;
136  mobiletype.old_anim[id].delay = 1;
137  }
138  if ( values.size() > 1 )
139  mobiletype.old_anim[id].framecount =
140  static_cast<u16>( strtoul( values[1].c_str(), nullptr, 0 ) );
141  if ( values.size() > 2 )
142  mobiletype.old_anim[id].repeatcount =
143  static_cast<u16>( strtoul( values[2].c_str(), nullptr, 0 ) );
144  if ( values.size() > 3 )
145  mobiletype.old_anim[id].backward =
146  static_cast<u8>( strtoul( values[3].c_str(), nullptr, 0 ) );
147  if ( values.size() > 4 )
148  mobiletype.old_anim[id].repeatflag =
149  static_cast<u8>( strtoul( values[4].c_str(), nullptr, 0 ) );
150  if ( values.size() > 5 )
151  mobiletype.old_anim[id].delay =
152  static_cast<u8>( strtoul( values[5].c_str(), nullptr, 0 ) );
153  }
154  entry = "NewAnim" + std::to_string( id );
155  if ( elem.has_prop( entry.c_str() ) )
156  {
157  std::vector<std::string> values = split_str( elem.remove_string( entry.c_str() ) );
158  if ( !values.empty() )
159  {
160  mobiletype.new_anim[id].anim =
161  static_cast<u16>( strtoul( values[0].c_str(), nullptr, 0 ) );
162  mobiletype.new_anim[id].valid = true;
163  mobiletype.new_anim[id].action = 0;
164  mobiletype.new_anim[id].subaction = 0;
165  }
166  if ( values.size() > 1 )
167  mobiletype.new_anim[id].action =
168  static_cast<u16>( strtoul( values[1].c_str(), nullptr, 0 ) );
169  if ( values.size() > 2 )
170  mobiletype.new_anim[id].subaction =
171  static_cast<u8>( strtoul( values[2].c_str(), nullptr, 0 ) );
172  }
173  }
174  Core::gamestate.animation_translates[elem.rest()] = mobiletype;
175  }
176  }
177  }
178 }
179 
181  unsigned short framecount /*=0x05*/,
182  unsigned short repeatcount /*=0x01*/,
183  DIRECTION_FLAG_OLD backward /*=PKTOUT_6E::FORWARD*/,
184  REPEAT_FLAG_OLD repeatflag /*=PKTOUT_6E::NOREPEAT*/,
185  unsigned char delay /*=0x01*/ )
186 {
187  bool build = false;
190  if ( !build ) // only build if client in range
191  {
193  oldanim.valid = true;
194  oldanim.action = static_cast<u16>( action );
195  oldanim.framecount = framecount;
196  oldanim.repeatcount = repeatcount;
197  oldanim.backward = static_cast<u8>( backward );
198  oldanim.repeatflag = static_cast<u8>( repeatflag );
199  oldanim.delay = delay;
201  bool supports_mount = true;
202  build = true;
203  MobileTranslate const* translate = nullptr;
204  for ( const auto& translates : Core::gamestate.animation_translates )
205  {
206  if ( translates.second.has_graphic( obj->graphic ) )
207  {
208  translate = &translates.second;
209  supports_mount = translate->supports_mount;
210  break;
211  }
212  }
213 
214  if ( obj->on_mount() && supports_mount )
215  {
216  if ( action < ACTION_RIDINGHORSE1 || action > ACTION_RIDINGHORSE7 )
217  {
218  UACTION new_action = Core::gamestate.mount_action_xlate[action];
219  if ( new_action == 0 )
220  return;
221  action = new_action;
222  oldanim.action = static_cast<u16>( new_action );
223  }
224  }
225  if ( translate != nullptr )
226  {
227  oldanim = translate->old_anim[action];
228  newanim = translate->new_anim[action];
229  }
230  else
231  {
232  ERROR_PRINT << "Warning: undefined animXlate.cfg entry for graphic 0x"
233  << fmt::hexu( obj->graphic ) << "\n";
234  }
235 
236  msg.update( newanim.anim, newanim.action, newanim.subaction, oldanim.action,
237  oldanim.framecount, oldanim.repeatcount,
238  static_cast<DIRECTION_FLAG_OLD>( oldanim.backward ),
239  static_cast<REPEAT_FLAG_OLD>( oldanim.repeatflag ), oldanim.delay, oldanim.valid,
240  newanim.valid );
241  }
242 
243  msg.Send( zonechr->client );
244  } );
245 }
246 
248 {
249  if ( stricmp( (const char*)cmd->data, "bow" ) == 0 )
251  else if ( stricmp( (const char*)cmd->data, "salute" ) == 0 )
253 }
254 }
255 }
unsigned char u8
Definition: rawtypes.h:25
void update(u16 anim, u16 action, u8 subaction, u16 action_old, u16 framecount_old, u16 repeat_old, Core::DIRECTION_FLAG_OLD backward_old, Core::REPEAT_FLAG_OLD repeat_flag_old, u8 delay_old, bool oldanim_valid, bool newanim_valid)
Definition: packetdefs.cpp:282
bool has_graphic(u16 graphic) const
Definition: bowsalut.cpp:49
bool remove_first_prop(std::string *propname, std::string *value)
Definition: cfgfile.cpp:100
std::string remove_string(const char *propname)
Definition: cfgfile.cpp:381
NewAnimDef new_anim[ACTION__HIGHEST+1]
Definition: action.h:111
Network::Client * client
Definition: charactr.h:871
std::vector< u16 > graphics
Definition: action.h:109
bool on_mount() const
Definition: charactr.cpp:1490
UACTION mount_action_xlate[ACTION__HIGHEST+1]
Definition: uvars.h:217
Mobile::Character * chr
Definition: client.h:182
OldAnimDef old_anim[ACTION__HIGHEST+1]
Definition: action.h:110
unsigned short u16
Definition: rawtypes.h:26
const char * rest() const
Definition: cfgfile.cpp:71
POL_NORETURN void throw_error(const std::string &errmsg) const
Definition: cfgfile.cpp:285
std::map< std::string, MobileTranslate > animation_translates
Definition: uvars.h:218
REPEAT_FLAG_OLD
Definition: action.h:78
void load_anim_xlate_cfg(bool)
Definition: bowsalut.cpp:74
GameState gamestate
Definition: uvars.cpp:74
static void InVisualRange(const UObject *obj, F &&f)
Definition: uworld.h:245
void handle_action(Network::Client *client, PKTIN_12 *cmd)
Definition: bowsalut.cpp:247
UACTION str_to_action(Clib::ConfigElem &elem, const std::string &str)
Definition: bowsalut.cpp:60
#define ISTRINGSTREAM
Definition: stlutil.h:73
bool type_is(const char *name) const
Definition: cfgfile.cpp:95
bool has_prop(const char *propname) const
Definition: cfgfile.cpp:112
u8 data[300]
Definition: pktin.h:185
unsigned short remove_ushort(const char *propname)
Definition: cfgfile.cpp:318
int translate(const std::string &name, TRANSLATION *table)
Definition: npctmpl.cpp:33
virtual void Send(Client *client) POL_OVERRIDE
Definition: packetdefs.cpp:325
#define ERROR_PRINT
Definition: logfacility.h:230
bool FileExists(const char *filename)
Definition: fileutil.cpp:118
bool read(ConfigElem &elem)
Definition: cfgfile.cpp:1015
DIRECTION_FLAG_OLD
Definition: action.h:73
bool UACTION_IS_VALID(unsigned short action)
Definition: action.h:67
Definition: berror.cpp:12
bool remove_bool(const char *propname)
Definition: cfgfile.cpp:426
void send_action_to_inrange(const Mobile::Character *obj, UACTION action, unsigned short framecount=0x05, unsigned short repeatcount=0x01, DIRECTION_FLAG_OLD backward=FORWARD, REPEAT_FLAG_OLD repeatflag=NOREPEAT, unsigned char delay=0x01)
Definition: bowsalut.cpp:180
size_t estimateSize() const
Definition: bowsalut.cpp:54