mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* implemented first aid kit including first aid secondary ability
This commit is contained in:
parent
85f463e479
commit
ac7bc76b7b
@ -258,7 +258,7 @@ void CBattleLogic::MakeStatistics(int currentCreatureId)
|
||||
BattleAction CBattleLogic::MakeDecision(int stackID)
|
||||
{
|
||||
const CStack *currentStack = m_cb->battleGetStackByID(stackID);
|
||||
if(currentStack->position < 0) //turret
|
||||
if(currentStack->position < 0 || currentStack->creature->idNumber == 147) //turret or first aid kit
|
||||
{
|
||||
return MakeDefend(stackID);
|
||||
}
|
||||
|
@ -1728,7 +1728,16 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
|
||||
{
|
||||
if(shere->owner == curInt->playerID) //our stack
|
||||
{
|
||||
if(sactive->hasFeatureOfType(StackFeature::HEALER))
|
||||
{
|
||||
//display the possibility to heal this creature
|
||||
CGI->curh->changeGraphic(1,17);
|
||||
}
|
||||
else
|
||||
{
|
||||
//info about creature
|
||||
CGI->curh->changeGraphic(1,5);
|
||||
}
|
||||
//setting console text
|
||||
char buf[500];
|
||||
sprintf(buf, CGI->generaltexth->allTexts[297].c_str(), shere->amount == 1 ? shere->creature->nameSing.c_str() : shere->creature->namePl.c_str());
|
||||
@ -1739,6 +1748,7 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
|
||||
{
|
||||
creAnims[shere->ID]->playOnce(1);
|
||||
}
|
||||
|
||||
}
|
||||
else if(curInt->cb->battleCanShoot(activeStack,myNumber)) //we can shoot enemy
|
||||
{
|
||||
@ -2336,7 +2346,6 @@ void CBattleInterface::hexLclicked(int whichOne)
|
||||
const CStack* dest = curInt->cb->battleGetStackByPos(whichOne); //creature at destination tile; -1 if there is no one
|
||||
if(!dest || !dest->alive()) //no creature at that tile
|
||||
{
|
||||
const CStack * sactive = curInt->cb->battleGetStackByID(activeStack);
|
||||
if(std::find(shadedHexes.begin(),shadedHexes.end(),whichOne)!=shadedHexes.end())// and it's in our range
|
||||
{
|
||||
CGI->curh->changeGraphic(1, 6); //cursor should be changed
|
||||
@ -2354,7 +2363,7 @@ void CBattleInterface::hexLclicked(int whichOne)
|
||||
giveCommand(2,whichOne,activeStack);
|
||||
}
|
||||
}
|
||||
else if(sactive->hasFeatureOfType(StackFeature::CATAPULT) && isCatapultAttackable(whichOne)) //attacking (catapult)
|
||||
else if(actSt->hasFeatureOfType(StackFeature::CATAPULT) && isCatapultAttackable(whichOne)) //attacking (catapult)
|
||||
{
|
||||
giveCommand(9,whichOne,activeStack);
|
||||
}
|
||||
@ -2519,6 +2528,12 @@ void CBattleInterface::hexLclicked(int whichOne)
|
||||
}
|
||||
|
||||
}
|
||||
else if (actSt->hasFeatureOfType(StackFeature::HEALER) && actSt->owner == dest->owner) //friendly creature we can heal
|
||||
{
|
||||
giveCommand(12, whichOne, activeStack); //command healing
|
||||
|
||||
CGI->curh->changeGraphic(1, 6); //cursor should be changed
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3162,7 +3177,7 @@ void CBattleInterface::startAction(const BattleAction* action)
|
||||
|
||||
char txt[400];
|
||||
|
||||
if(action->actionType == 1)
|
||||
if(action->actionType == 1) //when hero casts spell
|
||||
{
|
||||
if(action->side)
|
||||
defendingHero->setPhase(4);
|
||||
@ -3201,6 +3216,12 @@ void CBattleInterface::startAction(const BattleAction* action)
|
||||
sprintf(txt, CGI->generaltexth->allTexts[txtid].c_str(), (stack->amount != 1) ? stack->creature->namePl.c_str() : stack->creature->nameSing.c_str(), 0);
|
||||
console->addText(txt);
|
||||
}
|
||||
|
||||
//displaying heal animation
|
||||
if (action->actionType == 12)
|
||||
{
|
||||
displayEffect(50, action->destinationTile);
|
||||
}
|
||||
}
|
||||
|
||||
void CBattleHero::show(SDL_Surface *to)
|
||||
|
@ -164,7 +164,7 @@
|
||||
+ 140 DOUBLE_WIDE 0 0 0 //boar should be treated as double-wide
|
||||
+ 142 DOUBLE_WIDE 0 0 0 //nomads should be treated as double-wide
|
||||
+ 144 FULL_HP_REGENERATION 0 0 0 //troll
|
||||
+ 147 NOT_ACTIVE 0 0 0 //First Aid Tent //TODO: remove when support is added
|
||||
+ 147 HEALER 0 0 0 //first aid tent can heal
|
||||
+ 148 NOT_ACTIVE 0 0 0 //Ammo Cart
|
||||
+ 149 SHOOTER 0 0 0 //arrow turret
|
||||
- 46 FLYING //hell hound doesn't fly
|
||||
|
@ -15,7 +15,9 @@ struct BattleAction
|
||||
{
|
||||
ui8 side; //who made this action: false - left, true - right player
|
||||
ui32 stackNumber;//stack ID, -1 left hero, -2 right hero,
|
||||
ui8 actionType; // 0 = No action; 1 = Hero cast a spell 2 = Walk 3 = Defend 4 = Retreat from the battle 5 = Surrender 6 = Walk and Attack 7 = Shoot 8 = Wait 9 = Catapult 10 = Monster casts a spell (i.e. Faerie Dragons) 11 - Bad morale freeze
|
||||
ui8 actionType; // 0 = No action; 1 = Hero cast a spell 2 = Walk 3 = Defend 4 = Retreat from the battle
|
||||
//5 = Surrender 6 = Walk and Attack 7 = Shoot 8 = Wait 9 = Catapult
|
||||
//10 = Monster casts a spell (i.e. Faerie Dragons) 11 - Bad morale freeze 12 - stacks heals another stack
|
||||
ui16 destinationTile;
|
||||
si32 additionalInfo; // e.g. spell number if type is 1 || 10; tile to attack if type is 6
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
|
@ -3489,7 +3489,8 @@ si8 BattleInfo::Morale( const CStack * st ) const
|
||||
{
|
||||
si8 ret = st->morale;
|
||||
|
||||
if(st->hasFeatureOfType(StackFeature::NON_LIVING) || st->hasFeatureOfType(StackFeature::UNDEAD) || st->hasFeatureOfType(StackFeature::NO_MORALE))
|
||||
if(st->hasFeatureOfType(StackFeature::NON_LIVING) || st->hasFeatureOfType(StackFeature::UNDEAD) ||
|
||||
st->hasFeatureOfType(StackFeature::NO_MORALE) || st->hasFeatureOfType(StackFeature::SIEGE_WEAPON))
|
||||
return 0;
|
||||
|
||||
ret += st->valOfFeatures(StackFeature::MORALE_BONUS); //mirth & sorrow & other
|
||||
|
@ -812,7 +812,7 @@ DLL_EXPORT void StartAction::applyGs( CGameState *gs )
|
||||
case 8:
|
||||
st->state.insert(WAITING);
|
||||
return;
|
||||
case 2: case 6: case 7: case 9: case 10: case 11:
|
||||
case 0: case 2: case 6: case 7: case 9: case 10: case 11: case 12:
|
||||
st->state.insert(MOVED);
|
||||
break;
|
||||
}
|
||||
|
@ -437,6 +437,49 @@ void CGameHandler::startBattle(const CArmedInstance *army1, const CArmedInstance
|
||||
continue;
|
||||
}
|
||||
|
||||
if(next->creature->idNumber == 147 && (!curOwner || curOwner->getSecSkillLevel(27) == 0)) //first aid tent, hero has no first aid
|
||||
{
|
||||
BattleAction heal;
|
||||
|
||||
std::vector< const CStack * > possibleStacks;
|
||||
for (int v=0; v<gs->curB->stacks.size(); ++v)
|
||||
{
|
||||
const CStack * cstack = gs->curB->stacks[v];
|
||||
if (cstack->owner == next->owner && cstack->firstHPleft < cstack->MaxHealth() && cstack->alive()) //it's friendly and not fully healthy
|
||||
{
|
||||
possibleStacks.push_back(cstack);
|
||||
}
|
||||
}
|
||||
|
||||
if(possibleStacks.size() == 0)
|
||||
{
|
||||
//nothing to heal
|
||||
BattleAction doNothing;
|
||||
doNothing.actionType = 0;
|
||||
doNothing.additionalInfo = 0;
|
||||
doNothing.destinationTile = -1;
|
||||
doNothing.side = !next->attackerOwned;
|
||||
doNothing.stackNumber = next->ID;
|
||||
sendAndApply(&StartAction(doNothing));
|
||||
sendAndApply(&EndAction());
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
//heal random creature
|
||||
const CStack * toBeHealed = possibleStacks[ rand()%possibleStacks.size() ];
|
||||
heal.actionType = 12;
|
||||
heal.additionalInfo = 0;
|
||||
heal.destinationTile = toBeHealed->position;
|
||||
heal.side = !next->attackerOwned;
|
||||
heal.stackNumber = next->ID;
|
||||
|
||||
makeBattleAction(heal);
|
||||
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
askInterfaceForMove:
|
||||
//ask interface and wait for answer
|
||||
if(!battleResult.get())
|
||||
@ -3210,6 +3253,44 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
||||
|
||||
sendAndApply(&ca);
|
||||
}
|
||||
sendAndApply(&EndAction());
|
||||
break;
|
||||
}
|
||||
case 12: //healing
|
||||
{
|
||||
static const int healingPerLevel[] = {50, 50, 75, 100};
|
||||
sendAndApply(&StartAction(ba));
|
||||
const CGHeroInstance * attackingHero = gs->curB->heroes[ba.side];
|
||||
CStack *healer = gs->curB->getStack(ba.stackNumber),
|
||||
*destStack = gs->curB->getStackT(ba.destinationTile);
|
||||
|
||||
if(healer == NULL || destStack == NULL || !healer->hasFeatureOfType(StackFeature::HEALER))
|
||||
{
|
||||
complain("There is either no healer, no destination, or healer cannot heal :P");
|
||||
}
|
||||
int maxHealable = destStack->MaxHealth() - destStack->firstHPleft;
|
||||
int maxiumHeal = healingPerLevel[ attackingHero->getSecSkillLevel(27) ];
|
||||
|
||||
int healed = std::min(maxHealable, maxiumHeal);
|
||||
|
||||
if(healed == 0)
|
||||
{
|
||||
//nothing to heal.. should we complain?
|
||||
}
|
||||
else
|
||||
{
|
||||
StacksHealedOrResurrected shr;
|
||||
StacksHealedOrResurrected::HealInfo hi;
|
||||
|
||||
hi.healedHP = healed;
|
||||
hi.lowLevelResurrection = 0;
|
||||
hi.stackID = destStack->ID;
|
||||
|
||||
shr.healedStacks.push_back(hi);
|
||||
sendAndApply(&shr);
|
||||
}
|
||||
|
||||
|
||||
sendAndApply(&EndAction());
|
||||
break;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user