Skip to content

Commit d95fd20

Browse files
authored
Merge pull request #2841 from ivan-mogilko/ags4--frameevents
AGS 4: View Frame events
2 parents 33c34b5 + 6d08efc commit d95fd20

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+1769
-877
lines changed

Common/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ target_sources(common
7979
game/room_version.h
8080
game/roomstruct.cpp
8181
game/roomstruct.h
82-
game/scripteventstable.cpp
83-
game/scripteventstable.h
82+
game/scripteventtable.cpp
83+
game/scripteventtable.h
8484
game/tra_file.cpp
8585
game/tra_file.h
8686
gfx/allegrobitmap.cpp

Common/ac/characterinfo.cpp

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,31 +19,30 @@
1919

2020
using namespace AGS::Common;
2121

22+
/* static */ ScriptEventSchema CharacterInfo::_eventSchema = {{
23+
{ "OnAnyClick", kCharacterEvent_AnyClick },
24+
{ "OnFrameEvent", kCharacterEvent_OnFrameEvent },
25+
}};
26+
2227
void CharacterInfo::RemapOldInteractions()
2328
{
24-
ScriptEventHandlers new_interactions;
29+
std::vector<ScriptEventHandler> old_interactions = interactions.GetHandlers();
30+
std::vector<ScriptEventHandler> new_interactions;
2531
// this is just for safety, it's supposed to be that large
26-
interactions.Handlers.resize(NUM_STANDARD_VERBS);
27-
new_interactions.Handlers.resize(NUM_STANDARD_VERBS);
28-
new_interactions.Handlers[MODE_WALK] = {};
29-
new_interactions.Handlers[MODE_LOOK] = interactions.Handlers[0];
30-
new_interactions.Handlers[MODE_HAND] = interactions.Handlers[1];
31-
new_interactions.Handlers[MODE_TALK] = interactions.Handlers[2];
32-
new_interactions.Handlers[MODE_USE] = interactions.Handlers[3];
33-
new_interactions.Handlers[MODE_PICKUP] = interactions.Handlers[5];
34-
new_interactions.Handlers[MODE_CUSTOM1] = interactions.Handlers[6];
35-
new_interactions.Handlers[MODE_CUSTOM2] = interactions.Handlers[7];
36-
37-
events.EventMap["OnAnyClick"] = interactions.Handlers[4].FunctionName;
38-
interactions = std::move(new_interactions);
39-
interactions.ScriptModule = events.ScriptModule;
40-
}
32+
old_interactions.resize(NUM_STANDARD_VERBS);
33+
new_interactions.resize(NUM_STANDARD_VERBS);
34+
new_interactions[MODE_WALK] = {};
35+
new_interactions[MODE_LOOK] = old_interactions[0];
36+
new_interactions[MODE_HAND] = old_interactions[1];
37+
new_interactions[MODE_TALK] = old_interactions[2];
38+
new_interactions[MODE_USE] = old_interactions[3];
39+
new_interactions[MODE_PICKUP] = old_interactions[5];
40+
new_interactions[MODE_CUSTOM1] = old_interactions[6];
41+
new_interactions[MODE_CUSTOM2] = old_interactions[7];
4142

42-
void CharacterInfo::ResolveEventHandlers()
43-
{
44-
events.CreateIndexedList(std::vector<String>() = {
45-
"OnAnyClick"
46-
});
43+
_events.SetHandler(kCharacterEvent_AnyClick, old_interactions[4].FunctionName);
44+
interactions.SetScriptModule(_events.GetScriptModule());
45+
interactions.SetHandlers(std::move(new_interactions));
4746
}
4847

4948
void CharacterInfo::ReadBaseFields(Stream *in)

Common/ac/characterinfo.h

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include "core/types.h"
2020
#include "ac/common_defines.h" // constants
2121
#include "ac/game_version.h"
22-
#include "game/scripteventstable.h"
22+
#include "game/scripteventtable.h"
2323
#include "util/bbop.h"
2424
#include "util/string_types.h"
2525

@@ -120,7 +120,9 @@ enum CharacterSvgVersion
120120
enum CharacterEventID
121121
{
122122
// an interaction with any cursor mode that normally has a event
123-
kCharacterEvent_AnyClick = 0
123+
kCharacterEvent_AnyClick,
124+
// a view frame triggering a custom event
125+
kCharacterEvent_OnFrameEvent,
124126
};
125127

126128
// Design-time Character data.
@@ -170,8 +172,9 @@ struct CharacterInfo
170172
AGS::Common::String name = {}; // regular name (aka description)
171173
// Interaction events (cursor-based)
172174
AGS::Common::ScriptEventHandlers interactions = {};
173-
// Common events
174-
AGS::Common::ScriptEventsTable events = {};
175+
176+
// Gets a events schema corresponding to this object's type
177+
static const AGS::Common::ScriptEventSchema &GetEventSchema() { return CharacterInfo::_eventSchema; }
175178

176179
int get_baseline() const; // return baseline, or Y if not set
177180
int get_blocking_top() const; // return Y - BlockingHeight/2
@@ -221,10 +224,19 @@ struct CharacterInfo
221224
flags = (flags & ~CHF_BEHINDSHEPHERD) | (CHF_BEHINDSHEPHERD * sort_behind);
222225
}
223226

