FlCodebase3.1/
FlCodebase3.1/bounty/
FlCodebase3.1/challenge/
FlCodebase3.1/clans/
FlCodebase3.1/gods/
FlCodebase3.1/mobprogs/
FlCodebase3.1/player/
FlCodebase3.1/savemud/
/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
 *  Chastain, Michael Quan, and Mitchell Tse.                              *
 *                                                                         *
 *  In order to use any part of this Envy Diku Mud, you must comply with   *
 *  the original Diku license in 'license.doc', the Merc license in        *
 *  'license.txt', as well as the Envy license in 'license.nvy'.           *
 *  In particular, you may not remove either of these copyright notices.   *
 *                                                                         *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  * 
 *                                                                         *
 *      ROM 2.4 is copyright 1993-1998 Russ Taylor                         *
 *      ROM has been brought to you by the ROM consortium                  *
 *          Russ Taylor (rtaylor@hypercube.org)                            *
 *          Gabrielle Taylor (gtaylor@hypercube.org)                       *
 *          Brian Moore (zump@rom.org)                                     *
 *      By using this code, you have agreed to follow the terms of the     *
 *      ROM license, in the file Rom24/doc/rom.license                     *
 *                                                                         *
 * Code Adapted and Improved by Abandoned Realms Mud                       *
 * and Aabahran: The Forsaken Lands Mud by Virigoth                        *
 *                                                                         *
 * Continued Production of this code is available at www.flcodebase.com    *
 ***************************************************************************/

#include "misc.h"

#ifndef __ARMY_H__
#define __ARMY_H__

#define	SAVEARMY_DIR		"../savemud/"
#define	SAVEARMY_FILE		"armies.sav"
#define	SAVEARMY_TEMPFILE	"armies.tmp"

#define DEFENSE_AIWAIT		600	//seconds before AI defends
#define ARMY_DEFENSE_MULT	100
#define ARMY_DAMAGE_MULT	100
#define ARMY_NODEFENDER_MULT	50
#define	ARMY_HASH_SIZE		256
#define ARMY_HASH_KEY		251

/* MAX VALS */
#define MAX_ARMY_ID		512
#define ARMY_VARS		3
#define ARMY_MAXREPORT		16
#define ARMY_PATH_MAX	       1024

/* DEFINES for pcdata->armies COUNTS */
/*
  NOR   = normal armies in barracks
  UPG   = elite armies in barracks
  NORQ  = normal units queued up
  UPGQ  = elites units queued up
  TIMN  = ticks before normal units trained or -1 for pause
  TIMU  = ticks for elite units
  OTIN  = saved ticks while normal queue paused
  OTIU  = saved ticks while elites paused
*/
#define NOR	0
#define UPG	1
#define NORQ	2
#define UPGQ	3
#define TIMN	4
#define TIMU	5
#define OTIN	6
#define OTIU	7
#define MAX_TRAIN_QUEUE	8

/* army report types */
#define	REPORT_NEUT	0
#define	REPORT_GOOD	1
#define	REPORT_BAD	3

/* ARMY STATES */
#define	AS_NONE		0
#define	AS_GARR		1
#define	AS_FORT		2
#define	AS_PATR		3
#define	AS_ATTA		4
#define	AS_MOVE		5
#define	AS_RETU		6
#define	AS_LEAV		7
#define	AS_SHAD		8
#define	AS_FIGH		9
#define	AS_DISB		10
#define	AS_DEFE		11
#define	AS_CIRC		12
#define	AS_BESE		13
#define	AS_MAX		14

/* ARMY TYPES (index->type) */
#define ARMY_TYPE_UNIT		0
#define ARMY_TYPE_BASTION	(A)

/* ARMY FLAGS (index->army_flags) */
#define ARMY_FLAG_NONE		0
#define ARMY_FLAG_ELITE		(A)
#define ARMY_FLAG_FLYING	(B)
#define ARMY_FLAG_GARRISON	(C)
#define ARMY_FLAG_FOUGHT	(D)

/* ARMY_ROOM_DATA->armies DESIGNATIONS */
/*  0 1 2 3 4 5 
 *  ___________
 * |B|D|D|A|A|A|
 *  -----------
 */
#define	INROOM_BASTION		0
#define	INROOM_DEFENDERS	1
#define	INROOM_ATTACKERS	3
#define	INROOM_MAXARMIES	6


