void CFactory::FinishBuild(CUnit* buildee) { if (buildee->beingBuilt) { return; } if (unitDef->fullHealthFactory && buildee->health < buildee->maxHealth) { return; } { GML_RECMUTEX_LOCK(group); // FinishBuild if (group && buildee->group == 0) { buildee->SetGroup(group, true); } } const CCommandAI* bcai = buildee->commandAI; const bool assignOrders = bcai->commandQue.empty() || (dynamic_cast<const CMobileCAI*>(bcai) && static_cast<const CMobileCAI*>(bcai)->unimportantMove); if (assignOrders) { AssignBuildeeOrders(buildee); waitCommandsAI.AddLocalUnit(buildee, this); } // inform our commandAI finishedBuildFunc(this, finishedBuildCommand); finishedBuildFunc = NULL; eventHandler.UnitFromFactory(buildee, this, !assignOrders); StopBuild(); }
void CFactory::FinishBuild(CUnit* buildee) { if (buildee->beingBuilt) { return; } if (unitDef->fullHealthFactory && buildee->health < buildee->maxHealth) { return; } { if (group && !buildee->group) { buildee->SetGroup(group, true); } } const CCommandAI* bcai = buildee->commandAI; // if not idle, the buildee already has user orders const bool buildeeIdle = (bcai->commandQue.empty()); const bool buildeeMobile = (dynamic_cast<const CMobileCAI*>(bcai) != NULL); if (buildeeIdle || buildeeMobile) { AssignBuildeeOrders(buildee); waitCommandsAI.AddLocalUnit(buildee, this); } // inform our commandAI finishedBuildFunc(this, finishedBuildCommand); finishedBuildFunc = NULL; eventHandler.UnitFromFactory(buildee, this, !buildeeIdle); StopBuild(); }
void CFactory::DependentDied(CObject* o) { if (o == curBuild) { curBuild = 0; StopBuild(); } CUnit::DependentDied(o); }
void CFactory::Update() { nanoPieceCache.Update(); if (beingBuilt) { // factory is under construction, cannot build anything yet CUnit::Update(); #if 1 // this can happen if we started being reclaimed *while* building a // unit, in which case our buildee can either be allowed to finish // construction (by assisting builders) or has to be killed --> the // latter is easier if (curBuild != NULL) { StopBuild(); } #endif return; } if (curBuildDef != NULL) { if (!yardOpen && !IsStunned()) { if (groundBlockingObjectMap->CanOpenYard(this)) { script->Activate(); groundBlockingObjectMap->OpenBlockingYard(this); // make sure the idle-check does not immediately trigger // (scripts have 7 seconds to set inBuildStance to true) lastBuildUpdateFrame = gs->frameNum; } } if (yardOpen && inBuildStance && !IsStunned()) { StartBuild(curBuildDef); } } if (curBuild != NULL) { UpdateBuild(curBuild); FinishBuild(curBuild); } const bool wantClose = (!IsStunned() && yardOpen && (gs->frameNum >= (lastBuildUpdateFrame + GAME_SPEED * 7))); const bool closeYard = (wantClose && curBuild == NULL && groundBlockingObjectMap->CanCloseYard(this)); if (closeYard) { // close the factory after inactivity groundBlockingObjectMap->CloseBlockingYard(this); script->Deactivate(); } CBuilding::Update(); }
void CFactory::StartBuild(string type) { if(beingBuilt) return; #ifdef TRACE_SYNC tracefile << "Start build: "; tracefile << type.c_str() << "\n"; #endif if(curBuild) StopBuild(); quedBuild=true; nextBuild=type; if(!opening){ cob->Call(COBFN_Activate); readmap->OpenBlockingYard(this, unitDef->yardmap); opening=true; } }
void CFactory::StartBuild(string type) { if(beingBuilt) return; #ifdef TRACE_SYNC tracefile << "Start build: "; tracefile << type.c_str() << "\n"; #endif if(curBuild) StopBuild(); quedBuild=true; nextBuild=type; if(!opening){ animator->AnimAction(ANIMFN_Activate); readmap->OpenBlockingYard(this, yardMap); opening=true; } }
void CFactory::StartBuild(string type) { if (beingBuilt) return; #ifdef TRACE_SYNC tracefile << "Start build: "; tracefile << type.c_str() << "\n"; #endif if (curBuild) StopBuild(); quedBuild = true; nextBuild = type; if (!opening && !stunned) { cob->Call(COBFN_Activate); groundBlockingObjectMap->OpenBlockingYard(this, yardMap); opening = true; } }
void CFactory::StartBuild(const UnitDef* ud) { if (beingBuilt) return; if (curBuild) StopBuild(); quedBuild = true; nextBuild = ud; nextBuildName = ud->name; #ifdef TRACE_SYNC tracefile << "Start build: "; tracefile << ud->name.c_str() << "\n"; #endif if (!opening && !stunned) { script->Activate(); groundBlockingObjectMap->OpenBlockingYard(this, curYardMap); opening = true; } }
LRESULT CALLBACK ProjectProc(HWND hwnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { int i; RECT rs; NM_TREEVIEW *nm; DWINFO info; LPNMTVKEYDOWN key; PROJECTITEM *data; TVHITTESTINFO hittest; HWND win; HTREEITEM oldSel; static HCURSOR origCurs; static BOOL dragging; static BOOL inView; static HTREEITEM srcItem, dstItem; switch (iMessage) { LOGFONT lf; case WM_SYSCOMMAND: if (wParam == SC_CLOSE) SendMessage(hwnd, WM_CLOSE, 0, 0); break; // case WM_SETTEXT: // return SendMessage(hwndTab, iMessage, wParam, lParam); case WM_LBUTTONDOWN: case WM_RBUTTONDOWN: SetFocus(hwnd); break; case WM_NOTIFY: nm = (NM_TREEVIEW*)lParam; switch (nm->hdr.code) { case NM_CUSTOMDRAW: return CustomDraw(hwnd, (LPNMTVCUSTOMDRAW)nm); case N_EDITDONE: DoneRenaming(); break; case TVN_BEGINDRAG: GetCursorPos(&hittest.pt); ScreenToClient(prjTreeWindow, &hittest.pt); srcItem = TreeView_HitTest(prjTreeWindow, &hittest); data = GetItemInfo(srcItem); if (data && (data->type == PJ_FILE || data->type == PJ_FOLDER)) { dragging = TRUE; SetCapture(hwnd); origCurs = SetCursor(dragCur); inView = TRUE; } break; case TVN_KEYDOWN: key = (LPNMTVKEYDOWN)lParam; switch (key->wVKey) { case VK_INSERT: if (GetKeyState(VK_CONTROL) &0x80000000) { data = GetItemInfo(prjSelectedItem); if (data) { int msg = -1; switch (data->type) { case PJ_WS: msg = IDM_EXISTINGPROJECT; break; case PJ_PROJ: msg = IDM_NEWFOLDER; break; case PJ_FOLDER: msg = IDM_EXISTINGFILE; break; } if (msg != -1) PostMessage(hwnd, WM_COMMAND, msg, 0); } } else if (GetKeyState(VK_SHIFT) &0x80000000) { data = GetItemInfo(prjSelectedItem); if (data) { int msg = -1; switch (data->type) { case PJ_WS: msg = IDM_NEWPROJECT; break; case PJ_PROJ: msg = IDM_NEWFOLDER; break; case PJ_FOLDER: msg = IDM_NEWFILE_P; break; } if (msg != -1) PostMessage(hwnd, WM_COMMAND, msg, 0); } } else { data = GetItemInfo(prjSelectedItem); if (data && (data->type != PJ_WS)) PostMessage(hwnd, WM_COMMAND, IDM_RENAME, 0); } break; case VK_DELETE: if (!(GetKeyState(VK_CONTROL) &0x80000000) && !(GetKeyState(VK_SHIFT) &0x8000000)) { data = GetItemInfo(prjSelectedItem); if (data && (data->type == PJ_FOLDER || data->type == PJ_FILE)) PostMessage(hwnd, WM_COMMAND, IDM_REMOVE, 0); } break; case VK_RETURN: SendMessage(hwnd, WM_COMMAND, IDM_OPENFILES, 0); break; } break; case NM_DBLCLK: oldSel = prjSelectedItem; GetCursorPos(&hittest.pt); ScreenToClient(prjTreeWindow, &hittest.pt); prjSelectedItem = TreeView_HitTest(prjTreeWindow, &hittest); if (prjSelectedItem) PostMessage(hwnd, WM_COMMAND, IDM_OPENFILES, 0); prjSelectedItem = oldSel; return 0; case NM_RCLICK: GetCursorPos(&hittest.pt); ScreenToClient(prjTreeWindow, &hittest.pt); prjSelectedItem = TreeView_HitTest(prjTreeWindow, &hittest); if (prjSelectedItem) { TreeView_SelectItem(prjTreeWindow, prjSelectedItem); } CreateProjectMenu(); break; case TVN_SELCHANGED: nm = (NM_TREEVIEW*)lParam; prjSelectedItem = nm->itemNew.hItem; if (prjSelectedItem == 0) prjSelectedItem = workArea->hTreeItem; break; case TVN_ITEMEXPANDED: nm = (NM_TREEVIEW *)lParam; data = GetItemInfo(nm->itemNew.hItem); if (data) { if (data->type == PJ_FOLDER) { TV_ITEM setitem; memset(&setitem, 0, sizeof(setitem)); setitem.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; setitem.iImage = setitem.iSelectedImage = nm->action == TVE_EXPAND ? ilfolderOpen : ilfolderClose; setitem.hItem = nm->itemNew.hItem; TreeView_SetItem(prjTreeWindow, &setitem); } if (nm->action == TVE_EXPAND) { data->expanded = TRUE; } else data->expanded = FALSE; return 0; } break; case TVN_DELETEITEM: nm = (NM_TREEVIEW *)lParam; if (nm->itemOld.hItem == prjSelectedItem) prjSelectedItem = TreeView_GetSelection(prjTreeWindow); break; } break; case WM_COMMAND: switch (LOWORD(wParam)) { case ID_TBPROFILE: if (HIWORD(wParam) == CBN_SELENDOK) { int i = SendMessage(hwndTbProfile, CB_GETCURSEL, 0 , 0); if (i != CB_ERR) { if (i == 0) { strcpy(currentProfileName, sysProfileName); } else { PROFILENAMELIST *pf = profileNames; while (pf && --i) pf = pf->next; if (pf) { strcpy(currentProfileName, pf->name); } } MarkChanged(workArea, TRUE); } } break; case ID_TBBUILDTYPE: if (HIWORD(wParam) == CBN_SELENDOK) { int i = SendMessage(hwndTbBuildType, CB_GETCURSEL, 0 , 0); if (i != CB_ERR) { profileDebugMode = i == 0 ? 1 : 0; MarkChanged(workArea, TRUE); } } break; case IDM_RESETPROFILECOMBOS: { HWND htemp; PROFILENAMELIST *pf; int selected,n; int count; POINT pt; pf = profileNames; selected = 0; count = 0; SendMessage(hwndTbProfile, CB_RESETCONTENT, 0, 0); SendMessage(hwndTbProfile, CB_ADDSTRING, 0, (LPARAM)sysProfileName); while (pf) { count++; if (!strcmp(pf->name,currentProfileName)) selected = count; SendMessage(hwndTbProfile, CB_ADDSTRING, 0, (LPARAM)pf->name); pf = pf->next; } SendMessage(hwndTbProfile, CB_SETCURSEL, selected, 0); SendMessage(hwndTbBuildType, CB_RESETCONTENT, 0, 0); SendMessage(hwndTbBuildType, CB_ADDSTRING, 0, (LPARAM)"Debug"); SendMessage(hwndTbBuildType, CB_ADDSTRING, 0, (LPARAM)"Release"); SendMessage(hwndTbBuildType, CB_SETCURSEL, profileDebugMode ? 0 : 1, 0); pt.x = 5; pt.y = 5; htemp = ChildWindowFromPoint(hwndTbProfile, pt); SendMessage(htemp, EM_SETREADONLY, 1, 0); htemp = ChildWindowFromPoint(hwndTbBuildType, pt); SendMessage(htemp, EM_SETREADONLY, 1, 0); EnableWindow(hwndTbProfile, TRUE); EnableWindow(hwndTbBuildType, TRUE); break; } case IDM_IMPORT_CWS: ImportProject(FALSE); break; case IDM_IMPORT_CTG: ImportProject(TRUE); break; case IDM_DOSWINDOW: { DosWindow(activeProject ? activeProject->realName : NULL, NULL, NULL, NULL, NULL); } break; case IDM_MAKEWINDOW: { char exec[MAX_PATH]; sprintf(exec, "%s\\bin\\imake.exe", szInstallPath); DosWindow(activeProject ? activeProject->realName : NULL, exec, "", "Custom Make", "Make Is Complete."); } break; case IDM_RUN: SaveWorkArea(workArea); dbgRebuildMain(wParam); break; case IDM_SETACTIVEPROJECT: ProjectSetActive(); break; case IDM_NEWFILE_P: ProjectNewFile(); PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0); break; case IDM_EXISTINGFILE: ProjectExistingFile(); PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0); break; case IDM_NEWPROJECT: ProjectNewProject(); PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0); break; case IDM_EXISTINGPROJECT: ProjectExistingProject(); PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0); break ; case IDM_REMOVE: ProjectRemove(); PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0); break; case IDM_RENAME: ProjectRename(); break; case IDM_NEWFOLDER: ProjectNewFolder(); PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0); break; case IDM_NEWWS: if (uState != notDebugging) { if (ExtendedMessageBox("WorkArea", MB_OKCANCEL, "This action requires the debugger to be stopped.") != IDOK) { break; } abortDebug(); } SelectWindow(DID_PROJWND); ProjectNewWorkArea(); break; case IDM_OPENWS: if (uState != notDebugging) { if (ExtendedMessageBox("WorkArea", MB_OKCANCEL, "This action requires the debugger to be stopped.") != IDOK) { break; } abortDebug(); } SelectWindow(DID_PROJWND); ProjectExistingWorkArea(); break; case IDM_CLOSEWS: if (making) break; if (uState != notDebugging) { if (ExtendedMessageBox("WorkArea", MB_OKCANCEL, "This action requires the debugger to be stopped.") != IDOK) { break; } abortDebug(); } CloseWorkArea(); break; case IDM_SAVEWS: SaveAllProjects(workArea, TRUE); break; case IDM_COMPILEFILEFROMTREE: { PROJECTITEM *data = GetItemInfo(prjSelectedItem); if (data && data->type == PJ_FILE) { unlink(data->outputName); Maker(data, TRUE); } } break; case IDM_COMPILEFILE: win = (HWND)SendMessage(hwndClient, WM_MDIGETACTIVE, 0, 0); if (IsWindow(win) && IsEditWindow(win)) { HTREEITEM item = FindItemByWind(win); PROJECTITEM *data = GetItemInfo(item); if (data) { unlink(data->outputName); Maker(data, TRUE); } } break; case IDM_GENMAKE: if (workArea && workArea->children) { genMakeFile(workArea); } else { ExtendedMessageBox("Makefile Generation", MB_SETFOREGROUND | MB_SYSTEMMODAL, "You need at least one project to generate a make file"); } break; case IDM_MAKE: if (HIWORD(wParam)) if (GetKeyState(VK_CONTROL) &0x80000000) SendMessage(hwnd, WM_COMMAND, IDM_COMPILEFILE, 0); else if (GetKeyState(VK_SHIFT) &0x80000000) Maker(activeProject, FALSE); else Maker(workArea, FALSE); else Maker(workArea, FALSE); break; case IDM_MAKE_RIGHTCLICK: if (HIWORD(wParam)) if (GetKeyState(VK_CONTROL) &0x80000000) SendMessage(hwnd, WM_COMMAND, IDM_COMPILEFILE, 0); else if (GetKeyState(VK_SHIFT) &0x80000000) Maker(activeProject, FALSE); else Maker(workArea, FALSE); else { if (prjSelectedItem) { PROJECTITEM *data = GetItemInfo(prjSelectedItem); if (data) { Maker(data, FALSE); break; } } Maker(workArea, FALSE); } break; case IDM_BUILDALL: Maker(workArea, TRUE); break; case IDM_BUILDALL_RIGHTCLICK: if (prjSelectedItem) { PROJECTITEM *data = GetItemInfo(prjSelectedItem); if (data) { Maker(data, TRUE); break; } } Maker(workArea, TRUE); break; case IDM_BUILDSELECTED: Maker(activeProject, FALSE); break; case IDM_STOPBUILD: StopBuild(); break; case IDM_CALCULATEDEPENDS: CalculateProjectDepends(GetItemInfo(prjSelectedItem)); break; case IDM_RUNNODEBUG: { SaveWorkArea(workArea); RunProgram(activeProject); break; } case IDM_SELECTPROFILE: SelectProfileDialog(); break; case IDM_ACTIVEPROJECTPROPERTIES: if (activeProject) prjSelectedItem = activeProject->hTreeItem; // fall through case IDM_PROJECTPROPERTIES: data = GetItemInfo(prjSelectedItem); ShowBuildProperties(data); break; case IDM_PROJECTDEPENDS: data = GetItemInfo(prjSelectedItem); EditProjectDependencies(data); break; case IDM_OPENFILES: data = GetItemInfo(prjSelectedItem); if (data) if (data->type == PJ_FILE) { if (strlen(data->realName) >= 3 && !stricmp(data->realName + strlen(data->realName) -3, ".rc")) { NavigateToResource(data); } else { strcpy(info.dwName, data->realName); strcpy(info.dwTitle, data->displayName); info.dwLineNo = - 1; info.logMRU = FALSE; info.newFile = FALSE; CreateDrawWindow(&info, TRUE); } } break; case IDM_CLOSE: SendMessage(hwnd, WM_CLOSE, 0, 0); break; default: return DefWindowProc(hwnd, iMessage, wParam, lParam); } break; case WM_LBUTTONUP: if (dragging) { SetCursor(origCurs); ReleaseCapture(); dragging = FALSE; TreeView_SelectDropTarget(prjTreeWindow, NULL); if (inView && dstItem != srcItem && srcItem && dstItem) { DragTo(dstItem, srcItem); } } break; case WM_MOUSEMOVE: if (dragging) { hittest.pt.x = (long)(short)LOWORD(lParam); hittest.pt.y = (long)(short)HIWORD(lParam); dstItem = TreeView_HitTest(prjTreeWindow, &hittest); if (dstItem && dstItem != srcItem) { PROJECTITEM *srcData = GetItemInfo(srcItem); data = GetItemInfo(dstItem); if (srcData && data) { PROJECTITEM *p = data->parent; while (p) if (p == srcData) break; else p = p->parent; if (p) { if (inView) { inView = FALSE; SetCursor(noCur); TreeView_SelectDropTarget(prjTreeWindow, NULL); } break; } } if (data && (data->type == PJ_PROJ || data->type == PJ_FOLDER)) { if (!inView) { inView = TRUE; SetCursor(dragCur); } TreeView_SelectDropTarget(prjTreeWindow, dstItem); } else { if (inView) { inView = FALSE; SetCursor(noCur); TreeView_SelectDropTarget(prjTreeWindow, NULL); } } } else { if (inView) { inView = FALSE; SetCursor(noCur); TreeView_SelectDropTarget(prjTreeWindow, NULL); } } } break; case WM_SETFOCUS: PostMessage(hwndFrame, WM_REDRAWTOOLBAR, 0, 0); SetFocus(prjTreeWindow); break; case WM_CREATE: hwndProject = hwnd; GetClientRect(hwnd, &rs); treeViewSelected = 0; dragCur = LoadCursor(hInstance, "ID_DRAGCUR"); noCur = LoadCursor(hInstance, "ID_NODRAGCUR"); folderClose = LoadBitmap(hInstance, "ID_FOLDERCLOSE"); folderOpen = LoadBitmap(hInstance, "ID_FOLDEROPEN"); treeIml = ImageList_Create(16, 16, ILC_COLOR24, IL_IMAGECOUNT+2, 0); mainIml = LoadBitmap(hInstance, "ID_FILES"); ChangeBitmapColor(mainIml, 0xffffff, RetrieveSysColor(COLOR_WINDOW)); ImageList_Add(treeIml, mainIml, NULL); ilfolderClose = ImageList_Add(treeIml, folderClose, 0); ilfolderOpen = ImageList_Add(treeIml, folderOpen, 0); DeleteObject(folderClose); DeleteObject(folderOpen); DeleteObject(mainIml); prjTreeWindow = CreateWindowEx(0, sztreeDoubleBufferName, "", WS_VISIBLE | WS_CHILD | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_TRACKSELECT, 0, 0, rs.right, rs.bottom, hwnd, (HMENU)ID_TREEVIEW, hInstance, NULL); TreeView_SetImageList(prjTreeWindow, treeIml, TVSIL_NORMAL); lf = systemDialogFont; projFont = CreateFontIndirect(&lf); lf.lfItalic = TRUE; italicProjFont = CreateFontIndirect(&lf); lf.lfItalic = FALSE; lf.lfWeight = FW_BOLD; boldProjFont = CreateFontIndirect(&lf); SendMessage(prjTreeWindow, WM_SETFONT, (WPARAM)boldProjFont, 0); return 0; case WM_CLOSE: SaveAllProjects(workArea, FALSE); break; case WM_DESTROY: FreeSubTree(workArea, FALSE); DestroyWindow(prjTreeWindow); DeleteObject(projFont); DeleteObject(boldProjFont); DeleteObject(italicProjFont); DestroyCursor(dragCur); DestroyCursor(noCur); hwndProject = 0; break; case WM_SIZE: MoveWindow(prjTreeWindow, 0, 0, LOWORD(lParam), HIWORD(lParam), 0); break; default: break; } return DefWindowProc(hwnd, iMessage, wParam, lParam); }
void CFactory::Update() { if (beingBuilt) { // factory under construction CUnit::Update(); return; } if (quedBuild && !opening && !stunned) { script->Activate(); groundBlockingObjectMap->OpenBlockingYard(this, curYardMap); opening = true; } if (quedBuild && inBuildStance && !stunned) { // start building a unit const float3 buildPos = CalcBuildPos(); const CSolidObject* solidObj = groundBlockingObjectMap->GroundBlocked(buildPos); if (solidObj == NULL || (dynamic_cast<const CUnit*>(solidObj) == this)) { quedBuild = false; CUnit* b = unitLoader.LoadUnit(nextBuild, buildPos + float3(0.01f, 0.01f, 0.01f), team, true, buildFacing, this); if (!unitDef->canBeAssisted) { b->soloBuilder = this; b->AddDeathDependence(this); } AddDeathDependence(b); curBuild = b; script->StartBuilding(); int soundIdx = unitDef->sounds.build.getRandomIdx(); if (soundIdx >= 0) { Channels::UnitReply.PlaySample( unitDef->sounds.build.getID(soundIdx), pos, unitDef->sounds.build.getVolume(0)); } } else { helper->BuggerOff(buildPos - float3(0.01f, 0, 0.02f), radius + 8, true, true, NULL); } } if (curBuild && !beingBuilt) { if (!stunned) { // factory not under construction and // nanolathing unit: continue building lastBuild = gs->frameNum; // buildPiece is the rotating platform const int buildPiece = GetBuildPiece(); const CMatrix44f& mat = script->GetPieceMatrix(buildPiece); const int h = GetHeadingFromVector(mat[2], mat[10]); //! x.z, z.z // rotate unit nanoframe with platform curBuild->heading = (h + GetHeadingFromFacing(buildFacing)) & 65535; const float3 buildPos = CalcBuildPos(buildPiece); curBuild->pos = buildPos; if (curBuild->floatOnWater) { float waterline = ground->GetHeight(buildPos.x, buildPos.z) - curBuild->unitDef->waterline; if (waterline > curBuild->pos.y) curBuild->pos.y = waterline; } curBuild->midPos = curBuild->pos + (UpVector * curBuild->relMidPos.y); const CCommandQueue& queue = commandAI->commandQue; if(!queue.empty() && (queue.front().id == CMD_WAIT)) { curBuild->AddBuildPower(0, this); } else { if (curBuild->AddBuildPower(buildSpeed, this)) { CreateNanoParticle(); } } } if (!curBuild->beingBuilt && (!unitDef->fullHealthFactory || (curBuild->health >= curBuild->maxHealth))) { if (group && curBuild->group == 0) { curBuild->SetGroup(group); } bool userOrders = true; if (curBuild->commandAI->commandQue.empty() || (dynamic_cast<CMobileCAI*>(curBuild->commandAI) && ((CMobileCAI*)curBuild->commandAI)->unimportantMove)) { userOrders = false; AssignBuildeeOrders(curBuild); waitCommandsAI.AddLocalUnit(curBuild, this); } eventHandler.UnitFromFactory(curBuild, this, userOrders); StopBuild(); } } if (((lastBuild + 200) < gs->frameNum) && !stunned && !quedBuild && opening && groundBlockingObjectMap->CanCloseYard(this)) { // close the factory after inactivity groundBlockingObjectMap->CloseBlockingYard(this, curYardMap); opening = false; script->Deactivate(); } CBuilding::Update(); }
bool CFactory::ChangeTeam(int newTeam, ChangeType type) { StopBuild(); return CBuilding::ChangeTeam(newTeam, type); }
void CFactory::Update() { if(beingBuilt){ CUnit::Update(); return; } if(quedBuild && inBuildStance){ std::vector<long> args; args.push_back(0); cob->Call("QueryBuildInfo",args); float3 relBuildPos=localmodel->GetPiecePos(args[0]); float3 buildPos=pos + frontdir*relBuildPos.z + updir*relBuildPos.y + rightdir*relBuildPos.x; bool canBuild=true; std::vector<CUnit*> units=qf->GetUnitsExact(buildPos,16); for(std::vector<CUnit*>::iterator ui=units.begin();ui!=units.end();++ui){ if((*ui)!=this) canBuild=false; } if(canBuild){ quedBuild=false; CUnit* b=unitLoader.LoadUnit(nextBuild,buildPos+float3(0.01,0.01,0.01),team,true); AddDeathDependence(b); curBuild=b; cob->Call("StartBuilding"); if(unitDef->sounds.build.id) sound->PlaySound(unitDef->sounds.build.id, pos, unitDef->sounds.build.volume); } else { helper->BuggerOff(buildPos-float3(0.01,0,0.02),radius+8); } } if(curBuild && !beingBuilt){ lastBuild=gs->frameNum; std::vector<long> args; args.push_back(0); cob->Call("QueryBuildInfo",args); CMatrix44f mat=localmodel->GetPieceMatrix(args[0]); int h=GetHeadingFromVector(mat[2],mat[10]); curBuild->heading=h; // if(curBuild->unitDef->canfly){ //hack to get naval air plant to work correctly, how to do it correctly ? float3 relBuildPos=localmodel->GetPiecePos(args[0]); float3 buildPos=pos + frontdir*relBuildPos.z + updir*relBuildPos.y + rightdir*relBuildPos.x; curBuild->pos=buildPos; if(curBuild->floatOnWater) curBuild->pos.y=ground->GetHeight(buildPos.x,buildPos.z)-curBuild->unitDef->waterline; curBuild->midPos=curBuild->pos+UpVector*curBuild->relMidPos.y; // } if(curBuild->AddBuildPower(buildSpeed,this)){ std::vector<long> args; args.push_back(0); cob->Call("QueryNanoPiece",args); float3 relWeaponFirePos=localmodel->GetPiecePos(args[0]); float3 weaponPos=pos + frontdir*relWeaponFirePos.z + updir*relWeaponFirePos.y + rightdir*relWeaponFirePos.x; float3 dif=curBuild->midPos-weaponPos; float l=dif.Length(); dif/=l; dif+=gs->randVector()*0.15f; new CGfxProjectile(weaponPos,dif,l,float3(0.2f,0.7f,0.2f)); } else { if(!curBuild->beingBuilt){ if(group) curBuild->SetGroup(group); Command c; c.id=CMD_MOVE_STATE; c.options=0; c.params.push_back(moveState); curBuild->commandAI->GiveCommand(c); c.params.clear(); c.id=CMD_FIRE_STATE; c.params.push_back(fireState); curBuild->commandAI->GiveCommand(c); if(curBuild->commandAI->commandQue.empty() || (dynamic_cast<CMobileCAI*>(curBuild->commandAI) && ((CMobileCAI*)curBuild->commandAI)->unimportantMove)){ if(((CFactoryCAI*)commandAI)->newUnitCommands.empty()){ SendToEmptySpot(curBuild); } else { for(std::deque<Command>::iterator ci=((CFactoryCAI*)commandAI)->newUnitCommands.begin();ci!=((CFactoryCAI*)commandAI)->newUnitCommands.end();++ci) curBuild->commandAI->GiveCommand(*ci); } } StopBuild(); } } } if(lastBuild+200 < gs->frameNum && !quedBuild && opening && uh->CanCloseYard(this)){ readmap->CloseBlockingYard(this); opening=false; cob->Call(COBFN_Deactivate); } CBuilding::Update(); }
void CFactory::ChangeTeam(int newTeam,ChangeType type) { StopBuild(); CBuilding::ChangeTeam(newTeam,type); }
void CFactory::Update() { if(beingBuilt){ CUnit::Update(); return; } if(quedBuild && inBuildStance){ float3 buildPos = CalcBuildPos(); bool canBuild=true; std::vector<CUnit*> units=qf->GetUnitsExact(buildPos,16); for(std::vector<CUnit*>::iterator ui=units.begin();ui!=units.end();++ui){ if((*ui)!=this) canBuild=false; } if(canBuild){ quedBuild=false; CUnit* b=unitLoader.LoadUnit(nextBuild,buildPos+float3(0.01,0.01,0.01),team,true,buildFacing); AddDeathDependence(b); curBuild=b; animator->AnimAction("StartBuilding"); if(unitDef->sounds.build.id) sound->PlaySound(unitDef->sounds.build.id, pos, unitDef->sounds.build.volume); } else { helper->BuggerOff(buildPos-float3(0.01,0,0.02),radius+8); } } if(curBuild && !beingBuilt){ lastBuild=gs->frameNum; int buildPiece = GetBuildPiece(); CMatrix44f mat=localmodel->GetPieceMatrix(buildPiece); int h=GetHeadingFromVector(mat[2],mat[10]); curBuild->heading=h; float3 buildPos = curBuild->pos = CalcBuildPos(buildPiece); if(curBuild->floatOnWater) curBuild->pos.y=ground->GetHeight(buildPos.x,buildPos.z)-curBuild->unitDef->waterline; curBuild->midPos=curBuild->pos+UpVector*curBuild->relMidPos.y; if(curBuild->AddBuildPower(buildSpeed,this)){ std::vector<int> args; args.push_back(0); animator->AnimAction("QueryNanoPiece",args); if(unitDef->showNanoSpray){ float3 relWeaponFirePos=localmodel->GetPiecePos(args[0]); float3 weaponPos=pos + frontdir*relWeaponFirePos.z + updir*relWeaponFirePos.y + rightdir*relWeaponFirePos.x; float3 dif=curBuild->midPos-weaponPos; float l=dif.Length(); dif/=l; dif+=gs->randVector()*0.15f; float3 color= unitDef->nanoColor; if(gu->teamNanospray){ unsigned char* tcol=gs->Team(team)->color; color = float3(tcol[0]*(1./255.),tcol[1]*(1./255.),tcol[2]*(1./255.)); } new CGfxProjectile(weaponPos,dif,(int)l,color); } } else { if(!curBuild->beingBuilt){ if(group) curBuild->SetGroup(group); Command c; c.id=CMD_MOVE_STATE; c.options=0; c.params.push_back(moveState); curBuild->commandAI->GiveCommand(c); c.params.clear(); c.id=CMD_FIRE_STATE; c.params.push_back(fireState); curBuild->commandAI->GiveCommand(c); if(curBuild->commandAI->commandQue.empty() || (dynamic_cast<CMobileCAI*>(curBuild->commandAI) && ((CMobileCAI*)curBuild->commandAI)->unimportantMove)){ if(((CFactoryCAI*)commandAI)->newUnitCommands.empty()){ SendToEmptySpot(curBuild); } else { for(std::deque<Command>::iterator ci=((CFactoryCAI*)commandAI)->newUnitCommands.begin();ci!=((CFactoryCAI*)commandAI)->newUnitCommands.end();++ci) curBuild->commandAI->GiveCommand(*ci); } } StopBuild(); } } } if(lastBuild+200 < gs->frameNum && !quedBuild && opening && uh->CanCloseYard(this)){ readmap->CloseBlockingYard(this); opening=false; animator->AnimAction(ANIMFN_Deactivate); } CBuilding::Update(); }
void CFactory::Update() { if (beingBuilt) { // factory under construction CUnit::Update(); return; } if (quedBuild && !opening && !stunned) { cob->Call(COBFN_Activate); groundBlockingObjectMap->OpenBlockingYard(this, yardMap); opening = true; } if (quedBuild && inBuildStance && !stunned) { // start building a unit float3 buildPos = CalcBuildPos(); bool canBuild = true; std::vector<CUnit*> units = qf->GetUnitsExact(buildPos, 16); for (std::vector<CUnit*>::iterator ui = units.begin(); ui != units.end(); ++ui) { if ((*ui) != this) canBuild = false; } if (canBuild) { quedBuild = false; CUnit* b = unitLoader.LoadUnit(nextBuild, buildPos + float3(0.01f, 0.01f, 0.01f), team, true, buildFacing, this); b->lineage = this->lineage; if (!unitDef->canBeAssisted) { b->soloBuilder = this; b->AddDeathDependence(this); } AddDeathDependence(b); curBuild = b; cob->Call("StartBuilding"); int soundIdx = unitDef->sounds.build.getRandomIdx(); if (soundIdx >= 0) { sound->PlaySample( unitDef->sounds.build.getID(soundIdx), pos, unitDef->sounds.build.getVolume(0)); } } else { helper->BuggerOff(buildPos - float3(0.01f, 0, 0.02f), radius + 8); } } if (curBuild && !beingBuilt) { if (!stunned) { // factory not under construction and // nanolathing unit: continue building lastBuild = gs->frameNum; // buildPiece is the rotating platform const int buildPiece = GetBuildPiece(); CMatrix44f mat = localmodel->GetPieceMatrix(buildPiece); const int h = GetHeadingFromVector(mat[2], mat[10]); // rotate unit nanoframe with platform curBuild->heading = (h + GetHeadingFromFacing(buildFacing)) & 65535; const float3 buildPos = CalcBuildPos(buildPiece); curBuild->pos = buildPos; if (curBuild->floatOnWater) { curBuild->pos.y = ground->GetHeight(buildPos.x, buildPos.z); curBuild->pos.y -= curBuild->unitDef->waterline; } curBuild->midPos = curBuild->pos + (UpVector * curBuild->relMidPos.y); const CCommandQueue& queue = commandAI->commandQue; if(!queue.empty() && (queue.front().id == CMD_WAIT)) { curBuild->AddBuildPower(0, this); } else { if (curBuild->AddBuildPower(buildSpeed, this)) { CreateNanoParticle(); } } } if (!curBuild->beingBuilt && (!unitDef->fullHealthFactory || (curBuild->health >= curBuild->maxHealth))) { if (group && curBuild->group == 0) { curBuild->SetGroup(group); } bool userOrders = true; if (curBuild->commandAI->commandQue.empty() || (dynamic_cast<CMobileCAI*>(curBuild->commandAI) && ((CMobileCAI*)curBuild->commandAI)->unimportantMove)) { userOrders = false; const CFactoryCAI* facAI = (CFactoryCAI*) commandAI; const CCommandQueue& newUnitCmds = facAI->newUnitCommands; if (newUnitCmds.empty()) { SendToEmptySpot(curBuild); } else { // XXX the pathfinder sometimes... makes mistakes, try to hack around it // XXX note this qualifies as HACK HACK HACK float3 testpos = curBuild->pos + frontdir * (this->radius - 1.0f); Command c; c.id = CMD_MOVE; c.params.push_back(testpos.x); c.params.push_back(testpos.y); c.params.push_back(testpos.z); curBuild->commandAI->GiveCommand(c); for (CCommandQueue::const_iterator ci = newUnitCmds.begin(); ci != newUnitCmds.end(); ++ci) { c = *ci; c.options |= SHIFT_KEY; curBuild->commandAI->GiveCommand(c); } } waitCommandsAI.AddLocalUnit(curBuild, this); } eventHandler.UnitFromFactory(curBuild, this, userOrders); StopBuild(); } } if (((lastBuild + 200) < gs->frameNum) && !stunned && !quedBuild && opening && groundBlockingObjectMap->CanCloseYard(this)) { // close the factory after inactivity groundBlockingObjectMap->CloseBlockingYard(this, yardMap); opening = false; cob->Call(COBFN_Deactivate); } CBuilding::Update(); }