227+
CharacterInfo() = default;
228+
CharacterInfo(const CharacterInfo&) = default;
229+
CharacterInfo(CharacterInfo &&) = default;
230+
231+
CharacterInfo &operator = (const CharacterInfo&) = default;
232+
CharacterInfo &operator = (CharacterInfo&&) = default;
233+
234+
// Provides a script events table
235+
const AGS::Common::ScriptEventTable &GetEvents() const { return _events; }
236+
AGS::Common::ScriptEventTable &GetEvents() { return _events; }
237+
224238
// Remaps old-format interaction list into new event table
225239
void RemapOldInteractions();
226-
// Generate indexed handlers list from the event handlers map
227-
void ResolveEventHandlers();
228240

229241
void ReadFromFile(Common::Stream *in, GameDataVersion data_ver);
230242
void WriteToFile(Common::Stream *out) const;
@@ -237,6 +249,11 @@ struct CharacterInfo
237249
// common for both game file and save.
238250
void ReadBaseFields(Common::Stream *in);
239251
void WriteBaseFields(Common::Stream *out) const;
252+
253+
// Script events schema
254+
static AGS::Common::ScriptEventSchema _eventSchema;
255+
// Common events
256+
AGS::Common::ScriptEventTable _events = AGS::Common::ScriptEventTable(&CharacterInfo::_eventSchema);
240257
};
241258

242259
#endif // __AC_CHARACTERINFO_H

Common/ac/gamesetupstruct.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#include "ac/mousecursor.h"
2727
#include "ac/dynobj/scriptaudioclip.h"
2828
#include "game/customproperties.h"
29-
#include "game/scripteventstable.h"
29+
#include "game/scripteventtable.h"
3030
#include "game/main_game_file.h" // TODO: constants to separate header or split out reading functions
3131
#include "gui/guidefines.h"
3232

Common/ac/inventoryiteminfo.cpp

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,29 @@
1818

1919
using namespace AGS::Common;
2020

