Skip to content

Commit

Permalink
Port over attunements infrastructure
Browse files Browse the repository at this point in the history
I think this should enable the attunement system in Magiclysm, although effect_on_condition and other support code will be needed to port much of the actual Maglclysm attunement content over
  • Loading branch information
sayke committed Sep 13, 2023
1 parent 1e22505 commit 376a52b
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,4 @@ Xcode/
/tests/pch/tests-pch.hpp.pch
/tests/catch/catch.hpp.gch
/tests/catch/catch.hpp.pch
cbn_notes.txt
95 changes: 95 additions & 0 deletions src/iexamine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,101 @@ void iexamine::gaspump( player &p, const tripoint &examp )
add_msg( m_info, _( "Out of order." ) );
}

static bool has_attunement_spell_prereqs( Character &you, const trait_id &attunement )
{
// for each prereq we need to check that the player has 2 level 15 spells
for( const trait_id &prereq : attunement->prereqs ) {
int spells_known = 0;
for( const spell &sp : you.spells_known_of_class( prereq ) ) {
if( sp.get_level() >= 15 ) {
spells_known++;
}
}
if( spells_known < 2 ) {
return false;
}
}
return true;
}

void iexamine::attunement_altar( Character &you, const tripoint & )
{
std::set<trait_id> attunements;
for( const mutation_branch &mut : mutation_branch::get_all() ) {
if( mut.flags.count( json_flag_ATTUNEMENT ) ) {
attunements.emplace( mut.id );
}
}
// remove the attunements the player does not have prereqs for
for( auto iter = attunements.begin(); iter != attunements.end(); ) {
bool has_prereq = true;
// the normal usage of prereqs only needs one, but attunements put all their prereqs into the same array
// each prereqs is required for it as well
for( const trait_id &prereq : ( *iter )->prereqs ) {
if( !you.has_trait( prereq ) ) {
has_prereq = false;
break;
}
}
if( has_prereq ) {
++iter;
} else {
iter = attunements.erase( iter );
}
}
if( attunements.empty() ) {
// the player doesn't have at least two base classes
you.add_msg_if_player( _( "This altar gives you the creeps." ) );
return;
}
// remove the attunements the player has conflicts for
for( auto iter = attunements.begin(); iter != attunements.end(); ) {
if( !you.has_opposite_trait( *iter ) && you.mutation_ok( *iter, true, true, true ) ) {
++iter;
} else {
iter = attunements.erase( iter );
}
}
if( attunements.empty() ) {
you.add_msg_if_player( _( "You've attained what you can for now." ) );
return;
}
for( auto iter = attunements.begin(); iter != attunements.end(); ) {
if( has_attunement_spell_prereqs( you, *iter ) ) {
++iter;
} else {
iter = attunements.erase( iter );
}
}
if( attunements.empty() ) {
you.add_msg_if_player( _( "You feel that the altar does not deem you worthy, yet." ) );
return;
}
uilist attunement_list;
attunement_list.title = _( "Pick an Attunement to show the world your Worth." );
for( const trait_id &attunement : attunements ) {
// There's no way for you to have this mutation, so a variant is pointless
attunement_list.addentry( attunement->name() );
}
attunement_list.query();
if( attunement_list.ret == UILIST_CANCEL ) {
you.add_msg_if_player( _( "Maybe later." ) );
return;
}
auto attunement_iter = attunements.begin();
std::advance( attunement_iter, attunement_list.ret );
const trait_id &attunement = *attunement_iter;
// There's no way for you to have this mutation, so a variant is pointless
if( query_yn( string_format( _( "Are you sure you want to pick %s? This selection is permanent." ),
attunement->name() ) ) ) {
you.toggle_trait( attunement );
// There's no way for you to have this mutation, so a variant is pointless
you.add_msg_if_player( m_info, attunement->desc() );
} else {
you.add_msg_if_player( _( "Maybe later." ) );
}
}

void iexamine::translocator( player &, const tripoint &examp )
{
// TODO: fix point types
Expand Down
2 changes: 2 additions & 0 deletions src/iexamine.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ void sign( player &p, const tripoint &examp );
void pay_gas( player &p, const tripoint &examp );
void ledge( player &p, const tripoint &examp );
void autodoc( player &p, const tripoint &examp );
bool has_attunement_spell_prereqs( Character &you, const trait_id &attunement )

Check failure on line 106 in src/iexamine.h

View workflow job for this annotation

GitHub Actions / Clang 14, Ubuntu, Tiles, NoSound, ASan, UBSan

expected ';' after top level declarator
void attunement_altar( Character &you, const tripoint &examp );

Check failure on line 107 in src/iexamine.h

View workflow job for this annotation

GitHub Actions / GCC 12, Ubuntu, Tiles, Sound, Lua, CMake, Languages

expected initializer before ‘void’

Check failure on line 107 in src/iexamine.h

View workflow job for this annotation

GitHub Actions / GCC 12, Ubuntu, Tiles, NoSound, ASan

expected initializer before ‘void’
void translocator( player &p, const tripoint &examp );
void on_smoke_out( const tripoint &examp,
const time_point &start_time ); //activates end of smoking effects
Expand Down
4 changes: 3 additions & 1 deletion src/mutation_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,9 @@ void mutation_branch::check_consistency()

nc_color mutation_branch::get_display_color() const
{
if( threshold || profession ) {
if( flags.count( STATIC( json_character_flag( "ATTUNEMENT" ) ) ) ) {
return c_green;
} else if( threshold || profession ) {
return c_white;
} else if( debug ) {
return c_light_cyan;
Expand Down

0 comments on commit 376a52b

Please sign in to comment.