/* DURATIONS */
//NEW
#define	ARMY_DUR_REC		4
#define	ARMY_DUR_SREC		3
#define	ARMY_DUR_UPG		2
#define	ARMY_DUR_SUPG		1
#define	ARMY_DUR_FORTIFY	24

//OLD (remove)
#define	BUILD_ARMY_DUR		8
#define	UPGRADE_ARMY_DUR	12
#define	BUILD_TOWER_DUR		120 //1 hour
#define	UPGRADE_TOWER_DUR	360 //3 hours
#define	COMBAT_SIEGE_DUR	120 //1 hour
#define	COMBAT_ARMY_DUR		60  //0.5 hour
#define	CORRUPT_DUR		720 //6 hours

/* TYPE DEFS */
typedef struct report_queue REPORT_QUEUE;
typedef struct army_report ARMY_REPORT;
typedef struct army_data  ARMY_DATA;
typedef struct tower_data TOWER_DATA;       
typedef struct army_index_data ARMY_INDEX_DATA;
typedef struct army_room_data ARMY_ROOM_DATA;

/* MACROS */
#define	IS_ARMY( army, flag )		( (army)->army_flags & (flag) )
#define	ARMY_HASHVAL( army )	( (army)->ID % ARMY_HASH_KEY )
#define	ID_HASHVAL( ID )	( (ID) % ARMY_HASH_KEY )

#define GARR_RED( ch )		( (ch)->pCabal ? get_parent((ch)->pCabal)->armies_ready : 0 )
#define GARR_NOR( ch )		( IS_NPC((ch)) || !(ch)->pcdata->member ? 0 : (ch)->pcdata->member->armies[NOR])
#define GARR_NORQ( ch )		( IS_NPC((ch)) || !(ch)->pcdata->member ? 0 : (ch)->pcdata->member->armies[NORQ])
#define GARR_UPG( ch )		( IS_NPC((ch)) || !(ch)->pcdata->member ? 0 : (ch)->pcdata->member->armies[UPG])
#define GARR_UPGQ( ch )		( IS_NPC((ch)) || !(ch)->pcdata->member ? 0 : (ch)->pcdata->member->armies[UPGQ])
#define GARR_TOT( ch )		( GARR_NOR((ch)) + GARR_UPG((ch)) )
#define GET_LETTER( pa )	( IS_ARMY( (pa), ARMY_FLAG_ELITE) ? UPPER((pa)->pCabal->who_name[2]) : LOWER((pa)->pCabal->who_name[2]))

#define SET_FOCUS( ch, focus )		( (ch)->pcdata->army_focus = (focus))
#define SET_LASTFOCUS( ch, focus )	( (ch)->pcdata->last_focus = (focus))
#define SET_QFOCUS(pc, focus)		( get_parent((pc))->last_focus = focus)
#define GET_FOCUS( ch )			( (ch)->pcdata->army_focus )
#define GET_LASTFOCUS( ch )		( (ch)->pcdata->last_focus )
#define GET_QFOCUS( pc )		( get_parent((pc))->last_focus )


#define AKEY( key, field, val)						\
if (!str_cmp( word, key)){						\
  (field)	=	(val);						\
  fMatch = TRUE;							\
  break;								\
}

#define AKEYS( key, field, val)						\
if (!str_cmp( word, key)){						\
  free_string( (field) );						\
  (field)	=	(val);						\
  fMatch = TRUE;							\
  break;								\
}


/* STRUCTS */
struct army_report{
  ARMY_REPORT*	next;
  ARMY_REPORT*	prev;
  time_t	time;
  char*		string;
};

struct report_queue{
  ARMY_REPORT	top;
  ARMY_REPORT	bot;
  int		size;
};



struct army_index_data{
  ARMY_INDEX_DATA*	next;
  AREA_DATA*		area;		//area this index is in
  int			vnum;		//army vnum
  char*			noun;		//Demons (used in short cabal updates)
  char*			short_desc;	//A Demon Horde
  char*			long_desc;	//A pack of demons is here.
  char*			desc;		//Detailed description
  sh_int		type;		//One of ARMY_TYPE (bastion, army etc.)
  int			cost;		//cost to raise
  int			support;	//% of each bastion's support share
  int			off_dice[3];	//offensive dice
  int			hit_dice[3];	//hp dice
  int			arm_dice[3];	//armor dice
  int			army_flags;	//special flags
};