21+
/* static */ ScriptEventSchema InventoryItemInfo::_eventSchema = {{
22+
{ "OnAnyClick", kInventoryEvent_AnyClick }
23+
}};
24+
2125
void InventoryItemInfo::RemapOldInteractions()
2226
{
23-
ScriptEventHandlers new_interactions;
27+
std::vector<ScriptEventHandler> old_interactions = interactions.GetHandlers();
28+
std::vector<ScriptEventHandler> new_interactions;
2429
// this is just for safety, it's supposed to be that large
25-
interactions.Handlers.resize(NUM_STANDARD_VERBS);
26-
new_interactions.Handlers.resize(NUM_STANDARD_VERBS);
27-
new_interactions.Handlers[MODE_WALK] = {};
28-
new_interactions.Handlers[MODE_LOOK] = interactions.Handlers[0];
29-
new_interactions.Handlers[MODE_HAND] = interactions.Handlers[1];
30-
new_interactions.Handlers[MODE_TALK] = interactions.Handlers[2];
31-
new_interactions.Handlers[MODE_USE] = interactions.Handlers[3];
30+
old_interactions.resize(NUM_STANDARD_VERBS);
31+
new_interactions.resize(NUM_STANDARD_VERBS);
32+
new_interactions[MODE_WALK] = {};
33+
new_interactions[MODE_LOOK] = old_interactions[0];
34+
new_interactions[MODE_HAND] = old_interactions[1];
35+
new_interactions[MODE_TALK] = old_interactions[2];
36+
new_interactions[MODE_USE] = old_interactions[3];
3237
// "Other click" event handler is assigned to any other standard interaction
33-
new_interactions.Handlers[MODE_PICKUP] = interactions.Handlers[4];
34-
new_interactions.Handlers[MODE_CUSTOM1] = interactions.Handlers[4];
35-
new_interactions.Handlers[MODE_CUSTOM2] = interactions.Handlers[4];
36-
37-
interactions = std::move(new_interactions);
38-
interactions.ScriptModule = events.ScriptModule;
39-
}
38+
new_interactions[MODE_PICKUP] = old_interactions[4];
39+
new_interactions[MODE_CUSTOM1] = old_interactions[4];
40+
new_interactions[MODE_CUSTOM2] = old_interactions[4];
4041

41-
void InventoryItemInfo::ResolveEventHandlers()
42-
{
43-
events.CreateIndexedList(std::vector<String>() = {
44-
"OnAnyClick"
45-
});
42+
interactions.SetScriptModule(_events.GetScriptModule());
43+
interactions.SetHandlers(std::move(new_interactions));
4644
}
4745

4846
void InventoryItemInfo::ReadFromFile(Stream *in)

Common/ac/inventoryiteminfo.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#ifndef __AC_INVENTORYITEMINFO_H
1515
#define __AC_INVENTORYITEMINFO_H
1616

17-
#include "game/scripteventstable.h"
17+
#include "game/scripteventtable.h"
1818
#include "util/stream.h"
1919
#include "util/string.h"
2020
#include "util/string_types.h"
@@ -37,18 +37,26 @@ struct InventoryItemInfo
3737
uint8_t flags = 0u; // IFLG_STARTWITH
3838
// Interaction events (cursor-based)
3939
AGS::Common::ScriptEventHandlers interactions = {};
40-
// Common events
41-
AGS::Common::ScriptEventsTable events = {};
4240

41+
// Gets a events schema corresponding to this object's type
42+
static const AGS::Common::ScriptEventSchema &GetEventSchema() { return InventoryItemInfo::_eventSchema; }
43+
44+
// Provides a script events table
45+
const AGS::Common::ScriptEventTable &GetEvents() const { return _events; }
46+
AGS::Common::ScriptEventTable &GetEvents() { return _events; }
4347
// Remaps old-format interaction list into new event table
4448
void RemapOldInteractions();
45-
// Generate indexed handlers list from the event handlers map
46-
void ResolveEventHandlers();
4749

4850
void ReadFromFile(AGS::Common::Stream *in);
4951
void WriteToFile(AGS::Common::Stream *out);
5052
void ReadFromSavegame(AGS::Common::Stream *in);
5153
void WriteToSavegame(AGS::Common::Stream *out) const;
54+
55+
private:
56+
// Script events schema
57+
static AGS::Common::ScriptEventSchema _eventSchema;
58+
// Common events
59+
AGS::Common::ScriptEventTable _events = AGS::Common::ScriptEventTable(&InventoryItemInfo::_eventSchema);
5260
};
5361

