Пример #1
0
/**
** Send command: Unit patrol between current and position.
**
** @param unit     pointer to unit.
** @param pos      map tile position to patrol between.
** @param flush    Flag flush all pending commands.
*/
void SendCommandPatrol(CUnit &unit, const Vec2i &pos, int flush)
{
	if (!IsNetworkGame()) {
		CommandLog("patrol", &unit, flush, pos.x, pos.y, NoUnitP, NULL, -1);
		CommandPatrolUnit(unit, pos, flush);
	} else {
		NetworkSendCommand(MessageCommandPatrol, unit, pos.x, pos.y, NoUnitP, 0, flush);
	}
}
Пример #2
0
/**
** Execute a command (from network).
**
** @param msgnr    Network message type
** @param unum     Unit number (slot) that receive the command.
** @param x        optional X map position.
** @param y        optional y map position.
** @param dstnr    optional destination unit.
*/
void ExecCommand(unsigned char msgnr, UnitRef unum,
				 unsigned short x, unsigned short y, UnitRef dstnr)
{
	CUnit &unit = UnitManager.GetSlotUnit(unum);
	const Vec2i pos(x, y);
	const int arg1 = x;
	const int arg2 = y;
	//
	// Check if unit is already killed?
	//
	if (unit.Destroyed) {
		DebugPrint(" destroyed unit skipping %d\n" _C_ UnitNumber(unit));
		return;
	}
	Assert(unit.Type);

	const int status = (msgnr & 0x80) >> 7;
	// Note: destroyed destination unit is handled by the action routines.

	switch (msgnr & 0x7F) {
		case MessageSync:
			return;
		case MessageQuit:
			return;
		case MessageChat:
			return;

		case MessageCommandStop:
			CommandLog("stop", &unit, FlushCommands, -1, -1, NoUnitP, NULL, -1);
			CommandStopUnit(unit);
			break;
		case MessageCommandStand:
			CommandLog("stand-ground", &unit, status, -1, -1, NoUnitP, NULL, -1);
			CommandStandGround(unit, status);
			break;
		case MessageCommandDefend: {
			if (dstnr != (unsigned short)0xFFFF) {
				CUnit &dest = UnitManager.GetSlotUnit(dstnr);
				Assert(dest.Type);
				CommandLog("defend", &unit, status, -1, -1, &dest, NULL, -1);
				CommandDefend(unit, dest, status);
			}
			break;
		}
		case MessageCommandFollow: {
			if (dstnr != (unsigned short)0xFFFF) {
				CUnit &dest = UnitManager.GetSlotUnit(dstnr);
				Assert(dest.Type);
				CommandLog("follow", &unit, status, -1, -1, &dest, NULL, -1);
				CommandFollow(unit, dest, status);
			}
			break;
		}
		case MessageCommandMove:
			//Wyrmgus start
//			CommandLog("move", &unit, status, pos.x, pos.y, NoUnitP, NULL, -1);
//			CommandMove(unit, pos, status);
			if (!unit.CanMove()) { //FIXME: find better way to identify whether the unit should move or set a rally point
				CommandLog("rally-point", &unit, status, pos.x, pos.y, NoUnitP, NULL, -1);
				CommandRallyPoint(unit, pos);
			} else {
				CommandLog("move", &unit, status, pos.x, pos.y, NoUnitP, NULL, -1);
				CommandMove(unit, pos, status);
			}
			//Wyrmgus end
			break;
		//Wyrmgus start
		case MessageCommandPickUp: {
			if (dstnr != (unsigned short)0xFFFF) {
				CUnit &dest = UnitManager.GetSlotUnit(dstnr);
				Assert(dest.Type);
				CommandLog("pick-up", &unit, status, -1, -1, &dest, NULL, -1);
				CommandPickUp(unit, dest, status);
			}
			break;
		}
		//Wyrmgus end
		case MessageCommandRepair: {
			CUnit *dest = NoUnitP;
			if (dstnr != (unsigned short)0xFFFF) {
				dest = &UnitManager.GetSlotUnit(dstnr);
				Assert(dest && dest->Type);
			}
			CommandLog("repair", &unit, status, pos.x, pos.y, dest, NULL, -1);
			CommandRepair(unit, pos, dest, status);
			break;
		}
		case MessageCommandAutoRepair:
			CommandLog("auto-repair", &unit, status, arg1, arg2, NoUnitP, NULL, 0);
			CommandAutoRepair(unit, arg1);
			break;
		case MessageCommandAttack: {
			CUnit *dest = NoUnitP;
			if (dstnr != (unsigned short)0xFFFF) {
				dest = &UnitManager.GetSlotUnit(dstnr);
				Assert(dest && dest->Type);
			}
			CommandLog("attack", &unit, status, pos.x, pos.y, dest, NULL, -1);
			CommandAttack(unit, pos, dest, status);
			break;
		}
		case MessageCommandGround:
			CommandLog("attack-ground", &unit, status, pos.x, pos.y, NoUnitP, NULL, -1);
			CommandAttackGround(unit, pos, status);
			break;
		//Wyrmgus start
		case MessageCommandUse: {
			if (dstnr != (unsigned short)0xFFFF) {
				CUnit &dest = UnitManager.GetSlotUnit(dstnr);
				Assert(dest.Type);
				CommandLog("use", &unit, status, -1, -1, &dest, NULL, -1);
				CommandUse(unit, dest, status);
			}
			break;
		}
		//Wyrmgus end
		case MessageCommandPatrol:
			CommandLog("patrol", &unit, status, pos.x, pos.y, NoUnitP, NULL, -1);
			CommandPatrolUnit(unit, pos, status);
			break;
		case MessageCommandBoard: {
			if (dstnr != (unsigned short)0xFFFF) {
				CUnit &dest = UnitManager.GetSlotUnit(dstnr);
				Assert(dest.Type);
				CommandLog("board", &unit, status, arg1, arg2, &dest, NULL, -1);
				CommandBoard(unit, dest, status);
			}
			break;
		}
		case MessageCommandUnload: {
			CUnit *dest = NULL;
			if (dstnr != (unsigned short)0xFFFF) {
				dest = &UnitManager.GetSlotUnit(dstnr);
				Assert(dest && dest->Type);
			}
			CommandLog("unload", &unit, status, pos.x, pos.y, dest, NULL, -1);
			CommandUnload(unit, pos, dest, status);
			break;
		}
		case MessageCommandBuild:
			CommandLog("build", &unit, status, pos.x, pos.y, NoUnitP, UnitTypes[dstnr]->Ident.c_str(), -1);
			CommandBuildBuilding(unit, pos, *UnitTypes[dstnr], status);
			break;
		case MessageCommandDismiss:
			CommandLog("dismiss", &unit, FlushCommands, -1, -1, NULL, NULL, -1);
			CommandDismiss(unit);
			break;
		case MessageCommandResourceLoc:
			CommandLog("resource-loc", &unit, status, pos.x, pos.y, NoUnitP, NULL, -1);
			CommandResourceLoc(unit, pos, status);
			break;
		case MessageCommandResource: {
			if (dstnr != (unsigned short)0xFFFF) {
				CUnit &dest = UnitManager.GetSlotUnit(dstnr);
				Assert(dest.Type);
				CommandLog("resource", &unit, status, -1, -1, &dest, NULL, -1);
				CommandResource(unit, dest, status);
			}
			break;
		}
		case MessageCommandReturn: {
			CUnit *dest = (dstnr != (unsigned short)0xFFFF) ? &UnitManager.GetSlotUnit(dstnr) : NULL;
			CommandLog("return", &unit, status, -1, -1, dest, NULL, -1);
			CommandReturnGoods(unit, dest, status);
			break;
		}
		case MessageCommandTrain:
			//Wyrmgus start
//			CommandLog("train", &unit, status, -1, -1, NoUnitP, UnitTypes[dstnr]->Ident.c_str(), -1);
//			CommandTrainUnit(unit, *UnitTypes[dstnr], status);
			CommandLog("train", &unit, status, -1, -1, NoUnitP, UnitTypes[dstnr]->Ident.c_str(), arg1); // use X as a way to mark the player
			CommandTrainUnit(unit, *UnitTypes[dstnr], arg1, status);
			//Wyrmgus end
			break;
		case MessageCommandCancelTrain:
			// We need (short)x for the last slot -1
			if (dstnr != (unsigned short)0xFFFF) {
				CommandLog("cancel-train", &unit, FlushCommands, -1, -1, NoUnitP,
						   UnitTypes[dstnr]->Ident.c_str(), (short)x);
				CommandCancelTraining(unit, (short)x, UnitTypes[dstnr]);
			} else {
				CommandLog("cancel-train", &unit, FlushCommands, -1, -1, NoUnitP, NULL, (short)x);
				CommandCancelTraining(unit, (short)x, NULL);
			}
			break;
		case MessageCommandUpgrade:
			//Wyrmgus start
			/*
			CommandLog("upgrade-to", &unit, status, -1, -1, NoUnitP,
					   UnitTypes[dstnr]->Ident.c_str(), -1);
			CommandUpgradeTo(unit, *UnitTypes[dstnr], status);
			break;
			*/
			if (arg1 == 2) { //use X as a way to mark whether this is an upgrade or a transformation
				CommandLog("transform-into", &unit, status, -1, -1, NoUnitP,
						   UnitTypes[dstnr]->Ident.c_str(), -1);
				CommandTransformIntoType(unit, *UnitTypes[dstnr]);
			} else {
				CommandLog("upgrade-to", &unit, status, -1, -1, NoUnitP,
						   UnitTypes[dstnr]->Ident.c_str(), -1);
				CommandUpgradeTo(unit, *UnitTypes[dstnr], status);
			}
			break;
			//Wyrmgus end
		case MessageCommandCancelUpgrade:
			CommandLog("cancel-upgrade-to", &unit, FlushCommands, -1, -1, NoUnitP, NULL, -1);
			CommandCancelUpgradeTo(unit);
			break;
		case MessageCommandResearch:
			CommandLog("research", &unit, status, -1, -1, NoUnitP,
					   AllUpgrades[arg1]->Ident.c_str(), -1);
			CommandResearch(unit, *AllUpgrades[arg1], status);
			break;
		case MessageCommandCancelResearch:
			CommandLog("cancel-research", &unit, FlushCommands, -1, -1, NoUnitP, NULL, -1);
			CommandCancelResearch(unit);
			break;
		//Wyrmgus start
		case MessageCommandQuest: {
			CommandLog("quest", &unit, 0, 0, 0, NoUnitP, Quests[arg1]->Ident.c_str(), -1);
			CommandQuest(unit, Quests[arg1]);
			break;
		}
		case MessageCommandBuy: {
			if (dstnr != (unsigned short)0xFFFF) {
				CUnit &dest = UnitManager.GetSlotUnit(dstnr);
				Assert(dest.Type);
				CommandLog("buy", &unit, 0, -1, -1, &dest, NULL, arg1);
				CommandBuy(unit, &dest, arg1);
			}
			break;
		}
		//Wyrmgus end
		default: {
			int id = (msgnr & 0x7f) - MessageCommandSpellCast;
			if (arg2 != (unsigned short)0xFFFF) {
				CUnit *dest = NULL;
				if (dstnr != (unsigned short)0xFFFF) {
					dest = &UnitManager.GetSlotUnit(dstnr);
					Assert(dest && dest->Type);
				}
				CommandLog("spell-cast", &unit, status, pos.x, pos.y, dest, NULL, id);
				CommandSpellCast(unit, pos, dest, *SpellTypeTable[id], status);
			} else {
				CommandLog("auto-spell-cast", &unit, status, arg1, -1, NoUnitP, NULL, id);
				CommandAutoSpellCast(unit, id, arg1);
			}
			break;
		}
	}
}
Пример #3
0
/**
**  Order a unit
**
**  @param l  Lua state.
**
**  OrderUnit(player, unit-type, sloc, dloc, order)
*/
static int CclOrderUnit(lua_State *l)
{
	LuaCheckArgs(l, 5);

	lua_pushvalue(l, 1);
	const int plynr = TriggerGetPlayer(l);
	lua_pop(l, 1);
	lua_pushvalue(l, 2);
	const CUnitType *unittype = TriggerGetUnitType(l);
	lua_pop(l, 1);
	if (!lua_istable(l, 3)) {
		LuaError(l, "incorrect argument");
	}
	Vec2i pos1;
	pos1.x = LuaToNumber(l, 3, 1);
	pos1.y = LuaToNumber(l, 3, 2);

	Vec2i pos2;
	if (lua_rawlen(l, 3) == 4) {
		pos2.x = LuaToNumber(l, 3, 3);
		pos2.y = LuaToNumber(l, 3, 4);
	} else {
		pos2 = pos1;
	}
	if (!lua_istable(l, 4)) {
		LuaError(l, "incorrect argument");
	}
	Vec2i dpos1;
	Vec2i dpos2;
	dpos1.x = LuaToNumber(l, 4, 1);
	dpos1.y = LuaToNumber(l, 4, 2);
	if (lua_rawlen(l, 4) == 4) {
		dpos2.x = LuaToNumber(l, 4, 3);
		dpos2.y = LuaToNumber(l, 4, 4);
	} else {
		dpos2 = dpos1;
	}
	const char *order = LuaToString(l, 5);
	std::vector<CUnit *> table;
	Select(pos1, pos2, table);
	for (size_t i = 0; i != table.size(); ++i) {
		CUnit &unit = *table[i];

		if (unittype == ANY_UNIT
			|| (unittype == ALL_FOODUNITS && !unit.Type->Building)
			|| (unittype == ALL_BUILDINGS && unit.Type->Building)
			|| unittype == unit.Type) {
			if (plynr == -1 || plynr == unit.Player->Index) {
				if (!strcmp(order, "move")) {
					CommandMove(unit, (dpos1 + dpos2) / 2, 1);
				} else if (!strcmp(order, "attack")) {
					CUnit *attack = TargetOnMap(unit, dpos1, dpos2);

					CommandAttack(unit, (dpos1 + dpos2) / 2, attack, 1);
				} else if (!strcmp(order, "patrol")) {
					CommandPatrolUnit(unit, (dpos1 + dpos2) / 2, 1);
				} else {
					LuaError(l, "Unsupported order: %s" _C_ order);
				}
			}
		}
	}
	return 0;
}