/*********************************** item_set_anim_from a file name Input: - file name Output: ***********************************/ static int l_item_set_anim(lua_State* p_pLuaState) { item_t * l_pItem; lua_getglobal(p_pLuaState, "current_item"); l_pItem = (item_t*) lua_touserdata(p_pLuaState, -1); lua_pop(p_pLuaState, 1); const char * l_pFileName; l_pFileName = luaL_checkstring(p_pLuaState, -1); anim_t ** l_pAnimArray; const char * l_pSpriteNameArray[2] = { l_pFileName, nullptr }; l_pAnimArray = imageDB_get_anim_array(context_get_player(), (const char **) l_pSpriteNameArray); item_set_anim_array(l_pItem, l_pAnimArray); return 0; // number of results }
/*********************************** item_set_anim_from_context Input: - ID of context - entry name in context file Output: ***********************************/ static int l_item_set_anim_from_context(lua_State* p_pLuaState) { item_t * l_pItem; lua_getglobal(p_pLuaState, "current_item"); l_pItem = (item_t*) lua_touserdata(p_pLuaState, -1); lua_pop(p_pLuaState, 1); const char * l_pId = ""; l_pId = luaL_checkstring(p_pLuaState, -4); int l_IsMoving = 0; l_IsMoving = luaL_checkint(p_pLuaState, -3); const char * l_pMainOrientation = ""; l_pMainOrientation = luaL_checkstring(p_pLuaState, -2); const char * l_pSecondaryOrientation = ""; l_pSecondaryOrientation = luaL_checkstring(p_pLuaState, -1); // reset previous anim l_pItem->anim.list = nullptr; l_pItem->anim.num = 0; // Try regular moving flag with main orientation const char * l_pKey = getKey(l_IsMoving, l_pMainOrientation[0]); anim_t ** l_pAnimArray = getAnimArray(l_pId, l_pKey); // Try secondary orientation if (l_pAnimArray == nullptr) { l_pKey = getKey(l_IsMoving, l_pSecondaryOrientation[0]); l_pAnimArray = getAnimArray(l_pId, l_pKey); } // Auto-flip if (l_pAnimArray == nullptr) { char l_FlipOrientation = flip(l_pMainOrientation[0]); const char * l_pKey = getKey(l_IsMoving, l_FlipOrientation); l_pAnimArray = getAnimArray(l_pId, l_pKey); } if (l_pAnimArray == nullptr) { char l_FlipOrientation = flip(l_pSecondaryOrientation[0]); l_pKey = getKey(l_IsMoving, l_FlipOrientation); l_pAnimArray = getAnimArray(l_pId, l_pKey); } // Try opposite moving flag // main orientation if (l_pAnimArray == nullptr) { l_IsMoving = !l_IsMoving; l_pKey = getKey(l_IsMoving, l_pMainOrientation[0]); l_pAnimArray = getAnimArray(l_pId, l_pKey); } // secondary orientation if (l_pAnimArray == nullptr) { l_pKey = getKey(l_IsMoving, l_pSecondaryOrientation[0]); l_pAnimArray = getAnimArray(l_pId, l_pKey); } // Try default sprite if (l_pAnimArray == nullptr) { l_pAnimArray = getAnimArray(l_pId, CHARACTER_KEY_SPRITE); } if (l_pAnimArray == nullptr) { werr(LOGDESIGNER, "LUA item_set_anim_from_context: Failed to find anim for %s", l_pId); } else { item_set_anim_array(l_pItem, l_pAnimArray); } return 0; // number of results }
/********************************** Draw a single sprite if image_file_name is not NULL, this file is used as an image rather than the normal sprite image **********************************/ static void set_up_sprite(context_t * ctx, const char * image_file_name) { anim_t ** sprite_list; anim_t ** sprite_move_list; item_t * item; int px; int py; int opx; int opy; Uint32 current_time; int angle; int flip; int force_flip; int move_status; char * zoom_str = NULL; double zoom = 1.0; int sprite_align = ALIGN_CENTER; int sprite_offset_y = 0; bool force_position = false; context_t * player_context = context_get_player(); if( ctx->map == NULL ) { return; } if( ctx->in_game == false ) { return; } if( strcmp(ctx->map,player_context->map)) { return; } item = item_list_add(&item_list); current_time = sdl_get_global_time(); // Force position when the player has changed map if( change_map == true ) { ctx->move_start_tick = current_time; ctx->animation_tick = current_time; force_position = true; } // Force position when this context has changed map if( ctx->change_map == true ) { ctx->move_start_tick = current_time; ctx->animation_tick = current_time; ctx->change_map = false; force_position = true; } if( ctx->animation_tick == 0 ) { ctx->animation_tick = current_time; } if( ctx->cur_pos_px == INT_MAX || ctx->cur_pos_py == INT_MAX ) { force_position = true; } // Detect sprite movement, initiate animation if( ctx->pos_changed && force_position == false ) { ctx->pos_changed = false; ctx->move_start_tick = current_time; ctx->start_pos_px = ctx->cur_pos_px; ctx->start_pos_py = ctx->cur_pos_py; /* flip need to remember previous direction to avoid resetting a east -> west flip when a sprite goes to north for instance. On the contrary rotation must not remember previous state, or the rotation will be wrong. Hence the distinction between orientation (no memory) and direction (memory). */ ctx->orientation = 0; // Compute direction if( ctx->pos_tx > ctx->prev_pos_tx ) { ctx->direction &= ~WEST; ctx->direction |= EAST; ctx->orientation |= EAST; } if( ctx->pos_tx < ctx->prev_pos_tx ) { ctx->direction &= ~EAST; ctx->direction |= WEST; ctx->orientation |= WEST; } if( ctx->pos_ty > ctx->prev_pos_ty ) { ctx->direction &= ~NORTH; ctx->direction |= SOUTH; ctx->orientation |= SOUTH; } if( ctx->pos_ty < ctx->prev_pos_ty ) { ctx->direction &= ~SOUTH; ctx->direction |= NORTH; ctx->orientation |= NORTH; } } // Select sprite to display sprite_list = select_sprite(ctx,image_file_name); if( sprite_list == NULL ) { return; } if( sprite_list[0] == NULL ) { free(sprite_list); return; } sprite_move_list = select_sprite_move(ctx,image_file_name); // Get position in pixel px = map_t2p_x(ctx->pos_tx,ctx->pos_ty,default_layer); py = map_t2p_y(ctx->pos_tx,ctx->pos_ty,default_layer); // Get per sprite zoom if(entry_read_string(CHARACTER_TABLE,ctx->id,&zoom_str,CHARACTER_KEY_ZOOM,NULL) == RET_OK ) { zoom = atof(zoom_str); free(zoom_str); } // Align sprite on tile entry_read_int(CHARACTER_TABLE,ctx->id,&sprite_align,CHARACTER_KEY_ALIGN,NULL); if( sprite_align == ALIGN_CENTER ) { px -= ((sprite_list[0]->w*default_layer->map_zoom*zoom)-default_layer->tile_width)/2; py -= ((sprite_list[0]->h*default_layer->map_zoom*zoom)-default_layer->tile_height)/2; } if( sprite_align == ALIGN_LOWER ) { px -= ((sprite_list[0]->w*default_layer->map_zoom*zoom)-default_layer->tile_width)/2; py -= (sprite_list[0]->h*default_layer->map_zoom*zoom)-default_layer->tile_height ; } // Add Y offset entry_read_int(CHARACTER_TABLE,ctx->id,&sprite_offset_y,CHARACTER_KEY_OFFSET_Y,NULL); py += sprite_offset_y; // Set sprite to item item_set_anim_start_tick(item,ctx->animation_tick); if( force_position == true ) { ctx->start_pos_px = px; ctx->cur_pos_px = px; ctx->start_pos_py = py; ctx->cur_pos_py = py; } opx = ctx->start_pos_px; opy = ctx->start_pos_py; item_set_move(item,opx,opy,px,py,ctx->move_start_tick,VIRTUAL_ANIM_DURATION); item_set_save_coordinate(item,&ctx->cur_pos_px,&ctx->cur_pos_py); item_set_anim_array(item,sprite_list); free(sprite_list); item_set_anim_move_array(item,sprite_move_list); free(sprite_move_list); // Get rotation configuration angle = 0; if( ctx->orientation & NORTH && ctx->orientation & EAST ) { entry_read_int(CHARACTER_TABLE,ctx->id,&angle,CHARACTER_KEY_DIR_NE_ROT,NULL); item_set_angle(item,(double)angle); } else if ( ctx->orientation & SOUTH && ctx->orientation & EAST ) { entry_read_int(CHARACTER_TABLE,ctx->id,&angle,CHARACTER_KEY_DIR_SE_ROT,NULL); item_set_angle(item,(double)angle); } else if ( ctx->orientation & SOUTH && ctx->orientation & WEST ) { entry_read_int(CHARACTER_TABLE,ctx->id,&angle,CHARACTER_KEY_DIR_SW_ROT,NULL); item_set_angle(item,(double)angle); } else if ( ctx->orientation & NORTH && ctx->orientation & WEST ) { entry_read_int(CHARACTER_TABLE,ctx->id,&angle,CHARACTER_KEY_DIR_NW_ROT,NULL); item_set_angle(item,(double)angle); } else if ( ctx->orientation & NORTH ) { entry_read_int(CHARACTER_TABLE,ctx->id,&angle,CHARACTER_KEY_DIR_N_ROT,NULL); item_set_angle(item,(double)angle); } else if ( ctx->orientation & SOUTH ) { entry_read_int(CHARACTER_TABLE,ctx->id,&angle,CHARACTER_KEY_DIR_S_ROT,NULL); item_set_angle(item,(double)angle); } else if ( ctx->orientation & WEST ) { entry_read_int(CHARACTER_TABLE,ctx->id,&angle,CHARACTER_KEY_DIR_W_ROT,NULL); item_set_angle(item,(double)angle); } else if ( ctx->orientation & EAST ) { entry_read_int(CHARACTER_TABLE,ctx->id,&angle,CHARACTER_KEY_DIR_E_ROT,NULL); item_set_angle(item,(double)angle); } // Get flip configuration force_flip = 0; entry_read_int(CHARACTER_TABLE,ctx->id,&force_flip,CHARACTER_KEY_FORCE_FLIP,NULL); move_status = ctx->direction; if( force_flip == true ) { move_status = ctx->orientation; } flip = 0; if( angle == 0 ) { if( move_status & NORTH ) { entry_read_int(CHARACTER_TABLE,ctx->id,&flip,CHARACTER_KEY_DIR_N_FLIP,NULL); } if( move_status & SOUTH ) { entry_read_int(CHARACTER_TABLE,ctx->id,&flip,CHARACTER_KEY_DIR_S_FLIP,NULL); } if( move_status & WEST ) { entry_read_int(CHARACTER_TABLE,ctx->id,&flip,CHARACTER_KEY_DIR_W_FLIP,NULL); } if( move_status & EAST ) { entry_read_int(CHARACTER_TABLE,ctx->id,&flip,CHARACTER_KEY_DIR_E_FLIP,NULL); } switch(flip) { case 1: item_set_flip(item,SDL_FLIP_HORIZONTAL); break; case 2: item_set_flip(item,SDL_FLIP_VERTICAL); break; case 3: item_set_flip(item,SDL_FLIP_HORIZONTAL|SDL_FLIP_VERTICAL); break; default: item_set_flip(item,SDL_FLIP_NONE); } } item_set_click_left(item,cb_select_sprite,ctx->id,NULL); item_set_click_right(item,cb_redo_sprite,item,NULL); item_set_zoom_x(item,zoom * default_layer->map_zoom ); item_set_zoom_y(item,zoom * default_layer->map_zoom ); }