A few words about the mod: the working title is Hi-Tech-Toss. I'm going to bring some of the finest SC2 toss tech to BW, then create a storyline and campaign focused on the Protoss race.
WARP GATES
I almost succeeded with making these, the evil thing is I'll have to sacrifice one spell for every unit produced at gateway (5 spells including sentry) but it's ok since it's all about making Protoss cooler.
1. Pylon field requirement for unit placement.
This is something I can not figure out, but I think it's possible because protoss buildings require pylon field = there's a function that checks if certain part of terrain is pylon-powered. This would also allow me to kill zealots if psi provider is killed during the warp. Any tips?
2. Showing all psi fields when clicking on a Warp Gate.
So close yet so far. I did it by editing psi_field.cpp this way:
Quote
bool isReadyToMakePsiField(CUnit *unit) {
//Default StarCraft behavior
if (unit->id == UnitId::pylon
||unit->UnitId::Special_WarpGate)
return true;
return false;
}
3. Passable terrain check.
When I try to warp zealot on the water, nothing happens, so it's ok. But when I target some kind of an edge or any other unpasssable terrain, you can hear a sound for "Unit Unplaceable" error and the game crashes. Look at the end of the video I posted.
4. Iscript animation - warp overlay.
At the moment when zealot is warping in, I use the unused warp flash animation, which basically makes zealot glow white. It would be cooler if it was warp overlay instead of warp flash, but there's not much documentation about warpoverlay opcode, so I have no idea how to use it.
SOURCE
weapon_fire.cpp
Quote
//////*****Zealot Warp-In*****\\\\\\
//not enough minerals
if ((unit->id == UnitId::Special_WarpGate)
&& (unit->mainOrderId == OrderId::Ensnare)
&& (resources->minerals[unit->playerId]) < (units_dat::MineralCost[UnitId::zealot]))
{
scbw::showErrorMessageWithSfx(unit->playerId, 850, 149);
}
//construct additional pylons
if ((unit->id == UnitId::Special_WarpGate)
&& (unit->mainOrderId == OrderId::Ensnare)
&& (scbw::getSupplyRemaining(unit->playerId, RaceId::Protoss)) < (units_dat::SupplyRequired[UnitId::zealot]))
{
scbw::showErrorMessageWithSfx(unit->playerId, 846, 155);
}
//proceed with warp
if ((unit->id == UnitId::Special_WarpGate)
&& (unit->mainOrderId == OrderId::Ensnare)
&& (scbw::getSupplyRemaining(unit->playerId, RaceId::Protoss)) >= (units_dat::SupplyRequired[UnitId::zealot])
&& (resources->minerals[unit->playerId]) >= (units_dat::MineralCost[UnitId::zealot]))
{
CUnit *warpedZealot;
u32 WarpZealotX = unit->orderTarget.pt.x;
u32 WarpZealotY = unit->orderTarget.pt.y;
unit->playIscriptAnim(IscriptAnimation::IsWorking);
warpedZealot = scbw::createUnitAtPos(UnitId::zealot, unit->playerId, WarpZealotX, WarpZealotY);
warpedZealot->playIscriptAnim(IscriptAnimation::SpecialState1);
warpedZealot->hitPoints = 5120;
warpedZealot->shields = 5120;
warpedZealot->currentButtonSet = 202;
warpedZealot->stimTimer = 5;
warpedZealot->mainOrderId = OrderId::Stop;
resources->minerals[unit->playerId] = resources->minerals[unit->playerId] - units_dat::MineralCost[UnitId::zealot];
}
//not enough minerals
if ((unit->id == UnitId::Special_WarpGate)
&& (unit->mainOrderId == OrderId::Ensnare)
&& (resources->minerals[unit->playerId]) < (units_dat::MineralCost[UnitId::zealot]))
{
scbw::showErrorMessageWithSfx(unit->playerId, 850, 149);
}
//construct additional pylons
if ((unit->id == UnitId::Special_WarpGate)
&& (unit->mainOrderId == OrderId::Ensnare)
&& (scbw::getSupplyRemaining(unit->playerId, RaceId::Protoss)) < (units_dat::SupplyRequired[UnitId::zealot]))
{
scbw::showErrorMessageWithSfx(unit->playerId, 846, 155);
}
//proceed with warp
if ((unit->id == UnitId::Special_WarpGate)
&& (unit->mainOrderId == OrderId::Ensnare)
&& (scbw::getSupplyRemaining(unit->playerId, RaceId::Protoss)) >= (units_dat::SupplyRequired[UnitId::zealot])
&& (resources->minerals[unit->playerId]) >= (units_dat::MineralCost[UnitId::zealot]))
{
CUnit *warpedZealot;
u32 WarpZealotX = unit->orderTarget.pt.x;
u32 WarpZealotY = unit->orderTarget.pt.y;
unit->playIscriptAnim(IscriptAnimation::IsWorking);
warpedZealot = scbw::createUnitAtPos(UnitId::zealot, unit->playerId, WarpZealotX, WarpZealotY);
warpedZealot->playIscriptAnim(IscriptAnimation::SpecialState1);
warpedZealot->hitPoints = 5120;
warpedZealot->shields = 5120;
warpedZealot->currentButtonSet = 202;
warpedZealot->stimTimer = 5;
warpedZealot->mainOrderId = OrderId::Stop;
resources->minerals[unit->playerId] = resources->minerals[unit->playerId] - units_dat::MineralCost[UnitId::zealot];
}
game_hooks.cpp inside NextFrame() ofc.
Quote
//////**********ZEALOT WARP-IN LOOPS**********\\\\\\\\\\\\\\\\\\\
CUnit *warpzealot;
for (int zealot_warp_loop = 0; zealot_warp_loop < 1700; zealot_warp_loop++)
{
warpzealot = &unitTable[zealot_warp_loop];
if ((warpzealot->id == UnitId::zealot)
&& (warpzealot->stimTimer > 0)
&& (warpzealot->hitPoints) < (units_dat::MaxHitPoints[warpzealot->id]))
{
warpzealot->setHp(warpzealot->hitPoints + 512);
warpzealot->mainOrderId = OrderId::Stop;
}
if ((warpzealot->id == UnitId::zealot)
&& (warpzealot->stimTimer > 0)
&& (warpzealot->shields) < (units_dat::MaxHitPoints[warpzealot->id]))
{
warpzealot->shields = (warpzealot->shields + 256);
warpzealot->mainOrderId = OrderId::Stop;
}
if ((warpzealot->id == UnitId::zealot)
&& (warpzealot->stimTimer == 0))
{
//scbw::playSound(666, nullptr);
warpzealot->currentButtonSet = 65;
//warpzealot->orderToIdle();
}
CUnit *warpzealot;
for (int zealot_warp_loop = 0; zealot_warp_loop < 1700; zealot_warp_loop++)
{
warpzealot = &unitTable[zealot_warp_loop];
if ((warpzealot->id == UnitId::zealot)
&& (warpzealot->stimTimer > 0)
&& (warpzealot->hitPoints) < (units_dat::MaxHitPoints[warpzealot->id]))
{
warpzealot->setHp(warpzealot->hitPoints + 512);
warpzealot->mainOrderId = OrderId::Stop;
}
if ((warpzealot->id == UnitId::zealot)
&& (warpzealot->stimTimer > 0)
&& (warpzealot->shields) < (units_dat::MaxHitPoints[warpzealot->id]))
{
warpzealot->shields = (warpzealot->shields + 256);
warpzealot->mainOrderId = OrderId::Stop;
}
if ((warpzealot->id == UnitId::zealot)
&& (warpzealot->stimTimer == 0))
{
//scbw::playSound(666, nullptr);
warpzealot->currentButtonSet = 65;
//warpzealot->orderToIdle();
}
None.