viewing paste Unknown #12142 | Text

Posted on the
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
/*==========================================
 * Standard call when a player connection is closed.
 *------------------------------------------*/
int map_quit(struct map_session_data *sd) {
        int i;
 
        if(!sd->state.active) { //Removing a player that is not active.
                struct auth_node *node = chrif->search(sd->status.account_id);
                if (node && node->char_id == sd->status.char_id &&
                        node->state != ST_LOGOUT)
                        //Except when logging out, clear the auth-connect data immediately.
                        chrif->auth_delete(node->account_id, node->char_id, node->state);
                //Non-active players should not have loaded any data yet (or it was cleared already) so no additional cleanups are needed.
                return 0;
        }
       
        if( sd->expiration_tid != INVALID_TIMER )
                timer->delete(sd->expiration_tid,pc->expiration_timer);
 
        if (sd->npc_timer_id != INVALID_TIMER) //Cancel the event timer.
                npc->timerevent_quit(sd);
 
        if (sd->npc_id)
                npc->event_dequeue(sd);
 
        if( sd->bg_id && !sd->bg_queue.arena ) /* TODO: dump this chunk after bg_queue is fully enabled */
                bg->team_leave(sd,1);
 
        if( sd->state.autotrade && runflag != MAPSERVER_ST_SHUTDOWN && !hChSys.closing )
                pc->autotrade_update(sd,PAUC_REMOVE);
 
        skill->cooldown_save(sd);
        pc->itemcd_do(sd,false);
 
        for( i = 0; i < sd->queues_count; i++ ) {
                struct hQueue *queue;
                if( (queue = script->queue(sd->queues[i])) && queue->onLogOut[0] != '\0' ) {
                        npc->event(sd, queue->onLogOut, 0);
                }
        }
        /* two times, the npc event above may assign a new one or delete others */
        for( i = 0; i < sd->queues_count; i++ ) {
                if( sd->queues[i] != -1 )
                        script->queue_remove(sd->queues[i],sd->status.account_id);
        }
 
        npc->script_event(sd, NPCE_LOGOUT);
 
        //BEGIN Added by Matias [Harmony]
        harmony_logout(sd);
        //END Added
 
        //Unit_free handles clearing the player related data,
        //map->quit handles extra specific data which is related to quitting normally
        //(changing map-servers invokes unit_free but bypasses map->quit)
        if( sd->sc.count ) {
                //Status that are not saved...
                for(i=0; i < SC_MAX; i++){
                        if ( status->get_sc_type(i)&SC_NO_SAVE ) {
                                if ( !sd->sc.data[i] )
                                        continue;
                                switch( i ){
                                        case SC_ENDURE:
                                        case SC_GDSKILL_REGENERATION:
                                                if( !sd->sc.data[i]->val4 )
                                                        break;
                                        default:
                                                status_change_end(&sd->bl, (sc_type)i, INVALID_TIMER);
                                }
                        }
                }
        }
 
        for( i = 0; i < EQI_MAX; i++ ) {
                if( sd->equip_index[ i ] >= 0 )
                        if( !pc->isequip( sd , sd->equip_index[ i ] ) )
                                pc->unequipitem( sd , sd->equip_index[ i ] , 2 );
        }
 
        // Return loot to owner
        if( sd->pd ) pet->lootitem_drop(sd->pd, sd);
 
        if( sd->state.storage_flag == 1 ) sd->state.storage_flag = 0; // No need to Double Save Storage on Quit.
 
        if( sd->ed ) {
                elemental->clean_effect(sd->ed);
                unit->remove_map(&sd->ed->bl,CLR_TELEPORT,ALC_MARK);
        }
 
        if( hChSys.local && map->list[sd->bl.m].channel && idb_exists(map->list[sd->bl.m].channel->users, sd->status.char_id) ) {
                clif->chsys_left(map->list[sd->bl.m].channel,sd);
        }
 
        clif->chsys_quit(sd);
 
        unit->remove_map_pc(sd,CLR_RESPAWN);
 
        if( map->list[sd->bl.m].instance_id >= 0 ) { // Avoid map conflicts and warnings on next login
                int16 m;
                struct point *pt;
                if( map->list[sd->bl.m].save.map )
                        pt = &map->list[sd->bl.m].save;
                else
                        pt = &sd->status.save_point;
 
                if( (m=map->mapindex2mapid(pt->map)) >= 0 ) {
                        sd->bl.m = m;
                        sd->bl.x = pt->x;
                        sd->bl.y = pt->y;
                        sd->mapindex = pt->map;
                }
        }
 
        if( sd->state.vending ) {
                idb_remove(vending->db, sd->status.char_id);
        }
       
        party->booking_delete(sd); // Party Booking [Spiria]
        pc->makesavestatus(sd);
        pc->clean_skilltree(sd);
        chrif->save(sd,1);
        unit->free_pc(sd);
        return 0;
}
Viewed 439 times, submitted by Xgear.