struct army_data{
  ARMY_DATA*		next;
  ARMY_INDEX_DATA*	pIndexData;	//Original index data
  ARMY_DATA*		attacking;	//army we are attacking
  PATH_QUEUE*		path;		//path this army will move along
  CABAL_DATA*	pCabal;		//cabal this belongs to
  ROOM_INDEX_DATA*	in_room;	//room this army is in if any
  int			in_slot;	//in room_armies slot if any
  
  char*			commander;	//Name of commander, otherwise cabal's
  sh_int		command_rank;	//commander's cabal rank
  char*			noun;		//Demons (used in short cabal updates)
  char*			short_desc;	//A Demon Horde
  char*			long_desc;	//A pack of demons is here.
  char*			desc;		//Detailed description

  word			ID;		//ID of unit
  sh_int		order;		//The original order to the unit
  int			ovars[ARMY_VARS];//Original order's variables
  int			vars[ARMY_VARS];//state variables if any
  sh_int		state;		//Current army state
  int			lifetime;	//army ticks before next state decision
  int			cabal_ai_life;  //army ticks before next cabal_ai deci.

  int			src_room;	//start room vnum for path when its set
  int			att_slot;	//for fix_armies to repoint attackers

  int			off_dice[3];	//offensive dice
  int			hit;		//current hitpoints
  int			max_hit;	//max hit
  int			armor;		//current armor
  int			max_armor;	//max armor
  int			army_flags;	//flags
};

/* holds info about armies in room */
struct army_room_data{
  ARMY_DATA*	armies[INROOM_MAXARMIES];
  int		count;	//armies in slots.
  int		bastions;//how many bastions in slots
  int		defenders;//how many defenders in slots
  int		attackers;//how many attackers in slots
};

/* holds description/constant/lifetime of state */
struct state_table_s {
  char* name;
  int	bit;
  int	lifetime;
};

/* used for keeping track of towers in area */
struct tower_data{
  TOWER_DATA*		next;

  CABAL_DATA*	pCabal;
  AREA_DATA*	        pArea;

  int			towers;
  bool			fRein;	//does area have reinforcements
};

  
ARMY_INDEX_DATA*	new_army_index	( void );
ARMY_INDEX_DATA*	get_army_index	( int vnum );

void	refresh_area_support	( );
void	reinforce_refresh	( CABAL_DATA* pCabal );
bool	can_reinforce		( CABAL_DATA* pCabal, AREA_DATA* area );
void	area_to_cabal		( AREA_DATA* area, CABAL_DATA* pc, bool fSilent );
void	area_from_cabal		( AREA_DATA* area,  bool fSilent );
bool	break_alliance_check	( CABAL_DATA* pCab, CABAL_DATA* pExAlly );

void	save_armies		( void );
void	load_armies		( void );

void	add_army_index		( ARMY_INDEX_DATA* pai );
void	show_army_index		( CHAR_DATA* ch, ARMY_INDEX_DATA* pai );
void	save_army_indexes	( FILE *fp, AREA_DATA *pArea );
void	fread_army_indexes	( FILE* fp, AREA_DATA* pArea );
void	recruit_army		( CHAR_DATA* ch, bool fElite );
void	update_garrison		( CHAR_DATA*  ch, int nor, int upg );
void	update_garrison_cm	( CMEMBER_DATA*  cm, int nor, int upg );
bool	check_army_max		( CMEMBER_DATA* cm );

int	get_army_count		( char* name );
int	get_max_army		( int level );
TOWER_DATA* get_tower_data	( CABAL_DATA* pCabal, AREA_DATA* area );
void	army_update		( void );
void	show_room_armies	( CHAR_DATA* ch, ARMY_ROOM_DATA* pArd );
void	examine_room_armies	( CHAR_DATA* ch, ARMY_ROOM_DATA* pArd );
void	army_battle_echo	( ROOM_INDEX_DATA* room );

void	army_report		( ARMY_DATA* pa, char* string, int type, bool fSave );
void	cabal_report		( CABAL_DATA* pc, char* string, int type, bool fSave );
void	init_repq		( REPORT_QUEUE* q);


bool	army_interpret		( CHAR_DATA* ch, char* argument );
ARMY_DATA* get_army_room	( CHAR_DATA* ch, ROOM_INDEX_DATA* room,char* name);



#endif