コード例 #1
0
ファイル: FeatureHandler.cpp プロジェクト: Finkky/spring
CFeature* CFeatureHandler::CreateWreckage(const float3& pos, const string& name,
	float rot, int facing, int iter, int team, int allyteam, bool emitSmoke, const UnitDef* udef,
	const float3& speed)
{
	const FeatureDef* fd;
	const string* defname = &name;

	int i = iter;
	do {
		if (defname->empty()) return NULL;
		fd = GetFeatureDef(*defname);
		if (!fd) return NULL;
		defname = &(fd->deathFeature);
	} while (--i > 0);

	if (luaRules && !luaRules->AllowFeatureCreation(fd, team, pos))
		return NULL;

	if (!fd->modelname.empty()) {
		CFeature* f = new CFeature();

		if (fd->resurrectable == 0 || (iter > 1 && fd->resurrectable < 0)) {
			f->Initialize(pos, fd, (short int) rot, facing, team, allyteam, NULL, speed, emitSmoke ? fd->smokeTime : 0);
		} else {
			f->Initialize(pos, fd, (short int) rot, facing, team, allyteam, udef, speed, emitSmoke ? fd->smokeTime : 0);
		}

		return f;
	}
	return NULL;
}
コード例 #2
0
	CObject_pointer<CFeature>* FeatureLoaderLoadFeature( string name, float3 pos, int team )
	{
		FeatureDef *def = featureHandler->GetFeatureDef(name);
		CFeature* feature = new CFeature();
		feature->Initialize( pos,def,0, 0, team,"" );
		return new CObject_pointer<CFeature>(feature);
	}
