1
0
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:
mateuszb 2010-03-07 17:40:33 +00:00
parent 85f463e479
commit ac7bc76b7b
7 changed files with 114 additions and 9 deletions

View File

@ -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);
}

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}