stk-code_catmod/src/items/attachment.cpp
auria 2f6b05bace started converting user config to XML. Implementation is not 100% complete yet; saving works, not lodading. Implementation is not the prettiest but designed for minimal maintenance.
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@3625 178a84e3-b1eb-0310-8ba1-8eac791a3b58
2009-06-21 01:10:43 +00:00

203 lines
6.9 KiB
C++

// $Id$
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "items/attachment.hpp"
#include "config/stk_config.hpp"
#include "config/user_config.hpp"
#include "graphics/irr_driver.hpp"
#include "items/attachment_manager.hpp"
#include "items/projectile_manager.hpp"
#include "karts/kart.hpp"
#include "network/race_state.hpp"
#include "network/network_manager.hpp"
#include "utils/constants.hpp"
Attachment::Attachment(Kart* kart)
{
m_type = ATTACH_NOTHING;
m_time_left = 0.0;
m_kart = kart;
m_previous_owner = NULL;
m_node = NULL;
} // Attachment
//-----------------------------------------------------------------------------
Attachment::~Attachment()
{
if(m_node)
irr_driver->removeNode(m_node);
} // ~Attachment
//-----------------------------------------------------------------------------
void Attachment::set(attachmentType type, float time, Kart *current_kart)
{
clear();
m_node = irr_driver->addMesh(attachment_manager->getMesh(type));
m_node->setParent(m_kart->getNode());
m_type = type;
m_time_left = time;
m_previous_owner = current_kart;
// A parachute can be attached as result of the usage of an item. In this
// case we have to save the current kart speed so that it can be detached
// by slowing down.
if(m_type==ATTACH_PARACHUTE)
{
m_initial_speed = m_kart->getSpeed();
if(m_initial_speed <= 1.5) m_initial_speed = 1.5; // if going very slowly or backwards, braking won't remove parachute
}
} // set
// -----------------------------------------------------------------------------
/** Removes any attachement currently on the kart. As for the anvil attachment,
* takes care of resetting the owner kart's physics structures to account for
* the updated mass.
*/
void Attachment::clear()
{
m_type=ATTACH_NOTHING;
m_time_left=0.0;
if(m_node)
{
irr_driver->removeNode(m_node);
m_node = NULL;
}
// Resets the weight of the kart if the previous attachment affected it
// (e.g. anvil). This must be done *after* setting m_type to
// ATTACH_NOTHING in order to reset the physics parameters.
m_kart->updatedWeight();
} // clear
// -----------------------------------------------------------------------------
void Attachment::hitBanana(const Item &item, int new_attachment)
{
if(UserConfigParams::m_profile) return;
float leftover_time = 0.0f;
switch(getType()) // If there already is an attachment, make it worse :)
{
case ATTACH_BOMB:
projectile_manager->newExplosion(m_kart->getXYZ());
m_kart->handleExplosion(m_kart->getXYZ(), /*direct_hit*/ true);
clear();
if(new_attachment==-1)
new_attachment = m_random.get(3);
break;
case ATTACH_ANVIL:
// if the kart already has an anvil, attach a new anvil,
// and increase the overall time
new_attachment = 2;
leftover_time = m_time_left;
break;
case ATTACH_PARACHUTE:
new_attachment = 2; // anvil
leftover_time = m_time_left;
break;
default:
if(new_attachment==-1)
new_attachment = m_random.get(3);
} // switch
// Save the information about the attachment in the race state
// so that the clients can be updated.
if(network_manager->getMode()==NetworkManager::NW_SERVER)
{
race_state->itemCollected(m_kart->getWorldKartId(),
item.getItemId(),
new_attachment);
}
switch (new_attachment)
{
case 0:
set( ATTACH_PARACHUTE,stk_config->m_parachute_time+leftover_time);
m_initial_speed = m_kart->getSpeed();
if(m_initial_speed <= 1.5) m_initial_speed = 1.5; // if going very slowly or backwards, braking won't remove parachute
// if ( m_kart == m_kart[0] )
// sound -> playSfx ( SOUND_SHOOMF ) ;
break ;
case 1:
set( ATTACH_BOMB, stk_config->m_bomb_time+leftover_time);
// if ( m_kart == m_kart[0] )
// sound -> playSfx ( SOUND_SHOOMF ) ;
break ;
case 2:
set( ATTACH_ANVIL, stk_config->m_anvil_time+leftover_time);
// if ( m_kart == m_kart[0] )
// sound -> playSfx ( SOUND_SHOOMF ) ;
// Reduce speed once (see description above), all other changes are
// handled in Kart::updatePhysics
m_kart->adjustSpeed(stk_config->m_anvil_speed_factor);
m_kart->updatedWeight();
break ;
} // switch
} // hitBanana
//-----------------------------------------------------------------------------
//** Moves a bomb from kart FROM to kart TO.
void Attachment::moveBombFromTo(Kart *from, Kart *to)
{
to->setAttachmentType(ATTACH_BOMB,
from->getAttachment()->getTimeLeft()+
stk_config->m_bomb_time_increase, from);
from->getAttachment()->clear();
} // moveBombFromTo
//-----------------------------------------------------------------------------
void Attachment::update(float dt)
{
if(m_type==ATTACH_NOTHING) return;
m_time_left -=dt;
switch (m_type)
{
case ATTACH_PARACHUTE:
// Partly handled in Kart::updatePhysics
// Otherwise: disable if a certain percantage of
// initial speed was lost
if(m_kart->getSpeed() <= m_initial_speed*stk_config->m_parachute_done_fraction)
{
m_time_left = -1;
}
break;
case ATTACH_ANVIL: // handled in Kart::updatePhysics
case ATTACH_NOTHING: // Nothing to do, but complete all cases for switch
case ATTACH_MAX:
break;
case ATTACH_BOMB:
if(m_time_left<=0.0)
{
projectile_manager->newExplosion(m_kart->getXYZ());
m_kart->handleExplosion(m_kart->getXYZ(),
/*direct_hit*/ true);
}
break;
case ATTACH_TINYTUX:
if(m_time_left<=0.0) m_kart->endRescue();
break;
} // switch
// Detach attachment if its time is up.
if ( m_time_left <= 0.0f)
clear();
} // update
//-----------------------------------------------------------------------------