5462
#endif // __AC_INVENTORYITEMINFO_H

Common/ac/view.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <vector>
1818
#include "gfx/gfx_def.h"
19+
#include "util/string.h"
1920

2021
namespace AGS { namespace Common { class Stream; } }
2122
using namespace AGS; // FIXME later
@@ -29,6 +30,8 @@ struct ViewFrame
2930
Common::SpriteTransformFlags flags = Common::kSprTf_None;
3031
int sound = -1; // play sound when this frame comes round
3132
int reserved_for_future[2] = { 0 }; // kept only for plugin api // CLNUP: may remove in ags4?
33+
Common::String event_name;
34+
3235
ViewFrame() = default;
3336

3437
void ReadFromFile(Common::Stream *in);

Common/game/data_helpers.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
//
1717
//=============================================================================
1818

19+
#include "game/scripteventtable.h"
1920
#include "util/error.h"
2021
#include "util/stream.h"
2122
#include "util/string.h"
@@ -33,5 +34,59 @@ inline bool ReadAndAssertCount(Stream *in, const char *objname, uint32_t expecte
3334
return !err.HasError();
3435
}
3536

37+
// Reads ScriptEventSchema and ScriptEventsTables for an object list.
38+
// The object list is assumed to be already precreated.
39+
// NOTE: if there will be an issue with the Events member (diff name, protected),
40+
// then we would require a method that sets handlers into object's event table.
41+
// NOTE: made this a template function, because majority of objects in the engine
42+
// do not have a shared parent class (also we work with a vector of them here...).
43+
// Revise this later?
44+
template <typename TObj, typename TObjIter>
45+
HError ReadScriptEventsTablesForObjects(TObjIter begin, TObjIter end, const char *objname, Stream *in)
46+
{
47+
// TODO: figure out a more optimal way for handling all the operations here,
48+
// perhaps join schema read and remap into the member of the ScriptEventSchema class?
49+
// join Handlers read and remap? anything else that may be improved?
50+
ScriptEventSchema schema;
51+
HError err = schema.Read(in);
52+
if (!err)
53+
return err;
54+
std::vector<uint32_t> remap;
55+
const bool must_remap = schema.CreateRemap(TObj::GetEventSchema(), remap);
56+
57+
size_t obj_count = end - begin;
58+
if (!ReadAndAssertCount(in, objname, static_cast<uint32_t>(obj_count), err))
59+
return err;
60+
61+
ScriptEventHandlers handlers;
62+
for (size_t i = 0; i < obj_count; ++i)
63+
{
64+
err = handlers.Read(in);
65+
if (!err)
66+
return err;
67+
if (must_remap)
68+
handlers.Remap(remap);
69+
(*(begin + i)).GetEvents().SetHandlers(handlers);
70+
}
71+
return HError::None();
72+
}
73+
74+
// Reads ScriptEventSchema and ScriptEventsTables for an object list.
75+
// This is a variant for the objects stored in a std::vector
76+
template <typename TObj>
77+
HError ReadScriptEventsTablesForObjects(std::vector<TObj> &objs, const char *objname, Stream *in)
78+
{
79+
return ReadScriptEventsTablesForObjects<TObj, typename std::vector<TObj>::iterator>(objs.begin(), objs.end(), objname, in);
80+
}
81+
82+
// Reads ScriptEventSchema and ScriptEventsTables for an object list.
83+
// This is a variant for the objects stored in a C-style array.
84+
// TODO: store these in a vector too at some point, and remove this variant.
85+
template <typename TObj, size_t ObjListSize>
86+
HError ReadScriptEventsTablesForObjects(TObj (&objs)[ObjListSize], size_t obj_count, const char *objname, Stream *in)
87+
{
88+
return ReadScriptEventsTablesForObjects<TObj, TObj*>(objs, objs + obj_count, objname, in);
89+
}
90+
3691
} // namespace Common
3792
} // namespace AGS

0 commit comments

Comments
 (0)