Various stuff
- Export of monster missiles and summons - Rendering support for custom PC graphics - Fix display of stats on startup screen - Fix implementation of animate attack node
This commit is contained in:
@@ -361,7 +361,7 @@ void draw_startup_stats() {
|
||||
}
|
||||
style.pointSize = 12;
|
||||
pc_rect.offset(12,16);
|
||||
std::string status = "Level " + univ.party[i].level;
|
||||
std::string status = "Level " + std::to_string(univ.party[i].level);
|
||||
switch(univ.party[i].main_status) {
|
||||
case eMainStatus::ALIVE:
|
||||
switch(univ.party[i].race) {
|
||||
|
@@ -270,14 +270,26 @@ void draw_pcs(location center,short mode) {
|
||||
(/*cartoon_happening ||*/ party_can_see(univ.party[i].combat_pos) < 6)){
|
||||
where_draw.x = univ.party[i].combat_pos.x - center.x + 4;
|
||||
where_draw.y = univ.party[i].combat_pos.y - center.y + 4;
|
||||
source_rect = calc_rect(2 * (univ.party[i].which_graphic / 8), univ.party[i].which_graphic % 8);
|
||||
if(univ.party[i].dir >= 4)
|
||||
source_rect.offset(28,0);
|
||||
if(combat_posing_monster == i)
|
||||
source_rect.offset(0,288);
|
||||
sf::Texture* from_gw;
|
||||
if(univ.party[i].which_graphic >= 1000) {
|
||||
bool isParty = univ.party[i].which_graphic >= 10000;
|
||||
pic_num_t need_pic = univ.party[i].which_graphic % 1000;
|
||||
if(univ.party[i].dir >= 4)
|
||||
need_pic++;
|
||||
if(combat_posing_monster == i)
|
||||
need_pic += 2;
|
||||
graf_pos_ref(from_gw, source_rect) = spec_scen_g.find_graphic(need_pic, isParty);
|
||||
} else {
|
||||
source_rect = calc_rect(2 * (univ.party[i].which_graphic / 8), univ.party[i].which_graphic % 8);
|
||||
if(univ.party[i].dir >= 4)
|
||||
source_rect.offset(28,0);
|
||||
if(combat_posing_monster == i)
|
||||
source_rect.offset(0,288);
|
||||
from_gw = &pc_gworld;
|
||||
}
|
||||
|
||||
if(mode == 0) {
|
||||
Draw_Some_Item(pc_gworld, source_rect, terrain_screen_gworld, where_draw, 1, 0);
|
||||
Draw_Some_Item(*from_gw, source_rect, terrain_screen_gworld, where_draw, 1, 0);
|
||||
}
|
||||
|
||||
if((current_pc == i) && (mode == 1) && !monsters_going) {
|
||||
@@ -470,14 +482,24 @@ void draw_party_symbol(location center) {
|
||||
|
||||
if((univ.party.in_boat < 0) && (univ.party.in_horse < 0)) {
|
||||
i = first_active_pc();
|
||||
source_rect = calc_rect(2 * (univ.party[current_pc].which_graphic / 8), univ.party[i].which_graphic % 8);
|
||||
if(univ.party[current_pc].dir >= 4)
|
||||
source_rect.offset(28,0);
|
||||
sf::Texture* from_gw;
|
||||
if(univ.party[i].which_graphic >= 1000) {
|
||||
bool isParty = univ.party[i].which_graphic >= 10000;
|
||||
pic_num_t need_pic = univ.party[i].which_graphic % 1000;
|
||||
if(univ.party[i].dir >= 4)
|
||||
need_pic++;
|
||||
graf_pos_ref(from_gw, source_rect) = spec_scen_g.find_graphic(need_pic, isParty);
|
||||
} else {
|
||||
source_rect = calc_rect(2 * (univ.party[current_pc].which_graphic / 8), univ.party[i].which_graphic % 8);
|
||||
if(univ.party[current_pc].dir >= 4)
|
||||
source_rect.offset(28,0);
|
||||
from_gw = &pc_gworld;
|
||||
}
|
||||
ter_num_t ter = is_out() ? univ.out[univ.party.p_loc.x][univ.party.p_loc.y] : univ.town->terrain(univ.town.p_loc.x,univ.town.p_loc.y);
|
||||
// now wedge in bed graphic
|
||||
if(is_town() && univ.scenario.ter_types[ter].special == eTerSpec::BED)
|
||||
draw_one_terrain_spot((short) target.x,(short) target.y,10000 + univ.scenario.ter_types[ter].flag1.u);
|
||||
else Draw_Some_Item(pc_gworld, source_rect, terrain_screen_gworld, target, 1, 0);
|
||||
else Draw_Some_Item(*from_gw, source_rect, terrain_screen_gworld, target, 1, 0);
|
||||
}
|
||||
else if(univ.party.in_boat >= 0) {
|
||||
if(univ.party.direction == 0 || univ.party.direction > 4) i = 4;
|
||||
|
@@ -4052,8 +4052,14 @@ void townmode_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
if(which_mode == eSpecCtx::TALK)
|
||||
break;
|
||||
i = combat_posing_monster;
|
||||
if(l.y >= 0) combat_posing_monster = monst_there(l);
|
||||
else combat_posing_monster = spec.ex1a;
|
||||
if(l.y >= 0) {
|
||||
int monst = monst_there(l);
|
||||
if(monst < 90)
|
||||
combat_posing_monster = 100 + monst;
|
||||
else combat_posing_monster = pc_there(l);
|
||||
if(combat_posing_monster == 6)
|
||||
combat_posing_monster = -1;
|
||||
} else combat_posing_monster = spec.ex1a;
|
||||
if(combat_posing_monster < 0 || combat_posing_monster >= univ.town->max_monst()) {
|
||||
combat_posing_monster = i;
|
||||
break;
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
|
||||
#include "classes.h"
|
||||
#include "oldstructs.h"
|
||||
@@ -856,6 +857,8 @@ cOutdoors* cCurOut::operator->() {
|
||||
cUniverse::cUniverse(long party_type) : party(*this, party_type), out(*this), town(*this) {}
|
||||
|
||||
void cUniverse::check_monst(cMonster& monst) {
|
||||
if(monst.see_spec == -2) return; // Avoid infinite recursion
|
||||
monst.see_spec = -2;
|
||||
if(monst.picture_num >= 10000) {
|
||||
int pic = monst.picture_num - 10000;
|
||||
int sz = pic / 1000, base = pic % 1000;
|
||||
@@ -865,7 +868,34 @@ void cUniverse::check_monst(cMonster& monst) {
|
||||
for(int i = 0; i < numGraph; i++)
|
||||
used_graphics.insert(base + i);
|
||||
} else if(monst.picture_num >= 1000) {
|
||||
update_monsters[monst.picture_num].insert(&monst);
|
||||
update_monsters[monst.picture_num - 1000].insert(&monst);
|
||||
}
|
||||
for(auto& abil : monst.abil) {
|
||||
switch(getMonstAbilCategory(abil.first)) {
|
||||
case eMonstAbilCat::MISSILE:
|
||||
if(abil.second.missile.pic >= 10000) {
|
||||
for(int i = 0; i < 4; i++)
|
||||
used_graphics.insert(abil.second.missile.pic - 10000 + i);
|
||||
} else if(abil.second.missile.pic >= 1000) {
|
||||
update_missiles[abil.second.missile.pic - 1000].insert(&abil.second.missile.pic);
|
||||
}
|
||||
break;
|
||||
case eMonstAbilCat::GENERAL:
|
||||
if(abil.second.gen.pic >= 10000) {
|
||||
for(int i = 0; i < 4; i++)
|
||||
used_graphics.insert(abil.second.gen.pic - 10000 + i);
|
||||
} else if(abil.second.gen.pic >= 1000) {
|
||||
update_missiles[abil.second.gen.pic - 1000].insert(&abil.second.gen.pic);
|
||||
}
|
||||
break;
|
||||
case eMonstAbilCat::SUMMON:
|
||||
check_monst(scenario.scen_monsters[abil.second.summon.type]);
|
||||
break;
|
||||
case eMonstAbilCat::RADIATE:
|
||||
case eMonstAbilCat::SPECIAL:
|
||||
case eMonstAbilCat::INVALID:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -886,7 +916,7 @@ void cUniverse::check_item(cItem& item) {
|
||||
for(int i = 0; i < 4; i++)
|
||||
used_graphics.insert(item.missile - 10000 + i);
|
||||
else if(item.missile >= 1000)
|
||||
update_missiles[item.missile - 1000].insert(&item);
|
||||
update_missiles[item.missile - 1000].insert(&item.missile);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -970,8 +1000,8 @@ void cUniverse::exportGraphics() {
|
||||
update_items.clear();
|
||||
for(auto pic : update_missiles) {
|
||||
pic_num_t pos = addGraphic(pic.first, PIC_MISSILE);
|
||||
for(auto& item : pic.second)
|
||||
item->missile = 10000 + pos;
|
||||
for(auto& missile : pic.second)
|
||||
*missile = 10000 + pos;
|
||||
}
|
||||
update_missiles.clear();
|
||||
for(auto pic : update_monsters) {
|
||||
@@ -1030,6 +1060,21 @@ void cUniverse::exportSummons() {
|
||||
used_monsters.insert(party.imprisoned_monst[i] - 10000);
|
||||
else need_monsters.insert(party.imprisoned_monst[i]);
|
||||
}
|
||||
std::stack<mon_num_t> last_check;
|
||||
for(mon_num_t m : need_monsters) last_check.push(m);
|
||||
while(!last_check.empty()) {
|
||||
mon_num_t monst = last_check.top();
|
||||
last_check.pop();
|
||||
if(scenario.scen_monsters[monst].abil[eMonstAbil::SUMMON].active) {
|
||||
mon_num_t summon = scenario.scen_monsters[monst].abil[eMonstAbil::SUMMON].summon.type;
|
||||
if(summon >= 10000)
|
||||
used_monsters.insert(summon - 10000);
|
||||
else if(!need_monsters.count(summon)) {
|
||||
last_check.push(summon);
|
||||
need_monsters.insert(summon);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Now that we know which exported summon slots are still in use and which new monsters need to be exported,
|
||||
// we can copy the monster records from the scenario record into the exported summon slots.
|
||||
if(used_monsters.empty()) party.summons.clear();
|
||||
|
@@ -154,9 +154,10 @@ enum eAmbientSound {
|
||||
|
||||
class cUniverse{
|
||||
template<typename T> using update_info = std::set<T*>;
|
||||
std::map<pic_num_t, update_info<cItem>> update_items, update_missiles;
|
||||
std::map<pic_num_t, update_info<cItem>> update_items;
|
||||
std::map<pic_num_t, update_info<cMonster>> update_monsters;
|
||||
std::map<pic_num_t, update_info<cPlayer>> update_pcs;
|
||||
std::map<pic_num_t, update_info<miss_num_t>> update_missiles;
|
||||
std::set<pic_num_t> used_graphics;
|
||||
pic_num_t addGraphic(pic_num_t pic, ePicType type);
|
||||
void check_monst(cMonster& monst);
|
||||
|
Reference in New Issue
Block a user