Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

unit.h

Go to the documentation of this file.
00001 /* Definitions relating to units in Xconq.
00002    Copyright (C) 1987-1989, 1991-2000 Stanley T. Shebs.
00003    Copyright (C) 2004-2005 Eric A. McDonald.
00004 
00005 Xconq is free software; you can redistribute it and/or modify
00006 it under the terms of the GNU General Public License as published by
00007 the Free Software Foundation; either version 2, or (at your option)
00008 any later version.  See the file COPYING.  */
00009 
00016 #include "parambox.h"
00017 
00018 /* Advanced unit support. */
00019 
00021 extern short default_size; 
00023 extern short default_usedcells; 
00025 extern short default_maxcells; 
00027 extern long default_population; 
00028 
00029 /* Forward declarations of various structs. */
00030 struct a_unit;
00031 struct a_unit_extras;
00032 struct a_unit_view;
00033 
00045 typedef struct a_unit {
00046     short type;                         
00047     int id;                             
00048     char *name;                         
00049     int number;                         
00050     struct a_unit_view *uview;          
00051     struct a_image_family *imf;         
00052     char *image_name;                   
00053     short x;                            
00054     short y;                            
00055     short z;                            
00056     struct a_side *side;                
00057     struct a_side *origside;            
00058     short hp;                   
00059     short hp2;                  
00060     short cp;                   
00061     short cxp;                  
00062     short morale;               
00063     struct a_unit *transport;   
00064     SideMask tracking;          
00065     long *supply;               
00066     short s_flow;               
00067     short s_conn;       
00068     short *tooling;     
00069     short *opinions;    
00070     struct a_actorstate *act;           
00071     struct a_plan *plan;                
00072     struct a_unit_extras *extras;       
00073     char *aihook;               
00074     /* Following slots are never saved. */
00075     struct a_unit *occupant;    
00076     struct a_unit *nexthere;    
00077     struct a_unit *prev;        
00078     struct a_unit *next;        
00079     struct a_unit *unext;       
00080     short prevx;                
00081     short prevy;                
00082     Obj *transport_id;          
00083                                 /* (transport_id should be tmp array instead) */
00084     short flags;                
00085     /* (should make optional in UnitExtras?) */
00086     short size;                 
00087     short reach;                
00088     short usedcells;            
00089     short maxcells;             
00090     short curadvance;           
00091     long population;            
00092     short *production;          
00093     short cp_stash;        
00094     short researchdone;    
00095     short busy;     
00102     int creation_id;            
00103 } Unit;
00104 
00114 typedef struct a_unit_extras {
00115     short point_value;          
00116     short appear;               
00117     short appear_var_x;         
00118     short appear_var_y;         
00119     short disappear;            
00120     short priority;             
00121     Obj *sym;                   
00122     Obj *sides;                 
00123 } UnitExtras;
00124 
00130 typedef struct a_unit_view {
00131     short observer;             
00132     short type;                 
00133     short siden;                
00134     char *name;                 
00135     struct a_image_family *imf; 
00136     char *image_name;           
00137     short size;                 
00138     short x;                    
00139     short y;                    
00140     short complete;     
00141     short date;         
00142     int id;             
00143     struct a_unit *unit;            
00144     struct a_unit_view *transport;  
00145     struct a_unit_view *occupant;   
00146     struct a_unit_view *nexthere;   
00148     struct a_unit_view *nextinhash; 
00150     struct a_unit_view *vnext;      
00152 } UnitView;
00153 
00154 /* Unit parameter box. */
00155 struct ParamBoxUnit : public ParamBox {
00156     Unit *unit;
00157     ParamBoxUnit() { pboxtype = PBOX_TYPE_UNIT; unit = NULL; }
00158 };
00159 
00160 /* "Unit at" parameter box. */
00161 struct ParamBoxUnitAt : public ParamBoxUnit {
00162     int x, y;
00163     ParamBoxUnitAt() : ParamBoxUnit() {
00164         pboxtype = PBOX_TYPE_UNIT_AT;
00165         x = -1;  y = -1;
00166     }
00167 };
00168 
00169 /* Unit-unit parameter box. */
00170 struct ParamBoxUnitUnit : public ParamBox {
00171     Unit *unit1, *unit2;
00172     ParamBoxUnitUnit() { 
00173         pboxtype = PBOX_TYPE_UNIT_UNIT;
00174         unit1 = NULL;
00175         unit2 = NULL;
00176     }
00177 };
00178 
00179 /* Unit-side parameter box. */
00180 struct ParamBoxUnitSide : public ParamBoxUnit {
00181     Side *side;
00182     ParamBoxUnitSide() : ParamBoxUnit() {
00183         pboxtype = PBOX_TYPE_UNIT_SIDE;
00184         side = NULL;
00185     }
00186 };
00187 
00188 /* SeerNode is an useful struct for tracking who sees clearly,
00189    and who doesn't. */
00190 
00191 typedef struct a_seer_node {
00192     Unit *seer;
00193     int mistakes;
00194 } SeerNode;
00195 
00196 /* Parameter boxen related to seers. */
00197 
00198 struct ParamBoxUnitSideSeers : public ParamBoxUnitSide {
00199     SeerNode *seers;
00200     ParamBoxUnitSideSeers() : ParamBoxUnitSide () {
00201         pboxtype = PBOX_TYPE_UNIT_SIDE_SEERS;
00202         seers = NULL;
00203     }
00204     virtual ~ParamBoxUnitSideSeers() { seers = NULL; }
00205 };
00206 
00207 struct ParamBoxUnitUnitSeers : public ParamBoxUnitUnit {
00208     SeerNode *seers;
00209     ParamBoxUnitUnitSeers() : ParamBoxUnitUnit () {
00210         pboxtype = PBOX_TYPE_UNIT_UNIT_SEERS;
00211         seers = NULL;
00212     }
00213     virtual ~ParamBoxUnitUnitSeers() { seers = NULL; }
00214 };
00215 
00216 /* The global linked list of all unit views. */
00217 
00218 extern UnitView *viewlist;
00219 
00220 /* Some convenient macros. */
00221 
00222 
00233 #define for_all_units(v)  \
00234     for (v = unitlist; v != NULL; v = v->unext)
00235 
00243 #define for_all_side_units(s,v) \
00244     for (v = (s)->unithead->next; v != (s)->unithead; v = v->next)
00245 
00253 #define for_all_occupants(u1,v) \
00254   for (v = (u1)->occupant; v != NULL; v = v->nexthere)
00255 
00268 #define for_all_occs_with_occs(u,var)  \
00269   for ((var) = (u)->occupant; \
00270        (var) != NULL && (var) != (u)->nexthere; \
00271          (var) = ((var)->occupant != NULL ? \
00272                         (var)->occupant : \
00273                       ((var)->nexthere != NULL ? \
00274                         (var)->nexthere : \
00275                       ((var)->transport != NULL && \
00276                         (var)->transport->nexthere != NULL ? \
00277                         (var)->transport->nexthere : \
00278                       ((var)->transport != NULL && \
00279                         (var)->transport->transport != NULL && \
00280                         (var)->transport->transport->nexthere != NULL ? \
00281                         (var)->transport->transport->nexthere : NULL)))))
00282 
00289 #define is_unit(unit) ((unit) != NULL && is_unit_type((unit)->type))
00290 
00297 #define alive(unit) ((unit)->hp > 0)
00298 
00305 #define indep(unit) ((unit)->side == indepside)
00306 
00313 #define completed(unit) \
00314   ((unit)->cp >= u_cp((unit)->type))
00315 
00322 #define unit_alt(unit) (((unit)->z & 1) == 0 ? ((unit)->z >> 1) : 0)
00323 
00327 #define unit_conn(unit) (((unit)->z & 1) == 1 ? ((unit)->z >> 1) : NONTTYPE)
00328 
00335 #define in_play(unit) \
00336   (is_unit(unit) && alive(unit) && inside_area((unit)->x, (unit)->y))
00337 
00345 #define is_active(unit) (in_play(unit) && completed(unit))
00346 
00356 #define is_located_at(unit,x,y) (in_play(unit) && (unit)->x == wrapx(x) && (unit)->y == (y))
00357 
00368 #define was_located_at(unit,x,y) (is_unit(unit) && (unit)->prevx == wrapx(x) && (unit)->prevy == (y))
00369 
00378 #define side_tracking_unit(side,unit) (side_in_set((side), (unit)->tracking))
00379 
00395 #define unit_opinion(unit,side)  \
00396   ((unit)->opinions != NULL ? x_opinion((unit)->opinions[side_number(side)]) : 0)
00397 
00409 #define unit_courage(unit,side)  \
00410   ((unit)->opinions != NULL ? x_courage((unit)->opinions[side_number(side)]) : 0)
00411 
00418 #define x_opinion(val) (((val) & 0xff) - 128)
00419 
00426 #define x_courage(val) (((val) >> 8) & 0xff)
00427 
00436 #define s_opinion(val,val2) (((val) & ~0xff) | (val2 + 128))
00437 
00446 #define s_courage(val,val2) (((val) & ~0xff00) | (val2 << 8))
00447 
00448 /* These return a percentage value. */
00449 
00450 #define supply_inflow(unit) ((unit)->s_flow / 163)
00451 
00452 #define supply_connectedness(unit) ((unit)->s_conn / 254)
00453 
00454 /* (could use bit fields in struct I suppose...) */
00455 
00456 #define DETONATE_FLAG_BIT 0
00457 
00458 #define was_detonated(unit) ((unit)->flags & (1 << DETONATE_FLAG_BIT))
00459 
00460 #define set_was_detonated(unit, v) \
00461   ((v) ? ((unit)->flags |= 1 << DETONATE_FLAG_BIT) \
00462    : ((unit)->flags &= ~(1 << DETONATE_FLAG_BIT)))
00463 
00464 #define unit_point_value(unit) ((unit)->extras ? (unit)->extras->point_value : -1)
00465 
00466 #define unit_appear_turn(unit) ((unit)->extras ? (unit)->extras->appear : -1)
00467 
00468 #define unit_appear_var_x(unit) ((unit)->extras ? (unit)->extras->appear_var_x : -1)
00469 
00470 #define unit_appear_var_y(unit) ((unit)->extras ? (unit)->extras->appear_var_y : -1)
00471 
00472 #define unit_disappear_turn(unit) ((unit)->extras ? (unit)->extras->disappear : -1)
00473 
00474 #define unit_extra_priority(unit) ((unit)->extras ? (unit)->extras->priority : -1)
00475 
00476 #define unit_symbol(unit) ((unit)->extras ? (unit)->extras->sym : lispnil)
00477 
00478 #define unit_sides(unit) ((unit)->extras ? (unit)->extras->sides : lispnil)
00479 
00480 #define unit_doctrine(unit)  \
00481   ((unit)->side->udoctrine[(unit)->type])
00482 
00483 #define construction_run_doctrine(unit,u2) \
00484   (unit_doctrine(unit)->construction_run[u2])
00485 
00486 #define unit_side_treasury(unit) \
00487   ((unit)->side->treasury)
00488 
00489 /* A sortable vector of units, generally useful. */
00490 
00494 enum sortkeys {
00495     bynothing,                  
00496     bytype,                     
00497     byname,                     
00498     byactorder,         
00499     bylocation,                 
00500     byside,                     
00501     numsortkeytypes     
00502 };
00503 
00505 #define MAXSORTKEYS 5
00506 
00508 typedef struct a_unitvectorentry {
00509     Unit *unit;         
00510     int flag;           
00511 } UnitVectorEntry;
00512 
00514 typedef struct a_unitvector {
00515     int size;                               
00516     int numunits;                           
00517     enum sortkeys sortkeys[MAXSORTKEYS];    
00518     UnitVectorEntry units[1];               
00519 } UnitVector;
00520 
00524 /* \note (should check args?) */
00525 #define unit_in_vector(uvec,ix) ((uvec)->units[ix].unit)
00526 
00527 #undef  DEF_ACTION
00528 #define DEF_ACTION(name,CODE,args,prepfn,netprepfn,dofn,checkfn,argdecl,doc) CODE,
00529 
00534 typedef enum actiontype {
00535 
00536 #include "action.def"
00537 
00538     NUMACTIONTYPES
00539 
00540 } ActionType;
00541 
00543 typedef struct a_actiondefn {
00544     ActionType typecode;        
00545     char *name;                 
00546     char *argtypes;             
00547 } ActionDefn;
00548 
00550 #define MAXACTIONARGS 4
00551 
00553 typedef struct a_action {
00554     ActionType type;            
00555     int args[MAXACTIONARGS];    
00556     int actee;                  
00557     struct a_action *next;      
00558 } Action;
00559 
00561 typedef struct a_actorstate {
00562     short initacp;              
00563     short acp;                  
00564     short actualmoves;          
00565     Action nextaction;          
00566 } ActorState;
00567 
00568 #define valid(x) ((x) == A_ANY_OK)
00569 
00570 #define has_pending_action(unit)  \
00571   ((unit)->act && (unit)->act->nextaction.type != ACTION_NONE)
00572 
00573 #define acp_indep(unit) u_acp_independent((unit)->type)
00574 
00586 #define has_acp_left(unit) \
00587   ((unit)->act && ((0 < (unit)->act->acp) || acp_indep(unit)))
00588 
00589 /* What is the maximum amount of ACP an unit type can have? */
00590 #define type_acp_max(u) ((u_acp_max(u) >= 0) ? u_acp_max(u) : u_acp(u)) 
00591 
00592 /* All the definitions that govern planning. */
00593 
00594 #undef  DEF_GOAL
00595 #define DEF_GOAL(name,dname,GOALTYPE,args) GOALTYPE,
00596 
00605 enum goaltype {
00606 
00607 #include "goal.def"
00608 
00609     g_t_dummy
00610 };
00611 typedef enum goaltype GoalType;
00612 
00614 typedef struct a_goaldefn {
00615     char *name;             
00616     char *display_name;     
00617     char *argtypes;         
00618 } GoalDefn;
00619 
00620 /* The goal structure proper. */
00621 
00623 #define MAXGOALARGS 5
00624 
00626 typedef struct a_goal {
00627     GoalType type;              
00628     short tf;                   
00629     Side *side;                 
00630     short args[MAXGOALARGS];    
00631 } Goal;
00632 
00633 #undef  DEF_TASK
00634 #define DEF_TASK(name,dname,CODE,argtypes,dofn,createfn,setfn,netsetfn,pushfn,netpushfn,argdecl) CODE,
00635 
00649 typedef enum a_tasktype {
00650 
00651 #include "task.def"
00652 
00653     NUMTASKTYPES
00654 } TaskType;
00655 
00657 typedef enum a_taskoutcome {
00658   TASK_UNKNOWN,         
00659   TASK_FAILED,          
00660   TASK_IS_INCOMPLETE,   
00661   TASK_PREPPED_ACTION,  
00662   TASK_IS_COMPLETE      
00663 } TaskOutcome;
00664 
00666 #define MAXTASKARGS 6
00667 
00669 typedef struct a_task {
00670     TaskType type;              
00671     int args[MAXTASKARGS];      
00672     short execnum;              
00673     short retrynum;             
00674     struct a_task *next;        
00675 } Task;
00676 
00678 typedef struct a_taskdefn {
00679     char *name;                 
00680     char *display_name; 
00681     char *argtypes;             
00682     TaskOutcome (*exec)(Unit *unit, Task *task); 
00683 } TaskDefn;
00684 
00685 #define is_task_type(x) (between(0, (x), NUMTASKTYPES - 1))
00686 
00687 #undef  DEF_PLAN
00688 #define DEF_PLAN(name,CODE) CODE,
00689 
00699 typedef enum plantype {
00700 
00701 #include "plan.def"
00702 
00703     NUMPLANTYPES
00704 } PlanType;
00705 
00707 typedef struct a_plan {
00708     PlanType type;                              
00709     short creation_turn;                        
00710     short initial_turn;                         
00711     short final_turn;                           
00712     short asleep;                                       
00713     short reserve;                                      
00714     short delayed;                                      
00715     short waitingfortasks;                      
00716     short aicontrol;                            
00717     short supply_alarm;                         
00718     short supply_is_low;                        
00719     short waitingfortransport;          
00720     struct a_goal *maingoal;                    
00721     struct a_goal *formation;                   
00722     struct a_task *tasks;                       
00723     /* Not saved/restored. (little value, some trouble to do) */
00724     struct a_unit *funit;                       
00725     Action lastaction;                          
00726     short lastresult;                           
00727     Task last_task;                             
00728     TaskOutcome last_task_outcome;      
00729     short execs_this_turn;                      
00730 } Plan;
00731 
00732 #define for_all_tasks(plan,task)  \
00733   for (task = (plan)->tasks; task != NULL; task = task->next)
00734 
00735 #define ai_controlled(unit)  \
00736   ((unit)->plan && (unit)->plan->aicontrol && side_has_ai(unit->side))
00737 
00738 /* Global unit variables. */
00739 
00741 extern Unit *unitlist;
00743 extern Unit *tmpunit;
00744 
00746 extern int numunits;
00748 extern int numliveunits;
00749 
00751 extern enum sortkeys tmpsortkeys[];
00752 
00753 
00754 /* \brief Action definition array. */
00755 extern ActionDefn actiondefns[];
00756 
00758 extern GoalDefn goaldefns[];
00759 
00761 extern TaskDefn taskdefns[];
00762 
00764 extern char *plantypenames[];
00765 
00766 /* Declarations of unit-related functions that do not change the kernel state. 
00767 Those that actually do something have been moved to kernel.h. */
00768 
00769 /* Testable conditions etc. */
00770 
00771 extern int side_owns_occupant_of_unit(Side *side, Unit *unit);
00772 extern int side_owns_viewer_in_unit(Side *side, Unit *unit);
00773 extern int type_can_occupy_cell(int u, int x, int y);
00774 extern int side_thinks_type_can_occupy_cell(Side *side, int u, int x, int y);
00775 extern int type_can_occupy_empty_cell(int u, int x, int y);
00776 extern int type_can_occupy_terrain(int u, int t);
00777 extern int can_occupy_cell_without(Unit *unit, int x, int y, Unit *unit3);
00778 extern int type_can_occupy_cell_without(int u, int x, int y, Unit *unit3);
00779 extern int side_can_put_type_at(Side *side, int u, int x, int y);
00780 extern int side_can_put_type_at_without(Side *side, int u, int x, int y, Unit *unit);
00781 extern int side_thinks_it_can_put_type_at(Side *side, int u, int x, int y);
00782 extern int side_thinks_it_can_put_type_at_without(Side *side, int u, int x, int y, Unit *unit);
00783 extern int can_occupy(Unit *unit, Unit *transport);
00784 extern int type_can_occupy(int u, Unit *transport);
00785 extern int side_thinks_type_can_occupy(Side *side, int u, UnitView *transport);
00786 extern int type_can_occupy_without(int u, Unit *transport, Unit *unit);
00787 extern int side_thinks_type_can_occupy_without(int u, UnitView *transport, Unit *unit);
00788 extern int type_can_occupy_empty_type(int u, int u2);
00789 extern int type_can_have_occs(int u);
00790 extern int new_unit_allowed_on_side(int u, Side *side);
00791 extern int unit_allowed_on_side(Unit *unit, Side *side);
00792 extern int num_sides_allowed(int u);
00793 extern int type_allowed_on_side(int u, Side *side);
00794 extern int type_ever_available(int u, Side *side);
00795 extern int unit_trusts_unit(Unit *unit1, Unit *unit2);
00796 extern int type_survives_in_cell(int u, int nx, int ny);
00797 extern int type_survives_in_terrain(int u, int t);
00798 extern int can_build(Unit *unit);
00799 extern int type_can_build(int u, Side *side);
00800 extern int can_move(Unit *unit);
00801 extern int can_extract_at(Unit *unit, int x, int y, int *mp);
00802 extern int can_load_at(Unit *unit, int x, int y, int *mp);
00803 extern int can_develop(Unit *unit);
00804 extern int type_can_develop(int u);
00805 extern int can_change_type(Unit *unit);
00806 extern int can_change_type_to(Unit *unit, int u2);
00807 extern int could_change_type(int u);
00808 extern int could_change_type_to(int u, int u2);
00809 #define could_auto_upgrade_to(u,u2) ((u2) == u_auto_upgrade_to(u))
00810 extern int can_disband(Unit *unit);
00811 extern int type_can_disband(int u);
00812 extern int side_can_disband(Side *side, Unit *unit);
00813 extern int can_add_terrain(Unit *unit);
00814 extern int type_can_add_terrain(int u);
00815 extern int can_remove_terrain(Unit *unit);
00816 extern int type_can_remove_terrain(int u);
00817 extern int can_build_attackers(Side *side, int u);
00818 extern int can_build_defenders(Side *side, int u);
00819 extern int can_build_explorers(Side *side, int u);
00820 extern int can_build_colonizers(Side *side, int u);
00821 extern int can_build_facilities(Side *side, int u);
00822 extern int can_build_or_help(Unit *unit);
00823 extern int can_research(Unit *unit);
00824 extern int can_produce(Unit *unit);
00825 extern int total_production(Unit *unit, int m);
00826 extern int base_production(Unit *unit, int m);
00827 extern int total_consumption(Unit *unit, int m);
00828 extern int base_consumption(Unit *unit, int m);
00829 extern int survival_time(Unit *unit);
00830 extern int will_not_move(Unit *unit);
00831 extern int needs_material_to_move(Unit *unit, int m);
00832 extern int needs_material_to_survive(Unit *unit, int m);
00833 extern int operating_range_best(int u);
00834 extern int operating_range_worst(int u);
00835 extern int real_operating_range_best(Unit *unit);
00836 extern int real_operating_range_worst(Unit *unit);
00837 extern int can_build_type(Unit *unit, int u2);
00838 extern int can_develop_or_build_type(Unit *unit, int u2);
00839 extern int unit_can_build_type_at(Unit *unit, int u2, int x, int y);
00840 extern int unit_can_build_type(Unit *unit, int u2);
00841 extern int type_can_build_type(int u, Side *side, int u2);
00842 
00843 extern Unit *incomplete_build_target(Unit *unit);
00844 
00845 #if 0
00846 extern int moves_till_low_supplies(Unit *unit);
00847 extern int num_occupants(Unit *unit);
00848 extern int num_units_at(int x, int y);
00849 #endif
00850 
00851 extern int see_chance(int u, int u2, int dist);
00852 extern int see_chance(Unit *seer, Unit *tosee);
00853 
00854 /* Unit names and designations. */
00855 
00856 extern char *unit_desig(Unit *unit);
00857 extern char *unit_desig_no_loc(Unit *unit);
00858 extern char *utype_name_n(int u, int n);
00859 extern char *shortest_unique_name(int u);
00860 extern char *shortest_generic_name(int u);
00861 extern char *actorstate_desig(struct a_actorstate *as);
00862 
00863 /* Unit locators. */
00864 
00865 extern Unit *find_unit(int n);
00866 extern Unit *find_unit_dead_or_alive(int n);
00867 extern Unit *find_unit_by_name(char *nm);
00868 extern Unit *find_unit_by_number(int nb);
00869 extern Unit *find_unit_by_symbol(Obj *sym);
00870 
00871 /* Unit vector manipulating functions. Declared here rather than in kernel.h 
00872 since they also are used in the interfaces. */
00873 
00874 extern UnitVector *make_unit_vector(int initsize);
00875 extern void clear_unit_vector(UnitVector *vec);
00876 extern UnitVector *add_unit_to_vector(UnitVector *vec, Unit *unit, int flag);
00877 extern void remove_unit_from_vector(UnitVector *vec, Unit *unit, int pos);
00878 extern void sort_unit_vector(UnitVector *vec);
00879 
00880 /* Used in mknames.c. */
00881 
00882 extern void sort_units(int byidonly);
00883 
00884 /* Turn init code - does not really belong here. */
00885 
00886 extern void check_all_units(void);
00887 
00888 #undef  DEF_ACTION
00889 #define DEF_ACTION(name,code,args,prepfn,netprepfn,dofn,CHECKFN,ARGDECL,doc)  \
00890   extern int CHECKFN ARGDECL;
00891 
00892 #include "action.def"
00893 
00894 #undef  DEF_TASK
00895 #define DEF_TASK(name,dname,code,argtypes,dofn,CREATEFN,setfn,netsetfn,pushfn,netpushfn,ARGDECL)  \
00896   extern Task *CREATEFN ARGDECL;
00897 
00898 #include "task.def"

Generated on Sat Sep 17 10:28:53 2005 for XconqKernel by doxygen 1.3.6