diff options
| author | fusion32 <marcopuzziello@gmail.com> | 2025-05-28 00:39:29 -0300 |
|---|---|---|
| committer | fusion32 <marcopuzziello@gmail.com> | 2025-05-28 00:39:29 -0300 |
| commit | 5505f28c358a50e9d610784303485cc757459162 (patch) | |
| tree | 7756da65dde0d3c125ae71f2ce2afdeb7dc8cd54 | |
| parent | 42959207914208438261810757abea43422a28fe (diff) | |
| download | game-5505f28c358a50e9d610784303485cc757459162.tar.gz game-5505f28c358a50e9d610784303485cc757459162.zip | |
finish objects.cc
| -rw-r--r-- | TODO.md | 2 | ||||
| -rw-r--r-- | reference/enums.hh | 30 | ||||
| -rw-r--r-- | reference/game.c | 689 | ||||
| -rw-r--r-- | src/enums.hh | 30 | ||||
| -rw-r--r-- | src/main.cc | 5 | ||||
| -rw-r--r-- | src/map.cc | 5 | ||||
| -rw-r--r-- | src/map.hh | 1 | ||||
| -rw-r--r-- | src/objects.cc | 487 | ||||
| -rw-r--r-- | src/objects.hh | 19 | ||||
| -rw-r--r-- | src/stubs.hh | 3 |
10 files changed, 521 insertions, 750 deletions
@@ -1,6 +1,4 @@ ## TODO NEXT -- MAP.CC -- OBJECTS.CC - STRINGS.CC - TCreature - TPlayer diff --git a/reference/enums.hh b/reference/enums.hh index 6a84666..ed42c26 100644 --- a/reference/enums.hh +++ b/reference/enums.hh @@ -85,36 +85,6 @@ enum ConditionType: int { CONDITION_RANDOM=25 }; -enum SPECIALMEANING: int { - MONEY_ONE=1, - MONEY_HUNDRED=2, - MONEY_TENTHOUSAND=3, - INVENTORY_RIGHTHAND=10, - INVENTORY_LEFTHAND=11, - INVENTORY_BODY_MALE=12, - INVENTORY_BODY_FEMALE=13, - INVENTORY_CONTAINER=14, - INVENTORY_FOOD=15, - DEPOT_LOCKER=20, - DEPOT_CHEST=21, - PARCEL_NEW=22, - PARCEL_STAMPED=23, - PARCEL_LABEL=24, - LETTER_NEW=25, - LETTER_STAMPED=26, - BLOOD_SPLASH=30, - BLOOD_POOL=31, - RUNE_BLANK=40, - MAGICFIELD_FIRE_DANGEROUS=41, - MAGICFIELD_FIRE_HARMLESS=42, - MAGICFIELD_POISON_DANGEROUS=43, - MAGICFIELD_POISON_HARMLESS=44, - MAGICFIELD_ENERGY_DANGEROUS=45, - MAGICFIELD_ENERGY_HARMLESS=46, - MAGICFIELD_MAGICWALL=47, - MAGICFIELD_RUSHWOOD=48 -}; - enum TWriterThreadReplyType: int { REPLY_BROADCAST=0, REPLY_DIRECT=1, diff --git a/reference/game.c b/reference/game.c index b8991a1..722a5aa 100644 --- a/reference/game.c +++ b/reference/game.c @@ -4398,695 +4398,6 @@ void __static_initialization_and_destruction_0(int __initialize_p,int __priority return;
}
-
-
-int GetFlagByName(char *Name)
-
-{
- int iVar1;
- int i;
- int iVar2;
- char (*s1) [20];
-
- iVar2 = 0;
- s1 = FlagNames;
- do {
- iVar1 = stricmp(*s1,Name,-1);
- if (iVar1 == 0) {
- return iVar2;
- }
- iVar2 = iVar2 + 1;
- s1 = s1 + 1;
- } while (iVar2 < 0x42);
- return -1;
-}
-
-
-
-int GetTypeAttributeByName(char *Name)
-
-{
- int iVar1;
- int i;
- int iVar2;
- char (*s1) [30];
-
- iVar2 = 0;
- s1 = TypeAttributeNames;
- do {
- iVar1 = stricmp(*s1,Name,-1);
- if (iVar1 == 0) {
- return iVar2;
- }
- iVar2 = iVar2 + 1;
- s1 = s1 + 1;
- } while (iVar2 < 0x3e);
- return -1;
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void LoadObjects(void)
-
-{
- FLAG FVar1;
- bool bVar2;
- bool bVar3;
- char cVar4;
- char *pcVar5;
- TObjectType *pTVar6;
- ulong uVar7;
- int iVar8;
- uint uVar9;
- int iVar10;
- int TypeID;
- int i;
- FLAG FVar11;
- char *pcVar12;
- undefined1 uVar13;
- char *pcVar14;
- char (*local_5084) [20];
- char (*local_5080) [30];
- int local_5074;
- uchar b;
- char *local_5050;
- int local_5048;
- int i_2;
- int Offset;
- char local_501c [4];
- char Ident [30];
- TReadScriptFile Script;
- char local_101c [4];
- char FileName [4096];
-
- local_5050 = local_101c;
- pcVar14 = DATAPATH;
- sprintf(local_5050,"%s/objects.srv");
- // try { // try from 08054e09 to 08054e0d has its CatchHandler @ 08055640
- TReadScriptFile::TReadScriptFile((TReadScriptFile *)(Ident + 0x1c));
- // try { // try from 08054e1b to 080555fd has its CatchHandler @ 08055620
- TReadScriptFile::open((TReadScriptFile *)(Ident + 0x1c),local_5050,(int)pcVar14);
- pcVar14 = (char *)0xffffffff;
-LAB_08054e25:
- TReadScriptFile::nextToken((TReadScriptFile *)(Ident + 0x1c));
- if (stack0xffffb004 == 0) {
- TReadScriptFile::close((TReadScriptFile *)(Ident + 0x1c),(int)local_5050);
- // try { // try from 08055607 to 0805560b has its CatchHandler @ 08055640
- TReadScriptFile::~TReadScriptFile((TReadScriptFile *)(Ident + 0x1c),(int)local_5050);
- return;
- }
- uVar13 = stack0xffffb004 == 1;
- if (!(bool)uVar13) {
- TReadScriptFile::error((TReadScriptFile *)(Ident + 0x1c),"Identifier expected");
- }
- pcVar5 = TReadScriptFile::getIdentifier((TReadScriptFile *)(Ident + 0x1c));
- strcpy(local_501c,pcVar5);
- local_5050 = (char *)0x3d;
- TReadScriptFile::readSymbol((TReadScriptFile *)(Ident + 0x1c),'=');
- iVar10 = 7;
- pcVar5 = local_501c;
- pcVar12 = "typeid";
- do {
- if (iVar10 == 0) break;
- iVar10 = iVar10 + -1;
- uVar13 = *pcVar5 == *pcVar12;
- pcVar5 = pcVar5 + 1;
- pcVar12 = pcVar12 + 1;
- } while ((bool)uVar13);
- if ((bool)uVar13) {
- pcVar14 = (char *)TReadScriptFile::readNumber((TReadScriptFile *)(Ident + 0x1c));
- pTVar6 = vector<>::operator()(&ObjectTypes,(int)pcVar14);
- pTVar6->Name = (char *)0x0;
- pTVar6 = vector<>::operator()(&ObjectTypes,(int)pcVar14);
- pTVar6->Description = (char *)0x0;
- pTVar6 = vector<>::operator()(&ObjectTypes,(int)pcVar14);
- pTVar6->Flags[0] = '\0';
- pTVar6->Flags[1] = '\0';
- pTVar6->Flags[2] = '\0';
- pTVar6->Flags[3] = '\0';
- iVar10 = 0;
- pTVar6->Flags[4] = '\0';
- pTVar6->Flags[5] = '\0';
- pTVar6->Flags[6] = '\0';
- pTVar6->Flags[7] = '\0';
- pTVar6->Flags[8] = '\0';
- do {
- pTVar6 = vector<>::operator()(&ObjectTypes,(int)pcVar14);
- pTVar6->Attributes[iVar10] = 0;
- iVar10 = iVar10 + 1;
- } while (iVar10 < 0x3e);
- iVar10 = 0;
- do {
- local_5050 = pcVar14;
- pTVar6 = vector<>::operator()(&ObjectTypes,(int)pcVar14);
- pTVar6->AttributeOffsets[iVar10] = -1;
- iVar10 = iVar10 + 1;
- } while (iVar10 < 0x12);
- }
- uVar13 = pcVar14 == (char *)0x0;
- if ((int)pcVar14 < 0) {
- local_5050 = "Invalid type id";
- TReadScriptFile::error((TReadScriptFile *)(Ident + 0x1c),"Invalid type id");
- }
- iVar10 = 5;
- pcVar5 = local_501c;
- pcVar12 = "name";
- do {
- if (iVar10 == 0) break;
- iVar10 = iVar10 + -1;
- uVar13 = *pcVar5 == *pcVar12;
- pcVar5 = pcVar5 + 1;
- pcVar12 = pcVar12 + 1;
- } while ((bool)uVar13);
- if ((bool)uVar13) {
- local_5050 = pcVar14;
- pTVar6 = vector<>::operator()(&ObjectTypes,(int)pcVar14);
- pcVar5 = TReadScriptFile::readString((TReadScriptFile *)(Ident + 0x1c));
- pcVar5 = AddStaticString(pcVar5);
- pTVar6->Name = pcVar5;
- }
- iVar10 = 0xc;
- pcVar5 = local_501c;
- pcVar12 = "description";
- do {
- if (iVar10 == 0) break;
- iVar10 = iVar10 + -1;
- uVar13 = *pcVar5 == *pcVar12;
- pcVar5 = pcVar5 + 1;
- pcVar12 = pcVar12 + 1;
- } while ((bool)uVar13);
- if ((bool)uVar13) {
- local_5050 = pcVar14;
- pTVar6 = vector<>::operator()(&ObjectTypes,(int)pcVar14);
- pcVar5 = TReadScriptFile::readString((TReadScriptFile *)(Ident + 0x1c));
- pcVar5 = AddStaticString(pcVar5);
- pTVar6->Description = pcVar5;
- }
- iVar10 = 6;
- pcVar5 = local_501c;
- pcVar12 = "flags";
- do {
- if (iVar10 == 0) break;
- iVar10 = iVar10 + -1;
- uVar13 = *pcVar5 == *pcVar12;
- pcVar5 = pcVar5 + 1;
- pcVar12 = pcVar12 + 1;
- } while ((bool)uVar13);
- if ((bool)uVar13) {
- TReadScriptFile::readSymbol((TReadScriptFile *)(Ident + 0x1c),'{');
-LAB_08055258:
- TReadScriptFile::nextToken((TReadScriptFile *)(Ident + 0x1c));
- if (stack0xffffb004 != 6) goto LAB_080552b0;
- cVar4 = TReadScriptFile::getSpecial((TReadScriptFile *)(Ident + 0x1c));
- i_2 = 0;
- local_5048 = 0;
- if (cVar4 != '}') goto code_r0x08055295;
- goto LAB_08055365;
- }
- goto LAB_08054f04;
-code_r0x08055295:
- if ((stack0xffffb004 != 6) ||
- (cVar4 = TReadScriptFile::getSpecial((TReadScriptFile *)(Ident + 0x1c)), cVar4 != ',')) {
-LAB_080552b0:
- pcVar5 = TReadScriptFile::getIdentifier((TReadScriptFile *)(Ident + 0x1c));
- iVar10 = 0;
- local_5084 = FlagNames;
- do {
- iVar8 = stricmp(*local_5084,pcVar5,-1);
- if (iVar8 == 0) goto LAB_08055307;
- local_5084 = local_5084 + 1;
- iVar10 = iVar10 + 1;
- } while (iVar10 < 0x42);
- iVar10 = -1;
-LAB_08055307:
- if (iVar10 == -1) {
- TReadScriptFile::error((TReadScriptFile *)(Ident + 0x1c),"Unknown flag");
- }
- pTVar6 = vector<>::operator()(&ObjectTypes,(int)pcVar14);
- iVar8 = iVar10 + 7;
- if (-1 < iVar10) {
- iVar8 = iVar10;
- }
- pTVar6->Flags[iVar8 >> 3] =
- pTVar6->Flags[iVar8 >> 3] |
- (byte)(1 << ((char)iVar10 - (char)((iVar8 >> 3) << 3) & 0x1fU));
- }
- goto LAB_08055258;
-LAB_08055365:
- do {
- bVar3 = false;
- bVar2 = false;
- if ((ObjectTypes.min <= (int)pcVar14) && ((int)pcVar14 <= ObjectTypes.max)) {
- bVar2 = true;
- }
- local_5050 = pcVar14;
- if (!bVar2) {
- error(&DAT_080f0a80,pcVar14);
- local_5050 = (char *)0x0;
- }
- FVar1 = InstanceAttributeFlags[local_5048];
- FVar11 = FVar1;
- if (0x7fffffff < FVar1) {
- FVar11 = FVar1 + USEEVENT;
- }
- uVar9 = 1 << ((char)FVar1 + (char)((int)FVar11 >> 3) * -8 & 0x1fU);
- pTVar6 = vector<>::operator()(&ObjectTypes,(int)local_5050);
- if ((uint)(pTVar6->Flags[(int)FVar11 >> 3] & (byte)uVar9) == (uVar9 & 0xff)) {
-LAB_08055442:
- bVar3 = true;
- }
- else if (local_5048 == 0) {
- bVar2 = false;
- if ((ObjectTypes.min <= (int)pcVar14) && (bVar2 = true, ObjectTypes.max < (int)pcVar14))
- {
- bVar2 = false;
- }
- local_5050 = pcVar14;
- if (!bVar2) {
- error(&DAT_080f0a80,pcVar14);
- local_5050 = (char *)0x0;
- }
- pTVar6 = vector<>::operator()(&ObjectTypes,(int)local_5050);
- if ((pTVar6->Flags[0] & 0x20) != 0) goto LAB_08055442;
- }
- if (bVar3) {
- local_5050 = pcVar14;
- pTVar6 = vector<>::operator()(&ObjectTypes,(int)pcVar14);
- pTVar6->AttributeOffsets[local_5048] = i_2;
- i_2 = i_2 + 1;
- }
- local_5048 = local_5048 + 1;
- uVar13 = local_5048 == 0x11;
- } while (local_5048 < 0x12);
-LAB_08054f04:
- iVar10 = 0xb;
- pcVar5 = local_501c;
- pcVar12 = "attributes";
- do {
- if (iVar10 == 0) break;
- iVar10 = iVar10 + -1;
- uVar13 = *pcVar5 == *pcVar12;
- pcVar5 = pcVar5 + 1;
- pcVar12 = pcVar12 + 1;
- } while ((bool)uVar13);
- if ((bool)uVar13) {
- local_5050 = (char *)0x7b;
- TReadScriptFile::readSymbol((TReadScriptFile *)(Ident + 0x1c),'{');
-LAB_08054f35:
- TReadScriptFile::nextToken((TReadScriptFile *)(Ident + 0x1c));
- if (stack0xffffb004 != 6) goto LAB_08054f7d;
- cVar4 = TReadScriptFile::getSpecial((TReadScriptFile *)(Ident + 0x1c));
- if (cVar4 != '}') goto code_r0x08054f62;
- }
- goto LAB_08054e25;
-code_r0x08054f62:
- if ((stack0xffffb004 != 6) ||
- (cVar4 = TReadScriptFile::getSpecial((TReadScriptFile *)(Ident + 0x1c)), cVar4 != ',')) {
-LAB_08054f7d:
- pcVar5 = TReadScriptFile::getIdentifier((TReadScriptFile *)(Ident + 0x1c));
- local_5074 = 0;
- local_5080 = TypeAttributeNames;
- do {
- iVar10 = stricmp(*local_5080,pcVar5,-1);
- if (iVar10 == 0) goto LAB_08054fde;
- local_5080 = local_5080 + 1;
- local_5074 = local_5074 + 1;
- } while (local_5074 < 0x3e);
- local_5074 = -1;
-LAB_08054fde:
- if (local_5074 == -1) {
- TReadScriptFile::error((TReadScriptFile *)(Ident + 0x1c),"Unknown attribute");
- }
- TReadScriptFile::readSymbol((TReadScriptFile *)(Ident + 0x1c),'=');
- local_5050 = pcVar14;
- pTVar6 = vector<>::operator()(&ObjectTypes,(int)pcVar14);
- uVar7 = TReadScriptFile::readNumber((TReadScriptFile *)(Ident + 0x1c));
- pTVar6->Attributes[local_5074] = uVar7;
- if (local_5074 == 0x3d) {
- local_5050 = pcVar14;
- pTVar6 = vector<>::operator()(&ObjectTypes,(int)pcVar14);
- uVar7 = pTVar6->Attributes[0x3d];
- bVar2 = false;
- if ((0 < (int)uVar7) && ((int)uVar7 < 0x32)) {
- bVar2 = true;
- }
- if (!bVar2) {
- local_5050 = "Unknown meaning";
- TReadScriptFile::error((TReadScriptFile *)(Ident + 0x1c),"Unknown meaning");
- }
- bVar2 = false;
- if ((ObjectTypes.min < 1) && ((uint)ObjectTypes.max < 0x80000000)) {
- bVar2 = true;
- }
- if (!bVar2) {
- local_5050 = (char *)0x0;
- error(&DAT_080f0a80);
- }
- bVar2 = false;
- if ((ObjectTypes.min < 1) && (bVar2 = true, ObjectTypes.max < 0)) {
- bVar2 = false;
- }
- if (!bVar2) {
- local_5050 = (char *)0x0;
- error(&DAT_080f0a80);
- }
- if (SpecialObjects[uVar7].TypeID != 0) {
- local_5050 = "Special object already defined";
- TReadScriptFile::error
- ((TReadScriptFile *)(Ident + 0x1c),"Special object already defined");
- }
- bVar2 = false;
- if ((ObjectTypes.min <= (int)pcVar14) && ((int)pcVar14 <= ObjectTypes.max)) {
- bVar2 = true;
- }
- pcVar5 = pcVar14;
- if (!bVar2) {
- local_5050 = pcVar14;
- error(&DAT_080f0a80);
- pcVar5 = (char *)0x0;
- }
- bVar2 = false;
- if ((ObjectTypes.min <= (int)pcVar5) && ((int)pcVar5 <= ObjectTypes.max)) {
- bVar2 = true;
- }
- if (!bVar2) {
- local_5050 = pcVar5;
- error(&DAT_080f0a80);
- pcVar5 = (char *)0x0;
- }
- iVar8 = ObjectTypes.max;
- iVar10 = ObjectTypes.min;
- SpecialObjects[uVar7].TypeID = (int)pcVar5;
- if ((int)pcVar5 < iVar10 || iVar8 < (int)pcVar5) {
- error(&DAT_080f0a80);
- local_5050 = pcVar5;
- }
- }
- }
- goto LAB_08054f35;
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void LoadConversionList(void)
-
-{
- istream *this;
- int i;
- int iVar1;
- undefined4 *puVar2;
- int local_1148;
- int Type;
- int Number;
- int Group;
- char FileName [4096];
- ifstream IN;
- undefined4 local_134 [3];
- uint auStack_128 [23];
- __basic_file<char> local_cc [25];
- undefined1 local_b3;
- undefined *local_ac;
- ios_base local_a8 [16];
- uint local_98;
-
- this = (istream *)(FileName + 0xffc);
- // try { // try from 0805566b to 0805566f has its CatchHandler @ 08055a21
- std::ios_base::ios_base(local_a8);
- local_ac = (undefined *)0x8128950;
- // try { // try from 0805568e to 08055692 has its CatchHandler @ 080559a2
- std::istream::istream(this,(streambuf *)(std::ifstream::VTT + 4));
- FileName._4092_4_ = &DAT_08128994;
- local_ac = &DAT_081289a8;
- // try { // try from 080556b2 to 080556b6 has its CatchHandler @ 0805599c
- std::filebuf::filebuf((filebuf *)local_134);
- // try { // try from 080556ca to 080556ce has its CatchHandler @ 08055955
- std::ios::init((EVP_PKEY_CTX *)&local_ac);
- iVar1 = 0;
- do {
- OldGroup[iVar1] = '\0';
- OldNumber[iVar1] = '\0';
- iVar1 = iVar1 + 1;
- } while (iVar1 < 0x2000);
- iVar1 = 0;
- do {
- NewType[iVar1] = -1;
- iVar1 = iVar1 + 1;
- } while (iVar1 < 0x10000);
- sprintf((char *)&Group,"%s/conversion.lst",DATAPATH);
- // try { // try from 08055742 to 08055831 has its CatchHandler @ 080559a8
- iVar1 = std::filebuf::open((char *)local_134,(int)&Group,8);
- if (iVar1 == 0) {
- std::ios::clear(this + *(int *)(FileName._4092_4_ + -0xc),
- *(uint *)((int)auStack_128 + *(int *)(FileName._4092_4_ + -0xc)) | 4);
- }
- if ((local_98 & 5) == 0) {
- while( true ) {
- std::istream::operator>>(this,&Number);
- if ((local_98 & 2) != 0) {
- iVar1 = std::filebuf::close((int)local_134);
- if (iVar1 == 0) {
- // try { // try from 08055904 to 0805594f has its CatchHandler @ 080559a8
- std::ios::clear(this + *(int *)(FileName._4092_4_ + -0xc),
- *(uint *)((int)auStack_128 + *(int *)(FileName._4092_4_ + -0xc))
- | 4);
- }
- iVar1 = 0;
- do {
- OldGroup[iVar1] = '\0';
- OldNumber[iVar1] = (uchar)iVar1;
- NewType[iVar1] = iVar1;
- iVar1 = iVar1 + 1;
- } while (iVar1 < 0xb);
- OldGroup[99] = 0xfa;
- NewType[64000] = 99;
- OldNumber[99] = '\0';
- FileName._4092_4_ = &DAT_08128994;
- local_ac = &DAT_081289a8;
- local_134[0] = 0x8128ad0;
- // try { // try from 08055899 to 080558de has its CatchHandler @ 08055a21
- std::filebuf::close((int)local_134);
- local_b3 = 0;
- std::__basic_file<char>::~__basic_file(local_cc);
- std::streambuf::~streambuf((streambuf *)local_134);
- std::istream::~istream(this);
- std::ios::~ios((ios *)&local_ac);
- return;
- }
- std::istream::operator>>(this,&Type);
- std::istream::operator>>(this,&local_1148);
- if (0x1ffe < local_1148 - 1U) break;
- OldGroup[local_1148] = (uchar)Number;
- OldNumber[local_1148] = (uchar)Type;
- NewType[Number * 0x100 + Type] = local_1148;
- }
- error(&DAT_080f0ae0,local_1148);
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = "Error while loading conversion.lst";
- }
- else {
- error(&DAT_080f0b60);
- puVar2 = (undefined4 *)__cxa_allocate_exception(4);
- *puVar2 = "Cannot open conversion.lst";
- }
- // WARNING: Subroutine does not return
- __cxa_throw(puVar2,char_const*::typeinfo,0);
-}
-
-
-
-ObjectType GetNewObjectType(uchar Group,uchar Number)
-
-{
- bool bVar1;
- int Type;
- uint uVar2;
- int iVar3;
- undefined3 in_stack_00000005;
- byte in_stack_0000000c;
-
- uVar2 = (uint)in_stack_0000000c;
- iVar3 = NewType[CONCAT11(Number,in_stack_0000000c)];
- if (iVar3 == -1) {
- error("GetNewObjectType: Objekttyp %d/%d existiert nicht.\n",(uint)Number,uVar2);
- bVar1 = false;
- if ((ObjectTypes.min < 1) && ((uint)ObjectTypes.max < 0x80000000)) {
- bVar1 = true;
- }
- if (!bVar1) {
- error(&DAT_080f0a80,0,uVar2);
- }
- *_Group = 0;
- }
- else {
- bVar1 = false;
- if ((ObjectTypes.min <= iVar3) && (iVar3 <= ObjectTypes.max)) {
- bVar1 = true;
- }
- if (!bVar1) {
- error(&DAT_080f0a80,iVar3);
- iVar3 = 0;
- }
- *_Group = iVar3;
- }
- return (ObjectType)(int)_Group;
-}
-
-
-
-void GetOldObjectType(ObjectType *Type,uchar *Group,uchar *Number)
-
-{
- int iVar1;
- bool bVar2;
-
- bVar2 = false;
- iVar1 = Type->TypeID;
- if ((ObjectTypes.min <= iVar1) && (iVar1 <= ObjectTypes.max)) {
- bVar2 = true;
- }
- if (bVar2) {
- *Group = OldGroup[iVar1];
- *Number = OldNumber[Type->TypeID];
- return;
- }
- error(&DAT_080f0be0);
- return;
-}
-
-
-
-bool ObjectTypeExists(uchar Group,uchar Number)
-
-{
- return (bool)((byte)~(byte)((uint)NewType[CONCAT11(Group,Number)] >> 0x18) >> 7);
-}
-
-ObjectType GetSpecialObject(SPECIALMEANING Meaning)
-
-{
- bool bVar1;
- int in_stack_00000008;
- char *Text;
- int _TypeID;
- ObjectType local_2c [7];
-
- bVar1 = false;
- if ((0 < in_stack_00000008) && (in_stack_00000008 < 0x32)) {
- bVar1 = true;
- }
- if (bVar1) {
- ObjectType::setTypeID(local_2c,0);
- _TypeID = SpecialObjects[in_stack_00000008].TypeID;
- if (_TypeID != local_2c[0].TypeID) goto LAB_08055ec3;
- Text = "GetSpecialObject: Kein Objekttyp mit Bedeutung %d definiert.\n";
- }
- else {
- Text = &DAT_080f0cc0;
- }
- error(Text);
- _TypeID = 0;
-LAB_08055ec3:
- ObjectType::setTypeID((ObjectType *)Meaning,_TypeID);
- return (ObjectType)Meaning;
-}
-
-
-
-ObjectType GetObjectTypeByName(char *SearchName,bool Movable)
-
-{
- TObjectType *pTVar1;
- char *pcVar2;
- int iVar3;
- char *ObjectName;
- int TypeID;
- int _TypeID;
- undefined3 in_stack_00000009;
- char in_stack_0000000c;
- ObjectType _TypeID_00;
- char local_dc [3];
- bool Movable_local;
- char Help [50];
- ObjectType local_9c [4];
- ObjectType local_8c [4];
- ObjectType local_7c;
- ObjectType Type;
- ObjectType local_6c;
- ObjectType BestType;
- char local_5c [4];
- char Pattern [50];
-
- if (_Movable == (char *)0x0) {
- error("GetObjectTypeByName: SearchName ist NULL.\n");
- _TypeID_00.TypeID = 0;
- }
- else {
- snprintf(local_5c,0x32," %s ",_Movable);
- ObjectType::setTypeID(&local_6c,0);
- ObjectType::setTypeID(&local_7c,99);
- _TypeID = local_7c.TypeID + 1;
- _TypeID_00.TypeID = local_6c.TypeID;
- if (_TypeID <= ObjectTypes.max) {
- do {
- ObjectType::setTypeID(&local_7c,_TypeID);
- if ((((in_stack_0000000c == '\0') ||
- (pTVar1 = vector<>::operator()(&ObjectTypes,local_7c.TypeID),
- (pTVar1->Flags[4] & 2) == 0)) &&
- (pcVar2 = ObjectType::getName(&local_7c), pcVar2 != (char *)0x0)) &&
- (*pcVar2 != '\0')) {
- iVar3 = stricmp(pcVar2,_Movable,-1);
- _TypeID_00.TypeID = local_7c.TypeID;
- if (iVar3 == 0) break;
- ObjectType::setTypeID(local_8c,0);
- ObjectType::setTypeID(local_9c,local_8c[0].TypeID);
- if (local_6c.TypeID == local_9c[0].TypeID) {
- snprintf(local_dc,0x32," %s ",pcVar2);
- pcVar2 = strstr(local_dc,local_5c);
- if (pcVar2 != (char *)0x0) {
- ObjectType::setTypeID(local_8c,local_7c.TypeID);
- ObjectType::setTypeID(&local_6c,local_8c[0].TypeID);
- ObjectType::setTypeID(local_9c,local_6c.TypeID);
- }
- }
- }
- _TypeID = _TypeID + 1;
- _TypeID_00.TypeID = local_6c.TypeID;
- } while (_TypeID <= ObjectTypes.max);
- }
- }
- ObjectType::setTypeID((ObjectType *)SearchName,_TypeID_00.TypeID);
- return (ObjectType)(int)SearchName;
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void InitObjects(void)
-
-{
- // try { // try from 08056126 to 0805612f has its CatchHandler @ 08056134
- LoadObjects();
- LoadConversionList();
- return;
-}
-
-
-
-// WARNING: Unknown calling convention -- yet parameter storage is locked
-
-void ExitObjects(void)
-
-{
- return;
-}
-
-
-
void __tcf_0(void *param_1)
{
diff --git a/src/enums.hh b/src/enums.hh index ea0d87a..f7aee3a 100644 --- a/src/enums.hh +++ b/src/enums.hh @@ -324,6 +324,36 @@ enum Skill: int { SKILL_SOUL = 22, }; +enum SPECIALMEANING: int { + MONEY_ONE = 1, + MONEY_HUNDRED = 2, + MONEY_TENTHOUSAND = 3, + INVENTORY_RIGHTHAND = 10, + INVENTORY_LEFTHAND = 11, + INVENTORY_BODY_MALE = 12, + INVENTORY_BODY_FEMALE = 13, + INVENTORY_CONTAINER = 14, + INVENTORY_FOOD = 15, + DEPOT_LOCKER = 20, + DEPOT_CHEST = 21, + PARCEL_NEW = 22, + PARCEL_STAMPED = 23, + PARCEL_LABEL = 24, + LETTER_NEW = 25, + LETTER_STAMPED = 26, + BLOOD_SPLASH = 30, + BLOOD_POOL = 31, + RUNE_BLANK = 40, + MAGICFIELD_FIRE_DANGEROUS = 41, + MAGICFIELD_FIRE_HARMLESS = 42, + MAGICFIELD_POISON_DANGEROUS = 43, + MAGICFIELD_POISON_HARMLESS = 44, + MAGICFIELD_ENERGY_DANGEROUS = 45, + MAGICFIELD_ENERGY_HARMLESS = 46, + MAGICFIELD_MAGICWALL = 47, + MAGICFIELD_RUSHWOOD = 48, +}; + enum SpellShapeType: int { SHAPE_ACTOR = 0, SHAPE_VICTIM = 1, diff --git a/src/main.cc b/src/main.cc index e0cf156..ecdb333 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,6 +1,7 @@ #include "common.hh" #include "config.hh" #include "map.hh" +#include "objects.hh" #include "stubs.hh" @@ -227,7 +228,7 @@ static void InitAll(void){ //InitStrings(); //InitWriter(); //InitReader(); - //InitObjects(); + InitObjects(); InitMap(); //InitInfo(); //InitMoveUse(); @@ -253,7 +254,7 @@ static void ExitAll(void){ //ExitInfo(); //ExitHouses(); ExitMap(SaveMapOn); - //ExitObjects(); + ExitObjects(); //ExitReader(); //ExitWriter(); //ExitStrings(); @@ -1830,9 +1830,7 @@ Object CreateObject(void){ return Object(NextObjectID); } -// TODO(fusion): This is only used from `DeleteObject`. Should probably be an -// internal helper. -void DestroyObject(Object Obj){ +static void DestroyObject(Object Obj){ if(!Obj.exists()){ error("DestroyObject: Übergebenes Objekt existiert nicht.\n"); return; @@ -1972,6 +1970,7 @@ void ChangeObject(Object Obj, INSTANCEATTRIBUTE Attribute, uint32 Value){ Obj.setAttribute(Attribute, Value); } +// TODO(fusion): This probably belongs to `operate.cc`. void ChangeObject(Object Obj, ObjectType NewType, uint32 Value){ if(!Obj.exists()){ error("ChangeObject: Übergebenes Objekt existiert nicht (1, NewType=%d).\n", NewType.TypeID); @@ -129,7 +129,6 @@ void ExitMap(bool Save); // NOTE(fusion): Object related functions. TObject *AccessObject(Object Obj); Object CreateObject(void); -void DestroyObject(Object Obj); void DeleteObject(Object Obj); void ChangeObject(Object Obj, ObjectType NewType); void ChangeObject(Object Obj, INSTANCEATTRIBUTE Attribute, uint32 Value); diff --git a/src/objects.cc b/src/objects.cc index de62aca..e6903cd 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -1,8 +1,17 @@ #include "objects.hh" +#include "config.hh" #include "containers.hh" +#include "script.hh" + +#include "stubs.hh" + +#include <fstream> static vector<TObjectType> ObjectTypes(0, 5000, 1000); static ObjectType SpecialObjects[49]; +static uint8 OldGroup[8192]; +static uint8 OldNumber[8192]; +static int NewType[65536]; static FLAG TypeAttributeFlags[62] = { BANK, // WAYPOINTS @@ -90,6 +99,140 @@ static FLAG InstanceAttributeFlags[18] = { WEAROUT, // REMAININGUSES }; +static const char FlagNames[66][30] = { + "Bank" // BANK + "Clip" // CLIP + "Bottom", // BOTTOM + "Top", // TOP + "Container", // CONTAINER + "Chest", // CHEST + "Cumulative", // CUMULATIVE + "UseEvent", // USEEVENT + "ChangeUse", // CHANGEUSE + "ForceUse", // FORCEUSE + "MultiUse", // MULTIUSE + "DistUse", // DISTUSE + "MovementEvent", // MOVEMENTEVENT + "CollisionEvent", // COLLISIONEVENT + "SeparationEvent", // SEPARATIONEVENT + "Key", // KEY + "KeyDoor", // KEYDOOR + "NameDoor", // NAMEDOOR + "LevelDoor", // LEVELDOOR + "QuestDoor", // QUESTDOOR + "Bed", // BED + "Food", // FOOD + "Rune", // RUNE + "Information", // INFORMATION + "Text", // TEXT + "Write", // WRITE + "WriteOnce", // WRITEONCE + "LiquidContainer", // LIQUIDCONTAINER + "LiquidSource", // LIQUIDSOURCE + "LiquidPool", // LIQUIDPOOL + "TeleportAbsolute", // TELEPORTABSOLUTE + "TeleportRelative", // TELEPORTRELATIVE + "Unpass", // UNPASS + "Unmove", // UNMOVE + "Unthrow", // UNTHROW + "Unlay", // UNLAY + "Avoid", // AVOID + "MagicField", // MAGICFIELD + "RestrictLevel", // RESTRICTLEVEL + "RestrictProfession", // RESTRICTPROFESSION + "Take", // TAKE + "Hang", // HANG + "HookSouth", // HOOKSOUTH + "HookEast", // HOOKEAST + "Rotate", // ROTATE + "Destroy", // DESTROY + "Clothes", // CLOTHES + "SkillBoost", // SKILLBOOST + "Protection", // PROTECTION + "Light", // LIGHT + "RopeSpot", // ROPESPOT + "Corpse", // CORPSE + "Expire", // EXPIRE + "ExpireStop", // EXPIRESTOP + "WearOut", // WEAROUT + "Weapon", // WEAPON + "Shield", // SHIELD + "Bow", // BOW + "Throw", // THROW + "Wand", // WAND + "Ammo", // AMMO + "Armor", // ARMOR + "Height", // HEIGHT + "Disguise", // DISGUISE + "ShowDetail", // SHOWDETAIL + "Special", // SPECIALOBJECT +}; + +static const char TypeAttributeNames[62][30] = { + "Waypoints", // WAYPOINTS + "Capacity", // CAPACITY + "ChangeTarget", // CHANGETARGET + "KeydoorTarget", // KEYDOORTARGET + "NamedoorTarget", // NAMEDOORTARGET + "LeveldoorTarget", // LEVELDOORTARGET + "QuestdoorTarget", // QUESTDOORTARGET + "Nutrition", // NUTRITION + "InformationType", // INFORMATIONTYPE + "FontSize", // FONTSIZE + "MaxLength", // MAXLENGTH + "MaxLengthOnce", // MAXLENGTHONCE + "SourceLiquidType", // SOURCELIQUIDTYPE + "AbsTeleportEffect", // ABSTELEPORTEFFECT + "RelTeleportDisplacement", // RELTELEPORTDISPLACEMENT + "RelTeleportEffect", // RELTELEPORTEFFECT + "AvoidDamageTypes", // AVOIDDAMAGETYPES + "MinimumLevel", // MINIMUMLEVEL + "Professions", // PROFESSIONS + "Weight", // WEIGHT + "RotateTarget", // ROTATETARGET + "DestroyTarget", // DESTROYTARGET + "BodyPosition", // BODYPOSITION + "SkillNumber", // SKILLNUMBER + "SkillModification", // SKILLMODIFICATION + "ProtectionDamageTypes", // PROTECTIONDAMAGETYPES + "DamageReduction", // DAMAGEREDUCTION + "Brightness", // BRIGHTNESS + "LightColor", // LIGHTCOLOR + "CorpseType", // CORPSETYPE + "TotalExpireTime", // TOTALEXPIRETIME + "ExpireTarget", // EXPIRETARGET + "TotalUses", // TOTALUSES + "WearoutTarget", // WEAROUTTARGET + "WeaponType", // WEAPONTYPE + "WeaponAttackValue", // WEAPONATTACKVALUE + "WeaponDefendValue", // WEAPONDEFENDVALUE + "ShieldDefendValue", // SHIELDDEFENDVALUE + "BowRange", // BOWRANGE + "BowAmmoType", // BOWAMMOTYPE + "ThrowRange", // THROWRANGE + "ThrowAttackValue", // THROWATTACKVALUE + "ThrowDefendValue", // THROWDEFENDVALUE + "ThrowMissile", // THROWMISSILE + "ThrowSpecialEffect", // THROWSPECIALEFFECT + "ThrowEffectStrength", // THROWEFFECTSTRENGTH + "ThrowFragility", // THROWFRAGILITY + "WandRange", // WANDRANGE + "WandManaConsumption", // WANDMANACONSUMPTION + "WandAttackStrength", // WANDATTACKSTRENGTH + "WandAttackVariation", // WANDATTACKVARIATION + "WandDamageType", // WANDDAMAGETYPE + "WandMissile", // WANDMISSILE + "AmmoType", // AMMOTYPE + "AmmoAttackValue", // AMMOATTACKVALUE + "AmmoMissile", // AMMOMISSILE + "AmmoSpecialEffect", // AMMOSPECIALEFFECT + "AmmoEffectStrength", // AMMOEFFECTSTRENGTH + "ArmorValue", // ARMORVALUE + "Elevation", // ELEVATION + "DisguiseTarget", // DISGUISETARGET + "Meaning", // MEANING +}; + static const char InstanceAttributeNames[18][30] = { "Content", // CONTENT "ChestQuestNumber", // CHESTQUESTNUMBER @@ -111,10 +254,32 @@ static const char InstanceAttributeNames[18][30] = { "RemainingUses", // REMAININGUSES }; +// + +// BITSET Helpers +// ============================================================================= +static inline bool CheckBit(uint8 *Set, int Index){ + int ByteIndex = (int)(Index / 8); + uint8 BitMask = (uint8)(1 << (Index % 8)); + return (Set[ByteIndex] & BitMask) != 0; +} + +static inline void SetBit(uint8 *Set, int Index){ + int ByteIndex = (int)(Index / 8); + uint8 BitMask = (uint8)(1 << (Index % 8)); + Set[ByteIndex] |= BitMask; +} + +static inline void ClearBit(uint8 *Set, int Index){ + int ByteIndex = (int)(Index / 8); + uint8 BitMask = (uint8)(1 << (Index % 8)); + Set[ByteIndex] &= ~BitMask; +} + // ObjectType // ============================================================================= void ObjectType::setTypeID(int TypeID){ - if(TypeID < ObjectTypes.min || ObjectTypes.max < TypeID){ + if(!ObjectTypeExists(TypeID)){ error("ObjectType::setTypeID: Ungültiger Typ %d.\n", TypeID); TypeID = 0; } @@ -123,10 +288,8 @@ void ObjectType::setTypeID(int TypeID){ } bool ObjectType::getFlag(FLAG Flag){ - TObjectType *Type = ObjectTypes.at(this->TypeID); - int FlagIndex = (int)(Flag / 8); - uint8 FlagMask = (uint8)(1 << (Flag % 8)); - return (Type->Flags[FlagIndex] & FlagMask) != 0; + TObjectType *TypeP = ObjectTypes.at(this->TypeID); + return CheckBit(TypeP->Flags, (int)Flag); } uint32 ObjectType::getAttribute(TYPEATTRIBUTE Attribute){ @@ -136,23 +299,24 @@ uint32 ObjectType::getAttribute(TYPEATTRIBUTE Attribute){ return 0; } - TObjectType *Type = ObjectTypes.at(this->TypeID); - return Type->Attributes[Attribute]; + TObjectType *TypeP = ObjectTypes.at(this->TypeID); + return TypeP->Attributes[Attribute]; } int ObjectType::getAttributeOffset(INSTANCEATTRIBUTE Attribute){ if(!this->getFlag(InstanceAttributeFlags[Attribute])){ + // TODO(fusion): Review this? if(Attribute != CONTENT || !this->getFlag(CHEST)){ return -1; } } - TObjectType *Type = ObjectTypes.at(this->TypeID); - return Type->AttributeOffsets[Attribute]; + TObjectType *TypeP = ObjectTypes.at(this->TypeID); + return TypeP->AttributeOffsets[Attribute]; } const char *ObjectType::getName(int Count){ - if(this->TypeID == 99){ + if(this->isCreatureContainer()){ error("ObjectType::getName: Der Kreaturtyp hat keinen Namen.\n"); return NULL; } @@ -162,9 +326,9 @@ const char *ObjectType::getName(int Count){ // buffer. #if 0 char ObjectName[50]; - TObjectType *Type = ObjectTypes.at(this->TypeID); + TObjectType *TypeP = ObjectTypes.at(this->TypeID); if(Type->Name != NULL){ - strcpy(ObjectName, Type->Name); + strcpy(ObjectName, TypeP->Name); }else{ ObjectName[0] = 0; } @@ -175,15 +339,32 @@ const char *ObjectType::getName(int Count){ } const char *ObjectType::getDescription(void){ - TObjectType *Type = ObjectTypes.at(this->TypeID); - return Type->Description; + TObjectType *TypeP = ObjectTypes.at(this->TypeID); + return TypeP->Description; } // Object Type Related Functions // ============================================================================= -const char *GetInstanceAttributeName(int Attribute){ - ASSERT(Attribute >= 0 && Attribute <= 17); - return InstanceAttributeNames[Attribute]; +int GetFlagByName(const char *Name){ + int Result = -1; + for(int i = 0; i < NARRAY(FlagNames); i += 1){ + if(stricmp(FlagNames[i], Name) == 0){ + Result = i; + break; + } + } + return Result; +} + +int GetTypeAttributeByName(const char *Name){ + int Result = -1; + for(int i = 0; i < NARRAY(TypeAttributeNames); i += 1){ + if(stricmp(TypeAttributeNames[i], Name) == 0){ + Result = i; + break; + } + } + return Result; } int GetInstanceAttributeByName(const char *Name){ @@ -197,6 +378,278 @@ int GetInstanceAttributeByName(const char *Name){ return Result; } +const char *GetFlagName(int Flag){ + ASSERT(Flag >= 0 && Flag < NARRAY(FlagNames)); + return FlagNames[Flag]; +} + +const char *GetTypeAttributeName(int Attribute){ + ASSERT(Attribute >= 0 && Attribute < NARRAY(TypeAttributeFlags)); + return TypeAttributeNames[Attribute]; +} + +const char *GetInstanceAttributeName(int Attribute){ + ASSERT(Attribute >= 0 && Attribute < NARRAY(InstanceAttributeNames)); + return InstanceAttributeNames[Attribute]; +} + bool ObjectTypeExists(int TypeID){ return ObjectTypes.min <= TypeID && TypeID <= ObjectTypes.max; } + +// NOTE(fusion): Small helper to compute the index into the `NewType` array +// from old object type values. +static uint16 GetNewTypeIndex(uint8 Group, uint8 Number){ + return ((uint16)Group << 8) | (uint16)Number; +} + +bool ObjectTypeExists(uint8 Group, uint8 Number){ + // TODO(fusion): Check bounds? + return NewType[GetNewTypeIndex(Group, Number)] >= 0; +} + +ObjectType GetNewObjectType(uint8 Group, uint8 Number){ + int TypeID = NewType[GetNewTypeIndex(Group, Number)]; + if(TypeID < 0){ + error("GetNewObjectType: Objekttyp %u/%u existiert nicht.\n", Group, Number); + TypeID = 0; + } + + return ObjectType(TypeID); +} + +void GetOldObjectType(ObjectType Type, uint8 *Group, uint8 *Number){ + if(!ObjectTypeExists(Type.TypeID)){ + error("GetOldObjectType: Ungültiger Typ %d.\n", Type.TypeID); + return; + } + + // TODO(fusion): Check bounds? + *Group = OldGroup[Type.TypeID]; + *Number = OldNumber[Type.TypeID]; +} + +ObjectType GetSpecialObject(SPECIALMEANING Meaning){ + int TypeID = 0; + if(Meaning > 0 && Meaning < NARRAY(SpecialObjects)){ + TypeID = SpecialObjects[Meaning].TypeID; + if(TypeID == 0){ + error("GetSpecialObject: Kein Objekttyp mit Bedeutung %d definiert.\n", Meaning); + } + }else{ + error("GetSpecialObject: Ungültige Bedeutung %d.\n", Meaning); + } + return ObjectType(TypeID); +} + +ObjectType GetObjectTypeByName(const char *SearchName, bool Movable){ + if(SearchName == NULL){ + error("GetObjectTypeByName: SearchName ist NULL.\n"); + return ObjectType(); + } + + // NOTE(fusion): We add spaces around the search term to match whole words + // or sentences. This requires use to also add spaces around the searching + // text, in case the search term is at edge. + ObjectType BestMatch; + char Help[50]; + char Pattern[50]; + snprintf(Pattern, sizeof(Pattern), " %s ", SearchName); + for(int TypeID = TYPEID_CREATURE_CONTAINER + 1; + TypeID <= ObjectTypes.max; + TypeID += 1){ + ObjectType Type = TypeID; + if(!Movable || !Type.getFlag(UNMOVE)){ + const char *TypeName = Type.getName(-1); + if(TypeName && TypeName[0] != 0){ + if(stricmp(SearchName, TypeName) == 0){ + BestMatch = Type; + break; + } + + if(BestMatch.TypeID == 0){ + snprintf(Help, sizeof(Help), " %s ", TypeName); + if(strstr(Help, Pattern) != NULL){ + BestMatch = Type; + } + } + } + } + } + + return BestMatch; +} + +static void LoadObjects(void){ + char FileName[4096]; + snprintf(FileName, sizeof(FileName), "%s/objects.srv", DATAPATH); + + int TypeID = -1; + TReadScriptFile Script; + Script.open(FileName); + while(true){ + Script.nextToken(); + if(Script.Token == ENDOFFILE){ + Script.close(); + break; + } + + if(Script.Token != IDENTIFIER){ + Script.error("Identifier expected"); + } + + char Identifier[MAX_IDENT_LENGTH]; + strcpy(Identifier, Script.getIdentifier()); + Script.readSymbol('='); + + if(strcmp(Identifier, "typeid") == 0){ + TypeID = Script.readNumber(); + // NOTE(fusion): Initialize object type. + TObjectType *TypeP = ObjectTypes.at(TypeID); + memset(TypeP, 0, sizeof(TObjectType)); + for(int i = 0; i < NARRAY(TypeP->AttributeOffsets); i += 1){ + TypeP->AttributeOffsets[i] = -1; + } + }else{ + if(TypeID < 0){ + Script.error("Invalid type id"); + } + + TObjectType *TypeP = ObjectTypes.at(TypeID); + if(strcmp(Identifier, "name") == 0){ + TypeP->Name = AddStaticString(Script.readString()); + }else if(strcmp(Identifier, "description") == 0){ + TypeP->Description = AddStaticString(Script.readString()); + }else if(strcmp(Identifier, "flags") == 0){ + Script.readSymbol('{'); + while(true){ + Script.nextToken(); + if(Script.Token == SPECIAL){ + char Special = Script.getSpecial(); + if(Special == ',') continue; + if(Special == '}') break; + } + + int Flag = GetFlagByName(Script.getIdentifier()); + if(Flag == -1){ + Script.error("Unknown flag"); + } + + SetBit(TypeP->Flags, Flag); + } + + // NOTE(fusion): Assign instance attribute offsets after parsing flags. + int InstanceAttributeCount = 0; + for(int InstanceAttribute = 0; + InstanceAttribute < NARRAY(TypeP->AttributeOffsets); + InstanceAttribute += 1){ + // TODO(fusion): This thing with CONTENT, CONTAINER, and CHEST have + // been a trend so my guess it that CONTENT is the only instance + // attribute that has two flags (CONTAINER and CHEST), and we need + // to check it here. + if(CheckBit(TypeP->Flags, InstanceAttributeFlags[InstanceAttribute]) + || (InstanceAttribute == CONTENT && CheckBit(TypeP->Flags, CHEST))){ + TypeP->AttributeOffsets[InstanceAttribute] = InstanceAttributeCount; + InstanceAttributeCount += 1; + } + } + }else if(strcmp(Identifier, "attributes") == 0){ + Script.readSymbol('{'); + while(true){ + Script.nextToken(); + if(Script.Token == SPECIAL){ + char Special = Script.getSpecial(); + if(Special == ',') continue; + if(Special == '}') break; + } + + int TypeAttribute = GetTypeAttributeByName(Script.getIdentifier()); + if(TypeAttribute == -1){ + Script.error("Unknown attribute"); + } + + Script.readSymbol('='); + uint32 Value = (uint32)Script.readNumber(); + TypeP->Attributes[TypeAttribute] = Value; + if(TypeAttribute == MEANING){ + if(Value == 0 || Value >= NARRAY(SpecialObjects)){ + Script.error("Unknown meaning"); + } + + if(SpecialObjects[Value].TypeID != 0){ + Script.error("Special object already defined"); + } + + SpecialObjects[Value].setTypeID(TypeID); + } + } + }else{ + // TODO(fusion): + // error("Invalid object type field \"%s\"", Identifier); + } + } + } +} + +static void LoadConversionList(void){ + STATIC_ASSERT(NARRAY(OldGroup) == NARRAY(OldNumber)); + + for(int i = 0; i < NARRAY(OldGroup); i += 1){ + OldGroup[i] = 0; + OldNumber[i] = 0; + } + + for(int i = 0; i < NARRAY(NewType); i += 1){ + NewType[i] = -1; + } + + char FileName[4096]; + snprintf(FileName, sizeof(FileName), "%s/conversion.lst", DATAPATH); + std::ifstream IN(FileName, std::ios_base::in); + if(IN.fail()){ + error("LoadConversionList: Kann Datei %s nicht öffnen.\n", FileName); + throw "Cannot open conversion.lst"; + } + + while(true){ + int Group, Number, TypeID; + IN >> Group >> Number >> TypeID; + if(IN.fail()){ + // TODO(fusion): if(!IN.eof()) { error(...); } + IN.close(); + break; + } + + // TODO(fusion): Review this? + if(TypeID <= 0 || TypeID >= NARRAY(OldGroup)){ + error("LoadConversionList: Ungültiger Typ %d.\n", TypeID); + throw "Error while loading conversion.lst"; + } + + OldGroup[TypeID] = Group; + OldNumber[TypeID] = Number; + NewType[GetNewTypeIndex(Group, Number)] = TypeID; + } + + + // NOTE(fusion): Map and body containers. + for(int TypeID = 0; TypeID <= 10; TypeID += 1){ + OldGroup[TypeID] = 0; + OldNumber[TypeID] = (uint8)TypeID; + NewType[GetNewTypeIndex(0, (uint8)TypeID)] = TypeID; + } + + // NOTE(fusion): Creature container. + OldGroup[99] = 250; + OldNumber[00] = 0; + NewType[GetNewTypeIndex(250, 0)] = 99; +} + +void InitObjects(void){ + LoadObjects(); + LoadConversionList(); +} + +void ExitObjects(void){ + // no-op +} diff --git a/src/objects.hh b/src/objects.hh index eec0565..84801e3 100644 --- a/src/objects.hh +++ b/src/objects.hh @@ -66,17 +66,26 @@ struct ObjectType { }; struct TObjectType { - char *Name; - char *Description; + const char *Name; + const char *Description; uint8 Flags[9]; uint32 Attributes[62]; int AttributeOffsets[18]; }; -const char *GetInstanceAttributeName(int Attribute); +int GetFlagByName(const char *Name); +int GetTypeAttributeByName(const char *Name); int GetInstanceAttributeByName(const char *Name); +const char *GetFlagName(int Flag); +const char *GetTypeAttributeName(int Attribute); +const char *GetInstanceAttributeName(int Attribute); bool ObjectTypeExists(int TypeID); -//void InitObjects(void); -//void ExitObjects(void); +bool ObjectTypeExists(uint8 Group, uint8 Number); +ObjectType GetNewObjectType(uint8 Group, uint8 Number); +void GetOldObjectType(ObjectType Type, uint8 *Group, uint8 *Number); +ObjectType GetSpecialObject(SPECIALMEANING Meaning); +ObjectType GetObjectTypeByName(const char *SearchName, bool Movable); +void InitObjects(void); +void ExitObjects(void); #endif //TIBIA_OBJECTS_HH_ diff --git a/src/stubs.hh b/src/stubs.hh index d0b7d90..316a2fe 100644 --- a/src/stubs.hh +++ b/src/stubs.hh @@ -15,7 +15,8 @@ typedef void TRefreshSectorFunction(int SectorX, int SectorY, int SectorZ, const typedef void TSendMailsFunction(TPlayerData *PlayerData); extern void AbortWriter(void); -extern uint32 AddDynamicString(const char *Text); +extern uint32 AddDynamicString(const char *String); +extern const char *AddStaticString(const char *String); extern void AnnounceChangedCreature(uint32 CreatureID, int Type); extern void BroadcastMessage(int Mode, const char *Text, ...) ATTR_PRINTF(2, 3); extern void Change(Object Obj, ObjectType NewType, uint32 Value); |
