1 #pragma once
2 
3 //********************************************************************************************
4 //*
5 //*    This file is part of Egoboo.
6 //*
7 //*    Egoboo is free software: you can redistribute it and/or modify it
8 //*    under the terms of the GNU General Public License as published by
9 //*    the Free Software Foundation, either version 3 of the License, or
10 //*    (at your option) any later version.
11 //*
12 //*    Egoboo is distributed in the hope that it will be useful, but
13 //*    WITHOUT ANY WARRANTY; without even the implied warranty of
14 //*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 //*    General Public License for more details.
16 //*
17 //*    You should have received a copy of the GNU General Public License
18 //*    along with Egoboo.  If not, see <http://www.gnu.org/licenses/>.
19 //*
20 //********************************************************************************************
21 
22 /// @file ChrList.h
23 /// @brief Routines for character list management
24 
25 #include "egoboo_object.h"
26 
27 #include "char.h"
28 
29 //--------------------------------------------------------------------------------------------
30 // testing macros
31 //--------------------------------------------------------------------------------------------
32 
33 #define VALID_CHR_RANGE( ICHR )    ( ((ICHR) < MAX_CHR) && ((ICHR) >= 0) )
34 #define DEFINED_CHR( ICHR )        ( VALID_CHR_RANGE( ICHR ) && ALLOCATED_PBASE ( POBJ_GET_PBASE(ChrList.lst + (ICHR)) ) && !TERMINATED_PBASE ( POBJ_GET_PBASE(ChrList.lst + (ICHR)) ) )
35 #define ALLOCATED_CHR( ICHR )      ( VALID_CHR_RANGE( ICHR ) && ALLOCATED_PBASE ( POBJ_GET_PBASE(ChrList.lst + (ICHR)) ) )
36 #define ACTIVE_CHR( ICHR )         ( VALID_CHR_RANGE( ICHR ) && ACTIVE_PBASE    ( POBJ_GET_PBASE(ChrList.lst + (ICHR)) ) )
37 #define WAITING_CHR( ICHR )        ( VALID_CHR_RANGE( ICHR ) && WAITING_PBASE   ( POBJ_GET_PBASE(ChrList.lst + (ICHR)) ) )
38 #define TERMINATED_CHR( ICHR )     ( VALID_CHR_RANGE( ICHR ) && TERMINATED_PBASE( POBJ_GET_PBASE(ChrList.lst + (ICHR)) ) )
39 
40 #define GET_INDEX_PCHR( PCHR )      ((NULL == (PCHR)) ? MAX_CHR : (size_t)GET_INDEX_POBJ( PCHR, MAX_CHR ))
41 #define GET_REF_PCHR( PCHR )        ((CHR_REF)GET_INDEX_PCHR( PCHR ))
42 #define DEFINED_PCHR( PCHR )        ( VALID_CHR_PTR( PCHR ) && ALLOCATED_PBASE ( POBJ_GET_PBASE(PCHR) ) && !TERMINATED_PBASE ( POBJ_GET_PBASE(PCHR) ) )
43 #define VALID_CHR_PTR( PCHR )       ( (NULL != (PCHR)) && VALID_CHR_RANGE( GET_REF_POBJ( PCHR, MAX_CHR) ) )
44 #define ALLOCATED_PCHR( PCHR )      ( VALID_CHR_PTR( PCHR ) && ALLOCATED_PBASE( POBJ_GET_PBASE(PCHR) ) )
45 #define ACTIVE_PCHR( PCHR )         ( VALID_CHR_PTR( PCHR ) && ACTIVE_PBASE( POBJ_GET_PBASE(PCHR) ) )
46 #define TERMINATED_PCHR( PCHR )     ( VALID_CHR_PTR( PCHR ) && TERMINATED_PBASE( POBJ_GET_PBASE(PCHR) ) )
47 
48 // Macros to determine whether the character is in the game or not.
49 // If objects are being spawned, then any object that is just "defined" is treated as "in game"
50 #define INGAME_CHR_BASE(ICHR)       ( VALID_CHR_RANGE( ICHR ) && ACTIVE_PBASE( POBJ_GET_PBASE(ChrList.lst + (ICHR)) ) && ON_PBASE( POBJ_GET_PBASE(ChrList.lst + (ICHR)) ) )
51 #define INGAME_PCHR_BASE(PCHR)      ( VALID_CHR_PTR( PCHR ) && ACTIVE_PBASE( POBJ_GET_PBASE(PCHR) ) && ON_PBASE( POBJ_GET_PBASE(PCHR) ) )
52 
53 #define INGAME_CHR(ICHR)            ( (ego_object_spawn_depth) > 0 ? DEFINED_CHR(ICHR) : INGAME_CHR_BASE(ICHR) )
54 #define INGAME_PCHR(PCHR)           ( (ego_object_spawn_depth) > 0 ? DEFINED_PCHR(PCHR) : INGAME_PCHR_BASE(PCHR) )
55 
56 //--------------------------------------------------------------------------------------------
57 // looping macros
58 //--------------------------------------------------------------------------------------------
59 
60 // Macros automate looping through the ChrList. This hides code which defers the creation and deletion of
61 // objects until the loop terminates, so tha the length of the list will not change during the loop.
62 #define CHR_BEGIN_LOOP_ACTIVE(IT, PCHR)  {int IT##_internal; int chr_loop_start_depth = chr_loop_depth; chr_loop_depth++; for(IT##_internal=0;IT##_internal<ChrList.used_count;IT##_internal++) { CHR_REF IT; chr_t * PCHR = NULL; IT = (CHR_REF)ChrList.used_ref[IT##_internal]; if(!ACTIVE_CHR (IT)) continue; PCHR =  ChrList.lst + IT;
63 #define CHR_END_LOOP() } chr_loop_depth--; EGOBOO_ASSERT(chr_loop_start_depth == chr_loop_depth); ChrList_cleanup(); }
64 
65 //--------------------------------------------------------------------------------------------
66 // external variables
67 //--------------------------------------------------------------------------------------------
68 
69 DECLARE_LIST_EXTERN( chr_t, ChrList, MAX_CHR );
70 
71 extern int chr_loop_depth;
72 
73 //--------------------------------------------------------------------------------------------
74 // Function prototypes
75 //--------------------------------------------------------------------------------------------
76 
77 void    ChrList_init();
78 void    ChrList_dtor();
79 
80 CHR_REF ChrList_allocate( const CHR_REF override );
81 
82 bool_t  ChrList_free_one( const CHR_REF ichr );
83 void    ChrList_free_all();
84 
85 bool_t  ChrList_add_used( const CHR_REF ichr );
86 
87 void    ChrList_update_used();
88 
89 void    ChrList_cleanup();
90 
91 bool_t ChrList_add_activation( CHR_REF ichr );
92 bool_t ChrList_add_termination( CHR_REF ichr );