diff options
-rw-r--r-- | modules/gdscript/gd_parser.cpp | 114 | ||||
-rw-r--r-- | scene/animation/animation_tree_player.cpp | 69 | ||||
-rw-r--r-- | scene/animation/animation_tree_player.h | 2 | ||||
-rw-r--r-- | tools/editor/project_manager.cpp | 7 | ||||
-rw-r--r-- | tools/editor/project_manager.h | 1 |
5 files changed, 151 insertions, 42 deletions
diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp index c55bfee591..4339a13edf 100644 --- a/modules/gdscript/gd_parser.cpp +++ b/modules/gdscript/gd_parser.cpp @@ -2381,10 +2381,48 @@ void GDParser::_parse_class(ClassNode *p_class) { current_export.hint=PROPERTY_HINT_ALL_FLAGS; tokenizer->advance(); - if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_CLOSE) { - _set_error("Expected ')' in hint."); + + if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_CLOSE) { + break; + } + if (tokenizer->get_token()!=GDTokenizer::TK_COMMA) + { + _set_error("Expected ')' or ',' in bit flags hint."); return; } + + current_export.hint=PROPERTY_HINT_FLAGS; + tokenizer->advance(); + + bool first = true; + while(true) { + + if (tokenizer->get_token()!=GDTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type()!=Variant::STRING) { + current_export=PropertyInfo(); + _set_error("Expected a string constant in named bit flags hint."); + return; + } + + String c = tokenizer->get_token_constant(); + if (!first) + current_export.hint_string+=","; + else + first=false; + + current_export.hint_string+=c.xml_escape(); + + tokenizer->advance(); + if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_CLOSE) + break; + + if (tokenizer->get_token()!=GDTokenizer::TK_COMMA) { + current_export=PropertyInfo(); + _set_error("Expected ')' or ',' in named bit flags hint."); + return; + } + tokenizer->advance(); + } + break; } @@ -2439,6 +2477,23 @@ void GDParser::_parse_class(ClassNode *p_class) { break; } + // range + if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier()=="EXP") { + + current_export.hint=PROPERTY_HINT_EXP_RANGE; + tokenizer->advance(); + + if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_CLOSE) + break; + else if (tokenizer->get_token()!=GDTokenizer::TK_COMMA) { + _set_error("Expected ')' or ',' in exponential range hint."); + return; + } + tokenizer->advance(); + } + else + current_export.hint=PROPERTY_HINT_RANGE; + float sign=1.0; if (tokenizer->get_token()==GDTokenizer::TK_OP_SUB) { @@ -2452,8 +2507,6 @@ void GDParser::_parse_class(ClassNode *p_class) { return; } - //enumeration - current_export.hint=PROPERTY_HINT_RANGE; current_export.hint_string=rtos(sign*double(tokenizer->get_token_constant())); tokenizer->advance(); @@ -2556,10 +2609,32 @@ void GDParser::_parse_class(ClassNode *p_class) { if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier()=="DIR") { - current_export.hint=PROPERTY_HINT_DIR; tokenizer->advance(); - if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_CLOSE) { - _set_error("Expected ')' in hint."); + + if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_CLOSE) + current_export.hint=PROPERTY_HINT_DIR; + else if (tokenizer->get_token()==GDTokenizer::TK_COMMA ) { + + tokenizer->advance(); + + if (tokenizer->get_token()!=GDTokenizer::TK_IDENTIFIER || !(tokenizer->get_token_identifier()=="GLOBAL")) { + _set_error("Expected 'GLOBAL' after comma in directory hint."); + return; + } + if (!p_class->tool) { + _set_error("Global filesystem hints may only be used in tool scripts."); + return; + } + current_export.hint=PROPERTY_HINT_GLOBAL_DIR; + tokenizer->advance(); + + if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_CLOSE) { + _set_error("Expected ')' in hint."); + return; + } + } + else { + _set_error("Expected ')' or ',' in hint."); return; } break; @@ -2573,9 +2648,32 @@ void GDParser::_parse_class(ClassNode *p_class) { if (tokenizer->get_token()==GDTokenizer::TK_COMMA) { tokenizer->advance(); + + if (tokenizer->get_token()==GDTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier()=="GLOBAL") { + + if (!p_class->tool) { + _set_error("Global filesystem hints may only be used in tool scripts."); + return; + } + current_export.hint=PROPERTY_HINT_GLOBAL_FILE; + tokenizer->advance(); + + if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_CLOSE) + break; + else if (tokenizer->get_token()==GDTokenizer::TK_COMMA) + tokenizer->advance(); + else { + _set_error("Expected ')' or ',' in hint."); + return; + } + } + if (tokenizer->get_token()!=GDTokenizer::TK_CONSTANT || tokenizer->get_token_constant().get_type()!=Variant::STRING) { - _set_error("Expected string constant with filter"); + if (current_export.hint==PROPERTY_HINT_GLOBAL_FILE) + _set_error("Expected string constant with filter"); + else + _set_error("Expected 'GLOBAL' or string constant with filter"); return; } current_export.hint_string=tokenizer->get_token_constant(); diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp index c7e259c3c6..c04c653819 100644 --- a/scene/animation/animation_tree_player.cpp +++ b/scene/animation/animation_tree_player.cpp @@ -432,7 +432,7 @@ void AnimationTreePlayer::_notification(int p_what) { } -float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode **r_prev_anim,float p_weight, float p_time, bool p_seek,const HashMap<NodePath,bool> *p_filter, float p_reverse_weight) { +float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode **r_prev_anim,float p_weight, float p_time, bool switched, bool p_seek,const HashMap<NodePath,bool> *p_filter, float p_reverse_weight) { ERR_FAIL_COND_V(!node_map.has(p_node), 0); NodeBase *nb=node_map[p_node]; @@ -445,7 +445,7 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode case NODE_OUTPUT: { NodeOut *on = static_cast<NodeOut*>(nb); - return _process_node(on->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek); + return _process_node(on->inputs[0].node,r_prev_anim,p_weight,p_time,switched,p_seek); } break; case NODE_ANIMATION: { @@ -479,6 +479,9 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode an->time=anim_size; } + if (switched && an->time >= anim_size) { + an->time = 0.0; + } an->skip=true; for (List<AnimationNode::TrackRef>::Element *E=an->tref.front();E;E=E->next()) { @@ -520,7 +523,7 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode if (!osn->active) { //make it as if this node doesn't exist, pass input 0 by. - return _process_node(osn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek,p_filter,p_reverse_weight); + return _process_node(osn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,p_seek,p_filter,p_reverse_weight); } if (p_seek) @@ -551,13 +554,13 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode if (!osn->filter.empty()) { - main_rem = _process_node(osn->inputs[0].node,r_prev_anim,(osn->mix?p_weight:p_weight*(1.0-blend)),p_time,p_seek,&osn->filter,p_weight); - os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,p_seek,&osn->filter,-1); + main_rem = _process_node(osn->inputs[0].node,r_prev_anim,(osn->mix?p_weight:p_weight*(1.0-blend)),p_time,switched,p_seek,&osn->filter,p_weight); + os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,osn->start,p_seek,&osn->filter,-1); } else { - main_rem = _process_node(osn->inputs[0].node,r_prev_anim,(osn->mix?p_weight:p_weight*(1.0-blend)),p_time,p_seek); - os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,p_seek); + main_rem = _process_node(osn->inputs[0].node,r_prev_anim,(osn->mix?p_weight:p_weight*(1.0-blend)),p_time,switched,p_seek); + os_rem = _process_node(osn->inputs[1].node,r_prev_anim,p_weight*blend,p_time,osn->start,p_seek); } if (osn->start) { @@ -578,8 +581,8 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode MixNode *mn = static_cast<MixNode*>(nb); - float rem = _process_node(mn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek,p_filter,p_reverse_weight); - _process_node(mn->inputs[1].node,r_prev_anim,p_weight*mn->amount,p_time,p_seek,p_filter,p_reverse_weight); + float rem = _process_node(mn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,p_seek,p_filter,p_reverse_weight); + _process_node(mn->inputs[1].node,r_prev_anim,p_weight*mn->amount,p_time,switched,p_seek,p_filter,p_reverse_weight); return rem; } break; @@ -590,12 +593,12 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode float rem; if (!bn->filter.empty()) { - rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,p_seek,&bn->filter,p_weight); - _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value,p_time,p_seek,&bn->filter,-1); + rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,switched,p_seek,&bn->filter,p_weight); + _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value,p_time,switched,p_seek,&bn->filter,-1); } else { - rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,p_seek,p_filter,p_reverse_weight*(1.0-bn->value)); - _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value,p_time,p_seek,p_filter,p_reverse_weight*bn->value); + rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,switched,p_seek,p_filter,p_reverse_weight*(1.0-bn->value)); + _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value,p_time,switched,p_seek,p_filter,p_reverse_weight*bn->value); } return rem; @@ -606,16 +609,16 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode float rem; if (bn->value==0) { - rem = _process_node(bn->inputs[1].node,r_prev_anim,p_weight,p_time,p_seek,p_filter,p_reverse_weight); + rem = _process_node(bn->inputs[1].node,r_prev_anim,p_weight,p_time,switched,p_seek,p_filter,p_reverse_weight); } else if (bn->value>0) { - rem = _process_node(bn->inputs[1].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,p_seek,p_filter,p_reverse_weight*(1.0-bn->value)); - _process_node(bn->inputs[2].node,r_prev_anim,p_weight*bn->value,p_time,p_seek,p_filter,p_reverse_weight*bn->value); + rem = _process_node(bn->inputs[1].node,r_prev_anim,p_weight*(1.0-bn->value),p_time,switched,p_seek,p_filter,p_reverse_weight*(1.0-bn->value)); + _process_node(bn->inputs[2].node,r_prev_anim,p_weight*bn->value,p_time,switched,p_seek,p_filter,p_reverse_weight*bn->value); } else { - rem = _process_node(bn->inputs[1].node,r_prev_anim,p_weight*(1.0+bn->value),p_time,p_seek,p_filter,p_reverse_weight*(1.0+bn->value)); - _process_node(bn->inputs[0].node,r_prev_anim,p_weight*-bn->value,p_time,p_seek,p_filter,p_reverse_weight*-bn->value); + rem = _process_node(bn->inputs[1].node,r_prev_anim,p_weight*(1.0+bn->value),p_time,switched,p_seek,p_filter,p_reverse_weight*(1.0+bn->value)); + _process_node(bn->inputs[0].node,r_prev_anim,p_weight*-bn->value,p_time,switched,p_seek,p_filter,p_reverse_weight*-bn->value); } return rem; @@ -623,10 +626,10 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode case NODE_BLEND4: { Blend4Node *bn = static_cast<Blend4Node*>(nb); - float rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value.x),p_time,p_seek,p_filter,p_reverse_weight*(1.0-bn->value.x)); - _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value.x,p_time,p_seek,p_filter,p_reverse_weight*bn->value.x); - float rem2 = _process_node(bn->inputs[2].node,r_prev_anim,p_weight*(1.0-bn->value.y),p_time,p_seek,p_filter,p_reverse_weight*(1.0-bn->value.y)); - _process_node(bn->inputs[3].node,r_prev_anim,p_weight*bn->value.y,p_time,p_seek,p_filter,p_reverse_weight*bn->value.y); + float rem = _process_node(bn->inputs[0].node,r_prev_anim,p_weight*(1.0-bn->value.x),p_time,switched,p_seek,p_filter,p_reverse_weight*(1.0-bn->value.x)); + _process_node(bn->inputs[1].node,r_prev_anim,p_weight*bn->value.x,p_time,switched,p_seek,p_filter,p_reverse_weight*bn->value.x); + float rem2 = _process_node(bn->inputs[2].node,r_prev_anim,p_weight*(1.0-bn->value.y),p_time,switched,p_seek,p_filter,p_reverse_weight*(1.0-bn->value.y)); + _process_node(bn->inputs[3].node,r_prev_anim,p_weight*bn->value.y,p_time,switched,p_seek,p_filter,p_reverse_weight*bn->value.y); return MAX(rem,rem2); @@ -634,9 +637,9 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode case NODE_TIMESCALE: { TimeScaleNode *tsn = static_cast<TimeScaleNode*>(nb); if (p_seek) - return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,true,p_filter,p_reverse_weight); + return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,true,p_filter,p_reverse_weight); else - return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time*tsn->scale,false,p_filter,p_reverse_weight); + return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time*tsn->scale,switched,false,p_filter,p_reverse_weight); } break; case NODE_TIMESEEK: { @@ -644,12 +647,12 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode TimeSeekNode *tsn = static_cast<TimeSeekNode*>(nb); if (tsn->seek_pos>=0) { - float res = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,tsn->seek_pos,true,p_filter,p_reverse_weight); + float res = _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,tsn->seek_pos,switched,true,p_filter,p_reverse_weight); tsn->seek_pos=-1; return res; } else - return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek); + return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,switched,p_seek); } break; case NODE_TRANSITION: { @@ -658,7 +661,7 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode if (tn->prev<0) { - float rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight,p_time,p_seek,p_filter,p_reverse_weight); + float rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight,p_time,switched,p_seek,p_filter,p_reverse_weight); if (p_seek) tn->time=p_time; else @@ -687,10 +690,10 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode if (!p_seek && tn->switched) { //just switched - rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight*(1.0-blend),0,true,p_filter,p_reverse_weight*(1.0-blend)); + rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight*(1.0-blend),0,true,true,p_filter,p_reverse_weight*(1.0-blend)); } else { - rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight*(1.0-blend),p_time,p_seek,p_filter,p_reverse_weight*(1.0-blend)); + rem = _process_node(tn->inputs[tn->current].node,r_prev_anim,p_weight*(1.0-blend),p_time,switched,p_seek,p_filter,p_reverse_weight*(1.0-blend)); } @@ -700,10 +703,10 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode if (p_seek) { - _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,0,false,p_filter,p_reverse_weight*blend); + _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,0,true,false,p_filter,p_reverse_weight*blend); tn->time=p_time; } else { - _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,p_time,false,p_filter,p_reverse_weight*blend); + _process_node(tn->inputs[tn->prev].node,r_prev_anim,p_weight*blend,p_time,switched,false,p_filter,p_reverse_weight*blend); tn->time+=p_time; tn->prev_xfading-=p_time; if (tn->prev_xfading<0) { @@ -740,10 +743,10 @@ void AnimationTreePlayer::_process_animation(float p_delta) { AnimationNode *prev=NULL; if (reset_request) { - _process_node(out_name,&prev, 1.0, 0, true ); + _process_node(out_name,&prev, 1.0, 0, true, true ); reset_request=false; } else - _process_node(out_name,&prev, 1.0, p_delta, false ); + _process_node(out_name,&prev, 1.0, p_delta, false, false ); if (dirty_caches) { //some animation changed.. ignore this pass diff --git a/scene/animation/animation_tree_player.h b/scene/animation/animation_tree_player.h index 9ea5ccf330..fb1c9016ff 100644 --- a/scene/animation/animation_tree_player.h +++ b/scene/animation/animation_tree_player.h @@ -267,7 +267,7 @@ private: Map<StringName,NodeBase*> node_map; // return time left to finish animation - float _process_node(const StringName& p_node,AnimationNode **r_prev_anim, float p_weight,float p_step, bool p_seek=false,const HashMap<NodePath,bool> *p_filter=NULL, float p_reverse_weight=0); + float _process_node(const StringName& p_node,AnimationNode **r_prev_anim, float p_weight,float p_step, bool switched, bool p_seek=false,const HashMap<NodePath,bool> *p_filter=NULL, float p_reverse_weight=0); void _process_animation(float p_delta); bool reset_request; diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp index 4db56ea2f9..880df85c19 100644 --- a/tools/editor/project_manager.cpp +++ b/tools/editor/project_manager.cpp @@ -348,6 +348,13 @@ struct ProjectItem { _FORCE_INLINE_ bool operator ==(const ProjectItem& l) const { return project==l.project; } }; +void ProjectManager::_notification(int p_what) { + + if (p_what==NOTIFICATION_ENTER_TREE) { + + get_tree()->set_editor_hint(true); + } +} void ProjectManager::_panel_draw(Node *p_hb) { diff --git a/tools/editor/project_manager.h b/tools/editor/project_manager.h index 1e6ea9c1c9..f8edb6dc10 100644 --- a/tools/editor/project_manager.h +++ b/tools/editor/project_manager.h @@ -85,6 +85,7 @@ class ProjectManager : public Control { protected: + void _notification(int p_what); static void _bind_methods(); public: ProjectManager(); |