38 #include "Core-Level-JR.h"
41 #include "AI\aiNPCDialog.h"
45 laPlayer::laPlayer(
rpgSheet* pSheet):
50 _uiPotionsWindow.toggleHorizontal(M_FALSE);
51 _uiPotionsWindow.toggleSelection(M_FALSE);
53 _ttTurn.parameters(0.2);
57 laSettings* ps = laSystemIntegrator::getSettings();
58 enableBattleZoom(ps->gp_enable_battle_zoom);
59 _bBattleMode = M_TRUE;
61 getLevelObject()->zoom(1.8);
63 _ttBattleStance.parameters(1, 1, M_FALSE);
64 _ttBattleStance.force();
70 _ttAttack.parameters(M_PLAYER_ATTACK_INTERVAL);
71 _ttAttack.enable(M_FALSE);
73 shutterDeath.parameters( laColor(), 2);
74 shutterHit.parameters( laColor(200,0,0,100), 0.5, M_FALSE, M_TRUE);
83 _ttPeacefulAction.parameters(1);
84 _ttPeacefulAction.enable();
85 _ttPeacefulAction.force();
91 laPlayer::~laPlayer(
void)
98 void laPlayer::respawn()
102 _pSheet->bResetProperties = M_FALSE;
103 laFightingCreature::respawn();
106 psh->properties()->nHP = psh->properties()->nHP_Max;
112 this->getLevelObject()->forceSave();
114 laSettings* ps = laSystemIntegrator::getSettings();
115 enableBattleZoom(ps->gp_enable_battle_zoom);
118 _ptPivot.x( _ptPivot.x() +
M_UNIT/2 );
124 pInv->add( _pwPeace );
129 void laPlayer::_load_profile(
char* strName)
132 if(strName[0] ==
'\0')
return;
136 sprintf(strfile,
"save\\%s.profile", strName);
139 if( fp.fileOpen(strfile) )
143 fp.readObj(&pl, M_FALSE);
145 _pSheet->load( pl.getChild(
"rpg-sheet") );
149 catch(
laError&) { MLOG(
"Defaulting to Level 1 RPG sheet for the player object."); };
157 void laPlayer::saveProfile(FILE* f)
178 laFightingCreature::load(fp);
179 _ptPivot.x( _ptPivot.x() +
M_UNIT/2 );
185 _load_profile(laSystemIntegrator::getSettings()->load_player_name);
192 _IndicatorHP.setColor(laColor(255,255,255));
193 _IndicatorHP.setSize(512, 128);
195 _IndicatorHP.setTextures(
"gui\\HP_empty.png",
"gui\\HP_full.png", 32, 512-360);
197 _IndicatorXP.setColor(laColor(255,255,255));
198 _IndicatorXP.setSize(512, 128);
200 _IndicatorXP.setTextures(
"gui\\XP_empty.png",
"gui\\XP_full.png", 260, 512-444);
204 _pDieSound = laSystemIntegrator::getSound()->soundCreate(
"sound\\die(hearth beath).mp3");
205 _pLevelupSound = laSystemIntegrator::getSound()->soundCreate(
"sound\\_level_up(chant).wav");
207 _pLandSound = laSystemIntegrator::getSound()->soundCreate(
"sound\\land(klick).WAV");
208 _pCollectSound = laSystemIntegrator::getSound()->soundCreate(
"sound\\collect(sonar).mp3");
210 _pAttackSound = laSystemIntegrator::getSound()->soundCreate(
"sound\\attack(sword).mp3");
215 fxParticleSystem_params par;
218 _cbLevelUp.create(par);
219 _cbLevelUp.enable(M_FALSE);
227 _cbSkillUp.create(par);
228 _cbSkillUp.enable(M_FALSE);
237 _pwPeace =
new rpgWeapon();
238 _pwPeace->load( getTS()->getElement(
"Peaceful")->getChild(
"weapon") );
241 pInv->add( _pwPeace );
244 _ai.controllers(
this,
this, getLevelObject()->getGlobalPercepts() );
251 void laPlayer::reflect(
const laRect2 &rReference)
253 if(!isAlive() )
return;
254 if( isImmune() )
return;
263 void laPlayer::attackInitiate(M_BOOL bQuick)
265 if(!isControlEnabled())
return;
269 if( _ttPeacefulAction.isElapsed() )
270 _ttPeacefulAction.reset();
274 laFightingCreature::attackInitiate(bQuick);
284 if( attack.spPotion && (!isImmune()) )
295 if( ! attack.spPotion.get()->pAnimatorObj )
302 unsigned nTS = getTS()->getElementIndex( attack.spPotion.get()->strName );
305 pAO->setTS( getTS() );
306 pAO->setObject( nTS, getTS()->getElement( nTS) );
307 pAO->setLevel( getLevelObject() );
308 pAO->create( getPosition() + laPoint3(0, -
M_UNIT), attack.spPotion.get() );
311 attack.spPotion.get()->pAnimatorObj = pAO;
325 attack.spPotion.get()->pAnimatorObj->resetPotion();
326 attack.spPotion.get()->pAnimatorObj->setPosition( getPosition() + laPoint3(0, -
M_UNIT) );
330 laFightingCreature::hit(attack);
338 void laPlayer::_draw_positioned(
laRenderer *r) {
340 if( getState()==M_STATE_SOMERSAULT ) r->transTranslate( laPoint3(0, -0.8*
M_UNIT, 0) );
343 laFightingCreature::_draw_positioned(r);
346 void laPlayer::_draw_positioned_rotated(
laRenderer *r) {
350 if( getState()==M_STATE_SOMERSAULT ) r->transTranslate( laPoint3(0, +0.8*
M_UNIT, 0) );
356 if( pInv->size() && (!isPeaceful()) )
358 rpgItem *pItem = pInv->activePtr();
359 pItem->hook.sample( getStateModel() );
363 if(_ttDeath.isEnabled()) _trans_deathfx(r);
365 r->transTranslate( pItem->hook.arPointSample[0] );
366 r->transRotate(
M_R2D(pItem->hook.angle)-180, pItem->hook.rotationAxis() );
369 r->styleSet( _color );
370 ((
laElement*) (pItem->pTSE->getParent()) )->drawGeometry( r );
376 laFightingCreature::_draw_positioned_rotated(r);
383 void laPlayer::drawFx(
laRenderer *r, laPoint3 ptBasePos)
386 if(_pNPCDialog) _pNPCDialog->draw(r, ptBasePos);
387 laFightingCreature::drawFx(r, ptBasePos);
391 void laPlayer::_drawFx_positioned(
laRenderer *r)
396 laFightingCreature::_drawFx_positioned(r);
401 void laPlayer::drawInterface(
laRenderer *r, laPoint3 ptBasePos)
408 _uiInventoryWindow.
draw();
409 _uiPotionsWindow.
draw();
411 shutterHit.draw(r, ptBasePos);
412 _draw_status_ui(r, ptBasePos);
415 _pNPCDialog->drawGUI(r, ptBasePos);
417 laFightingCreature::drawInterface(r, ptBasePos);
418 shutterDeath.draw(r, ptBasePos);
425 unsigned laPlayer::_next_state(
unsigned nCurrentState )
429 static int nOldFacing;
431 if( (!_ttBattleStance.isElapsed()) && (nCurrentState==M_STATE_STAND))
432 return M_STATE_BSTAND;
434 if(
M_ABS(_dMonsterDistance) < M_PLAYER_ATTACK_RANGE )
436 nOldFacing = getFaceDirection();
437 setExplicitFacing(M_TRUE);
438 setFaceDirection(
M_SIGN(_dMonsterDistance) );
439 if(getState()==M_STATE_WALK)
return M_STATE_BWALK;
441 else if(isFacingExplict())
443 setFaceDirection(nOldFacing);
444 setExplicitFacing(M_FALSE);
448 return laFightingCreature::_next_state( nCurrentState );
453 void laPlayer::animate(laTimer &t)
457 _uiInventoryWindow.
reply();
458 _uiPotionsWindow.
reply();
462 animate_DeathMode(t);
464 animate_TrapDamage(t);
465 animate_BattleZoom(t);
471 _ttPeacefulAction.animate(t);
472 _ttBattleStance.animate(t);
473 _cbLevelUp.animate(t);
474 _cbSkillUp.animate(t);
476 shutterDeath.animate(t);
477 shutterHit.animate(t);
481 _bBattleMode = M_FALSE;
482 _dMonsterDistance = 100 *
M_UNIT;
485 if(_pNPCDialog) _pNPCDialog->animate(t);
487 laFightingCreature::animate(t);
491 _uiInventoryWindow.
move( laPoint3( 25, -15 ),
M_AL,
M_AB);
492 _uiPotionsWindow.
move( laPoint3( -15, 25 ),
M_AR,
M_AT);
499 void laPlayer::animate_DeathMode(laTimer &t)
503 if( isAlive() && (!_ttHitImmunity.isElapsed()) && (!shutterHit.isActive()) )
504 shutterHit.activate();
505 else if( _ttHitImmunity.isElapsed() && shutterHit.isActive() )
506 shutterHit.activate(M_FALSE);
510 if( ( !isAlive() ) && (!shutterDeath.isActive()) ) shutterDeath.activate();
511 else if( isAlive() && shutterDeath.isActive() ) shutterDeath.activate(M_FALSE);
518 _bBattleMode = M_TRUE;
520 if( (!_ttDeath.isEnabled()) )
523 _ttDeath.enable(M_TRUE);
526 if( _ttDeath.isElapsed() )
527 getLevelObject()->reset();
529 else if( _ttDeath.isElapsed() )
530 _ttDeath.enable(M_FALSE);
535 void laPlayer::animate_BattleZoom(laTimer &t)
537 if(_bEnableBattleZoom)
539 double current = getLevelObject()->zoom(), target = 1;
543 if( current < 1.499 ) target = current + 1.7*t.delta();
548 if( current > 1.001 ) target = current - 0.4*t.delta();
552 getLevelObject()->zoom( target );
558 void laPlayer::animate_TrapDamage(laTimer &t)
560 if(!isAlive() )
return;
564 _pActiveTrap->timer.animate(t);
565 if(_pActiveTrap->timer.isElapsed()) _pActiveTrap = NULL;
567 else if(_ptPivot.pTrap)
569 _pActiveTrap = _ptPivot.pTrap;
572 hit( *_pActiveTrap );
574 _pActiveTrap->timer.enable(M_TRUE);
575 _pActiveTrap->timer.reset();
579 if( (_ptPivot.y()>1.1*
M_UNIT*M_SEGH) ) ((rpgSheet_Fighter*)_pSheet)->properties()->nHP = 0;
584 void laPlayer::animate_Attack(laTimer &t)
590 void laPlayer::animate_Movement(laTimer &t)
592 static M_BOOL bOnGround=M_TRUE;
596 if( (_ptPivot.bOnGround) && (!bOnGround) )
601 bOnGround = _ptPivot.bOnGround;
606 if( (! isImmune() ) && (_nMovementDirection !=
M_SIGN(_ptPivot.velocity.x())) )
608 _ptPivot.velocity.x(0);
612 void laPlayer::_draw_status_ui(
laRenderer *r, laPoint3 ptBasePos)
616 _IndicatorHP.value( ((rpgSheet_Fighter*)_pSheet)->properties()->nHP) ;
617 _IndicatorHP.draw(r, ptBasePos);
620 _IndicatorXP.draw(r, ptBasePos);
623 r->
font(
"deco")->ctlSize(16);
626 r->styleSet(laColor(255,117,117,255));
627 r->
font(
"deco")->draw(ptBasePos+laPoint3(118, 86),
"%d / %d",
628 ((rpgSheet_Fighter*)_pSheet)->properties()->nHP, ((rpgSheet_Fighter*)_pSheet)->properties()->nHP_Max );
639 void laPlayer::_level_up()
652 _pLevelupSound->play();
660 void laPlayer::heal(
unsigned nHP )
666 _pCollectSound->play();
667 fxMessages.add(1, laColor(255,0,0),
"+%d HP", (
int)nHP);
672 void laPlayer::collect(
unsigned nXP )
682 _pCollectSound->play();
683 fxMessages.add(1, laColor(255,0,255),
"%d Crystals", (
int)nXP );
688 M_BOOL laPlayer::collect( rpgItem *item )
691 rpgInventory* pInv = NULL;
692 laColor color = laColor(255,255,0);
694 if( !strcmp(item->name().c_str(),
"rpgPotion") )
706 _pCollectSound->play();
707 fxMessages.add(1, color,
"%s", item->strName);
709 M_BOOL nNewEntry = pInv->add( item );
711 if( strcmp(item->name().c_str(),
"rpgPotion") )
712 _uiInventoryWindow.select( pInv->size()-1 );
718 void laPlayer::skillUp(
unsigned nSkill )
723 if( psi->skill(nSkill)->getCurrentIndex() + 1 < psi->skill(nSkill)->getUpgradeCount() )
725 psi->skill(nSkill)->upgrade();
727 fxMessages.add(1, laColor(255,255,0),
"Skill Acquired");
laFont * font(char *strName)
Get a font renderer.
#define M_R2D(r)
Convert radians to degrees.
#define M_AB
Text align bottom.
#define M_UNIT
Unit of 1 meter.
Base Class for Tileset Elements.
virtual void move(laPoint3 ptNewPos, unsigned nHReference=M_AL, unsigned nVReference=M_AT)
Change window position.
#define M_AL
Text align left.
M_BOOL bTopmost
If set the outline is visible even when the object is behind something.
#define M_AT
Text align top.
#define M_AR
Text align right.
Abstract RPG Properties Sheet.
2D rectangle (used by the GUI and also as a simple tool for proximity testing)
#define M_ABS(a)
Return abs(a)
virtual void modeOutline(const laOutline &outline)
Set outline parameters.
#define M_AC
Text align center.
virtual void reply()
Handle input message.
Virtual interface for the Engine graphics renderer.
#define M_SIGN(a)
Return sign (+1 or -1)
Collectable Level Object.
virtual void draw()
Display the window.