Beispiel #1
0
/* virtual */ void CAnimation_SpawnUnit::Action(CUnit &unit, int &/*move*/, int /*scale*/) const
{
	Assert(unit.Anim.Anim == this);

	const int offX = ParseAnimInt(unit, this->offXStr.c_str());
	const int offY = ParseAnimInt(unit, this->offYStr.c_str());
	const int range = ParseAnimInt(unit, this->rangeStr.c_str());
	const int playerId = ParseAnimInt(unit, this->playerStr.c_str());
	const SpawnUnit_Flags flags = (SpawnUnit_Flags)(ParseAnimFlags(unit, this->flagsStr.c_str()));

	CPlayer &player = Players[playerId];
	const Vec2i pos(unit.tilePos.x + offX, unit.tilePos.y + offY);
	CUnitType *type = UnitTypeByIdent(this->unitTypeStr.c_str());
	Assert(type);
	Vec2i resPos;
	DebugPrint("Creating a %s\n" _C_ type->Name.c_str());
	FindNearestDrop(*type, pos, resPos, LookingW);
	if (SquareDistance(pos, resPos) <= square(range)) {
		CUnit *target = MakeUnit(*type, &player);
		if (target != NULL) {
			target->tilePos = resPos;
			target->Place(resPos);
			if (flags & SU_Summoned) {
				target->Summoned = 1;
			}
			if ((flags & SU_JoinToAIForce) && unit.Player->AiEnabled) {
				int force = unit.Player->Ai->Force.GetForce(unit);
				if (force != -1) {
					unit.Player->Ai->Force[force].Insert(*target);
					target->GroupId = unit.GroupId;
					CommandDefend(*target, unit, FlushCommands);
				}
			}
			//DropOutOnSide(*target, LookingW, NULL);
		} else {
			DebugPrint("Unable to allocate Unit");
		}
	}
}
/* virtual */ void CAnimation_SpawnMissile::Action(CUnit &unit, int &/*move*/, int /*scale*/) const
{
	Assert(unit.Anim.Anim == this);

	const int startx = ParseAnimInt(&unit, this->startXStr.c_str());
	const int starty = ParseAnimInt(&unit, this->startYStr.c_str());
	const int destx = ParseAnimInt(&unit, this->destXStr.c_str());
	const int desty = ParseAnimInt(&unit, this->destYStr.c_str());
	const int flags = ParseAnimFlags(unit, this->flagsStr.c_str());
	const int offsetnum = ParseAnimInt(&unit, this->offsetNumStr.c_str());
	const CUnit *goal = flags & ANIM_SM_RELTARGET ? unit.CurrentOrder()->GetGoal() : &unit;
	const int dir = ((goal->Direction + NextDirection / 2) & 0xFF) / NextDirection;
	const PixelPos moff = goal->Type->MissileOffsets[dir][!offsetnum ? 0 : offsetnum - 1];
	PixelPos start;
	PixelPos dest;
	MissileType *mtype = MissileTypeByIdent(this->missileTypeStr);
	if (mtype == NULL) {
		return;
	}

	if (!goal || goal->Destroyed) {
		return;
	}
	if ((flags & ANIM_SM_PIXEL)) {
		start.x = goal->tilePos.x * PixelTileSize.x + goal->IX + moff.x + startx;
		start.y = goal->tilePos.y * PixelTileSize.y + goal->IY + moff.y + starty;
	} else {
		start.x = (goal->tilePos.x + startx) * PixelTileSize.x + PixelTileSize.x / 2 + moff.x;
		start.y = (goal->tilePos.y + starty) * PixelTileSize.y + PixelTileSize.y / 2 + moff.y;
	}
	if ((flags & ANIM_SM_TOTARGET)) {
		CUnit *target = goal->CurrentOrder()->GetGoal();
		if (!target || target->Destroyed) {
			Assert(!mtype->AlwaysFire || mtype->Range);
			if (!target && mtype->AlwaysFire == false) {
				return;
			}
		}
		if (!target) {
			if (goal->CurrentAction() == UnitActionAttack || goal->CurrentAction() == UnitActionAttackGround) {
				COrder_Attack &order = *static_cast<COrder_Attack *>(goal->CurrentOrder());
				dest = Map.TilePosToMapPixelPos_Center(order.GetGoalPos());
			} else if (goal->CurrentAction() == UnitActionSpellCast) {
				COrder_SpellCast &order = *static_cast<COrder_SpellCast *>(goal->CurrentOrder());
				dest = Map.TilePosToMapPixelPos_Center(order.GetGoalPos());
			}
			if (flags & ANIM_SM_PIXEL) {
				dest.x += destx;
				dest.y += desty;
			} else {
				dest.x += destx * PixelTileSize.x;
				dest.y += desty * PixelTileSize.y;
			}
		} else if (flags & ANIM_SM_PIXEL) {
			dest.x = target->GetMapPixelPosCenter().x + destx;
			dest.y = target->GetMapPixelPosCenter().y + desty;
		} else {
			dest.x = (target->tilePos.x + destx) * PixelTileSize.x;
			dest.y = (target->tilePos.y + desty) * PixelTileSize.y;
			dest += target->Type->GetPixelSize() / 2;
		}
	} else {
		if ((flags & ANIM_SM_PIXEL)) {
			dest.x = goal->GetMapPixelPosCenter().x + destx;
			dest.y = goal->GetMapPixelPosCenter().y + desty;
		} else {
			dest.x = (goal->tilePos.x + destx) * PixelTileSize.x;
			dest.y = (goal->tilePos.y + desty) * PixelTileSize.y;
			dest += goal->Type->GetPixelSize() / 2;
		}
	}
	Vec2i destTilePos = Map.MapPixelPosToTilePos(dest);
	const int dist = goal->MapDistanceTo(destTilePos);
	if ((flags & ANIM_SM_RANGED) && !(flags & ANIM_SM_PIXEL)
		&& dist > goal->Stats->Variables[ATTACKRANGE_INDEX].Max
		&& dist < goal->Type->MinAttackRange) {
	} else {
		Missile *missile = MakeMissile(*mtype, start, dest);
		if (flags & ANIM_SM_SETDIRECTION) {
			PixelPos posd;
			posd.x = Heading2X[goal->Direction / NextDirection];
			posd.y = Heading2Y[goal->Direction / NextDirection];
			missile->MissileNewHeadingFromXY(posd);
		}
		if (flags & ANIM_SM_DAMAGE) {
			missile->SourceUnit = &unit;
		}
		if (flags & ANIM_SM_TOTARGET) {
			missile->TargetUnit = goal->CurrentOrder()->GetGoal();
		}
	}
}