예제 #1
0
iStringT FormatDate(uint32 timestamp, bool bShowTime)
{
	FILETIME ft;
	SYSTEMTIME st;
	LONGLONG ll;
	ll = Int32x32To64(timestamp, 600000000);
	ft.dwLowDateTime = (DWORD)ll;
	ft.dwHighDateTime = ll >> 32;
	FileTimeToSystemTime(&ft, &st);
	if (bShowTime) return iFormat(_T("%d %s %d (%d:%02d)"), st.wDay, gTextMgr[TRID_MONTH_JAN+st.wMonth-1], st.wYear, st.wHour, st.wMinute);
	else return iFormat(_T("%d %s %d"), st.wDay, gTextMgr[TRID_MONTH_JAN+st.wMonth-1], st.wYear);
}
예제 #2
0
void iComposer::ComposeAvatar(const iAvatar& avt, const iPoint& pos, bool bShadow, PLAYER_ID pid)
{
	iSpriteMgr& spriteMgr = gItemMgr.m_SpriteMgr;

	// Shadow
	for (uint32 sid=0; sid<avt.SpritesCount(); ++sid) {
		const iSprite* pSprite = spriteMgr.GetSpritePtr(avt.SpriteEntry(sid).spriteId);
		if (bShadow && pSprite->shadow) ComposeShadow(pSprite->dib,m_ComposeMemDC.m_Dib,pos + pSprite->anchor + avt.SpriteEntry(sid).anchor);
	}
	// Sprites
	for (sid=0; sid<avt.SpritesCount(); ++sid) {
		const iSprite* pSprite = spriteMgr.GetSpritePtr(avt.SpriteEntry(sid).spriteId);
		pSprite->dib.CopyToDibXY(&m_ComposeMemDC.m_Dib,pos + pSprite->anchor + avt.SpriteEntry(sid).anchor,BLEND_ALPHABLEND);
	}

	// Flags
	if (pid != PID_NEUTRAL){
		const iDib& fdib = spriteMgr.GetSpritePtr(iFormat(_T("common.flags_%04d"),pid))->dib;
		// Compose flags
		for (uint32 fid=0; fid<avt.FlagsCount(); ++fid){
			iPoint fop = pos + avt.FlagEntry(fid);
			fdib.CopyToDibXY(&m_ComposeMemDC.m_Dib, fop,BLEND_ALPHABLEND);
		}
	}
}
예제 #3
0
void iPlayer::OnSelect(bool bNewWeek, bool bAfterLoad)
{
	check(PlayerType() == PT_HUMAN);

	// Show new week dialog
	if (bNewWeek) {
		iDlg_NewWeek dlg(&gApp.ViewMgr(), m_PlayerId, gGame.Map().WeekDesc());
		dlg.DoModal();
	}

	// show current day
	uint32 days = gGame.Map().m_CurDay-1;
	gGame.AddMsg(iFormat(_T("#F4B4%s: #F9F9%d  #F4B4%s: #F9F9%d  #F4B4%s: #F9F9%d"),gTextMgr[TRID_MONTH], days/28+1,gTextMgr[TRID_WEEK], (days%28)/7+1,gTextMgr[TRID_DAY],days%7+1));

	// update fog map
	UpdateFogMap();

	// Select current hero and castle
	if (!m_pCurHero && m_Heroes.Count()){
		m_pCurHero = *m_Heroes.First();
	}
	if (m_pCurHero) m_pCurHero->OnSelect();
	else if (m_pCurCastle) m_pCurCastle->OnSelect();

	// Process time events
	if (!bAfterLoad) gGame.Map().ProcessTimeEvents(this);
}
예제 #4
0
void iSettingsDlg::UpdateSliderLabel(uint32 sliderId)
{
	if (sliderId == 101) {
		// Sfx Volume
		if (!m_sfxVolumeSlider->CurPos()) m_sfxVolumeLabel->SetText(iStringT(gTextMgr[TRID_SFX_VOLUME]) + _T(": ") + gTextMgr[TRID_OFF]);
		else m_sfxVolumeLabel->SetText(iFormat(_T("%s: #FFF0%d"), gTextMgr[TRID_CFGENTRY_SFXVOL], m_sfxVolumeSlider->CurPos()));
	} else if (sliderId == 102) {
		// Display gamma
		m_dispGammaLabel->SetText(iFormat(_T("%s: #FFF0%d"), gTextMgr[TRID_CFGENTRY_DISPGAMMA], m_dispGammaSlider->CurPos()));
	} else if (sliderId == 103) {
		// Map scroll speed
		m_mapScrollLabel->SetText(iStringT(gTextMgr[TRID_CFGENTRY_MAPSCROLLSPEED]) + _T(": #FFF0") + gTextMgr[TRID_CFG_SPEED_VSLOW + m_mapScrollSlider->CurPos()]);
	} else if (sliderId == 104) {
		// Hero speed
		m_heroSpeedLabel->SetText(iStringT(gTextMgr[TRID_CFGENTRY_HEROSPEED]) + _T(": #FFF0") + gTextMgr[TRID_CFG_SPEED_VSLOW + m_heroSpeedSlider->CurPos()]);
	} else if (sliderId == 105) {
		// Combat speed
		m_combatSpeedLabel->SetText(iStringT(gTextMgr[TRID_CFGENTRY_COMBATSPEED]) + _T(": #FFF0") + gTextMgr[TRID_CFG_SPEED_VSLOW + m_combatSpeedSlider->CurPos()]);
	}
}
예제 #5
0
void iDlg_HallOfFame::DoCompose(const iRect& clRect)
{
	iRect rc(clRect);

	// title
	gTextComposer.TextOut(dlgfc_hdr, gApp.Surface(),rc.point(),gTextMgr[TRID_MENU_HIGHSCORE], iRect(rc.x,rc.y,rc.w,15),AlignCenter);
	rc.y+=17;

	// Header
	gTextComposer.TextOut(dlgfc_topic, gApp.Surface(),rc, gTextMgr[TRID_HOF_RANK], iRect(rc.x, rc.y, 30, 15),AlignTop);
	gTextComposer.TextOut(dlgfc_topic, gApp.Surface(),rc, gTextMgr[TRID_HOF_LAND], iRect(rc.x+30, rc.y, 120, 15),AlignTop);
	gTextComposer.TextOut(dlgfc_topic, gApp.Surface(),rc, gTextMgr[TRID_HOF_DATE], iRect(rc.x+30+120, rc.y, 50, 15),AlignTop);
	gTextComposer.TextOut(dlgfc_topic, gApp.Surface(),rc, gTextMgr[TRID_HOF_DAYS], iRect(rc.x+30+120+50, rc.y, 40, 15),AlignTop);
	gTextComposer.TextOut(dlgfc_topic, gApp.Surface(),rc, gTextMgr[TRID_HOF_SCORE], iRect(rc.x+30+120+50+40, rc.y, 40, 15),AlignTop);
	rc.y += 15;

	// Entries
	uint32 eid;
	iTextComposer::FontConfig fc(iTextComposer::FS_MEDIUM, RGB16(192,192,192));
	for (eid = 0; eid<m_hScore.Count() && eid<10; ++eid) {
		if (eid == (uint32)m_curScore) fc.cmpProps.faceColor = RGB16(255,192,128);
		else fc.cmpProps.faceColor = RGB16(192,192,192);
		gTextComposer.TextOut(fc, gApp.Surface(),rc, iFormat(_T("%d."),eid+1), iRect(rc.x, rc.y, 30, 15),AlignTop);
		gTextComposer.TextOut(fc, gApp.Surface(),rc, m_hScore.Entry(eid).land, iRect(rc.x+30, rc.y, 120, 15),AlignTopLeft);
		gTextComposer.TextOut(fc, gApp.Surface(),rc, FormatDate(m_hScore.Entry(eid).date, false), iRect(rc.x+30+120, rc.y, 50, 15),AlignTop);
		gTextComposer.TextOut(fc, gApp.Surface(),rc, iFormat(_T("%d"),m_hScore.Entry(eid).days), iRect(rc.x+30+120+50, rc.y, 40, 15),AlignTop);
		gTextComposer.TextOut(fc, gApp.Surface(),rc, iFormat(_T("%d"),m_hScore.Entry(eid).score), iRect(rc.x+30+120+50+40, rc.y, 40, 15),AlignTop);
		rc.y += 14;
	}
	fc.cmpProps.faceColor = RGB16(192,192,192);
	for (; eid<10; ++eid) {
		gTextComposer.TextOut(fc, gApp.Surface(),rc, iFormat(_T("%d."),eid+1), iRect(rc.x, rc.y, 30, 15),AlignTop);
		gTextComposer.TextOut(fc, gApp.Surface(),rc, _T("-"), iRect(rc.x+30, rc.y, 120, 15),AlignTopLeft);
		gTextComposer.TextOut(fc, gApp.Surface(),rc, _T("-"), iRect(rc.x+30+120, rc.y, 50, 15),AlignTop);
		gTextComposer.TextOut(fc, gApp.Surface(),rc, _T("-"), iRect(rc.x+30+120+50, rc.y, 40, 15),AlignTop);
		gTextComposer.TextOut(fc, gApp.Surface(),rc, _T("-"), iRect(rc.x+30+120+50+40, rc.y, 40, 15),AlignTop);
		rc.y += 14;
	}
}
예제 #6
0
bool SaveGameFile( const iStringT& fname, iGameWorld& gmap )
{
	// Check and create save directory (if not exists)
	iStringT saveDir = gSavePath.Left(gSavePath.Length()-1);
	bool dirIsOk = iFile::DirExists(saveDir);
	if ( !dirIsOk ) {
		dirIsOk = iFile::DirCreate(saveDir);
	}
	if (!dirIsOk) {
		DWORD dwErr = GetLastError();
		iTextDlg tdlg(&gApp.ViewMgr(), _T(""), iFormat(_T("Unable to create '%s' folder: ErrorCode: 0x%08X"), saveDir.CStr(), dwErr), PID_NEUTRAL);
		tdlg.DoModal();
	}

	// normally we should create it in the save directory
	iStringT tempSaveName( gSavePath + _T("tempsave.tmp") );
	iFilePtr pFile( CreateWin32File( tempSaveName ) );

	if ( !pFile ) {
		DWORD dwErr = GetLastError();
		iTextDlg dlg( &gApp.ViewMgr(), _T("Failure"), iFormat(_T("Unable to save [%s], ErrorCode: 0x%08X"), fname.CStr(), dwErr), PID_NEUTRAL);
		dlg.DoModal();
		return false;
	}

	if ( !gGame.Map().SaveToFile( pFile.get() ) ) {
		iTextDlg dlg( &gApp.ViewMgr(), _T("Failure"), _T("Unable to save game!"), PID_NEUTRAL );
		dlg.DoModal();
		return false;
	}
	// close file
	pFile.reset();
	// rename file to the destination
	iFile::Delete( fname );
	iFile::Rename( tempSaveName, fname );
	iFile::Delete( tempSaveName );
	return true;
}
예제 #7
0
void iDlg_RiseSkeletons::DoCompose(const iRect& clRect)
{
	iRect rc(clRect);

	// title
	gTextComposer.TextOut(dlgfc_hdr, gApp.Surface(),rc.point(),gTextMgr[TRID_HSKILL_NECROMANCY], iRect(rc.x,rc.y,rc.w,15),AlignCenter);
	rc.y += 20;

	// text	

	rc.y += gTextComposer.TextBoxOut(dlgfc_splain, gApp.Surface(), iFormat(gTextMgr[TRID_MSG_RISE_SKELETONS], m_quant, gTextMgr[TRID_CREATURE_PEASANT_F3+m_ct*3]), iRect(rc.x,rc.y,rc.w,rc.h));
	rc.y += 5;

	// icon and quantity
	ComposeCreatureCell(gApp.Surface(), iRect((rc.x+rc.w/2)-18,rc.y,36,42), m_ct, m_quant, VL_EXPERT);
}
예제 #8
0
iSize iDlg_RiseSkeletons::ClientSize() const
{
	sint32 w = 150;
	sint32 h = 0;

	// title
	h += 20;
	// text
	h += gTextComposer.GetTextBoxSize(iFormat(gTextMgr[TRID_MSG_RISE_SKELETONS], m_quant, gTextMgr[TRID_CREATURE_PEASANT_F3+m_ct*3]), w, dlgfc_splain).h;
	h += 5;
	// icon and quantity
	h += 42;
	// button
	h += DEF_BTN_HEIGHT + 10;

	return iSize(w,h);
}
예제 #9
0
iStringT MakeTextEntryName(TextEntryType t, void* pObj)
{
	if (t == TET_DEFAULT) {
		return L"";
	} else if (t == TET_MAP_NAME) {
		return L"Map name";
	} else if (t == TET_MAP_DESC) {
		return L"Map Description";
	} else if (t == TET_TEVENT_TEXT) {
		iTimeEvent* pTE = (iTimeEvent*)pObj;
		return iFormat(L"Time Event (%s)", pTE->m_name.CStr());
	} else if (t == TET_HERO_CNAME) {
		iHero* pH = (iHero*)pObj;
		return iFormat(_T("Hero at (%d,%d) custom name"), pH->Pos().x, pH->Pos().y);
	} else if (t == TET_MAPITEM_MSG) {
		iMapItem* pMI = (iMapItem*)pObj;
		return iFormat(_T("Map item at (%d,%d) message"), pMI->Pos().x, pMI->Pos().y);
	} else if (t == TET_MAPGUARD_MSG) {
		iMapGuard* pMG = (iMapGuard*)pObj;
		return iFormat(_T("Map guard at (%d,%d) message"), pMG->Pos().x, pMG->Pos().y);
	} else if (t == TET_MEVENT_REWMSG) {
		iMapEvent* pME = (iMapEvent*)pObj;
		return iFormat(_T("Map event at (%d,%d) reward message"), pME->Pos().x, pME->Pos().y);
	} else if (t == TET_MEVENT_ATTMSG) {
		iMapEvent* pME = (iMapEvent*)pObj;
		return iFormat(_T("Map event at (%d,%d) attack message"), pME->Pos().x, pME->Pos().y);
	} else if (t == TET_VIS_MSG) {
		iVisCnst* pVC = (iVisCnst*)pObj;
		return iFormat(_T("Visitable at (%d,%d) custom message"), pVC->Pos().x, pVC->Pos().y);
	} else if (t == TET_CASTLE_CNAME) {
		iCastle* pC = (iCastle*)pObj;
		return iFormat(_T("Castle at (%d,%d) custom message"), pC->Pos().x, pC->Pos().y);
	}

	check(0);
	return L"";
}
예제 #10
0
iStringT iDwellEncCtlCnst::Desc() const
{
	return iFormat(gTextMgr[TRID_CTLCNST_DWELL_ENC_DESC], Name().CStr(), gTextMgr[TRID_CREATURE_PEASANT_F3 + CTLCNSTS_DESC[dwel].fparam * 3], mod);
}
예제 #11
0
iStringT iDwellCtlCnst::Desc() const
{
	return iFormat(gTextMgr[TRID_CTLCNST_DWELLINGS_DESC],Name().CStr(),gTextMgr[TRID_CREATURE_PEASANT_F1+crType*3+2]);
}
예제 #12
0
iMapGuard::iMapGuard(const iPoint& pos, CREATURE_TYPE ct, sint32 count, GUARD_DISPOS disp, bool bNotGrow)
: iBaseMapObject(pos), m_creat(ct, count), m_disp(disp), m_bNotGrow(bNotGrow) 
{
	if (ct < CREAT_RANDOM) m_spriteId = iFormat(_T("creatures.minimon_%04d"),ct);
	else m_spriteId = iFormat(_T("creatures.rand_guards_%04d"),ct-CREAT_RANDOM);
}
예제 #13
0
iMapItem_KeyGuard::iMapItem_KeyGuard(const iPoint& pos, uint8 key)
: iMapItem(pos, MAPITEM_KEYGUARD, iFormat(_T("resources.key_guards_%04d"),key)), m_key(key) {}
예제 #14
0
iMapItem_Mineral::iMapItem_Mineral(const iPoint& pos, MINERAL_TYPE mt, sint32 count)
: iMapItem(pos,MAPITEM_MINERAL, (mt==MINERAL_UNKNOWN)?_T("resources.rand_res_icn"):iFormat(_T("resources.icons_%04d"),mt)), m_mineralType(mt), m_count(count) {}
예제 #15
0
inline iStringT MineralSprite(MINERAL_TYPE mt)
{
	iStringT sm(MINERAL_ID[mt]);
	sm.Lower();
	return iFormat(_T("resources.%s"),sm.CStr());
}
예제 #16
0
void iSpellListView::OnCompose() 
{
	iRect rc = GetScrRect();

	// Buttons frame;
	iRect brc = m_pSchoolSwitch->GetScrRect();
	brc.InflateRect(1);
	gApp.Surface().FrameRect(brc, cColor_Black);


	rc.DeflateRect(m_pSchoolSwitch->GetRect().x2() + 5, -1, -1, -1);

	// Frame
	gApp.Surface().FrameRect(rc, cColor_Black);
	gApp.Surface().Darken25Rect(rc);
	rc.DeflateRect(3);


	// Spell
	if (m_curSel != MSP_INVALID) {
		// Name
		gTextComposer.TextOut(iTextComposer::FontConfig(iTextComposer::FS_MEDIUM,MSCH_COLORS[SPELL_DESCRIPTORS[m_curSel].school][0]), gApp.Surface(),iPoint(rc.x,rc.y),gTextMgr[TRID_SPNAME_MAGICARROW+m_curSel],rc, AlignTop);
		rc.DeflateRect(0,13,0,0);
		// Level
		gTextComposer.TextOut(iTextComposer::FontConfig(iTextComposer::FS_SMALL,MSCH_COLORS[SPELL_DESCRIPTORS[m_curSel].school][0]), gApp.Surface(),iPoint(rc.x,rc.y),gTextMgr[TRID_LEVEL] + iFormat(_T(": %d"), SPELL_DESCRIPTORS[m_curSel].level + 1),rc, AlignTop);
		rc.DeflateRect(0,16,0,0);
		// Icon
		rc.DeflateRect(0,40,0,0);
		// Hero school level
		ComposeSpellLevel(gApp.Surface(), rc, m_curSel, m_pOwner);
		rc.DeflateRect(0,12,0,0);
		// Cost
		uint8 cost = iBaseSpell::GetSpellCost(m_curSel, m_pOwner);
		uint8 school = SPELL_DESCRIPTORS[m_curSel].school;
		gTextComposer.TextOut(iTextComposer::FontConfig(iTextComposer::FS_SMALL,MSCH_COLORS[school][0]), gApp.Surface(),iPoint(rc.x,rc.y),gTextMgr[TRID_COST]+iFormat(_T(" %d"),cost),rc, AlignTop);
		rc.DeflateRect(0,20,0,0);
		// Inaccessebility reason
		if (m_pOwner->ManaPts() < cost) {
			iStringT msgStr(gTextMgr[TRID_MSG_SPELL_NOT_ENOUGH_MANA]);
			iTextComposer::FontConfig fntSmall(iTextComposer::FS_SMALL,RGB16(255,96,0));
			gTextComposer.TextBoxOut( fntSmall, gApp.Surface(), msgStr,rc);
		} else if (iCombatSpell* pCombatSpell = DynamicCast<iCombatSpell*>(gGame.ItemMgr().m_spellMgr.Spell(m_curSel))) {
			iTextComposer::FontConfig fntSmallDifferentColor(iTextComposer::FS_SMALL,RGB16(255,255,0));
			gTextComposer.TextBoxOut( fntSmallDifferentColor, gApp.Surface(), pCombatSpell->ActionText(m_pOwner),rc);
		}
	} else {
		iTextComposer::FontConfig fntSmall(iTextComposer::FS_SMALL,RGB16(255,96,0));
		gTextComposer.TextBoxOut(fntSmall, gApp.Surface(), gTextMgr[TRID_NO_SPELL_SELECTED],rc);
	}
}
예제 #17
0
void iComposer::Compose(HDC hdc, const iSize& siz, const iPoint &offset, const iPoint& snode, iBaseNode* pSelItem)
{
	DWORD btime = timeGetTime();

	const iSpriteMgr& spriteMgr = gItemMgr.m_SpriteMgr;
	iAvatarMgr& avatarMgr = gItemMgr.m_AvatarMgr;
	iIsoMetric im(5);
	iPoint aanch = offset-iPoint(GetMapPixelWidth()/2+40,20);
	iPoint fpos = im.Screen2Map(aanch);
	fpos.Move(-1,-1);
	iPoint ppos = im.Map2Screen(fpos);
	ppos.Move(-20,-8);
	iPoint offs = aanch-ppos;

	sint32 cnt_x = siz.w/40+3;
	sint32 cnt_y = siz.h/8+5;

	sint32 step_x = im.GetCellStepX()*2;
	sint32 step_y = im.GetCellStepY();
	
	const iPoint anchor_coor(fpos);
	iPoint init_map_coor(fpos);
	iPoint map_coor(fpos);

	ResizeComposeDib(siz);
	m_ComposeMemDC.m_Dib.Fill(cColorBlue64);
	// 
	// Surface and grid
	for (sint32 yy=0; yy<cnt_y; ++yy) {
		for (sint32 xx=0; xx<cnt_x; ++xx){
			if (m_pMap->IsValidPos(map_coor.x,map_coor.y)){
				sint32 xpos = xx*step_x;
				sint32 ypos = yy*step_y;
				if (yy%2!=0) xpos -= step_x >> 1;
				iPoint op(xpos-offs.x,ypos-offs.y);

				iMapHandler::iSurfCell cell;
				if ( m_pMap->GetCellSurf(map_coor,cell) ) {
					// solid cell - do nothing
					const iSprite* pSprite = spriteMgr.GetSpritePtr(iFormat(_T("common.surf_tiles_%04d"),cell.lowestLayer*4+CalcCellSeq(map_coor,4)));
					pSprite->dib.CopyToDibXY(&m_ComposeMemDC.m_Dib,op+pSprite->anchor,BLEND_ALPHABLEND);
				} else {
					// Compose inclusive transition Water->Sand
					if (cell.lowestLayer == STYPE_WATER){
						uint8 cfg = 0;//(uint8)( ((ccfg & 0xF0)>>4) | ((ccfg & 0xF00)>>8) | ((ccfg & 0xF000)>>12) | ((ccfg & 0xF0000)>>16) | ((ccfg & 0xF00000)>>20) | ((ccfg & 0xF000000)>>24));
						for (uint32 zz=0; zz<STYPE_COUNT; ++zz) cfg |= cell.layers[zz];
						const iSprite* pSprite = spriteMgr.GetSpritePtr(iFormat(_T("common.ws_tiles_%04d"),cfg-1));
						pSprite->dib.CopyToDibXY(&m_ComposeMemDC.m_Dib,op+pSprite->anchor,BLEND_ALPHABLEND);
					} else {
						const iSprite* pSprite = spriteMgr.GetSpritePtr(iFormat(_T("common.surf_tiles_%04d"),cell.lowestLayer*4+CalcCellSeq(map_coor,4)));
						pSprite->dib.CopyToDibXY(&m_ComposeMemDC.m_Dib,op+pSprite->anchor,BLEND_ALPHABLEND);
					}
					// Compose other layers
					for (uint32 zz=1; zz<STYPE_COUNT; ++zz){
						if (cell.layers[zz]){
							const iSprite* pTransMask = spriteMgr.GetSpritePtr(iFormat(_T("common.trans_tiles_%04d"),cell.layers[zz]-1));
							iGrayDib gmask;
							iDibGrayDibHandl::DibChannel2GrayDib(pTransMask->dib,gmask,Channel_Alpha);
							iDib vdib(&spriteMgr.GetSpritePtr(iFormat(_T("common.surf_tiles_%04d"),zz*4+CalcCellSeq(map_coor,4)))->dib);
							iDibGrayDibHandl::GrayDib2DibChannel(gmask,vdib,Channel_Alpha);
							vdib.CopyToDibXY(&m_ComposeMemDC.m_Dib,op,BLEND_ALPHABLEND);
						}
					}
				}

				if (m_bGrid) {
					m_dibGrid.CopyToDibXY(&m_ComposeMemDC.m_Dib, op, BLEND_ALPHABLEND);
				}
			}
			map_coor.x += 1;
			map_coor.y -= 1;
		}
		if (yy%2 != 0) {
			init_map_coor.x+=1;
			map_coor = init_map_coor;
		} else {
			init_map_coor.y+=1;
			map_coor = init_map_coor;
		}
	}
예제 #18
0
iStringT iScenPropsDlg::GetDfcString(DIFFICULTY_LEVEL dl)
{
	return iFormat(_T("#FCCC%s: #FFF0%s"), gTextMgr[TRID_DIFFICULTY_LEVEL], gTextMgr[TRID_DIFF_EASY+dl]);
}
int main(int argc, char *argv[])
{
//    argc = 2;
//variables

  int i;//Holds length of inpit file name; counts down during while loop
  int j;//Holds length of input file name

  char inputName[sizeof(argv[1])];//holds input file name
  char *opCodes[ARRAYSIZE];//array of pointers to character arrays
  //char *directives[];//array of pointers to character arrays

  char *symbolName = malloc((int)strlen(inputName)+FILEEXTENTIONLENGTH);//holds filename of symbol table
  char *objectName = malloc((int)strlen(inputName)+FILEEXTENTIONLENGTH);//holds name of object file
  char *errorName = malloc((int)strlen(inputName)+FILEEXTENTIONLENGTH); //holds name of error file

  char inputLine[LINELENGTH];//holds line from input file
  //char *token;//holds token from inputLine //defined as global

  int labelLength;//holds length of label
  //int LCvalue;//holds LC value//defined as a global variable
  int num1;//holds number read in while parsing preprocessor directives
  int num2;//holds number read in while parsing preprocessor directives
  int num3;//holds opperand from .resw during 2nd pass
  int num4;//holds 1st opperand from .word during 2nd pass
  int num5;//holds 2nd opperand from .word during 2nd pass

  int o1;//holds first opperand
  int o2;//holds 2nd opperand
  int o3;//holds 3rd opperand


  int firstLabelFlag;// used to not increment LC value of first label
  int passTwoFlag;// LC value is incremented if this flag is 0

  int opCodeLoop;// used when comparing opcode to opcode array


  FILE *inputFile;//pointer to input file


//check for correct number of arguments
  if(argc != EXPECTEDARGS){return 1;}

//open input file; close program if file can't be opened
  if((inputFile=fopen(argv[1],"r"))==NULL){
    return 1;
  }//end if

//  printf("%s\n",argv[1]);
//assign op codes to opCodes[]

  opCodes[AZERO] = "hlt";
  opCodes[AONE] = "add";
  opCodes[ATWO] = "sub";
  opCodes[ATHREE] = "mul";
  opCodes[AFOUR] = "div";
  opCodes[AFIVE] = "mod";
  opCodes[ASIX] = "move";
  opCodes[ASEVEN] = "and";
  opCodes[AEIGHT] = "or";
  opCodes[ANINE] = "xor";
  opCodes[ATEN] ="com";
  opCodes[AELEVEN] ="sll";
  opCodes[ATWELVE] ="srl";
  opCodes[ATHIRTEEN] ="sra";
  opCodes[AFOURTEEN] ="jr";
  opCodes[AFIFTEEN] ="rdr";
  opCodes[ASIXTEEN] ="prr";
  opCodes[ASEVENTEEN] ="prh";
  opCodes[AEIGHTEEN] ="li";
  opCodes[ANINETEEN] ="addi";
  opCodes[ATWENTY] ="subi";
  opCodes[ATWENTYONE] ="muli";
  opCodes[ATWENTYTWO] ="divi";
  opCodes[ATWENTYTHREE] ="modi";
  opCodes[ATWENTYFOUR] ="lwb";
  opCodes[ATWENTYFIVE] ="swb";
  opCodes[ATWENTYSIX] ="lwa";
  opCodes[ATWENTYSEVEN] ="swa";
  opCodes[ATWENTYEIGHT] ="j";
  opCodes[ATWENTYNINE] ="jal";
  opCodes[ATHIRTY] ="jeq";
  opCodes[ATHIRTYONE] ="jne";
  opCodes[ATHIRTYTWO] ="jlt";
  opCodes[ATHIRTYTHREE] ="jle";
  opCodes[ATHIRTYFOUR] ="jgt";
  opCodes[ATHIRTYFIVE] ="jge";

  //printf("%s",opCodes[1]);
  //
  strcpy((char*)inputName,(char*)argv[1]/*,sizeof(argv[1])*/);//copies  file from command line input
  i = (int)strlen((char*)inputName);//assigns length to int i
  j=i;

  while (inputName[i]!= '.' && i>=0){//loop through inputFileName backwards until negative position
    i--;}//decrement i

  if(i==-1){//'.' wasn't found in input file name

/*
//new strings to hold file names
    char symbolName[sizeof(inputName)+4];//holds filename of symbol table
    char objectName[sizeof(inputName)+4];//holds name of object file
    char errorName[sizeof(inputName)+4]; //holds name of error file
    */

//copy modified inputName into new strings
    strncpy(symbolName,(char*)inputName,(int)strlen(inputName));
    strncpy(objectName,(char*)inputName,(int)strlen(inputName));
    strncpy(errorName,(char*)inputName,(int)strlen(inputName));

    strcat(symbolName, ".sym");//add file extensions
    strcat(objectName, ".obj");//''    ''
    strcat(errorName, ".err");//""   ""
//    printf("%s",symbolName);
  }//end of if

  else{//'.' was as found
    while(i<j){//traverse to the end of inputFileName
      inputName[i] = '\0';//erase file extention
      i++;}//end of while


/*
//new strings to hold file names
    char symbolName[sizeof(inputName)+4];//holds filename of symbol table
    char objectName[sizeof(inputName)+4];//holds name of object file
    char errorName[sizeof(inputName)+4]; //holds name of error file */


//copy modified inputName into new strings
    strcpy(symbolName,/*(char*)*/inputName/*,(int)strlen(inputName)*/);
    strcpy(objectName,/*(char*)*/inputName/*,(int)strlen(inputName)*/);
    strcpy(errorName,/*(char*)*/inputName/*,(int)strlen(inputName)*/);

//    printf("%s\n",symbolName);
//    printf("%s\n", objectName);
//    printf("%s\n",errorName);

//add file extensions to new file names
    strcat(symbolName, ".sym");

//     printf("%s\n",symbolName);

    strcat(objectName, ".obj");
    strcat(errorName, ".err");


//    printf("%s\n",symbolName);
//    printf("%s\n",objectName);
//    printf("%s\n",errorName);
  }//end of else

//    printf("%s\n","1");
  if((sym = fopen(symbolName,"w"))==NULL){return 1;}
  if((obj = fopen(objectName,"w"))==NULL){return 1;}
  if((err = fopen(errorName,"w"))==NULL){return 1;}

  //correct numbers of arguments, files opened and renamed, start reading in .asm file line by line
  firstLabelFlag = 1;
  listFlag = 1;//indicates that list is empty
  lineNumber = 0;//set line number to 0 initially
  errorFlag = 0;//starts off and is set to 1 if an error is detected


  fprintf(err,"%s\n", "Error(s) detected:");

  while(fgets(inputLine, LINELENGTH, inputFile)!= NULL){
//    printf("%s\n","4");
    lineNumber++;//increment line number for every line read in
    i = 0;//set i to zero initially
//printf("%d\n",lineNumber);

    while(i<81){//loop through array character by character
      if(inputLine[i]== '#'){
        //i =0;//set i back to 0
        //fgets(inputLine, 81, inputFile);//get next line of .asm
      //  printf("\n%s %d\n","pound sign found before non-whitespace character",i);
        break;
      }//end if '#' was found first

     else if(inputLine[i]!=' '&& inputLine[i]!='\t' && inputLine[i]!='\n'){
       // printf("\n%s\n","non-whitespace character was found before pound; processing line");
        break;//must have read in a non whitespace character that isn't a #; parse line.
      }//end if a character other than white space or sharp sign.
      else{i++;//read a white space character; read next char
     //  printf("%s %d ","character in line being examined:",i);
     }
    }//end loop through list

    if(inputLine[i]=='#'){
     // printf("%s\n","comment found first; reading in new line");
      continue;//ignore this line
    }//end if line is a comment

    if(inputLine[i]=='\0'){
    //    printf("%s\n","examined entire line and found only whitespace; reading in new line");
      continue;
    }//end if input line is NULL
    token = strtok(inputLine, "\t ");//braks inputLine by tabs and spaces
    labelLength = (int)strlen(token)-1;//assign length of string to  labelLength

    if(token[labelLength]==':'){//If last character in token is a : then it is a label
       // printf("%s\n","label found");
      if(firstLabelFlag==1){
         firstLabelFlag=0;
        // printf("%s\n","1st label; calling insert function");
        // printf("%s\n",token);
          token[labelLength] = '\0';//strip colon
         insert(LCvalue, token);
         //printf("%s","label: ");
         //printf("%s\n",token);

       //insert token into hash table as label without increasing LCvalue
      }//end if firstLabelFlag equals 1
      else{//LCvalue++;
    //    printf("%s\n","2nd or later label; calling insert function");
        token[labelLength] ='\0';//strip colon
        insert(LCvalue, token);
      //    printf("%s\n%s","insert was just called","label: ");
       // printf("%s\n",token);
      }//end else; firstLabelFlag equals 0
      token = strtok(NULL, "\t ");//assign return of strtok to token; delimit by whitespace
    }//end if

    if(token[0]== '.'){//if 1st character of token is a '.' then the token is a preprocessor directive

      if(token[1]=='r'){
        token=strtok(NULL, "\t \n");
        num1 = atoi(token); //assign integer value of read in resw paramter
        LCvalue += num1;//increase LCvalue by number of words reserved
        continue;
      }//end if resw

      else if(token[1]=='w'){
          //printf("\n\n\n\n%s\n\n\n\n",".word found");
        strtok(NULL,":");//throw away first character
        token = strtok(NULL, "\t ");//assign next token to token; delimters are space and tab
        num2 = atoi(token);
  //      printf("%s %d\n","number or words reserved by .word directive",num2);
        LCvalue += num2;
        continue;
      }//end if word

      if(token[1]== 't'){
        //text segment
        //printf("\n\n\n\n%s\n\n\n\n","text segment:");
        continue;
      }//end if 2nd character of token t

      if(token[1]=='d'){
        //data segment
        //printf("\n\n\n\n%s\n\n\n\n","data segment:");
        continue;
      }//end if 2nd character of token is a d

    }//end if preprocessor directive


  //current line was erronious or had a label
  //incremet LCvalue by 1 word
  LCvalue++;

  }//end while .asm has lines

//printf("\n\n%s\n\n","Printing list's contents");
printList();

//Symbol Table has been formed; ready for pass 2
rewind(inputFile);//rewinds position indicator for 2nd pass
lineNumber = 0;//set line number back to zero
LCvalue = 0;//set LC value back to 0

while(fgets(inputLine, LINELENGTH, inputFile)!= NULL){//read input line by line until there is nothing left(pass2)

  passTwoFlag = 0;
  lineNumber++;//increment line number for every line read in
  i = 0;//set i to zero initially
  //printf("%d %s\n",lineNumber,"pass two");

  while(i<LINELENGTH){//loop through array character by character
    if(inputLine[i]== '#'){
      //printf("\n%s %d\n","pound sign found before non-whitespace character",i);
      break;
    }//end if '#' was found first

    else if(inputLine[i]!=' '&& inputLine[i]!='\t' && inputLine[i]!='\n'){
      //printf("\n%s\n","non-whitespace character was found before pound; processing line");
      break;//must have read in a non whitespace character that isn't a #; parse line.
     }//end if a character other than white space or sharp sign.

    else{i++;//read a white space character; read next char
      //printf("%s %d ","character in line being examined:",i);
      }
    }//end loop through list

    if(inputLine[i]=='#'){
      //printf("%s\n","comment found first; reading in new line");
      continue;//ignore this line
    }//end if line is a comment

    if(inputLine[i]=='\0'){
      //printf("%s\n","examined entire line and found only whitespace; reading in new line");
      continue;
    }//end if input line is NULL

    token = strtok(inputLine, " \t \n");//parse line by whitespace characters
    labelLength = strlen(token)-1;//assign length of label; token is one longer than label

    if(token[labelLength]==':'){//if final position of token is a : then token must be a label
     //store token as label
     //passTwoFlag =1;
     //LCvalue++;
     token = strtok(NULL, " \t \n");// continue to parse line
    }//end if token is a label

    if(token[0]=='.'){//if 1st position of token is a . the the token is a directive
      passTwoFlag = 1;
      if(token[1]=='r'){//if 2nd position of token is an r then the dierective is .resw
          //printf("%s\n","2nd pass resw");
          token = strtok(NULL, " \t\n");//grab opperand
          num3 = atoi(token);//assign the integer value of the opperand to num3
          resw(LCvalue, num3);
          LCvalue = LCvalue +num3;

          //call function to write object code for .resw

      }// end if 2nd position is a r
      else if(token[1]=='w'){//if the 2nd position of token is a w, then the directive is .word
          //printf("%s\n","2nd pass word");
        num4 = atoi(strtok(NULL, ":"));//assign num4 the integer value of the opperand before the :
        num5 = atoi(strtok(NULL," \t\n"));//assign num5 the integer value of the opperand after the :
        word(LCvalue, num4, num5);
        LCvalue = LCvalue + num5;
      }//end if 2nd position is a w
      else if(token[1]=='t'){//text directive

      }//end if 2nd position is a t

      else if(token[1]=='d'){//data directive


      }//end if 2nd position is a d
      continue;
    }//end if token is a directive



  //At this point we know that the token isn't a preprocessor directive or a a label
  //so we will treat it as an opcode.

  opCodeLoop = 0;//assign opCodeLoop to zero before looping through array of opcodes
  while(opCodeLoop<ARRAYSIZE){//while elements remain in the opcode array
    if(strcmp(opCodes[opCodeLoop],token)==0){//if current token matches an opcode
        //printf("%s\n","opcode found");
      //value of opCodeLoop determines opperands to expect
      if(opCodeLoop == 0){
        //hlt takes no opperands
        rFormat(LCvalue, 0,0,0,0,0);
        break;
      }//end if hlt

      else if(opCodeLoop > 0 && opCodeLoop < ASIX){
        //these take three registers
        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        token[0] = ' ';//replace $ with ' '
        o1 = atoi(token);

        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        token[0] = ' ';//replace $ with ' '
        o2 = atoi(token);

        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        token[0] = ' ';//replace $ with ' '
        o3 = atoi(token);


        rFormat(LCvalue, opCodeLoop, o2, o3, o1,  0);
        break;
      }//end if opcode is an arithmatic operator(1)

      else if(opCodeLoop > ASIX && opCodeLoop <ATEN){
        //these take three registers
        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        token[0] = ' ';//replace $ with ' '
        o1 = atoi(token);

        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        token[0] = ' ';//replace $ with ' '
        o2 = atoi(token);

        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        token[0] = ' ';//replace $ with ' '
        o3 = atoi(token);


        rFormat(LCvalue, opCodeLoop, o2, o3, o1, 0);
        break;
      }//end if opcode is arithmatic

      else if(opCodeLoop ==ASIX || opCodeLoop == ATEN ){
        //these take two registers
        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        token[0] = ' ';//replace $ with ' '
        o1 = atoi(token);

        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        token[0] = ' ';//replace $ with ' '
        o2 = atoi(token);

        rFormat(LCvalue, opCodeLoop, o2, 0, o1, 0);
        break;
      }//end if opcode is move or com

      else if(opCodeLoop > ATEN && opCodeLoop <AFOURTEEN){
        //these take two registers then an int
        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        token[0] = ' ';//replace $ with ' '
        o1 = atoi(token);

        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        token[0] = ' ';//replace $ with ' '
        o2 = atoi(token);

        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        o3 = atoi(token);


        rFormat(LCvalue, opCodeLoop, o2, 0, o1, o3);
        break;
      }//end if opcode is a shift

      else if(opCodeLoop > ATHIRTEEN && opCodeLoop< AEIGHTEEN){
        //these take one register
        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        token[0] = ' ';//replace $ with ' '
        o1 = atoi(token);
        rFormat(LCvalue, opCodeLoop, 0, 0, o1, 0);
        break;
      }//end if opcode is idk something

      else if(opCodeLoop == AEIGHTEEN){
        //this takes one register and one int
        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        token[0] = ' ';//replace $ with ' '
        o1 = atoi(token);

        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        o2 = atoi(token);
         iFormat(LCvalue, opCodeLoop, 0, o1, o2);
         break;
      }//end if opcode is li

      else if(opCodeLoop > AEIGHTEEN && opCodeLoop< ATWENTYFOUR){
        //these take two registers and an int
        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        token[0] = ' ';//replace $ with ' '
        o1 = atoi(token);

        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        token[0] = ' ';//replace $ with ' '
        o2 = atoi(token);

        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        o3 = atoi(token);
        iFormat(LCvalue, opCodeLoop, o2, o1, o3);
        break;
      }//end if opcode is an immediate

      else if(opCodeLoop == ATWENTYFOUR || opCodeLoop == ATWENTYFIVE){
        //these take a register followed by an immediate and another regiester in ()

        token = strtok(NULL, " ,\t\n()");//parse by whitespace, (, ), and ,
        token[0] = ' ';//replace $ with ' '
        o1 = atoi(token);

        token = strtok(NULL, " ,\t\n()");//parse by whitespace, (, ),  and ,
        o2 = atoi(token);

        token = strtok(NULL, " ,\t\n()");//parse by whitespace, (, ),  and ,
        token[0] = ' ';//replace $ with ' '
        o3 = atoi(token);
        iFormat(LCvalue, opCodeLoop, o3, o1, o2);
        break;
      }//end if opcode is lwb or swb

      else if(opCodeLoop == ATWENTYSIX || opCodeLoop == ATWENTYSEVEN){
//        printf("%s\n","opcode 26 or 27");
        //these take a regiester and a label
        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        token[0] = ' ';//replace $ with ' '
        o1 = atoi(token);

        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        //token[0] = ' ';

        jFormat(LCvalue, opCodeLoop, 0, o1, token);
        break;

      }//end if opcode is lwa or swa

      else if(opCodeLoop == ATWENTYEIGHT){
        //these take only a label
        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        //token[0]= ' ';

        jFormat(LCvalue, opCodeLoop, 0, 0, token);
        break;

      }//end if opcode is an unconditional jump

      else if(opCodeLoop > ATWENTYEIGHT && opCodeLoop<= ATHIRTYFIVE){
        //these take two registers and a label
        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        token[0] = ' ';//replace $ with ' '
        o1 = atoi(token);

        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        token[0] = ' ';//replace $ with ' '
        o2 = atoi(token);

        token = strtok(NULL, " ,\t\n");//parse by whitespace and ,
        //token[0] = ' ';

        jFormat(LCvalue,opCodeLoop, o2, o1, token);
        break;

      }//end if opcode is a conditional jump


    }//end if token matches opCode

    opCodeLoop++;
    if(opCodeLoop == ARRAYSIZE){//opCode wasn't found in list
      errorFlag = 1;//error detected
      fprintf(err, "%d\t%s\n", lineNumber, "Illegal opcode found in this line.");
    }//end if opcode wasn't found in opcode array*/

  }//end loop through opcode array

     if(passTwoFlag == 0){
      LCvalue++;
    }//end if passTwo Flag is 0

}//end loop reading lines of input (pass2)

//.asm's lines to error file
rewind(inputFile);//rewinds position indicator for 2nd pass
lineNumber = 0;//set line number back to zero



fprintf(err,"\n\n\n%s\n", "Multiply defined symbols:");
checkMulti();
fprintf(err, "\n\n\n%s\n", "Undefined symbols:");
printUndefined();

fprintf(err,"\n\n\n%s\n","File listings:");
while(fgets(inputLine, LINELENGTH, inputFile)!= NULL){
  lineNumber++;
  fprintf(err,"%d\t%s\n", lineNumber, inputLine);

}//end while there are lines remaining in the .asm file

if(errorFlag == 1){//one or more errors detected
  remove(symbolName);//delete symbol table file
  remove(objectName);//delete object code file
}//end if errors were detected

else{//no errors detected
  remove(errorName);//delete error file
}//end else errors weren't detected

return 0;}//end of main
예제 #20
0
bool ProcessBattleStepAI(iBattleEngine& engine)
{
	bool bRes = false;
	const sint32 INV_CVAL = -65536;
	_LOG(_T(">> Begin of Battle AI <<\r\n"));

	iBattleUnit* pCurUnit = engine.TurnSeq().CurUnit();

	if (iBattleUnit_CreatGroup* pCreatUnit = DynamicCast<iBattleUnit_CreatGroup*>(pCurUnit)) {
		iBattleGroup* pGroup = pCreatUnit->GetCreatGroup();

		// Shoot list
		if (pGroup->ShootListCount()) {
	#ifdef DEBUG_BATTLE_AI
			_LOG(iFormat(_T("Shot targets found:%d\r\n"),pGroup->ShootListCount()).CStr());
			for (uint32 ll=0; ll<pGroup->ShootListCount(); ++ll) 
				_LOG(iFormat(_T("%d,%d\r\n"),pGroup->GetShootEntry(ll)->m_pos.x,pGroup->GetShootEntry(ll)->m_pos.y).CStr());
	#endif // DEBUG_BATTLE_AI

			// select appropriate target
			sint32 cval = INV_CVAL;
			sint32 penalty = 0;
			iPoint mCell;
			for (uint32 xx=0; xx<pGroup->ShootListCount(); ++xx) {
				const iBattleGroup::iShootEntry* se = pGroup->GetShootEntry(xx);
				iBattleGroup* pTarget = engine.FindGroup(se->m_pos);
				check(pTarget);
				sint32 val = CalcShootValue(pGroup, se, pTarget);
				if ( cval == INV_CVAL || cval < val) {
					cval = val;
					mCell = se->m_pos;
					penalty = se->m_penalty;
				}
			}
			engine.Shot(mCell, penalty);
			bRes = true;
		} else if (pGroup->MeleeListCount()) {
	#ifdef DEBUG_BATTLE_AI
			_LOG(iFormat(_T("Melee targets found:%d\r\n"),pGroup->MeleeListCount()).CStr());
			for (uint32 ll=0; ll<pGroup->MeleeListCount(); ++ll) 
				_LOG(iFormat(_T("%d,%d\r\n"),pGroup->GetMeleeEntry(ll)->m_pos.x,pGroup->GetMeleeEntry(ll)->m_pos.y).CStr());
	#endif // DEBUG_BATTLE_AI

			// select appropriate target and direction
			sint32 cval = INV_CVAL;
			iPoint mCell;
			uint16 mDir = 0xffff;
			for (uint32 xx=0; xx<pGroup->MeleeListCount(); ++xx) {
				const iBattleGroup::iMeleeEntry* me = pGroup->GetMeleeEntry(xx);
				iBattleGroup* pTarget = engine.FindGroup(me->m_pos);
				check(pTarget);
				sint32 val = CalcMeleeValue(pGroup, me, pTarget);
				for (uint16 dd=0; dd<12; ++dd) {
					if (me->m_cfg & (1<<dd)) {
						sint32 dval = val;
						iPoint mp;
						uint8 aor;
						pGroup->GetMeleePosition(pTarget, me->m_pos, dd, mp, aor);
						dval -= (sint32)pGroup->DistMap().GetAt(mp.x,mp.y).dirs[aor].val;
						if ( cval == INV_CVAL || cval < dval) {
							cval = dval;
							mCell = me->m_pos;
							mDir = dd;
						}
					}
				}
			}
			check( mDir != 0xffff );
			engine.Melee(mCell, mDir);
			bRes = true;
		} else if (pGroup->PotTargetsCount()) {
			// first try to wait
			if (pCurUnit->CanWait()) {
				_LOG(_T("Found potential melee targets. Wait.\r\n"));
				engine.Wait();
			} else {
				#ifdef DEBUG_BATTLE_AI
						_LOG(iFormat(_T("Potential melee targets found:%d\r\n"),pGroup->PotTargetsCount()).CStr());
						for (uint32 ll=0; ll<pGroup->PotTargetsCount(); ++ll) 
							_LOG(iFormat(_T("%d,%d\r\n"),pGroup->GetPotTargetEntry(ll)->m_pos.x,pGroup->GetPotTargetEntry(ll)->m_pos.y).CStr());
				#endif // DEBUG_BATTLE_AI

				// select appropriate target and direction
				sint32 cval = INV_CVAL;
				iPoint mCell;
				uint16 mDir;
				uint8 mOrient;
				iPoint mPos;
				for (uint32 xx=0; xx<pGroup->PotTargetsCount(); ++xx) {
					const iBattleGroup::iMeleeEntry* me = pGroup->GetPotTargetEntry(xx);
					iBattleGroup* pTarget = engine.FindGroup(me->m_pos);
					check(pTarget);
					sint32 val = CalcMeleeValue(pGroup, me, pTarget);
					for (uint16 dd=0; dd<12; ++dd) {
						if (me->m_cfg & (1<<dd)) {
							sint32 dval = val;
							iPoint mp;
							uint8 aor;
							pGroup->GetMeleePosition(pTarget, me->m_pos, dd, mp, aor);
							dval -= (sint32)pGroup->DistMap().GetAt(mp.x,mp.y).dirs[aor].val;
							if ( cval == INV_CVAL || cval < dval) {
								cval = dval;
								mCell = me->m_pos;
								mDir = dd;
								mOrient = aor;
								mPos = mp;
							}
						}
					}
				}

				CalculatePath(pGroup, mPos, mOrient);
				_LOG(iFormat(_T("Group at (%d,%d) move to (%d,%d)\r\n"),pGroup->Pos().x,pGroup->Pos().y,mPos.x,mPos.y).CStr());
				engine.Move(mPos, mOrient);
				bRes = true;
			}
		} else {
			if (pCurUnit->CanWait()) {
				_LOG(_T("Nothing to do. Wait.\r\n"));
				engine.Wait();
			} else {
				_LOG(_T("Nothing to do. Skip the turn.\r\n"));
				bRes = engine.Defend();
			}
		}
	} else if (iBattleUnit_Catapult* pCatapult = DynamicCast<iBattleUnit_Catapult*>(pCurUnit)) {
		engine.CatapultShot(engine.CastleFort()->GetTarget());
		bRes = true;
	} else if (iBattleUnit_Turret* pTurret = DynamicCast<iBattleUnit_Turret*>(pCurUnit)) {
		iBattleGroup* pTarget = SelectTurretTarget(engine);
		check(pTarget);
		engine.TurretShot(pTarget);
		bRes = true;
	} else {
		check(0);
	}

	_LOG(_T(">> End of Battle AI <<\r\n"));
	return bRes;
}