mirror of
https://github.com/Heretek-AI/GDevelop.git
synced 2026-07-22 10:05:37 -04:00
feb5098899
git-svn-id: svn://localhost@357 8062f311-0dae-4547-b526-b8ab9ac864a5
385 lines
13 KiB
C++
385 lines
13 KiB
C++
/**
|
|
|
|
Game Develop - Function Extension
|
|
Copyright (c) 2008-2011 Florian Rival (Florian.Rival@gmail.com)
|
|
|
|
This software is provided 'as-is', without any express or implied
|
|
warranty. In no event will the authors be held liable for any damages
|
|
arising from the use of this software.
|
|
|
|
Permission is granted to anyone to use this software for any purpose,
|
|
including commercial applications, and to alter it and redistribute it
|
|
freely, subject to the following restrictions:
|
|
|
|
1. The origin of this software must not be misrepresented; you must not
|
|
claim that you wrote the original software. If you use this software
|
|
in a product, an acknowledgment in the product documentation would be
|
|
appreciated but is not required.
|
|
|
|
2. Altered source versions must be plainly marked as such, and must not be
|
|
misrepresented as being the original software.
|
|
|
|
3. This notice may not be removed or altered from any source
|
|
distribution.
|
|
|
|
*/
|
|
|
|
#include "GDL/OpenSaveGame.h"
|
|
#include "FunctionEvent.h"
|
|
#include "GDL/ObjectsConcerned.h"
|
|
#include "GDL/RuntimeScene.h"
|
|
#include "GDL/tinyxml.h"
|
|
|
|
#if defined(GD_IDE_ONLY)
|
|
#include "GDL/EventsRenderingHelper.h"
|
|
#endif
|
|
|
|
std::map < const Scene* , std::map < std::string, FunctionEvent* > > FunctionEvent::functionsList;
|
|
std::map < const Scene* , std::vector < std::string >* > FunctionEvent::currentFunctionParameter;
|
|
|
|
FunctionEvent::FunctionEvent() :
|
|
BaseEvent(),
|
|
name("MyFunction")
|
|
#if defined(GD_IDE_ONLY)
|
|
,nameSelected(false)
|
|
#endif
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Check the conditions, and launch actions and subevents if necessary
|
|
*/
|
|
void FunctionEvent::Launch( RuntimeScene & scene, ObjectsConcerned & objectsConcerned, std::vector < string > parameters )
|
|
{
|
|
std::vector < std::string > * parentFunctionParameters = currentFunctionParameter[&scene];
|
|
currentFunctionParameter[&scene] = ¶meters;
|
|
|
|
if ( ExecuteConditions( scene, objectsConcerned) == true )
|
|
{
|
|
ExecuteActions( scene, objectsConcerned);
|
|
|
|
for (unsigned int i = 0;i<events.size();++i)
|
|
{
|
|
ObjectsConcerned objectsConcernedForSubEvent;
|
|
objectsConcernedForSubEvent.InheritsFrom(&objectsConcerned);
|
|
|
|
events[i]->Execute(scene, objectsConcernedForSubEvent);
|
|
}
|
|
}
|
|
|
|
currentFunctionParameter[&scene] = parentFunctionParameters;
|
|
}
|
|
|
|
/**
|
|
* Check if all conditions are true
|
|
*/
|
|
bool FunctionEvent::ExecuteConditions( RuntimeScene & scene, ObjectsConcerned & objectsConcerned )
|
|
{
|
|
for ( unsigned int k = 0; k < conditions.size(); ++k )
|
|
{
|
|
if ( conditions[k].function != NULL &&
|
|
!conditions[k].function( scene, objectsConcerned, conditions[k]) )
|
|
return false; //Return false as soon as a condition is false
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Run actions of the event
|
|
*/
|
|
void FunctionEvent::ExecuteActions( RuntimeScene & scene, ObjectsConcerned & objectsConcerned )
|
|
{
|
|
for ( unsigned int k = 0; k < actions.size();k++ )
|
|
{
|
|
if ( actions[k].function != NULL )
|
|
actions[k].function( scene, objectsConcerned, actions[k]);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
vector < vector<Instruction>* > FunctionEvent::GetAllConditionsVectors()
|
|
{
|
|
vector < vector<Instruction>* > allConditions;
|
|
allConditions.push_back(&conditions);
|
|
|
|
return allConditions;
|
|
}
|
|
|
|
vector < vector<Instruction>* > FunctionEvent::GetAllActionsVectors()
|
|
{
|
|
vector < vector<Instruction>* > allActions;
|
|
allActions.push_back(&actions);
|
|
|
|
return allActions;
|
|
}
|
|
#if defined(GD_IDE_ONLY)
|
|
void FunctionEvent::SaveToXml(TiXmlElement * eventElem) const
|
|
{
|
|
TiXmlElement * objectElem = new TiXmlElement( "Name" );
|
|
eventElem->LinkEndChild( objectElem );
|
|
objectElem->SetAttribute("value", name.c_str());
|
|
|
|
//Les conditions
|
|
TiXmlElement * conditionsElem = new TiXmlElement( "Conditions" );
|
|
eventElem->LinkEndChild( conditionsElem );
|
|
OpenSaveGame::SaveConditions(conditions, conditionsElem);
|
|
|
|
//Les actions
|
|
TiXmlElement * actionsElem = new TiXmlElement( "Actions" );
|
|
eventElem->LinkEndChild( actionsElem );
|
|
OpenSaveGame::SaveActions(actions, actionsElem);
|
|
|
|
//Sous évènements
|
|
if ( !GetSubEvents().empty() )
|
|
{
|
|
TiXmlElement * subeventsElem;
|
|
subeventsElem = new TiXmlElement( "Events" );
|
|
eventElem->LinkEndChild( subeventsElem );
|
|
|
|
OpenSaveGame::SaveEvents(events, subeventsElem);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void FunctionEvent::LoadFromXml(const TiXmlElement * eventElem)
|
|
{
|
|
if ( eventElem->FirstChildElement( "Name" ) != NULL )
|
|
name = eventElem->FirstChildElement("Name")->Attribute("value");
|
|
|
|
//Conditions
|
|
if ( eventElem->FirstChildElement( "Conditions" ) != NULL )
|
|
OpenSaveGame::OpenConditions(conditions, eventElem->FirstChildElement( "Conditions" ));
|
|
else
|
|
cout << "Aucune informations sur les conditions d'un évènement";
|
|
|
|
//Actions
|
|
if ( eventElem->FirstChildElement( "Actions" ) != NULL )
|
|
OpenSaveGame::OpenActions(actions, eventElem->FirstChildElement( "Actions" ));
|
|
else
|
|
cout << "Aucune informations sur les actions d'un évènement";
|
|
|
|
//Subevents
|
|
if ( eventElem->FirstChildElement( "Events" ) != NULL )
|
|
OpenSaveGame::OpenEvents(events, eventElem->FirstChildElement( "Events" ));
|
|
}
|
|
|
|
/**
|
|
* Register function during preprocessing
|
|
*/
|
|
void FunctionEvent::Preprocess(const Game & game, RuntimeScene & scene, std::vector < BaseEventSPtr > & eventList, unsigned int indexOfTheEventInThisList)
|
|
{
|
|
ReferenceFunction(&scene);
|
|
}
|
|
|
|
/**
|
|
* Unregister function when object is destroyed
|
|
*/
|
|
FunctionEvent::~FunctionEvent()
|
|
{
|
|
UnreferenceFunction();
|
|
}
|
|
|
|
/**
|
|
* Add function to functions list
|
|
*/
|
|
void FunctionEvent::ReferenceFunction(Scene * scene)
|
|
{
|
|
functionsList[scene][name] = this;
|
|
}
|
|
|
|
/**
|
|
* Suppress function from functions list
|
|
*/
|
|
void FunctionEvent::UnreferenceFunction()
|
|
{
|
|
std::map < const Scene* , std::map < std::string, FunctionEvent* > >::iterator siter = functionsList.begin();
|
|
std::map < const Scene* , std::map < std::string, FunctionEvent* > >::const_iterator send = functionsList.end();
|
|
for (;siter!=send;++siter)
|
|
{
|
|
std::map < std::string, FunctionEvent* >::iterator fiter = siter->second.begin();
|
|
std::map < std::string, FunctionEvent* >::const_iterator fend = siter->second.end();
|
|
for (;fiter!=fend;++fiter)
|
|
{
|
|
if ( fiter->second == this ) fiter->second = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
#if defined(GD_IDE_ONLY)
|
|
void FunctionEvent::OnSingleClick(int x, int y, vector < boost::tuple< vector < BaseEventSPtr > *, unsigned int, vector < Instruction > *, unsigned int > > & eventsSelected,
|
|
bool & conditionsSelected, bool & instructionsSelected)
|
|
{
|
|
const int forEachTextHeight = 20;
|
|
EventsRenderingHelper * renderingHelper = EventsRenderingHelper::getInstance();
|
|
|
|
//Test selection for the name
|
|
if ( y >= 0 && y <= forEachTextHeight )
|
|
{
|
|
nameSelected = true;
|
|
return;
|
|
}
|
|
|
|
//Test selection of actions/conditions
|
|
nameSelected = false;
|
|
y -= forEachTextHeight; //Substract the height of the "For Each object ..." text so as to simplify the tests
|
|
if ( x <= renderingHelper->GetConditionsColumnWidth())
|
|
{
|
|
conditionsSelected = true;
|
|
|
|
vector < Instruction > * conditionsListSelected = NULL;
|
|
unsigned int conditionIdInList = 0;
|
|
|
|
bool found = renderingHelper->GetConditionAt(conditions, x-0, y-0, conditionsListSelected, conditionIdInList);
|
|
|
|
if ( found )
|
|
{
|
|
//Update event and conditions selection information
|
|
if ( conditionIdInList < conditionsListSelected->size() ) (*conditionsListSelected)[conditionIdInList].selected = true;
|
|
|
|
//Update editor selection information
|
|
instructionsSelected = true;
|
|
boost::tuples::get<2>(eventsSelected.back()) = conditionsListSelected;
|
|
boost::tuples::get<3>(eventsSelected.back()) = conditionIdInList;
|
|
|
|
return;
|
|
}
|
|
else if ( y <= 18 )
|
|
{
|
|
//Update selection information
|
|
instructionsSelected = true;
|
|
boost::tuples::get<2>(eventsSelected.back()) = &conditions;
|
|
boost::tuples::get<3>(eventsSelected.back()) = 0;
|
|
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
conditionsSelected = false;
|
|
|
|
vector < Instruction > * actionsListSelected = NULL;
|
|
unsigned int actionIdInList = 0;
|
|
|
|
bool found = renderingHelper->GetActionAt(actions, x-0, y-0, actionsListSelected, actionIdInList);
|
|
|
|
if ( found )
|
|
{
|
|
//Update event and action selection information
|
|
if ( actionIdInList < actionsListSelected->size() ) (*actionsListSelected)[actionIdInList].selected = true;
|
|
|
|
//Update selection information
|
|
instructionsSelected = true;
|
|
boost::tuples::get<2>(eventsSelected.back()) = actionsListSelected;
|
|
boost::tuples::get<3>(eventsSelected.back()) = actionIdInList;
|
|
}
|
|
else
|
|
{
|
|
//Update selection information
|
|
instructionsSelected = true;
|
|
boost::tuples::get<2>(eventsSelected.back()) = &actions;
|
|
boost::tuples::get<3>(eventsSelected.back()) = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Render the event in the bitmap
|
|
*/
|
|
void FunctionEvent::Render(wxBufferedPaintDC & dc, int x, int y, unsigned int width) const
|
|
{
|
|
EventsRenderingHelper * renderingHelper = EventsRenderingHelper::getInstance();
|
|
const int functionTextHeight = 20;
|
|
|
|
//Draw event rectangle
|
|
dc.SetPen(*wxTRANSPARENT_PEN);
|
|
dc.SetBrush(wxBrush(wxColour(255, 255, 255), wxBRUSHSTYLE_SOLID));
|
|
{
|
|
wxRect rect(x, y, width, GetRenderedHeight(width));
|
|
wxColor color1 = selected ? renderingHelper->selectionColor : (IsDisabled() ? renderingHelper->disabledColor2 :renderingHelper->eventGradient1);
|
|
wxColor color2 = IsDisabled() ? renderingHelper->disabledColor : renderingHelper->eventGradient2;
|
|
wxColor color3 = IsDisabled() ? renderingHelper->disabledColor : renderingHelper->eventGradient3;
|
|
wxColor color4 = selected ? renderingHelper->selectionColor : (IsDisabled() ? renderingHelper->disabledColor2 :renderingHelper->eventGradient4);
|
|
|
|
renderingHelper->DrawNiceRectangle(dc, rect, color1, color2, color3, color4, renderingHelper->eventBorderColor);
|
|
}
|
|
|
|
//Name Selection
|
|
if ( selected && nameSelected )
|
|
{
|
|
dc.SetBrush(renderingHelper->GetSelectedRectangleFillBrush());
|
|
dc.SetPen(renderingHelper->GetSelectedRectangleOutlinePen());
|
|
dc.DrawRectangle(x+1, y+1, width-2, functionTextHeight-2);
|
|
}
|
|
|
|
//Name
|
|
dc.SetFont( renderingHelper->GetBoldFont() );
|
|
dc.DrawText( _("Fonction") + " " + name, x + 2, y + 1 );
|
|
|
|
//Draw actions and conditions
|
|
renderingHelper->DrawConditionsList(conditions, dc, x, y+functionTextHeight, renderingHelper->GetConditionsColumnWidth(), IsDisabled());
|
|
renderingHelper->DrawActionsList(actions, dc, x+renderingHelper->GetConditionsColumnWidth(), y+functionTextHeight, width-renderingHelper->GetConditionsColumnWidth(), IsDisabled());
|
|
}
|
|
|
|
unsigned int FunctionEvent::GetRenderedHeight(unsigned int width) const
|
|
{
|
|
if ( eventHeightNeedUpdate )
|
|
{
|
|
EventsRenderingHelper * renderingHelper = EventsRenderingHelper::getInstance();
|
|
const int functionTextHeight = 20;
|
|
|
|
//Get maximum height needed
|
|
int conditionsHeight = renderingHelper->GetRenderedConditionsListHeight(conditions, renderingHelper->GetConditionsColumnWidth());
|
|
int actionsHeight = renderingHelper->GetRenderedActionsListHeight(actions, width-renderingHelper->GetConditionsColumnWidth());
|
|
|
|
renderedHeight = (( conditionsHeight > actionsHeight ? conditionsHeight : actionsHeight ) + functionTextHeight);
|
|
eventHeightNeedUpdate = false;
|
|
}
|
|
|
|
return renderedHeight;
|
|
}
|
|
|
|
void FunctionEvent::EditEvent(wxWindow* parent_, Game & game_, Scene & scene_, MainEditorCommand & mainEditorCommand_)
|
|
{
|
|
string newName = string(wxGetTextFromUser(_("Entrez le nom de la fonction"), _("Nom de la fonction"), name).mb_str());
|
|
if ( newName != "" ) name = newName;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* Initialize from another FunctionEvent.
|
|
* Used by copy ctor and assignement operator
|
|
*/
|
|
void FunctionEvent::Init(const FunctionEvent & event)
|
|
{
|
|
events = CloneVectorOfEvents(event.events);
|
|
|
|
name = event.name;
|
|
conditions = event.conditions;
|
|
actions = event.actions;
|
|
}
|
|
|
|
/**
|
|
* Custom copy operator
|
|
*/
|
|
FunctionEvent::FunctionEvent(const FunctionEvent & event) :
|
|
BaseEvent(event)
|
|
{
|
|
Init(event);
|
|
}
|
|
|
|
/**
|
|
* Custom assignement operator
|
|
*/
|
|
FunctionEvent& FunctionEvent::operator=(const FunctionEvent & event)
|
|
{
|
|
if ( this != &event )
|
|
{
|
|
BaseEvent::operator=(event);
|
|
Init(event);
|
|
}
|
|
|
|
return *this;
|
|
}
|