Beispiel #1
0
/**
**  Cast a spell at position or unit.
**
**  @param unit   Pointer to unit.
**  @param pos    map position to spell cast on.
**  @param dest   Spell cast on unit (if exist).
**  @param spell  Spell type pointer.
**  @param flush  If true, flush command queue.
*/
void CommandSpellCast(CUnit &unit, const Vec2i &pos, CUnit *dest, const SpellType &spell, int flush, bool isAutocast)
{
	DebugPrint(": %d casts %s at %d %d on %d\n" _C_
			   UnitNumber(unit) _C_ spell.Ident.c_str() _C_ pos.x _C_ pos.y _C_ dest ? UnitNumber(*dest) : 0);
	Assert(unit.Type->CanCastSpell[spell.Slot]);
	Assert(Map.Info.IsPointOnMap(pos));

	if (IsUnitValidForNetwork(unit) == false) {
		return ;
	}
	//Wyrmgus start
	CMapField &mf = *Map.Field(unit.tilePos);
	if ((mf.Flags & MapFieldBridge) && !unit.Type->BoolFlag[BRIDGE_INDEX].value && unit.Type->UnitType == UnitTypeLand) { 
		std::vector<CUnit *> table;
		Select(unit.tilePos, unit.tilePos, table);
		for (size_t i = 0; i != table.size(); ++i) {
			if (!table[i]->Removed && table[i]->Type->BoolFlag[BRIDGE_INDEX].value && table[i]->CanMove()) {
				CommandStopUnit(*table[i]); //always stop the raft if a new command is issued
			}
		}
	}
	//Wyrmgus end
	COrderPtr *order = GetNextOrder(unit, flush);

	if (order == NULL) {
		return;
	}

	*order = COrder::NewActionSpellCast(spell, pos, dest, true);
	ClearSavedAction(unit);
}
Beispiel #2
0
/**
**  Prepare send of command message.
**
**  Convert arguments into network format and place it into output queue.
**
**  @param command  Command (Move,Attack,...).
**  @param unit     Unit that receive the command.
**  @param x        optional X map position.
**  @param y        optional y map position.
**  @param dest     optional destination unit.
**  @param type     optional unit-type argument.
**  @param status   Append command or flush old commands.
**
**  @warning  Destination and unit-type shares the same network slot.
*/
void NetworkSendCommand(int command, const CUnit &unit, int x, int y,
						const CUnit *dest, const CUnitType *type, int status)
{
	CNetworkCommandQueue ncq;

	ncq.Time = GameCycle;
	ncq.Type = command;
	if (status) {
		ncq.Type |= 0x80;
	}
	CNetworkCommand nc;
	nc.Unit = UnitNumber(unit);
	nc.X = x;
	nc.Y = y;
	Assert(!dest || !type); // Both together isn't allowed
	if (dest) {
		nc.Dest = UnitNumber(*dest);
	} else if (type) {
		nc.Dest = type->Slot;
	} else {
		nc.Dest = 0xFFFF; // -1
	}
	ncq.Data.resize(nc.Size());
	nc.Serialize(&ncq.Data[0]);
	// Check for duplicate command in queue
	if (std::find(CommandsIn.begin(), CommandsIn.end(), ncq) != CommandsIn.end()) {
		return;
	}
	CommandsIn.push_back(ncq);
}
Beispiel #3
0
	bool operator()(const CUnit *c1, const CUnit *c2)
	{
		int d1 = c1->MapDistanceTo(*referenceunit);
		int d2 = c2->MapDistanceTo(*referenceunit);
		if (d1 == d2) {
			return UnitNumber(*c1) < UnitNumber(*c2);
		} else {
			return d1 < d2;
		}
	}
