fix compile against newer giflib
[rofl0r-obeditor.git] / src / common__object_levels.cpp
blobfbb65e2abbbdf4f3210ebfded4ce0d5820827b3f
1 /*
2 * common__object_levels.cpp
4 * Created on: 24 avr. 2009
5 * Author: pat
6 */
8 #include "common__tools.h"
9 #include "common__object_stage.h"
12 /*\internal*********************************************
13 ******** OBJECT RELATED TO THE LEVELS.TXT FILE
14 ******************************************************/
18 //**********************************************
19 //**********************************************
20 //**********************************************
21 /**
22 * The object which hold the datas about a game (mod)
26 //**********************************************
27 ob_object*
28 ob_levels::Guess_and_ConstructNewObject(MyLine* line, const int _num_line )
30 // if Empty Line
31 if( line->GetTokensCount() <= 0 )
32 return new ob_object(line, _num_line);
34 wxString _name = *(line->GetToken(0)->data);
35 ob_object *temp;
36 if( _name.Upper() == wxT("SET") )
37 temp = new ob_StagesSet(line,_num_line);
38 else
39 temp = new ob_object( line, _num_line);
41 // wxLogInfo( "At line " + IntToStr( _num_line +1) + ", object build :" + temp->name );
43 return temp;
47 //**********************************************
48 ob_levels::ob_levels()
49 : ob_object_container()
51 SetType( OB_TYPE_LEVELS );
55 //-----------------------------------------------------------------
56 void
57 ob_levels::pClone(ob_object*& res )
59 if( res == NULL )
60 res = new ob_levels();
61 ob_object_container::pClone( res );
64 //**********************************************
65 ob_levels::~ob_levels()
70 //**********************************************
72 ob_StagesSet** ob_levels::GetSets( size_t& _nb_set)
74 return ((ob_StagesSet**) GetSubObjectS_ofType( OB_TYPE_STAGES_SET, _nb_set ));
78 //**********************************************
80 bool ob_levels::Set_Insert( ob_StagesSet* ta, int ind )
82 size_t _nb_set;
83 ob_StagesSet** t = ob_levels::GetSets( _nb_set);
85 // No set
86 if( t == NULL )
88 return Add_SubObj( ta );
91 bool res;
92 if( ind == -1 || ind == (int)_nb_set )
94 res = t[_nb_set-1]->InsertObject_After( ta );
96 else if( ind >= 0 && ind < (int) _nb_set )
98 res = t[ind]->InsertObject_Before( ta );
100 else
101 res = false;
103 delete[] t;
104 return res;
108 //**********************************************
110 bool ob_levels::Set_Tag(const wxString& _tag, const wxString& _token )
112 wxArrayString t;
113 t.Add( _token );
114 return Set_Tag( _tag, t );
117 //**********************************************
119 bool ob_levels::Set_Tag(const wxString& _tag, wxArrayString _tokens )
121 // If the tag is already here
122 ob_object* temp = GetSubObject( _tag );
123 if( temp != NULL )
125 temp->SetProperty( _tag, _tokens );
126 return true;
129 //-----------------
130 ob_object* t = new ob_object( _tag, _tokens );
132 // Get the first set object
133 temp = first_subobj;
134 while( temp != NULL )
136 if( temp->type == OB_TYPE_STAGES_SET)
137 break;
140 // No Set -> Append the new tag at the end
141 if( temp == NULL )
142 return Add_SubObj( t );
144 // Insert the new tag just before the first set
145 else
146 return temp->InsertObject_Before( t );
150 //**********************************************
151 //**********************************************
152 //**********************************************
154 * The object which hold the datas about a game (mod)
157 wxString stagedeclaration_tag[] = { wxT("Z"), wxT("FILE"), wxT("BRANCH"), };
159 bool IsStageDeclarationTag( wxString& t )
161 for( size_t i =0; i< t_size_of(stagedeclaration_tag); i++ )
162 if( stagedeclaration_tag[i].Upper() == t.Upper() )
163 return true;
164 return false;
167 //**********************************************
168 ob_StagesSet::ob_StagesSet( MyLine* line, const int _num_line )
169 : ob_object( line, _num_line )
171 SetType( OB_TYPE_STAGES_SET );
172 ungry = true;
176 //-----------------------------------------------------------------
177 void
178 ob_StagesSet::pClone(ob_object*& res )
180 if( res == NULL )
181 res = new ob_StagesSet();
182 ob_object::pClone( res );
183 res->ungry = ungry;
186 //**********************************************
188 bool ob_StagesSet::Eat( MyLine* line, const int _num_line )
190 if( ! ungry )
191 return false;
193 // If new set
194 if( ! line->IsComment() && ! line->IsEmpty() )
195 if( line->GetToken(0)->data->Upper() == wxT("SET") )
197 if( last_subobj->type == OB_TYPE_STAGE_DECLARATION
198 && ! ((ob_StageDeclaration*) last_subobj )->b_completed )
200 wxString __t;
201 if( line->GetToken(1) != NULL && line->GetToken(1)->data != NULL )
202 __t = *(line->GetToken(1)->data);
203 ObjectsLog( MYLOG_WARNING, 1 + _num_line,
204 wxT("new SET of Stage <") + __t + wxT("> declared although a stage declaration is still uncomplete.") );
206 ungry = false;
207 return false;
210 // A stage declaration is in progress
211 if( last_subobj != NULL && last_subobj->type == OB_TYPE_STAGE_DECLARATION && last_subobj->ungry )
213 ob_StageDeclaration* st = (ob_StageDeclaration*) last_subobj;
214 bool res = st->Eat( line, _num_line );
216 // ERROR CASE : Stage declaration don't eat the line BUT it had to (cause declaration are close with explicit tag "file" )
217 if( !res )
219 wxString __t;
220 if( line->GetToken(1) != NULL && line->GetToken(1)->data != NULL )
221 __t == *(line->GetToken(1)->data);
222 ObjectsLog( MYLOG_WARNING, _num_line + 1,
223 wxT("Tag <") + __t + wxT("> pop in a middle of a stage declaration !!") );
225 else
226 return true;
229 // comment line
230 if( line->IsComment() || line->IsEmpty() )
232 ob_object* temp = new ob_object( line, _num_line );
233 Add_SubObj( temp );
234 // Still hungry
235 return true;
238 //*************************
239 // Valid line
240 wxString _name = *(line->GetToken(0)->data);
243 //-------------------------
244 // Annoying "next" tag case :(
245 if( _name.Upper() == wxT("NEXT") )
247 // Gotta merge all from here up to the previous stage_declaration
248 ob_object* obj_next = new ob_object( line, _num_line );
249 ob_object* temp = last_subobj;
250 while( temp != NULL && temp->type != OB_TYPE_STAGE_DECLARATION && temp->type != OB_TYPE_STAGES_SET )
251 temp = temp->prev;
253 // Problem, having a "next" tag without previous Stage declaration ...
254 // No merging will be done
255 if( temp == NULL || temp->type != OB_TYPE_STAGE_DECLARATION )
257 ObjectsLog( MYLOG_WARNING, _num_line + 1,wxT("Tag <NEXT> found without previous stage declaration !!!") );
258 Add_SubObj( obj_next );
261 // Normal case, do the merging
262 else
264 ob_StageDeclaration* sd = (ob_StageDeclaration*) temp;
265 temp = sd->next;
266 while( temp != NULL )
268 sd->Add_SubObj( temp );
269 temp = sd->next;
272 // Append also the "NEXT" tag
273 sd->Add_SubObj( obj_next );
274 return true;
278 //-------------------------
279 // Stage declaration start here
280 if( IsStageDeclarationTag( _name ) )
282 Add_SubObj( new ob_StageDeclaration( line, _num_line ) );
283 return true;
286 // Basic object here
287 else
289 Add_SubObj( new ob_object( line, _num_line ) );
290 return true;
295 //**********************************************
297 ob_StagesSet::~ob_StagesSet()
302 //**********************************************
304 void ob_StagesSet::Validate()
309 //**********************************************
311 bool ob_StagesSet::Add_SubObj( ob_object* _obj )
313 // Add the next at the end
314 if( _obj->type == OB_TYPE_STAGE_DECLARATION )
316 return Append_SubObj( _obj );
319 // Add the obj just before the first stage declaration
320 else if( ! _obj->Is_EmptyOrComment() )
322 size_t dummy;
323 ob_object** arr_o = GetSubObjectS_ofType( OB_TYPE_STAGE_DECLARATION, dummy );
324 if( arr_o == NULL )
325 return Append_SubObj( _obj );
326 else
328 bool res = arr_o[0]->InsertObject_Before( _obj );
329 delete[] arr_o;
330 return res;
333 else
334 return Append_SubObj( _obj );
337 //**********************************************
338 bool ob_StagesSet::SetSetName(const wxString& _sn)
340 return SetToken( 0, _sn );
344 //**********************************************
346 wxString ob_StagesSet::GetSetName()
348 return GetToken( 0 );
352 //**********************************************
354 ob_StageDeclaration** ob_StagesSet::GetStages( size_t& _nb_stages)
356 return (ob_StageDeclaration**) GetSubObjectS_ofType( OB_TYPE_STAGE_DECLARATION, _nb_stages );
360 //**********************************************
362 bool ob_StagesSet::Stage_Insert( ob_StageDeclaration* t, int ind )
364 size_t nb_stages;
365 bool res = false;
366 ob_StageDeclaration** arr_stages = GetStages( nb_stages );
368 // case : there's already some stages in
369 if( arr_stages != NULL )
371 // Append case
372 if( ind == -1 || ind == (int) nb_stages )
374 res = arr_stages[nb_stages-1]->InsertObject_After( t );
377 // Valid indice case
378 else if( ind >= 0 && ind < (int) nb_stages )
380 res = arr_stages[ind]->InsertObject_Before( t );
383 // INValid indice case
384 else
386 res = false;
388 // Cleaning
389 delete[] arr_stages;
392 // First stage to add -> Juste append it at the end of the object
393 else
395 res = Add_SubObj( t );
397 return res;
401 //**********************************************
403 bool ob_StagesSet::Set_Tag(const wxString& _tag, const wxString& _token )
405 wxArrayString t;
406 t.Add( _token );
407 return Set_Tag( _tag, t );
410 //**********************************************
412 bool ob_StagesSet::Set_Tag(const wxString& _tag, wxArrayString _tokens )
414 // If the tag is already here
415 ob_object* temp = GetSubObject( _tag );
416 if( temp != NULL )
418 temp->SetProperty( _tag, _tokens );
419 return true;
422 //-----------------
423 ob_object* t = new ob_object( _tag, _tokens );
425 // Get the first stage object
426 temp = first_subobj;
427 while( temp != NULL )
429 if( temp->type == OB_TYPE_STAGE_DECLARATION)
430 break;
433 // No Stage -> Append the new tag at the end
434 if( temp == NULL )
435 return Add_SubObj( t );
437 // Insert the new tag just before the first stage
438 else
439 return temp->InsertObject_Before( t );
443 //**********************************************
445 void ob_StagesSet::SetToDefault()
447 name = wxT("SET");
448 SetToken( 0, wxT("UNAMED" ));
449 Add_SubObj( new ob_object(wxT("nosame"), wxT("1" )) );
450 Add_SubObj( new ob_object(wxT("noshare"), wxT("0" )) );
451 Add_SubObj( new ob_object(wxT("ifcomplete"), wxT("0") ) );
452 Add_SubObj( new ob_object(wxT("lives"), wxT("3") ) );
453 Add_SubObj( new ob_object(wxT("credits"), wxT("3") ) );
454 Add_SubObj( new ob_object(wxT("maxplayers"), wxT("2") ) );
455 Add_SubObj( new ob_object(wxT("typemp"), wxT("0") ) );
456 Add_SubObj( new ob_object(wxT("cansave"), wxT("0") ) );
460 //**********************************************
461 //**********************************************
462 //**********************************************
464 * The object which hold the datas about a game (mod)
467 //**********************************************
468 ob_StageDeclaration::ob_StageDeclaration( MyLine* line, const int _num_line )
469 : ob_object()
471 SetType( OB_TYPE_STAGE_DECLARATION );
472 b_completed = false;
473 stage = NULL;
475 // if default constructor => Nothing more
476 if( line == NULL )
477 return;
479 Eat( line, _num_line );
483 //**********************************************
485 ob_StageDeclaration::ob_StageDeclaration( const wxString& _name, wxArrayString& _tokens)
486 : ob_object()
488 SetType( OB_TYPE_STAGE_DECLARATION );
489 b_completed = false;
490 stage = NULL;
491 if( _name.Upper() == wxT("FILE") )
492 b_completed = true;
494 ob_object* temp = new ob_object( _name, _tokens );
495 Add_SubObj( temp );
498 //-----------------------------------------------------------------
499 void
500 ob_StageDeclaration::pClone(ob_object*& res )
502 if( res == NULL )
503 res = new ob_StageDeclaration();
504 ob_object::pClone( res );
505 ((ob_StageDeclaration*)res)->stage = NULL;
506 ((ob_StageDeclaration*)res)->b_completed = b_completed;
509 //**********************************************
511 ob_StageDeclaration::~ob_StageDeclaration()
513 UnLoadStage();
517 //**********************************************
519 bool ob_StageDeclaration::Eat( MyLine* line, const int _num_line )
521 if( ! ungry )
522 return false;
524 // comment line
525 if( line->IsComment() || line->IsEmpty() )
527 ob_object* temp = new ob_object( line, _num_line );
528 Add_SubObj( temp );
529 return true;
533 wxString _name = *(line->GetToken(0)->data);
534 if( _name.Upper() == wxT("FILE") )
536 b_completed = true;
537 ungry = false;
540 ob_object* temp = new ob_object( line, _num_line );
541 Add_SubObj( temp );
542 return true;
545 //**********************************************
547 bool ob_StageDeclaration::Add_SubObj( ob_object* _obj )
549 // Add the next at the end
550 if( _obj->name.Upper() == wxT("NEXT") )
552 return Append_SubObj( _obj );
554 // Add the branch just after "FILE"
555 else if( _obj->name.Upper() == wxT("BRANCH") )
557 ob_object * t = GetSubObject( wxT("BRANCH") );
558 if( t == NULL )
559 return Append_SubObj( _obj );
560 else
561 return t->InsertObject_After( _obj );
563 else
565 return Append_SubObj( _obj );
570 //**********************************************
572 wxString ob_StageDeclaration::ToStr()const
574 wxString res;
576 // Print prefixes
577 ob_object *temp = first_prefix;
578 while( temp != NULL )
580 res += temp->ToStr();
581 temp = temp->next;
584 temp = first_subobj;
585 while( temp != NULL )
587 res += temp->ToStr();
588 temp = temp->next;
591 return res;
594 //**********************************************
596 void ob_StageDeclaration::Validate()
601 //**********************************************
603 void ob_StageDeclaration::SetStageName(const wxString& _sn)
605 // Branch Name
606 ob_object* temp = GetSubObject( wxT("BRANCH") );
607 if( temp != NULL)
608 temp->SetToken( 0, _sn );
610 // Else, the name is set in the prefixs comments
611 ob_object* t = first_prefix;
612 while( t != NULL )
614 wxString c = t->GetComment();
615 int _ind = c.Find( wxT("# STAGENAME : ") );
616 if( _ind != wxNOT_FOUND )
618 _ind += wxString::FromAscii("# STAGENAME : ").Len();
619 wxString _pref = c.Mid(0, _ind);
620 t->SetComment( _pref + wxT(" ") + _sn);
621 return;
623 t = t->next;
626 // Have to add a prefix
627 PrependCommentLine( wxT("\t# STAGENAME : ") + _sn );
631 //**********************************************
633 wxString ob_StageDeclaration::GetStageName()
635 // Branch Name is mandatory
636 ob_object* temp = GetSubObject( wxT("BRANCH"));
637 if( temp != NULL)
638 return temp->GetToken( 0 );
640 // Else, the name is set in the prefixs comments
641 ob_object* t = first_prefix;
642 while( t != NULL )
644 wxString c = t->GetComment();
645 int _ind = c.Find( wxT("# STAGENAME : ") );
646 if( _ind != wxNOT_FOUND )
648 _ind += wxString::FromAscii("# STAGENAME : ").Len();
649 wxString res = c.Mid( _ind, c.Len() - _ind);
650 res.Trim().Trim(false );
651 return res;
653 t = t->next;
656 wxString res = wxFileName(GetFileName()).GetFullName();
657 if( res == wxString() )
658 res = wxT("UNNAMED");
659 return res;
663 //**********************************************
665 bool ob_StageDeclaration::SetFileName(const wxString& _fn)
667 ob_object* temp = GetSubObject( wxT("FILE") );
668 if( temp != NULL)
669 return temp->SetToken( 0, _fn );
671 temp = new ob_object( wxT("FILE"), _fn );
672 return Add_SubObj( temp );
676 //**********************************************
678 wxString ob_StageDeclaration::GetFileName()
680 return GetObFile( GetSubObject_Token( wxT("FILE"), 0 )).GetFullPath();
684 //**********************************************
686 // bool ob_StageDeclaration::Set_NextTag_State(bool b_next)
687 // {
688 // // If a "NEXT" tag is already setted
689 // ob_object* temp = GetSubObject( "NEXT" );
690 // if( temp != NULL )
691 // {
692 // // Already setted as wanted
693 // if( b_next == true )
694 // return true;
696 // // Remove the next TAG
697 // delete temp;
698 // return true;
699 // }
701 // // No Next Tag and want to be none ? -> Everythings fine
702 // if( b_next == false )
703 // return true;
705 // //try to find the FILE tag
706 // temp = GetSubObject( "FILE" );
708 // // No FILE Elt -> Cancel the operation
709 // if( temp != NULL)
710 // return false;
712 // // Ok File Elt is here, so just add the tag after it
713 // ob_object* _next = new ob_object( "next" );
714 // temp->InsertObject_After( _next );
716 // return true;
717 // }
719 //**********************************************
721 bool ob_StageDeclaration::Set_BranchTag( const wxString& _bn)
723 // If a "Branch" tag is already setted
724 ob_object* temp = GetSubObject(wxT("BRANCH") );
725 if( temp != NULL )
727 // Just Change the name
728 SetStageName( _bn );
729 return true;
732 // No branch tag ? -> Create one at the start of the stage declaration
733 ob_object* _branch = new ob_object( wxT("BRANCH"), _bn );
734 Prepend_SubObj( _branch );
735 SetStageName( _bn );
736 return true;
740 //**********************************************
742 bool ob_StageDeclaration::Set_Tag(const wxString& _tag, const wxString& _token )
744 wxArrayString t;
745 t.Add( _token );
746 return Set_Tag( _tag, t );
749 //**********************************************
751 bool ob_StageDeclaration::Set_Tag(const wxString& _tag, wxArrayString _tokens )
753 // If the tag is already here
754 ob_object* temp = GetSubObject( _tag );
755 if( temp != NULL )
757 temp->SetProperty( _tag, _tokens );
758 return true;
761 //try to find the FILE tag
762 temp = GetSubObject( wxT("FILE") );
764 // No FILE Elt -> Cancel the operation
765 if( temp != NULL)
766 return false;
768 // Ok File Elt is here, so just add the tag before it
769 ob_object* _new = new ob_object( _tag, _tokens );
770 temp->InsertObject_Before( _new );
772 return true;
775 //---------------------------------------------------------------------
776 wxSize
777 ob_StageDeclaration::GetDefScrollzBounds()
779 ob_object* subobj = GetSubObject( wxT("Z") );
780 if( subobj == NULL )
781 return wxSize(160,232);
782 return wxSize( StrToInt(subobj->GetToken(0)), StrToInt(subobj->GetToken(1)) );
787 //**********************************************
789 void ob_StageDeclaration::UnLoadStage()
791 if( stage != NULL )
793 delete stage;
794 stage = NULL;
798 //**********************************************
800 bool ob_StageDeclaration::LoadStage(bool b_reload)
802 if( ! b_reload && stage != NULL )
803 return true;
805 UnLoadStage();
807 wxFileName fn = GetFileName();
808 if( ! fn.FileExists() )
809 return false;
811 stage = new obFileStage( fn );
812 if( stage->textFile == NULL )
814 delete stage;
815 stage = NULL;
816 return false;
818 return true;
822 //**********************************************
824 bool ob_StageDeclaration::Is_EmptyOrComment()const
826 return false;