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 EncList.h
23 /// @brief Routines for enchant list management
24 
25 #include "egoboo_object.h"
26 
27 #include "enchant.h"
28 
29 //--------------------------------------------------------------------------------------------
30 // testing macros
31 //--------------------------------------------------------------------------------------------
32 
33 #define VALID_ENC_RANGE( IENC )    ( ((IENC) < MAX_ENC) && ((IENC) >= 0) )
34 #define DEFINED_ENC( IENC )        ( VALID_ENC_RANGE( IENC ) && ALLOCATED_PBASE ( POBJ_GET_PBASE(EncList.lst + (IENC)) ) && !TERMINATED_PBASE ( POBJ_GET_PBASE(EncList.lst + (IENC)) ) )
35 #define ALLOCATED_ENC( IENC )      ( VALID_ENC_RANGE( IENC ) && ALLOCATED_PBASE ( POBJ_GET_PBASE(EncList.lst + (IENC)) ) )
36 #define ACTIVE_ENC( IENC )         ( VALID_ENC_RANGE( IENC ) && ACTIVE_PBASE    ( POBJ_GET_PBASE(EncList.lst + (IENC)) ) )
37 #define WAITING_ENC( IENC )        ( VALID_ENC_RANGE( IENC ) && WAITING_PBASE   ( POBJ_GET_PBASE(EncList.lst + (IENC)) ) )
38 #define TERMINATED_ENC( IENC )     ( VALID_ENC_RANGE( IENC ) && TERMINATED_PBASE( POBJ_GET_PBASE(EncList.lst + (IENC)) ) )
39 
40 #define GET_INDEX_PENC( PENC )      ((NULL == (PENC)) ? MAX_ENC : (size_t)GET_INDEX_POBJ( PENC, MAX_ENC ))
41 #define GET_REF_PENC( PENC )        ((ENC_REF)GET_INDEX_PENC( PENC ))
42 #define DEFINED_PENC( PENC )        ( VALID_ENC_PTR( PENC ) && ALLOCATED_PBASE ( POBJ_GET_PBASE(PENC) ) && !TERMINATED_PBASE ( POBJ_GET_PBASE(PENC) ) )
43 #define VALID_ENC_PTR( PENC )       ( (NULL != (PENC)) && VALID_ENC_RANGE( GET_REF_POBJ( PENC, MAX_ENC) ) )
44 #define ALLOCATED_PENC( PENC )      ( VALID_ENC_PTR( PENC ) && ALLOCATED_PBASE( POBJ_GET_PBASE(PENC) ) )
45 #define ACTIVE_PENC( PENC )         ( VALID_ENC_PTR( PENC ) && ACTIVE_PBASE( POBJ_GET_PBASE(PENC) ) )
46 #define TERMINATED_PENC( PENC )     ( VALID_ENC_PTR( PENC ) && TERMINATED_PBASE( POBJ_GET_PBASE(PENC) ) )
47 
48 // Macros to determine whether the enchant 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_ENC_BASE(IENC)       ( VALID_ENC_RANGE( IENC ) && ACTIVE_PBASE( POBJ_GET_PBASE(EncList.lst + (IENC)) ) && ON_PBASE( POBJ_GET_PBASE(EncList.lst + (IENC)) ) )
51 #define INGAME_PENC_BASE(PENC)      ( VALID_ENC_PTR( PENC ) && ACTIVE_PBASE( POBJ_GET_PBASE(PENC) ) && ON_PBASE( POBJ_GET_PBASE(PENC) ) )
52 
53 #define INGAME_ENC(IENC)            ( (ego_object_spawn_depth) > 0 ? DEFINED_ENC(IENC) : INGAME_ENC_BASE(IENC) )
54 #define INGAME_PENC(PENC)           ( (ego_object_spawn_depth) > 0 ? DEFINED_PENC(PENC) : INGAME_PENC_BASE(PENC) )
55 
56 //--------------------------------------------------------------------------------------------
57 // looping macros
58 //--------------------------------------------------------------------------------------------
59 
60 // Macros automate looping through the EncList. 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 ENC_BEGIN_LOOP_ACTIVE(IT, PENC)  {int IT##_internal; int enc_loop_start_depth = enc_loop_depth; enc_loop_depth++; for(IT##_internal=0;IT##_internal<EncList.used_count;IT##_internal++) { ENC_REF IT; enc_t * PENC = NULL; IT = (ENC_REF)EncList.used_ref[IT##_internal]; if(!ACTIVE_ENC (IT)) continue; PENC =  EncList.lst + IT;
63 #define ENC_END_LOOP() } enc_loop_depth--; EGOBOO_ASSERT(enc_loop_start_depth == enc_loop_depth); EncList_cleanup(); }
64 
65 //--------------------------------------------------------------------------------------------
66 // external variables
67 //--------------------------------------------------------------------------------------------
68 
69 DECLARE_LIST_EXTERN( enc_t, EncList, MAX_ENC );
70 
71 extern int enc_loop_depth;
72 
73 //--------------------------------------------------------------------------------------------
74 // Function prototypes
75 //--------------------------------------------------------------------------------------------
76 
77 void    EncList_init();
78 void    EncList_dtor();
79 
80 ENC_REF EncList_allocate( const ENC_REF override );
81 
82 bool_t  EncList_free_one( const ENC_REF ienc );
83 void    EncList_free_all();
84 
85 bool_t  EncList_add_used( const ENC_REF ienc );
86 
87 void    EncList_update_used();
88 
89 void    EncList_cleanup();
90 
91 bool_t EncList_add_activation( ENC_REF ienc );
92 bool_t EncList_add_termination( ENC_REF ienc );
93