Beispiel #4
0
static bool IsPiercedUnit(const Missile &missile, const CUnit &unit)
{
	for (std::vector<CUnit *>::const_iterator it = missile.PiercedUnits.begin();
		 it != missile.PiercedUnits.end(); ++it) {
		CUnit &punit = **it;
		if (UnitNumber(unit) == UnitNumber(punit)) {
			return true;
		}
	}
	return false;
}
Beispiel #5
0
int AiForceManager::GetForce(const CUnit &unit)
{
	for (unsigned int i = 0; i < forces.size(); ++i) {
		AiForce &force = forces[i];

		for (unsigned int j = 0; j < force.Units.size(); ++j) {
			CUnit &aiunit = *force.Units[j];

			if (UnitNumber(unit) == UnitNumber(aiunit)) {
				return i;
			}
		}
	}
	return -1;
}
Beispiel #6
0
/**
**  Call a lua callback to make user actions in Lua script
**
**  @param caster   Unit that casts the spell
**  @param spell    Spell-type pointer
**  @param target   Target
**  @param goalPos  coord of target spot when/if target does not exist
**
**  @return        =!0 if spell should be repeated, 0 if not
*/
/* virtual */ int Spell_LuaCallback::Cast(CUnit &caster, const SpellType &spell, CUnit *target, const Vec2i &goalPos)
{
	if (this->Func) {
		this->Func->pushPreamble();
		this->Func->pushString(spell.Ident);
		this->Func->pushInteger(UnitNumber(caster));
		this->Func->pushInteger(goalPos.x);
		this->Func->pushInteger(goalPos.y);
		this->Func->pushInteger((target && target->IsAlive()) ? UnitNumber(*target) : -1);
		this->Func->run(1);
		bool result = this->Func->popBoolean();
		return result;
	}
	return 0;
}
Beispiel #7
0
/**
**  Cast a spell at position or unit.
**
**  @param unit   Pointer to unit.
**  @param x      X map position to spell cast on.
**  @param y      Y map position to spell cast on.
**  @param dest   Spell cast on unit (if exist).
**  @param spell  Spell type pointer.
**  @param flush  If true, flush command queue.
*/
void CommandSpellCast(CUnit *unit, int x, int y, CUnit *dest,
	SpellType *spell, int flush)
{
	COrder *order;

	Assert(x >= 0 && y >= 0 && x < Map.Info.MapWidth && y < Map.Info.MapHeight);

	DebugPrint(": %d casts %s at %d %d on %d\n" _C_
		UnitNumber(unit) _C_ spell->Ident.c_str() _C_ x _C_ y _C_ dest ? UnitNumber(dest) : 0);
	Assert(unit->Type->CanCastSpell[spell->Slot]);

	//
	// Check if unit is still valid? (NETWORK!)
	//
	if (!unit->Removed && unit->Orders[0]->Action != UnitActionDie) {
		// FIXME: should I check here, if there is still enough mana?

		if (!(order = GetNextOrder(unit, flush))) {
			return;
		}
		order->Init();

		order->Action = UnitActionSpellCast;
		order->Range = spell->Range;
		if (dest) {
			//
			// Destination could be killed.
			// Should be handled in action, but is not possible!
			// Unit::Refs is used as timeout counter.
			//
			if (dest->Destroyed) {
				// FIXME: where check if spell needs an unit as destination?
				// FIXME: dest->Type is now set to 0. maybe we shouldn't bother.
				order->X = dest->X /*+ dest->Type->TileWidth / 2*/  - order->Range;
				order->Y = dest->Y /*+ dest->Type->TileHeight / 2*/ - order->Range;
				order->Range <<= 1;
			} else {
				order->Goal = dest;
				dest->RefsIncrease();
			}
		} else {
			order->X = x;
			order->Y = y;
		}
		order->Arg1.Spell = spell;
	}
	ClearSavedAction(unit);
}
Beispiel #8
0
/**
**  Sends my selections to teammates
**
**  @param units  Units to send
**  @param count  Number of units to send
*/
void NetworkSendSelection(CUnit **units, int count)
{
	// Check if we have any teammates to send to
	bool hasteammates = false;
	for (int i = 0; i < HostsCount; ++i) {
		if (Players[Hosts[i].PlyNr].Team == ThisPlayer->Team) {
			hasteammates = true;
			break;
		}
	}
	if (!hasteammates) {
		return;
	}
	// Build and send packets to cover all units.
	CNetworkSelection ns;

	for (int i = 0; i != count; ++i) {
		ns.Units.push_back(UnitNumber(*units[i]));
	}
	CNetworkCommandQueue ncq;
	ncq.Time = GameCycle;
	ncq.Type = MessageSelection;

	ncq.Data.resize(ns.Size());
	ns.Serialize(&ncq.Data[0]);
	CommandsIn.push_back(ncq);
}
/**
**	Unit upgrades unit!
**
**	@param unit	Pointer to unit.
*/
global void HandleActionUpgradeTo(Unit* unit)
{
    Player* player;
    UnitType* type;
    const UnitStats* stats;

    DebugLevel3Fn(" %d\n" _C_ UnitNumber(unit));

    player=unit->Player;
    if( !unit->SubAction ) {		// first entry
        unit->Data.UpgradeTo.Ticks=0;
        unit->SubAction=1;
    }
    type=unit->Orders[0].Type;
    stats=&type->Stats[player->Player];

    UnitMarkSeen(unit);
    // FIXME: Should count down here
    unit->Data.UpgradeTo.Ticks+=SpeedUpgrade;
    if( unit->Data.UpgradeTo.Ticks>=stats->Costs[TimeCost] ) {

        unit->HP+=stats->HitPoints-unit->Type->Stats[player->Player].HitPoints;
        // don't have such unit now
        player->UnitTypesCount[unit->Type->Type]--;
        unit->Type=type;
        unit->Stats=(UnitStats*)stats;
        // and we have new one...
        player->UnitTypesCount[unit->Type->Type]++;
        UpdateForNewUnit(unit,1);

        NotifyPlayer(player,NotifyGreen,unit->X,unit->Y,
                     "Upgrade to %s complete",unit->Type->Name );
        if( unit->Player->Ai ) {
            AiUpgradeToComplete(unit,type);
        }
        unit->Reset=unit->Wait=1;
        unit->Orders[0].Action=UnitActionStill;
        unit->SubAction=0;

        //
        //	Update possible changed buttons.
        //
        if( IsOnlySelected(unit) ) {
            UpdateButtonPanel();
            MustRedraw|=RedrawPanels;
        } else if( player==ThisPlayer ) {
            UpdateButtonPanel();
            MustRedraw|=RedrawInfoPanel;
        }

        return;
    }

    if( IsOnlySelected(unit) ) {
        MustRedraw|=RedrawInfoPanel;
    }

    unit->Reset=1;
    unit->Wait=CYCLES_PER_SECOND/6;
}
Beispiel #10
0
/**
**  Ask to the sound server to play a sound attached to a unit. The
**  sound server may discard the sound if needed (e.g., when the same
**  unit is already speaking).
**
**  @param unit   Sound initiator, unit speaking
**  @param voice  Type of sound wanted (Ready,Die,Yes,...)
*/
void PlayUnitSound(const CUnit &unit, UnitVoiceGroup voice)
{
	CSound *sound = ChooseUnitVoiceSound(unit, voice);
	if (!sound) {
		return;
	}

	bool selection = (voice == VoiceSelected || voice == VoiceBuilding);
	Origin source = {&unit, unsigned(UnitNumber(unit))};

	//Wyrmgus start
//	if (UnitSoundIsPlaying(&source)) {
	if (UnitSoundIsPlaying(&source) && voice != VoiceHit && voice != VoiceMiss && voice != VoiceStep) {
	//Wyrmgus end
		return;
	}

	int channel = PlaySample(ChooseSample(sound, selection, source), &source);
	if (channel == -1) {
		return;
	}
	//Wyrmgus start
//	SetChannelVolume(channel, CalculateVolume(false, ViewPointDistanceToUnit(unit), sound->Range));
	SetChannelVolume(channel, CalculateVolume(false, ViewPointDistanceToUnit(unit), sound->Range) * sound->VolumePercent / 100);
	//Wyrmgus end
	SetChannelStereo(channel, CalculateStereo(unit));
	//Wyrmgus start
	SetChannelVoiceGroup(channel, voice);
	//Wyrmgus end
}
Beispiel #11
0
/**
**  Get a player's units in rectangle box specified with 2 coordinates
**
**  @param l  Lua state.
**
**  @return   Array of units.
*/
static int CclGetUnitsAroundUnit(lua_State *l)
{
	const int nargs = lua_gettop(l);
	if (nargs != 2 && nargs != 3) {
		LuaError(l, "incorrect argument\n");
	}

	const int slot = LuaToNumber(l, 1);
	const CUnit &unit = UnitManager.GetSlotUnit(slot);
	const int range = LuaToNumber(l, 2);
	bool allUnits = false;
	if (nargs == 3) {
		allUnits = LuaToBoolean(l, 3);
	}
	lua_newtable(l);
	std::vector<CUnit *> table;
	if (allUnits) {
		SelectAroundUnit(unit, range, table, HasNotSamePlayerAs(Players[PlayerNumNeutral]));
	} else {
		SelectAroundUnit(unit, range, table, HasSamePlayerAs(*unit.Player));
	}
	size_t n = 0;
	for (size_t i = 0; i < table.size(); ++i) {
		if (table[i]->IsAliveOnMap()) {
			lua_pushnumber(l, UnitNumber(*table[i]));
			lua_rawseti(l, -2, ++n);
		}
	}
	return 1;
}
Beispiel #12
0
/**
**  Generate a unit reference, a printable unique string for unit.
*/
std::string UnitReference(const CUnit &unit)
{
	std::ostringstream ss;
	ss << "U" << std::setfill('0') << std::setw(4) << std::uppercase
	   << std::hex << UnitNumber(unit);
	return ss.str();
}
Beispiel #13
0
/**
**  Called if upgrading of an unit is completed.
**
**  @param unit Pointer to unit working.
**  @param what Pointer to the new unit-type.
*/
void AiUpgradeToComplete(CUnit &unit, const CUnitType &what)
{
	DebugPrint("%d: %d(%s) upgrade-to %s at %d,%d completed\n" _C_
			   unit.Player->Index _C_ UnitNumber(unit) _C_ unit.Type->Ident.c_str() _C_
			   what.Ident.c_str() _C_ unit.tilePos.x _C_ unit.tilePos.y);

	Assert(unit.Player->Type != PlayerPerson);
}
Beispiel #14
0
CUnit* GetUnitByID(int unitID) {
    int i;
    for (i = 0; i < NumUnits; i++)
        if (UnitNumber(Units[i]) == unitID)
            return Units[i];

    return NoUnitP;
}
Beispiel #15
0
/**
**  Called if a member of Group is Attacked
**
**  @param attacker  Pointer to attacker unit.
**  @param defender  Pointer to unit that is being attacked.
*/
void GroupHelpMe(CUnit *attacker, CUnit &defender)
{
	/* Freandly Fire - typical splash */
	if (!attacker || attacker->Player->Index == defender.Player->Index) {
		return;
	}

	DebugPrint("%d: GroupHelpMe %d(%s) attacked at %d,%d\n" _C_
		defender.Player->Index _C_ UnitNumber(defender) _C_
		defender.Type->Ident.c_str() _C_ defender.tilePos.x _C_ defender.tilePos.y);

	//
	//  Don't send help to scouts (zeppelin,eye of vision).
	//
	if (!defender.Type->CanAttack && defender.Type->UnitType == UnitTypeFly) {
		return;
	}

	if (defender.GroupId) {
		int mask = 0;
		CUnitGroup *group;
		for (int num = 0; num < NUM_GROUPS; ++num) {

			//  Unit belongs to an group, check if brothers in arms can help
			if (defender.GroupId & (1<<num)) {
				mask |= (1<<num);
				group = &Groups[num];

				for (int i = 0; i < group->NumUnits; ++i) {
					CUnit &gunit = *group->Units[i];

					if (&defender == &gunit) {
						continue;
					}

					// if brother is idle or attack no-agressive target and
					// can attack our attacker then ask for help
					if (gunit.IsAgressive() && (gunit.IsIdle() ||
						!(gunit.CurrentAction() == UnitActionAttack &&
						gunit.CurrentOrder()->HasGoal() &&
						gunit.CurrentOrder()->GetGoal()->IsAgressive()))
						&& CanTarget(gunit.Type, attacker->Type)) {

						if (gunit.SavedOrder.Action == UnitActionStill) {
							// FIXME: should rewrite command handling
							CommandAttack(gunit, gunit.tilePos, NoUnitP, FlushCommands);
							gunit.SavedOrder = *gunit.Orders[1];
						}
						CommandAttack(gunit, attacker->tilePos, attacker, FlushCommands);
					}
				}
				if (!(defender.GroupId & ~mask)) {
					return;
				}
			}
		}
	}
}
Beispiel #16
0
/**
**  Called if a Unit is Attacked
**
**  @param attacker  Pointer to attacker unit.
**  @param defender  Pointer to unit that is being attacked.
*/
void AiHelpMe(const CUnit *attacker, CUnit *defender)
{
	PlayerAi *pai;
	CUnit *aiunit;
	int force;
	int destx, desty;

	DebugPrint("%d: %d(%s) attacked at %d,%d\n" _C_
		defender->Player->Index _C_ UnitNumber(defender) _C_
		defender->Type->Ident.c_str() _C_ defender->X _C_ defender->Y);

	AiPlayer = pai = defender->Player->Ai;
	if (pai->Force[0].Attacking)
	{
		// Force 0 busy
		return;
	}

	//
	//  If unit belongs to an attacking force, don't defend it.
	//
	for (force = 0; force < AI_MAX_ATTACKING_FORCES; ++force)
	{
		if (!pai->Force[force].Attacking)
		{
			// none attacking
			// FIXME, send the force for help
			continue;
		}

		for (size_t i = 0; i < pai->Force[force].Units.size(); ++i)
		{
			aiunit = pai->Force[force].Units[i];
			if (defender == aiunit)
			{
				return;
			}
		}
	}

	//
	//  Send forces
	//
	destx = attacker ? attacker->X : defender->X;
	desty = attacker ? attacker->Y : defender->Y;

	// Send force 0 defending
	AiAttackWithForceAt(0, destx, desty);
	pai->Force[0].Defending = true;

	// Also send force 1 if not already attacking
	if (!pai->Force[1].Attacking)
	{
		pai->Force[1].Defending = true;
		AiAttackWithForceAt(1, destx, desty);
	}
}
Beispiel #17
0
/**
**  Called if building can't be build.
**
**  @param unit  Pointer to unit what builds the building.
**  @param what  Pointer to unit-type.
*/
void AiCanNotBuild(const CUnit &unit, const CUnitType &what)
{
	DebugPrint("%d: %d(%s) Can't build %s at %d,%d\n" _C_
			   unit.Player->Index _C_ UnitNumber(unit) _C_ unit.Type->Ident.c_str() _C_
			   what.Ident.c_str() _C_ unit.tilePos.x _C_ unit.tilePos.y);

	Assert(unit.Player->Type != PlayerPerson);
	AiReduceMadeInBuilt(*unit.Player->Ai, what);
}
Beispiel #18
0
/**
**  Called if building can't be built.
**
**  @param unit      The unit trying to build.
**  @param unitType  Unit type trying to be built.
*/
void AiCanNotBuild(CUnit *unit, const CUnitType *unitType)
{
	DebugPrint("%d: %d(%s) Can't build %s at %d,%d\n" _C_
		unit->Player->Index _C_ UnitNumber(unit) _C_ unit->Type->Ident.c_str() _C_
		unitType->Ident.c_str() _C_ unit->X _C_ unit->Y);

	Assert(unit->Player->Type != PlayerPerson);
	AiReduceMadeInBuilt(unit->Player->Ai, unitType);
}
Beispiel #19
0
/** Called when unit is killed.
**  warn the AI module.
*/
void COrder_Build::AiUnitKilled(CUnit &unit)
{
	DebugPrint("%d: %d(%s) killed, with order %s!\n" _C_
			   unit.Player->Index _C_ UnitNumber(unit) _C_
			   unit.Type->Ident.c_str() _C_ this->Type->Ident.c_str());
	if (this->BuildingUnit == NULL) {
		AiReduceMadeInBuilt(*unit.Player->Ai, *this->Type);
	}
}
Beispiel #20
0
/**
**  Generate a unit reference, a printable unique string for unit.
*/
std::string UnitReference(const CUnitPtr &unit)
{
	Assert(unit != NULL);

	std::ostringstream ss;
	ss << "U" << std::setfill('0') << std::setw(4) << std::uppercase
	   << std::hex << UnitNumber(*unit);
	return ss.str();
}
Beispiel #21
0
/**
**  Cast a spell at position or unit.
**
**  @param unit   Pointer to unit.
**  @param pos    map position to spell cast on.
**  @param dest   Spell cast on unit (if exist).
**  @param spell  Spell type pointer.
**  @param flush  If true, flush command queue.
*/
void CommandSpellCast(CUnit &unit, const Vec2i &pos, CUnit *dest, const SpellType &spell, int flush)
{
	DebugPrint(": %d casts %s at %d %d on %d\n" _C_
			   UnitNumber(unit) _C_ spell.Ident.c_str() _C_ pos.x _C_ pos.y _C_ dest ? UnitNumber(*dest) : 0);
	Assert(unit.Type->CanCastSpell[spell.Slot]);
	Assert(Map.Info.IsPointOnMap(pos));

	if (IsUnitValidForNetwork(unit) == false) {
		return ;
	}
	COrderPtr *order = GetNextOrder(unit, flush);

	if (order == NULL) {
		return;
	}

	*order = COrder::NewActionSpellCast(spell, pos, dest);
	ClearSavedAction(unit);
}
Beispiel #22
0
/**
**  Called if reseaching of an unit is completed.
**
**  @param unit  Pointer to unit working.
**  @param what  Pointer to the new upgrade.
*/
void AiResearchComplete(CUnit &unit, const CUpgrade *what)
{
	DebugPrint("%d: %d(%s) research %s at %d,%d completed\n" _C_
			   unit.Player->Index _C_ UnitNumber(unit) _C_ unit.Type->Ident.c_str() _C_
			   what->Ident.c_str() _C_ unit.tilePos.x _C_ unit.tilePos.y);

	Assert(unit.Player->Type != PlayerPerson);

	// FIXME: upgrading knights -> paladins, must rebuild lists!
}
Beispiel #23
0
/**
**  Save the viewports.
**
**  @param file  Save file handle
**  @param ui    User interface to save
*/
static void SaveViewports(CFile &file, const CUserInterface &ui)
{
	// FIXME: don't save the number
	file.printf("DefineViewports(\"mode\", %d", ui.ViewportMode);
	for (int i = 0; i < ui.NumViewports; ++i) {
		const CViewport &vp = ui.Viewports[i];
		file.printf(",\n  \"viewport\", {%d, %d, %d}", vp.MapPos.x, vp.MapPos.y,
					vp.Unit ? UnitNumber(*vp.Unit) : -1);
	}
	file.printf(")\n\n");
}
Beispiel #24
0
/**
**  Ask to the sound server to play a sound attached to a unit. The
**  sound server may discard the sound if needed (e.g., when the same
**  unit is already speaking).
**
**  @param unit   Sound initiator, unit speaking
**  @param sound  Sound to be generated
*/
void PlayUnitSound(const CUnit &unit, CSound *sound)
{
	Origin source = {&unit, UnitNumber(unit)};

	int channel = PlaySample(ChooseSample(sound, false, source));
	if (channel == -1) {
		return;
	}
	SetChannelVolume(channel, CalculateVolume(false, ViewPointDistanceToUnit(unit), sound->Range));
	SetChannelStereo(channel, CalculateStereo(unit));
}
Beispiel #25
0
/**
**  Get a player's units
**
**  @param l  Lua state.
**
**  @return   Array of units.
*/
static int CclGetUnits(lua_State *l)
{
	LuaCheckArgs(l, 1);

	const int plynr = TriggerGetPlayer(l);

	lua_newtable(l);
	if (plynr == -1) {
		int i = 0;
		for (CUnitManager::Iterator it = UnitManager.begin(); it != UnitManager.end(); ++it, ++i) {
			const CUnit &unit = **it;
			lua_pushnumber(l, UnitNumber(unit));
			lua_rawseti(l, -2, i + 1);
		}
	} else {
		for (int i = 0; i < Players[plynr].GetUnitCount(); ++i) {
			lua_pushnumber(l, UnitNumber(Players[plynr].GetUnit(i)));
			lua_rawseti(l, -2, i + 1);
		}
	}
	return 1;
}
Beispiel #26
0
void HandleGet() {
    int i;
    char buf[256];

    sprintf(buf, "Units: %d\n", NumUnits);
    SendResponseMessage(buf, 1);
    for (i = 0; i < NumUnits; ++i) {
        if (Units[i]->Orders[0]->Goal) {
            sprintf(buf, "Unit %d, Slot %d, Player %d: %s (%d, %d) HP: %d/%d ACTION: (%d Goal: %d (%d, %d))\n",
                    UnitNumber(Units[i]),
                    Units[i]->Slot,
                    Units[i]->Player->Index,
                    Units[i]->Type->Ident.c_str(),
                    Units[i]->X,
                    Units[i]->Y,
                    Units[i]->Variable[HP_INDEX].Value,
                    Units[i]->Stats->Variables[HP_INDEX].Value,
                    Units[i]->Orders[0]->Action,
                    UnitNumber(Units[i]->Orders[0]->Goal),
                    Units[i]->Orders[0]->Goal->X,
                    Units[i]->Orders[0]->Goal->Y);
        } else {
            sprintf(buf, "Unit %d, Slot %d, Player %d: %s (%d, %d) HP: %d/%d ACTION: %d\n",
                    UnitNumber(Units[i]),
                    Units[i]->Slot,
                    Units[i]->Player->Index,
                    Units[i]->Type->Ident.c_str(),
                    Units[i]->X,
                    Units[i]->Y,
                    Units[i]->Variable[HP_INDEX].Value,
                    Units[i]->Stats->Variables[HP_INDEX].Value,
                    Units[i]->Orders[0]->Action);
        }
        SendResponseMessage(buf, 0);
    }
    sprintf(buf, "Map Size: %dx%d\n", Map.Info.MapWidth, Map.Info.MapHeight);
    SendResponseMessage(buf, 2);
}
Beispiel #27
0
/**
**  Called when a unit is killed.
**
**  @param unit  Pointer to unit.
*/
void AiUnitKilled(CUnit *unit)
{
	DebugPrint("%d: %d(%s) killed\n" _C_
		unit->Player->Index _C_ UnitNumber(unit) _C_ unit->Type->Ident.c_str());

	Assert(unit->Player->Type != PlayerPerson);

	// FIXME: must handle all orders...
	switch (unit->Orders[0]->Action)
	{
		case UnitActionStill:
		case UnitActionAttack:
		case UnitActionMove:
			break;

		case UnitActionBuilt:
			DebugPrint("%d: %d(%s) killed, under construction!\n" _C_
				unit->Player->Index _C_ UnitNumber(unit) _C_ unit->Type->Ident.c_str());
			AiReduceMadeInBuilt(unit->Player->Ai, unit->Type);
			break;

		case UnitActionBuild:
			DebugPrint("%d: %d(%s) killed, with order %s!\n" _C_
				unit->Player->Index _C_ UnitNumber(unit) _C_
				unit->Type->Ident.c_str() _C_ unit->Orders[0]->Type->Ident.c_str());
			if (!unit->Orders[0]->Goal)
			{
				AiReduceMadeInBuilt(unit->Player->Ai, unit->Orders[0]->Type);
			}
			break;

		default:
			DebugPrint("FIXME: %d: %d(%s) killed, with order %d!\n" _C_
				unit->Player->Index _C_ UnitNumber(unit) _C_
				unit->Type->Ident.c_str() _C_ unit->Orders[0]->Action);
			break;
	}
}
Beispiel #28
0
/**
**  Called when training of a unit is completed.
**
**  @param unit     Unit that trained the new unit.
**  @param newUnit  The new unit.
*/
void AiTrainingComplete(CUnit *unit, CUnit *newUnit)
{
	DebugPrint("%d: %d(%s) training %s at %d,%d completed\n" _C_
		unit->Player->Index _C_ UnitNumber(unit) _C_ unit->Type->Ident.c_str() _C_
		newUnit->Type->Ident.c_str() _C_ unit->X _C_ unit->Y);

	Assert(unit->Player->Type != PlayerPerson);

	AiRemoveFromBuilt(unit->Player->Ai, newUnit->Type);

	AiPlayer = unit->Player->Ai;
	AiCleanForces();
	AiAssignToForce(newUnit);
}
Beispiel #29
0
/**
**  Called if work complete (Buildings).
**
**  @param unit  Pointer to unit that builds the building.
**  @param what  Pointer to unit building that was built.
*/
void AiWorkComplete(CUnit *unit, CUnit &what)
{
	if (unit) {
		DebugPrint("%d: %d(%s) build %s at %d,%d completed\n" _C_
				   what.Player->Index _C_ UnitNumber(*unit) _C_ unit->Type->Ident.c_str() _C_
				   what.Type->Ident.c_str() _C_ unit->tilePos.x _C_ unit->tilePos.y);
	} else {
		DebugPrint("%d: building %s at %d,%d completed\n" _C_
				   what.Player->Index _C_ what.Type->Ident.c_str() _C_ what.tilePos.x _C_ what.tilePos.y);
	}

	Assert(what.Player->Type != PlayerPerson);
	AiRemoveFromBuilt(what.Player->Ai, *what.Type);
}
Beispiel #30
0
/**
**  Called if training of a unit is completed.
**
**  @param unit  Pointer to unit making.
**  @param what  Pointer to new ready trained unit.
*/
void AiTrainingComplete(CUnit &unit, CUnit &what)
{
	DebugPrint("%d: %d(%s) training %s at %d,%d completed\n" _C_
			   unit.Player->Index _C_ UnitNumber(unit) _C_ unit.Type->Ident.c_str() _C_
			   what.Type->Ident.c_str() _C_ unit.tilePos.x _C_ unit.tilePos.y);

	Assert(unit.Player->Type != PlayerPerson);

	AiRemoveFromBuilt(unit.Player->Ai, *what.Type);

	unit.Player->Ai->Force.RemoveDeadUnit();
	unit.Player->Ai->Force.Assign(what);

}