CUnit::CUnit(Global* GL, int uid){
		G = GL;
		
		NLOG("CUnit::CUnit");
		
		valid = true;
		
		if(!ValidUnitID(uid)){
			valid = false;
		}
		
		this->uid = uid;
		
		utd = G->UnitDefLoader->GetUnitTypeDataByUnitId(uid);

		if(utd==0){
			//
			G->L.eprint("ERROR IN CUNIT :: UTD == 0, ntai failed to retrieve the units unitdef object, something has gone wrong somewhere.");
			valid = false;
		}
		
		if(!valid){
			return;
		}

		if(!utd->IsMobile()){
			G->BuildingPlacer->Block(G->GetUnitPos(uid),utd);
		}
		currentTask = boost::shared_ptr<IModule>();
		doingplan=false;
		curplan=0;
		birth = G->GetCurrentFrame();
		//nolist=false;
		under_construction = true;
	}
CUnitTypeData* CUnitDefLoader::GetUnitTypeDataByUnitId(int uid){

	if(!ValidUnitID(uid)){
		return 0;
	}

	const UnitDef* ud = G->GetUnitDef(uid);
	if(ud == 0){
		return 0;
	}else{
		return this->GetUnitTypeDataById(ud->id);
	}
}
bool CKeywordConstructionTask::Init(){
	NLOG(("CKeywordConstructionTask::Init"+G->Manufacturer->GetTaskName(type)));
	G->L.print("CKeywordConstructionTask::Init "+G->Manufacturer->GetTaskName(type));

	//G->L.print("CKeywordConstructionTask::Init");

    NLOG("1");
    NLOG((string("tasktype: ")+G->Manufacturer->GetTaskName(type)));

	// register this modules listeners
	//G->RegisterMessageHandler("unitidle",me);
	//G->RegisterMessageHandler("unitdestroyed",me);

	if(type == B_RANDMOVE){
		if(G->Actions->RandomSpiral(unit)==false){
			End();
			return false;
		}else{
			return true;
		}
	} else if(type == B_RETREAT){
		if(!G->Actions->Retreat(unit)){
			End();
			return false;
		}else{
			return true;
		}
	} else if(type == B_GUARDIAN){
		if(!G->Actions->RepairNearby(unit,1200)){
			End();
			return false;
		}else{
			return true;
		}
	} else if(type == B_GUARDIAN_MOBILES){
		if(!G->Actions->RepairNearbyUnfinishedMobileUnits(unit,1200)){
			End();
			return false;
		}else{
			return true;
		}
	} else if(type == B_RESURECT){
		if(!G->Actions->RessurectNearby(unit)){
			End();
			return false;
		}else{
			return true;
		}
	}else if((type == B_RULE)||(type == B_RULE_EXTREME)||(type == B_RULE_EXTREME_NOFACT)||(type == B_RULE_EXTREME_CARRY)){//////////////////////////////

		type = G->Economy->Get(!(type == B_RULE),!(B_RULE_EXTREME_NOFACT == type));
		if(type == B_NA){
			valid = false;
			End();
			return false;
		}

		CUBuild b;
		b.Init(G,utd,unit);
		string targ = b(type);
		G->L.print("gotten targ value of " + targ + " for RULE");
		if (targ != string("")){

			building = G->UnitDefLoader->GetUnitTypeDataByName(targ);
			Build();
			return true;
		}else{
			G->L.print("B_RULE_EXTREME skipped bad return");
			End();
			return false;
		}
	}else if(type  == B_OFFENSIVE_REPAIR_RETREAT){
		if(G->Actions->OffensiveRepairRetreat(unit,800)==false){
			End();
			return false;
		}else{
			return true;
		}
	}else if(type  == B_REPAIR){
		if(G->Actions->RepairNearby(unit,500)==false){
			if(G->Actions->RepairNearby(unit,1000)==false){
				if(G->Actions->RepairNearby(unit,2600)==false){
					End();
					return false;
				}else{
					return true;
				}
			}else{
				return true;
			}
		}else{
			return true;
		}
		return valid;
	}else if(type  == B_RECLAIM){
		if(!G->Actions->ReclaimNearby(unit,400)){
			End();
			return false;
		}else{
			return true;
		}
	}else if(type  == B_GUARD_FACTORY){
		float3 upos = G->GetUnitPos(unit);
		if(G->Map->CheckFloat3(upos)==false){
			End();
			return false;
		}
		int* funits = new int[6000];
		int fnum = G->cb->GetFriendlyUnits(funits,upos,2000);
		if(fnum > 0){
			int closest=0;
			float d = 2500;
			for(int  i = 0; i < fnum; i++){
				if(funits[i] == unit) continue;
				float3 rpos = G->GetUnitPos(funits[i]);
				if(G->Map->CheckFloat3(rpos)==false){
					continue;
				}else{
					float q = upos.distance2D(rpos);
					if(q < d){
						const UnitDef* rd = G->GetUnitDef(funits[i]);
						if(rd == 0){
							continue;
						}else{
							if(rd->builder && (rd->movedata == 0) && (rd->buildOptions.empty()==false)){
								d = q;
								closest = funits[i];
								continue;
							}else{
								continue;
							}
						}
					}
				}
			}
			if(ValidUnitID(closest)){
				delete [] funits;
				if(!G->Actions->Guard(unit,closest)){
					End();
					return false;
				}else{
					return true;
				}
			}else{
				delete [] funits;
				End();
				return false;
			}
		}
		delete [] funits;
		End();
		return false;
	}else if(type  == B_GUARD_LIKE_CON){
		float3 upos = G->GetUnitPos(unit);
		if(G->Map->CheckFloat3(upos)==false){
			End();
			return false;
		}
		int* funits = new int[5005];
		int fnum = G->cb->GetFriendlyUnits(funits,upos,2000);
		if(fnum > 0){
			int closest=-1;
			float d = 2500;
			for(int  i = 0; i < fnum; i++){
				if(funits[i] == unit) continue;
				float3 rpos = G->GetUnitPos(funits[i]);
				if(G->Map->CheckFloat3(rpos)==false){
					continue;
				}else{
					float q = upos.distance2D(rpos);
					if(q < d){
						CUnitTypeData* rd = G->UnitDefLoader->GetUnitTypeDataByUnitId(funits[i]);
						if(rd == building){
							d = q;
							closest = funits[i];
						}
						continue;
					}
				}
			}
			if(ValidUnitID(closest)){
				delete [] funits;
				if(!G->Actions->Guard(unit,closest)){
					End();
					return false;
				}else{
					return true;
				}
			}else{
				delete [] funits;
				End();
				return false;
			}
		}
		delete [] funits;
	}else{// if(type != B_NA){
		CUBuild b;
		b.Init(G,utd,unit);
		b.SetWater(G->info->spacemod);
		//if(b.ud->floater==true){
		//	b.SetWater(true);
		//}
		string targ = b(type);
		if(targ == string("")){
			G->L << "if(targ == string(\"\")) for "<< G->Manufacturer->GetTaskName(type)<< endline;
			End();
			return false;
		}else{
			CUnitTypeData* udk = G->UnitDefLoader->GetUnitTypeDataByName(targ);
			building = udk;
			Build();
			return true;
		}
	}
	End();
	return false;
}
bool COrderRouter::GiveOrder(TCommand c, bool newer){
    NLOG("Global::GiveOrder");
    if(!ValidUnitID(c.unit)){
        G->L.print("ValidUnitID(c.unit)==false :: c.unit = " + to_string((c.unit))+" MAXUNITS = "+to_string(MAX_UNITS));
        return false;
    }
    if(c.clear == true){
        G->L.print("c.clear == true");
        return false;
    }
    //if(c.c.timeOut > 1){
    //	if(G->cb->GetCurrentFrame() > c.c.timeOut)return -1;
    //}
    //G->idlenextframe.erase(c.unit);
    if(c.type == B_CMD){
        if((c.c.params.empty()==true) || (c.c.params.size()==0)){
            if ((c.c.id == CMD_ATTACK)||(c.c.id == CMD_MOVE)||(c.c.id == CMD_DGUN)||(c.c.id == CMD_ONOFF)||(c.c.id == CMD_RECLAIM)||(c.c.id == CMD_GUARD)||(c.c.id == CMD_MOVE_STATE)||(c.c.id == CMD_FIRE_STATE)||(c.c.id == CMD_REPAIR)){
#ifdef TC_SOURCE
                G->L.print("empty params?!?!?!? :: " + c.source);
#else
G->L.print("empty params?!?!?!? :: ");
#endif
return false;
            }
        }else if(((c.c.params.size()==3)||(c.c.params.size()>3))&&(c.c.id > 0)){
            float3 p(c.c.params.at(0), c.c.params.at(1), c.c.params.at(2));
            if(G->Map->CheckFloat3(p)==false){
                G->L.print("intercepted erroneous float3 in a command");
                return false;
            }
        }else if ((c.c.params.size()==1)&&(c.c.id==CMD_DGUN)){
            if(c.c.params.at(0)<0){
                G->L.print("c.c.params.at(0)<0 in CMD_DGUN");
                return false;
            }
        }
        
    }
    if(newer == true){
        if(CommandCache.empty() == false){
            for(vector<TCommand>::iterator i = CommandCache.begin(); i != CommandCache.end();++i){
                if(i->clear == true) continue;
                if(i->unit == c.unit){
                    i->clear = true;
                }
            }
        }
    }
    if (c.type == B_IDLE){
        if(!ValidUnitID(c.unit)){
            G->L.print("!ValidUnitID(c.unit) :: c.unit = " + to_string((c.unit))+" MAXUNITS = "+to_string(MAX_UNITS));
            return false;
        }else{
            G->idlenextframe.insert(c.unit);
            return true;
        }
    }else if(c.type == B_CMD){
        G->idlenextframe.erase(c.unit);
        CommandCache.push_back(c);
        return true;
    }else{
        G->L.print("bad command type");
        return false;
    }
}