コード例 #3
0
CFeature* CFeatureHandler::CreateWreckage(const float3& pos, const std::string& name,
        float rot, int facing, int iter, int team, int allyteam, bool emitSmoke, std::string fromUnit,
        const float3& speed)
{
    const FeatureDef* fd;
    const std::string* defname = &name;

    int i = iter;
    do {
        if (name.empty()) return NULL;
        fd = GetFeatureDef(*defname);
        if (!fd) return NULL;
        defname = &(fd->deathFeature);
    } while (--i > 0);

    if (luaRules && !luaRules->AllowFeatureCreation(fd, team, pos))
        return NULL;

    if (!fd->modelname.empty()) {
        if (fd->resurrectable==0 || (iter>1 && fd->resurrectable<0))
            fromUnit = "";

        CFeature* f = new CFeature;
        f->Initialize(pos, fd, (short int) rot, facing, team, fromUnit, speed);

        // allow area-reclaiming wrecks of all units, including your own (they set allyteam = -1)
        f->allyteam = allyteam;
        if (emitSmoke && fd->blocking)
            f->emitSmokeTime = fd->smokeTime;

        return f;
    }
    return NULL;
}
コード例 #4
0
CFeature* CFeatureHandler::CreateWreckage(const float3& pos, const std::string& name,
	float rot, int facing, int iter, int team, int allyteam, bool emitSmoke, std::string fromUnit,
	const float3& speed)
{
	ASSERT_SYNCED_MODE;
	if (name.empty()) {
		return NULL;
	}
	const FeatureDef* fd = GetFeatureDef(name);

	if (!fd) {
		return NULL;
	}

	if (iter > 1) {
		return CreateWreckage(pos, fd->deathFeature, rot, facing, iter - 1, team, allyteam, emitSmoke, "", speed);
	}
	else {
		if (luaRules && !luaRules->AllowFeatureCreation(fd, team, pos)) {
			return NULL;
		}
		if (!fd->modelname.empty()) {
			CFeature* f = SAFE_NEW CFeature;
			f->Initialize(pos, fd, (short int) rot, facing, team, fromUnit, speed);
			// allow area-reclaiming wrecks of all units, including your own (they set allyteam = -1)
			f->allyteam = allyteam;
			if (emitSmoke && f->blocking)
				f->emitSmokeTime = 300;
			return f;
		}
	}
	return NULL;
}
コード例 #5
0
ファイル: FeatureHandler.cpp プロジェクト: Finkky/spring
void CFeatureHandler::LoadFeaturesFromMap(bool onlyCreateDefs)
{
	// add default tree and geo FeatureDefs defined by the map
	const int numFeatureTypes = readmap->GetNumFeatureTypes();

	for (int a = 0; a < numFeatureTypes; ++a) {
		const string& name = StringToLower(readmap->GetFeatureTypeName(a));

		if (GetFeatureDef(name, false) == NULL) {
			if (name.find("treetype") != string::npos) {
				AddFeatureDef(name, CreateDefaultTreeFeatureDef(name));
			}
			else if (name.find("geovent") != string::npos) {
				AddFeatureDef(name, CreateDefaultGeoFeatureDef(name));
			}
			else {
				LOG_L(L_ERROR, "[%s] unknown map feature type \"%s\"",
						__FUNCTION__, name.c_str());
			}
		}
	}

	// add a default geovent FeatureDef if the map did not
	if (GetFeatureDef("geovent", false) == NULL) {
		AddFeatureDef("geovent", CreateDefaultGeoFeatureDef("geovent"));
	}

	if (!onlyCreateDefs) {
		// create map-specified feature instances
		const int numFeatures = readmap->GetNumFeatures();
		MapFeatureInfo* mfi = new MapFeatureInfo[numFeatures];
		readmap->GetFeatureInfo(mfi);

		for (int a = 0; a < numFeatures; ++a) {
			const string& name = StringToLower(readmap->GetFeatureTypeName(mfi[a].featureType));
			map<string, const FeatureDef*>::iterator def = featureDefs.find(name);

			if (def == featureDefs.end()) {
				LOG_L(L_ERROR, "Unknown feature named '%s'", name.c_str());
				continue;
			}

			const float ypos = ground->GetHeightReal(mfi[a].pos.x, mfi[a].pos.z);
			const float3 fpos = float3(mfi[a].pos.x, ypos, mfi[a].pos.z);
			const FeatureDef* fdef = def->second;

			CFeature* f = new CFeature();
			f->Initialize(fpos, fdef, (short int) mfi[a].rotation, 0, -1, -1, NULL);
		}

		delete[] mfi;
	}
}
コード例 #6
0
void CFeatureHandler::LoadSaveFeatures(CLoadSaveInterface* file, bool loading)
{
	if(loading)
		freeIDs.clear();
	for(int a=0;a<MAX_FEATURES;++a){
		bool exists=!!features[a];
		file->lsBool(exists);
		if(exists){
			if(loading){
				overrideId=a;
				float3 pos;
				file->lsFloat3(pos);

				string def;
				file->lsString(def);
				if(featureDefs.find(def)==featureDefs.end())
					GetFeatureDef(def);

				short rotation;
				file->lsShort(rotation);
				string fromUnit;
				file->lsString(fromUnit);
				CFeature* f = SAFE_NEW CFeature;
				f->Initialize (pos,featureDefs[def],rotation,0,-1,fromUnit);
			} else {
				file->lsFloat3(features[a]->pos);
				file->lsString(features[a]->def->myName);
				file->lsShort(features[a]->heading);
				file->lsString(features[a]->createdFromUnit);
			}
			CFeature* f=features[a];
			file->lsFloat(f->health);
			file->lsFloat(f->reclaimLeft);
			file->lsInt(f->allyteam);
		} else {
			if(loading)
				freeIDs.push_back(a);
		}
	}
	overrideId=-1;
}
コード例 #7
0
ファイル: SyncedGameCommands.cpp プロジェクト: slogic/spring
// FOR SYNCED MESSAGES
void CGame::ActionReceived(const Action& action, int playernum)
{
	if (action.command == "cheat") {
		SetBoolArg(gs->cheatEnabled, action.extra);
		if (gs->cheatEnabled)
			logOutput.Print("Cheating!");
		else
			logOutput.Print("No more cheating");
	}
	else if (action.command == "nohelp") {
		SetBoolArg(gs->noHelperAIs, action.extra);
		selectedUnits.PossibleCommandChange(NULL);
		logOutput.Print("LuaUI control is %s", gs->noHelperAIs ? "disabled" : "enabled");
	}
	else if (action.command == "nospecdraw") {
		bool buf;
		SetBoolArg(buf, action.extra);
		inMapDrawer->SetSpecMapDrawingAllowed(buf);
	}
	else if (action.command == "godmode") {
		if (!gs->cheatEnabled)
			logOutput.Print("godmode requires /cheat");
		else {
			SetBoolArg(gs->godMode, action.extra);
			CLuaUI::UpdateTeams();
			if (gs->godMode) {
				logOutput.Print("God Mode Enabled");
			} else {
				logOutput.Print("God Mode Disabled");
			}
			CPlayer::UpdateControlledTeams();
		}
	}
	else if (action.command == "globallos") {
		if (!gs->cheatEnabled) {
			logOutput.Print("globallos requires /cheat");
		} else {
			SetBoolArg(gs->globalLOS, action.extra);
			if (gs->globalLOS) {
				logOutput.Print("Global LOS Enabled");
			} else {
				logOutput.Print("Global LOS Disabled");
			}
		}
	}
	else if (action.command == "nocost" && gs->cheatEnabled) {
		if (unitDefHandler->ToggleNoCost()) {
			logOutput.Print("Everything is for free!");
		} else {
			logOutput.Print("Everything costs resources again!");
		}
	}
	else if (action.command == "give" && gs->cheatEnabled) {
		std::string s = "give "; //FIXME lazyness
		s += action.extra;

		// .give [amount] <unitName> [team] <@x,y,z>
		const vector<string> &args = CSimpleParser::Tokenize(s, 0);

		if (args.size() < 3) {
			logOutput.Print("Someone is spoofing invalid .give messages!");
			return;
		}

		float3 pos;
		if (sscanf(args[args.size() - 1].c_str(), "@%f,%f,%f", &pos.x, &pos.y, &pos.z) != 3) {
			logOutput.Print("Someone is spoofing invalid .give messages!");
			return;
		}

		int amount = 1;
		int team = playerHandler->Player(playernum)->team;

		int amountArgIdx = -1;
		int teamArgIdx = -1;

		if (args.size() == 5) {
			amountArgIdx = 1;
			teamArgIdx = 3;
		}
		else if (args.size() == 4) {
			if (args[1].find_first_not_of("0123456789") == string::npos) {
				amountArgIdx = 1;
			} else {
				teamArgIdx = 2;
			}
		}

		if (amountArgIdx >= 0) {
			const string& amountStr = args[amountArgIdx];
			amount = atoi(amountStr.c_str());
			if ((amount < 0) || (amountStr.find_first_not_of("0123456789") != string::npos)) {
				logOutput.Print("Bad give amount: %s", amountStr.c_str());
				return;
			}
		}

		if (teamArgIdx >= 0) {
			const string& teamStr = args[teamArgIdx];
			team = atoi(teamStr.c_str());
			if ((!teamHandler->IsValidTeam(team)) || (teamStr.find_first_not_of("0123456789") != string::npos)) {
				logOutput.Print("Bad give team: %s", teamStr.c_str());
				return;
			}
		}

		const string unitName = (amountArgIdx >= 0) ? args[2] : args[1];

		if (unitName == "all") {
			// player entered ".give all"
			int numRequestedUnits = unitDefHandler->unitDefs.size() - 1; /// defid=0 is not valid
			int currentNumUnits = teamHandler->Team(team)->units.size();
			int sqSize = (int) streflop::ceil(streflop::sqrt((float) numRequestedUnits));

			// make sure team unit-limit not exceeded
			if ((currentNumUnits + numRequestedUnits) > uh->MaxUnitsPerTeam()) {
				numRequestedUnits = uh->MaxUnitsPerTeam() - currentNumUnits;
			}

			// make sure square is entirely on the map
			float sqHalfMapSize = sqSize / 2 * 10 * SQUARE_SIZE;
			pos.x = std::max(sqHalfMapSize, std::min(pos.x, float3::maxxpos - sqHalfMapSize - 1));
			pos.z = std::max(sqHalfMapSize, std::min(pos.z, float3::maxzpos - sqHalfMapSize - 1));

			for (int a = 1; a <= numRequestedUnits; ++a) {
				float posx = pos.x + (a % sqSize - sqSize / 2) * 10 * SQUARE_SIZE;
				float posz = pos.z + (a / sqSize - sqSize / 2) * 10 * SQUARE_SIZE;
				float3 pos2 = float3(posx, pos.y, posz);
				const UnitDef* ud = unitDefHandler->GetUnitDefByID(a);
				if (ud) {
					const CUnit* unit = unitLoader->LoadUnit(ud, pos2, team, false, 0, NULL);
					if (unit) {
						unitLoader->FlattenGround(unit);
					}
				}
			}
		}
		else if (!unitName.empty()) {
			int numRequestedUnits = amount;
			int currentNumUnits = teamHandler->Team(team)->units.size();

			if (currentNumUnits >= uh->MaxUnitsPerTeam()) {
				LogObject() << "Unable to give any more units to team " << team << "(current: " << currentNumUnits << ", max: " << uh->MaxUnits() << ")";
				return;
			}

			// make sure team unit-limit is not exceeded
			if ((currentNumUnits + numRequestedUnits) > uh->MaxUnitsPerTeam()) {
				numRequestedUnits = uh->MaxUnitsPerTeam() - currentNumUnits;
			}

			const UnitDef* unitDef = unitDefHandler->GetUnitDefByName(unitName);

			if (unitDef != NULL) {
				int xsize = unitDef->xsize;
				int zsize = unitDef->zsize;
				int squareSize = (int) streflop::ceil(streflop::sqrt((float) numRequestedUnits));
				int total = numRequestedUnits;

				float3 minpos = pos;
				minpos.x -= ((squareSize - 1) * xsize * SQUARE_SIZE) / 2;
				minpos.z -= ((squareSize - 1) * zsize * SQUARE_SIZE) / 2;

				for (int z = 0; z < squareSize; ++z) {
					for (int x = 0; x < squareSize && total > 0; ++x) {
						float minposx = minpos.x + x * xsize * SQUARE_SIZE;
						float minposz = minpos.z + z * zsize * SQUARE_SIZE;
						const float3 upos(minposx, minpos.y, minposz);
						const CUnit* unit = unitLoader->LoadUnit(unitDef, upos, team, false, 0, NULL);

						if (unit) {
							unitLoader->FlattenGround(unit);
						}
						--total;
					}
				}

				logOutput.Print("Giving %i %s to team %i", numRequestedUnits, unitName.c_str(), team);
			} else {
				int allyteam = -1;
				if (teamArgIdx < 0) {
					team = -1; // default to world features
					allyteam = -1;
				} else {
					allyteam = teamHandler->AllyTeam(team);
				}

				const FeatureDef* featureDef = featureHandler->GetFeatureDef(unitName);
				if (featureDef) {
					int xsize = featureDef->xsize;
					int zsize = featureDef->zsize;
					int squareSize = (int) streflop::ceil(streflop::sqrt((float) numRequestedUnits));
					int total = amount; // FIXME -- feature count limit?

					float3 minpos = pos;
					minpos.x -= ((squareSize - 1) * xsize * SQUARE_SIZE) / 2;
					minpos.z -= ((squareSize - 1) * zsize * SQUARE_SIZE) / 2;

					for (int z = 0; z < squareSize; ++z) {
						for (int x = 0; x < squareSize && total > 0; ++x) {
							float minposx = minpos.x + x * xsize * SQUARE_SIZE;
							float minposz = minpos.z + z * zsize * SQUARE_SIZE;
							float minposy = ground->GetHeightReal(minposx, minposz);
							const float3 upos(minposx, minposy, minposz);

							CFeature* feature = new CFeature();
							// Initialize() adds the feature to the FeatureHandler -> no memory-leak
							feature->Initialize(upos, featureDef, 0, 0, team, allyteam, "");
							--total;
						}
					}

					logOutput.Print("Giving %i %s (feature) to team %i",
									numRequestedUnits, unitName.c_str(), team);
				}
				else {
					logOutput.Print(unitName + " is not a valid unitname");
				}
			}
		}
	}
	else if (action.command == "destroy" && gs->cheatEnabled) {
		std::stringstream ss(action.extra);
		logOutput.Print("Killing units: %s", action.extra.c_str());
		do {
			unsigned id;
			ss >> id;
			if (!ss)
				break;
			if (id >= uh->units.size())
				continue;
			if (uh->units[id] == NULL)
				continue;
			uh->units[id]->KillUnit(false, false, 0);
		} while (true);
	}
コード例 #8
0
void CFeatureHandler::LoadFeaturesFromMap(CFileHandler* file,bool onlyCreateDefs)
{
	file->Seek(readmap->header.featurePtr);
	MapFeatureHeader fh;
	READ_MAPFEATUREHEADER(fh, file);
	if(file->Eof()){
		info->AddLine("No features in map file?");
		return;
	}
	string* mapids=new string[fh.numFeatureType];

	for(int a=0;a<fh.numFeatureType;++a){
		char c;
		file->Read(&c,1);
		while(c){
			mapids[a]+=c;
			file->Read(&c,1);
		}
		string name=mapids[a];
		if(name.find("TreeType")!=string::npos){
			FeatureDef* fd=new FeatureDef;
			fd->blocking=1;
			fd->burnable=true;
			fd->destructable=1;
			fd->drawType=DRAWTYPE_TREE;
			fd->modelType=atoi(name.substr(8).c_str());
			fd->energy=250;
			fd->metal=0;
			fd->maxHealth=5;
			fd->radius=20;
			fd->xsize=2;
			fd->ysize=2;
			fd->myName=name;
			fd->mass=20;
			featureDefs[name]=fd;
		} else if(name.find("GeoVent")!=string::npos){
			FeatureDef* fd=new FeatureDef;
			fd->blocking=0;
			fd->burnable=0;
			fd->destructable=0;
			fd->geoThermal=1;
			fd->drawType=DRAWTYPE_NONE;	//geos are drawn into the ground texture and emit smoke to be visible
			fd->modelType=0;
			fd->energy=0;
			fd->metal=0;
			fd->maxHealth=0;
			fd->radius=0;
			fd->xsize=0;
			fd->ysize=0;
			fd->myName=name;
			fd->mass=100000;
			featureDefs[name]=fd;
		} else if(wreckParser.SectionExist(name)){
			GetFeatureDef(name);
		} else {
			info->AddLine("Unknown feature type %s",name.c_str());
		}
	}

	if(!onlyCreateDefs){
		for(int a=0;a<fh.numFeatures;++a){
			MapFeatureStruct ffs;
			READ_MAPFEATURESTRUCT(ffs, file);

			string name=mapids[ffs.featureType];

			ffs.ypos=ground->GetHeight2(ffs.xpos,ffs.zpos);
			CFeature *f = new CFeature;
			f->Initialize (float3(ffs.xpos,ffs.ypos,ffs.zpos),featureDefs[name],(short int)ffs.rotation,-1,"");
		}
	}

	delete[] mapids;
}
コード例 #9
0
ファイル: UnitLoader.cpp プロジェクト: azotlikid/spring
void CUnitLoader::GiveUnits(const std::string& objectName, float3 pos, int amount, int team, int featureAllyTeam)
{
    const CTeam* receivingTeam = teamHandler->Team(team);

    if (objectName == "all") {
        unsigned int numRequestedUnits = unitDefHandler->unitDefs.size() - 1; /// defid=0 is not valid
        unsigned int currentNumUnits = receivingTeam->units.size();

        // make sure team unit-limit is not exceeded
        if ((currentNumUnits + numRequestedUnits) > receivingTeam->maxUnits) {
            numRequestedUnits = receivingTeam->maxUnits - currentNumUnits;
        }

        // make sure square is entirely on the map
        const int sqSize = math::ceil(math::sqrt((float) numRequestedUnits));
        const float sqHalfMapSize = sqSize / 2 * 10 * SQUARE_SIZE;

        pos.x = std::max(sqHalfMapSize, std::min(pos.x, float3::maxxpos - sqHalfMapSize - 1));
        pos.z = std::max(sqHalfMapSize, std::min(pos.z, float3::maxzpos - sqHalfMapSize - 1));

        for (int a = 1; a <= numRequestedUnits; ++a) {
            Watchdog::ClearPrimaryTimers(); // the other thread may be waiting for a mutex held by this one, triggering hang detection
            const float px = pos.x + (a % sqSize - sqSize / 2) * 10 * SQUARE_SIZE;
            const float pz = pos.z + (a / sqSize - sqSize / 2) * 10 * SQUARE_SIZE;
            const float3 unitPos = float3(px, ground->GetHeightReal(px, pz), pz);
            const UnitDef* unitDef = unitDefHandler->GetUnitDefByID(a);

            if (unitDef != NULL) {
                const CUnit* unit = LoadUnit(unitDef, unitPos, team, false, 0, NULL);

                if (unit != NULL) {
                    FlattenGround(unit);
                }
            }
        }
    } else {
        unsigned int numRequestedUnits = amount;
        unsigned int currentNumUnits = receivingTeam->units.size();

        if (receivingTeam->AtUnitLimit()) {
            LOG_L(L_WARNING,
                  "[%s] unable to give more units to team %d (current: %u, team limit: %u, global limit: %u)",
                  __FUNCTION__, team, currentNumUnits, receivingTeam->maxUnits, uh->MaxUnits()
                 );
            return;
        }

        // make sure team unit-limit is not exceeded
        if ((currentNumUnits + numRequestedUnits) > receivingTeam->maxUnits) {
            numRequestedUnits = receivingTeam->maxUnits - currentNumUnits;
        }

        const UnitDef* unitDef = unitDefHandler->GetUnitDefByName(objectName);
        const FeatureDef* featureDef = featureHandler->GetFeatureDef(objectName, false);

        if (unitDef == NULL && featureDef == NULL) {
            LOG_L(L_WARNING, "[%s] %s is not a valid object-name", __FUNCTION__, objectName.c_str());
            return;
        }

        if (unitDef != NULL) {
            const int xsize = unitDef->xsize;
            const int zsize = unitDef->zsize;
            const int squareSize = math::ceil(math::sqrt((float) numRequestedUnits));
            const float3 squarePos = float3(
                                         pos.x - (((squareSize - 1) * xsize * SQUARE_SIZE) / 2),
                                         pos.y,
                                         pos.z - (((squareSize - 1) * zsize * SQUARE_SIZE) / 2)
                                     );

            int total = numRequestedUnits;

            for (int z = 0; z < squareSize; ++z) {
                for (int x = 0; x < squareSize && total > 0; ++x) {
                    const float px = squarePos.x + x * xsize * SQUARE_SIZE;
                    const float pz = squarePos.z + z * zsize * SQUARE_SIZE;

                    const float3 unitPos = float3(px, ground->GetHeightReal(px, pz), pz);
                    Watchdog::ClearPrimaryTimers();
                    const CUnit* unit = LoadUnit(unitDef, unitPos, team, false, 0, NULL);

                    if (unit != NULL) {
                        FlattenGround(unit);
                    }

                    --total;
                }
            }

            LOG("[%s] spawned %i %s unit(s) for team %i",
                __FUNCTION__, numRequestedUnits, objectName.c_str(), team);
        }

        if (featureDef != NULL) {
            if (featureAllyTeam < 0) {
                team = -1; // default to world features
            }

            const int xsize = featureDef->xsize;
            const int zsize = featureDef->zsize;
            const int squareSize = math::ceil(math::sqrt((float) numRequestedUnits));
            const float3 squarePos = float3(
                                         pos.x - (((squareSize - 1) * xsize * SQUARE_SIZE) / 2),
                                         pos.y,
                                         pos.z - (((squareSize - 1) * zsize * SQUARE_SIZE) / 2)
                                     );

            int total = amount; // FIXME -- feature count limit?

            for (int z = 0; z < squareSize; ++z) {
                for (int x = 0; x < squareSize && total > 0; ++x) {
                    const float px = squarePos.x + x * xsize * SQUARE_SIZE;
                    const float pz = squarePos.z + z * zsize * SQUARE_SIZE;
                    const float3 featurePos = float3(px, ground->GetHeightReal(px, pz), pz);

                    Watchdog::ClearPrimaryTimers();
                    CFeature* feature = new CFeature();
                    // Initialize() adds the feature to the FeatureHandler -> no memory-leak
                    feature->Initialize(featurePos, featureDef, 0, 0, team, featureAllyTeam, NULL);

                    --total;
                }
            }

            LOG("[%s] spawned %i %s feature(s) for team %i",
                __FUNCTION__, numRequestedUnits, objectName.c_str(), team);
        }
    }
}