mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-26 22:57:00 +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)
|
BattleAction CBattleLogic::MakeDecision(int stackID)
|
||||||
{
|
{
|
||||||
const CStack *currentStack = m_cb->battleGetStackByID(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);
|
return MakeDefend(stackID);
|
||||||
}
|
}
|
||||||
|
@ -1728,7 +1728,16 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
|
|||||||
{
|
{
|
||||||
if(shere->owner == curInt->playerID) //our stack
|
if(shere->owner == curInt->playerID) //our stack
|
||||||
{
|
{
|
||||||
CGI->curh->changeGraphic(1,5);
|
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
|
//setting console text
|
||||||
char buf[500];
|
char buf[500];
|
||||||
sprintf(buf, CGI->generaltexth->allTexts[297].c_str(), shere->amount == 1 ? shere->creature->nameSing.c_str() : shere->creature->namePl.c_str());
|
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);
|
creAnims[shere->ID]->playOnce(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(curInt->cb->battleCanShoot(activeStack,myNumber)) //we can shoot enemy
|
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
|
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
|
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
|
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
|
CGI->curh->changeGraphic(1, 6); //cursor should be changed
|
||||||
@ -2354,7 +2363,7 @@ void CBattleInterface::hexLclicked(int whichOne)
|
|||||||
giveCommand(2,whichOne,activeStack);
|
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);
|
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];
|
char txt[400];
|
||||||
|
|
||||||
if(action->actionType == 1)
|
if(action->actionType == 1) //when hero casts spell
|
||||||
{
|
{
|
||||||
if(action->side)
|
if(action->side)
|
||||||
defendingHero->setPhase(4);
|
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);
|
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);
|
console->addText(txt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//displaying heal animation
|
||||||
|
if (action->actionType == 12)
|
||||||
|
{
|
||||||
|
displayEffect(50, action->destinationTile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleHero::show(SDL_Surface *to)
|
void CBattleHero::show(SDL_Surface *to)
|
||||||
|
@ -164,7 +164,7 @@
|
|||||||
+ 140 DOUBLE_WIDE 0 0 0 //boar should be treated as double-wide
|
+ 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
|
+ 142 DOUBLE_WIDE 0 0 0 //nomads should be treated as double-wide
|
||||||
+ 144 FULL_HP_REGENERATION 0 0 0 //troll
|
+ 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
|
+ 148 NOT_ACTIVE 0 0 0 //Ammo Cart
|
||||||
+ 149 SHOOTER 0 0 0 //arrow turret
|
+ 149 SHOOTER 0 0 0 //arrow turret
|
||||||
- 46 FLYING //hell hound doesn't fly
|
- 46 FLYING //hell hound doesn't fly
|
||||||
|
@ -15,7 +15,9 @@ struct BattleAction
|
|||||||
{
|
{
|
||||||
ui8 side; //who made this action: false - left, true - right player
|
ui8 side; //who made this action: false - left, true - right player
|
||||||
ui32 stackNumber;//stack ID, -1 left hero, -2 right hero,
|
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;
|
ui16 destinationTile;
|
||||||
si32 additionalInfo; // e.g. spell number if type is 1 || 10; tile to attack if type is 6
|
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)
|
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;
|
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;
|
return 0;
|
||||||
|
|
||||||
ret += st->valOfFeatures(StackFeature::MORALE_BONUS); //mirth & sorrow & other
|
ret += st->valOfFeatures(StackFeature::MORALE_BONUS); //mirth & sorrow & other
|
||||||
|
@ -812,7 +812,7 @@ DLL_EXPORT void StartAction::applyGs( CGameState *gs )
|
|||||||
case 8:
|
case 8:
|
||||||
st->state.insert(WAITING);
|
st->state.insert(WAITING);
|
||||||
return;
|
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);
|
st->state.insert(MOVED);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -437,6 +437,49 @@ void CGameHandler::startBattle(const CArmedInstance *army1, const CArmedInstance
|
|||||||
continue;
|
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:
|
askInterfaceForMove:
|
||||||
//ask interface and wait for answer
|
//ask interface and wait for answer
|
||||||
if(!battleResult.get())
|
if(!battleResult.get())
|
||||||
@ -3210,6 +3253,44 @@ bool CGameHandler::makeBattleAction( BattleAction &ba )
|
|||||||
|
|
||||||
sendAndApply(&ca);
|
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());
|
sendAndApply(&EndAction());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user