/************************************************************* Move every context on the same coordinate as platform context *************************************************************/ static void platform_move(context_t * platform, const char * map, int x, int y, bool change_map) { context_t * current = context_get_first(); int is_platform; if (entry_read_int(CHARACTER_TABLE, platform->id, &is_platform, CHARACTER_KEY_PLATFORM, nullptr) == RET_NOK) { return; } if (!is_platform) { return; } while (current) { if (current == platform) { current = current->next; continue; } if (platform->pos_tx == current->pos_tx && platform->pos_ty == current->pos_ty && !strcmp(platform->map, current->map)) { do_set_pos(current, map, x, y, change_map); } current = current->next; } }
/************************************** Reset all contexts position information used for smooth animation Called on screen switch **************************************/ void context_reset_all_position() { context_t * ctx = context_get_first(); context_lock_list(); while(ctx != NULL ) { ctx->move_start_tick = 0; ctx = ctx->next; } context_unlock_list(); }
/*********************************************************************** Call aggro script for each context in every npc context aggro dist ***********************************************************************/ void character_update_aggro(context_t * agressor) { context_t * target = nullptr; context_t * npc = nullptr; int aggro_dist; char * aggro_script; if (agressor == nullptr) { return; } if (agressor->map == nullptr) { return; } if (agressor->id == nullptr) { return; } /* If the current context is an NPC it might be an aggressor: compute its aggro */ if (character_get_npc(agressor->id) && agressor->luaVM != nullptr) { if (entry_read_int(CHARACTER_TABLE, agressor->id, &aggro_dist, CHARACTER_KEY_AGGRO_DIST, nullptr) == RET_OK) { if (entry_read_string(CHARACTER_TABLE, agressor->id, &aggro_script, CHARACTER_KEY_AGGRO_SCRIPT, nullptr) == RET_OK) { target = context_get_first(); while (target != nullptr) { /* Skip current context */ if (agressor == target) { target = target->next; continue; } if (target->id == nullptr) { target = target->next; continue; } if (target->map == nullptr) { target = target->next; continue; } /* Skip if not on the same map */ if (strcmp(agressor->map, target->map) != 0) { target = target->next; continue; } execute_aggro(agressor, target, aggro_script, aggro_dist); target = target->next; } free(aggro_script); } } } /* Compute aggro of all other NPC to the current context */ target = agressor; npc = context_get_first(); while (npc != nullptr) { /* Skip current context */ if (target == npc) { npc = npc->next; continue; } if (npc->id == nullptr) { npc = npc->next; continue; } if (npc->map == nullptr) { npc = npc->next; continue; } if (npc->luaVM == nullptr) { npc = npc->next; continue; } /* Skip if not on the same map */ if (strcmp(npc->map, target->map) != 0) { npc = npc->next; continue; } if (entry_read_int(CHARACTER_TABLE, npc->id, &aggro_dist, CHARACTER_KEY_AGGRO_DIST, nullptr) == RET_NOK) { npc = npc->next; continue; } if (entry_read_string(CHARACTER_TABLE, npc->id, &aggro_script, CHARACTER_KEY_AGGRO_SCRIPT, nullptr) == RET_NOK) { npc = npc->next; continue; } execute_aggro(npc, target, aggro_script, aggro_dist); free(aggro_script); npc = npc->next; } }
/************************************* context_free Deep free of a context_t struct *************************************/ void context_free(context_t * context) { context_t * ctx; context_lock_list(); if( context->user_name ) { free(context->user_name); } context->user_name = NULL; context->in_game = false; context->connected = false; if( context->socket != 0) { SDLNet_TCP_Close(context->socket); } context->socket = 0; if( context->socket_data != 0) { SDLNet_TCP_Close(context->socket_data); } context->socket_data = 0; SDL_DestroyMutex(context->send_mutex); if( context->hostname ) { free(context->hostname); } context->hostname = NULL; if( context->character_name ) { free(context->character_name); } context->character_name = NULL; if( context->map ) { free(context->map); } context->map = NULL; if( context->type ) { free(context->type); } context->type = NULL; if( context->selection.id ) { free(context->selection.id); } context->selection.id = NULL; context->selection.map_coord[0] = -1; context->selection.map_coord[1] = -1; if( context->selection.map ) { free(context->selection.map); } context->selection.map = NULL; if( context->selection.inventory ) { free(context->selection.inventory); } context->selection.inventory = NULL; if( context->selection.equipment ) { free(context->selection.equipment); } context->selection.equipment = NULL; if( context->prev_map ) { free(context->prev_map); } context->prev_map = NULL; if( context->luaVM != NULL) { lua_close(context->luaVM); } if( context->cond != NULL) { SDL_DestroyCond(context->cond); } if( context->cond_mutex != NULL) { SDL_DestroyMutex(context->cond_mutex); } /* First context of the list */ if( context->previous == NULL ) { context_list_start = context->next; if( context->next != NULL) { context->next->previous = NULL; } } else { context->previous->next = context->next; if( context->next != NULL) { context->next->previous = context->previous; } } /* Remove this context from other context's selection */ ctx = context_list_start; while( ctx != NULL ) { if( context->id && ctx->selection.id ) { if (strcmp(context->id,ctx->selection.id)==0) { ctx->selection.id = NULL; } } ctx = ctx->next; } if( context->id ) { free(context->id); } context->id = NULL; /* Remove this context from the list */ if( context == context_get_first() ) { context_list_start = context->next; } else { ctx = context_list_start; while( ctx != NULL ) { if( ctx->next == context ) { ctx->next = context->next; break; } ctx = ctx->next; } } free(context); context_unlock_list(); }