aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfusion32 <marcopuzziello@gmail.com>2025-07-21 19:23:42 -0300
committerfusion32 <marcopuzziello@gmail.com>2025-07-21 22:49:41 -0300
commite4b8bf807b76f6f446d9617d9a3957dc77dd6e90 (patch)
treef974c51ca7ea111c7e96990e39453ae5dba9a6c5
parent7b9e7dbbcf1d779419be8f22df812ff523a25450 (diff)
downloadgame-e4b8bf807b76f6f446d9617d9a3957dc77dd6e90.tar.gz
game-e4b8bf807b76f6f446d9617d9a3957dc77dd6e90.zip
multiple bug-fixes and improvements
- Make uint32 -> Object conversion explicit. This can be more verbose but will get a lot of small mistakes, especially with function overloads. - Fix problem with the path finder not including the last step when `MustReach` was false. - Fix problem with NPC conditions. - Fix problem with monster homes continuously spawning monsters. - Fix problem with creating the standard inventory. - Fix problem with creature timers (IMPORTANT). - Fix problem with `ThrowPossible` (IMPORTANT). - Fix problem with rune casting. - Fix problem with executing moveuse events. - Fix problem with `MoveRel` and `WriteName` moveuse actions. - Fix problem with eating food deleting the whole stack. - Many other bug-fixes and improvements.
-rw-r--r--TODO.md2
-rw-r--r--src/cract.cc26
-rw-r--r--src/crnonpl.cc11
-rw-r--r--src/crplayer.cc8
-rw-r--r--src/crskill.cc28
-rw-r--r--src/info.cc30
-rw-r--r--src/magic.cc8
-rw-r--r--src/map.cc18
-rw-r--r--src/map.hh2
-rw-r--r--src/moveuse.cc20
-rw-r--r--src/operate.cc49
-rw-r--r--src/query.cc1
-rw-r--r--src/receiving.cc4
-rw-r--r--src/sending.cc2
14 files changed, 111 insertions, 98 deletions
diff --git a/TODO.md b/TODO.md
index d1352f7..a7a2f84 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,3 +1,5 @@
+## TODO
+
## Synchronization
I'm not sure whether synchronization is done properly. The implementation of the first few `crplayer.cc` functions left me with a taste of race conditions although integer loads on x86 are generally atomic.
diff --git a/src/cract.cc b/src/cract.cc
index f30415d..41bbcca 100644
--- a/src/cract.cc
+++ b/src/cract.cc
@@ -151,7 +151,7 @@ void TShortway::Expand(TShortwayPoint *Node){
// add waypoints two more times.
int NeighborWaylength = MinNeighborWaylength;
if(OffsetX != 0 && OffsetY != 0){
- NeighborWaylength += Node->Waylength * 2;
+ NeighborWaylength += Node->Waypoints * 2;
}
if(NeighborWaylength < Neighbor->Waylength){
@@ -238,15 +238,12 @@ bool TShortway::Calculate(int DestX, int DestY, bool MustReach, int MaxSteps){
}
// NOTE(fusion): Walk back from the origin to reconstruct the path.
+ int CurDistance = std::max<int>(
+ std::abs(Node->x - DestX),
+ std::abs(Node->y - DestY));
Node = Node->Predecessor;
- while(Node != NULL && MaxSteps > 0){
- int MaxDistance = std::max<int>(
- std::abs(Node->x - DestX),
- std::abs(Node->y - DestY));
- if(!MustReach && MaxDistance <= 1){
- break;
- }
-
+ while(Node != NULL && MaxSteps > 0
+ && (MustReach || CurDistance > 1)){
TToDoEntry TD = {};
TD.Code = TDGo;
TD.Go.x = this->StartX + Node->x;
@@ -254,6 +251,9 @@ bool TShortway::Calculate(int DestX, int DestY, bool MustReach, int MaxSteps){
TD.Go.z = this->StartZ;
Creature->ToDoAdd(TD);
+ CurDistance = std::max<int>(
+ std::abs(Node->x - DestX),
+ std::abs(Node->y - DestY));
Node = Node->Predecessor;
MaxSteps -= 1;
}
@@ -768,22 +768,22 @@ void TCreature::Execute(void){
}
case TDMove:{
- this->Move(TD.Move.Obj, TD.Move.x, TD.Move.y, TD.Move.z, (uint8)TD.Move.Count);
+ this->Move(Object(TD.Move.Obj), TD.Move.x, TD.Move.y, TD.Move.z, (uint8)TD.Move.Count);
break;
}
case TDTrade:{
- this->Trade(TD.Trade.Obj, TD.Trade.Partner);
+ this->Trade(Object(TD.Trade.Obj), TD.Trade.Partner);
break;
}
case TDUse:{
- this->Use(TD.Use.Obj1, TD.Use.Obj2, TD.Use.Dummy);
+ this->Use(Object(TD.Use.Obj1), Object(TD.Use.Obj2), TD.Use.Dummy);
break;
}
case TDTurn:{
- this->Turn(TD.Turn.Obj);
+ this->Turn(Object(TD.Turn.Obj));
break;
}
diff --git a/src/crnonpl.cc b/src/crnonpl.cc
index 2e56f66..c425b02 100644
--- a/src/crnonpl.cc
+++ b/src/crnonpl.cc
@@ -324,7 +324,7 @@ TBehaviourDatabase::TBehaviourDatabase(TReadScriptFile *Script) :
Script->nextToken();
TBehaviourNode *Right = this->readTerm(Script);
Behaviour->addCondition(BEHAVIOUR_CONDITION_EXPRESSION,
- NewBehaviourNode(Operator, Right, Left));
+ NewBehaviourNode(Operator, Left, Right));
}else{
Script->nextToken();
}
@@ -1393,12 +1393,15 @@ void LoadMonsterhomes(void){
}
void ProcessMonsterhomes(void){
- for(int i = 0; i < Monsterhomes; i += 1){
+ for(int i = 1; i <= Monsterhomes; i += 1){
TMonsterhome *MH = Monsterhome.at(i);
- if(MH->Timer > 0){
- MH->Timer -= 1;
+
+ ASSERT(MH->Timer >= 0);
+ if(MH->Timer == 0){
+ continue;
}
+ MH->Timer -= 1;
if(MH->Timer > 0){
continue;
}
diff --git a/src/crplayer.cc b/src/crplayer.cc
index 8ecc926..621f103 100644
--- a/src/crplayer.cc
+++ b/src/crplayer.cc
@@ -657,10 +657,10 @@ void TPlayer::LoadInventory(bool SetStandardInventory){
Create(GetBodyContainer(this->ID, INVENTORY_LEFTHAND),
GetSpecialObject(DEFAULT_LEFTHAND), 0);
if(this->Sex == 1){
- Create(GetBodyContainer(this->ID, INVENTORY_LEFTHAND),
+ Create(GetBodyContainer(this->ID, INVENTORY_TORSO),
GetSpecialObject(DEFAULT_BODY_MALE), 0);
}else{
- Create(GetBodyContainer(this->ID, INVENTORY_LEFTHAND),
+ Create(GetBodyContainer(this->ID, INVENTORY_TORSO),
GetSpecialObject(DEFAULT_BODY_FEMALE), 0);
}
@@ -2559,7 +2559,7 @@ void SavePlayerData(TPlayerData *Slot){
break;
}
- if(FirstPosition){
+ if(!FirstPosition){
Script.writeText(",");
Script.writeLn();
Script.writeText(" ");
@@ -2581,7 +2581,7 @@ void SavePlayerData(TPlayerData *Slot){
DepotNr += 1){
if(Slot->Depot[DepotNr] != NULL){
TReadBuffer Buffer(Slot->Depot[DepotNr], Slot->DepotSize[DepotNr]);
- if(FirstDepot){
+ if(!FirstDepot){
Script.writeText(",");
Script.writeLn();
Script.writeText(" ");
diff --git a/src/crskill.cc b/src/crskill.cc
index e12e9c6..092e701 100644
--- a/src/crskill.cc
+++ b/src/crskill.cc
@@ -1201,20 +1201,18 @@ bool TSkillBase::SetSkills(int Race){
void TSkillBase::ProcessSkills(void){
int Index = 0;
- int End = this->FirstFreeTimer;
- while(Index < End){
+ while(Index < this->FirstFreeTimer){
// TODO(fusion): Probably remove if `Skill == NULL`?
TSkill *Skill = this->TimerList[Index];
- if(Skill && !Skill->Process()){
+ if(Skill != NULL && Skill->Process()){
// NOTE(fusion): A little swap and pop action.
- End -= 1;
- this->TimerList[Index] = this->TimerList[End];
- this->TimerList[End] = NULL;
+ this->FirstFreeTimer -= 1;
+ this->TimerList[Index] = this->TimerList[this->FirstFreeTimer];
+ this->TimerList[this->FirstFreeTimer] = NULL;
}else{
Index += 1;
}
}
- this->FirstFreeTimer = (uint16)End;
}
bool TSkillBase::SetTimer(uint16 SkNr, int Cycle, int Count, int MaxCount, int AdditionalValue){
@@ -1229,9 +1227,10 @@ bool TSkillBase::SetTimer(uint16 SkNr, int Cycle, int Count, int MaxCount, int A
TSkill *Skill = this->Skills[SkNr];
bool Result = Skill->SetTimer(Cycle, Count, MaxCount, AdditionalValue);
if(Result){
- // NOTE(fusion): A little push back action.
- // BUG(fusion): We don't check if there is room in `TimerList`. I'd assume
- // it is naturally bound by the maximum number of skills?
+ // NOTE(fusion): A little push back action. We don't check if there is
+ // room in `TimerList` because it should be naturally bound by the max
+ // number of skills.
+ ASSERT(this->FirstFreeTimer < NARRAY(this->TimerList));
this->TimerList[this->FirstFreeTimer] = Skill;
this->FirstFreeTimer += 1;
}
@@ -1249,13 +1248,12 @@ void TSkillBase::DelTimer(uint16 SkNr){
if(Skill != NULL){
Skill->DelTimer();
- int End = this->FirstFreeTimer;
- for(int Index = 0; Index < End; Index += 1){
+ for(int Index = 0; Index < this->FirstFreeTimer; Index += 1){
if(Skill == this->TimerList[Index]){
// NOTE(fusion): A little swap and pop action.
- End -= 1;
- this->TimerList[Index] = this->TimerList[End];
- this->TimerList[End] = NULL;
+ this->FirstFreeTimer -= 1;
+ this->TimerList[Index] = this->TimerList[this->FirstFreeTimer];
+ this->TimerList[this->FirstFreeTimer] = NULL;
break;
}
}
diff --git a/src/info.cc b/src/info.cc
index 08433f2..e24b819 100644
--- a/src/info.cc
+++ b/src/info.cc
@@ -365,16 +365,24 @@ Object GetBodyObject(uint32 CreatureID, int Position){
Object GetTopObject(int x, int y, int z, bool Move){
Object Obj = GetFirstObject(x, y, z);
- while(Obj != NONE){
- ObjectType ObjType = Obj.getObjectType();
- if(!ObjType.getFlag(BANK)
- && !ObjType.getFlag(CLIP)
- && !ObjType.getFlag(BOTTOM)
- && !ObjType.getFlag(TOP)
- && (!Move || !ObjType.isCreatureContainer())){
- break;
+ if(Obj != NONE){
+ while(true){
+ Object Next = Obj.getNextObject();
+ if(Next == NONE){
+ break;
+ }
+
+ ObjectType ObjType = Obj.getObjectType();
+ if(!ObjType.getFlag(BANK)
+ && !ObjType.getFlag(CLIP)
+ && !ObjType.getFlag(BOTTOM)
+ && !ObjType.getFlag(TOP)
+ && (!Move || !ObjType.isCreatureContainer())){
+ break;
+ }
+
+ Obj = Next;
}
- Obj = Obj.getNextObject();
}
return Obj;
}
@@ -575,7 +583,7 @@ int CountInventoryObjects(uint32 CreatureID, ObjectType Type, uint32 Value){
return 0;
}
- Object Help = GetFirstContainerObject(Help);
+ Object Help = GetFirstContainerObject(Creature->CrObject);
return CountObjects(Help, Type, Value);
}
@@ -1173,7 +1181,7 @@ bool ThrowPossible(int OrigX, int OrigY, int OrigZ,
// origin and destination.
int MaxT = std::max<int>(
std::abs(DestX - OrigX),
- std::abs(DestY - OrigX));
+ std::abs(DestY - OrigY));
int StartT = 1;
if((DestX < OrigX && CoordinateFlag(OrigX, OrigY, OrigZ, HOOKEAST))
diff --git a/src/magic.cc b/src/magic.cc
index 0f36bee..a47c730 100644
--- a/src/magic.cc
+++ b/src/magic.cc
@@ -814,7 +814,7 @@ void MassCombat(TCreature *Actor, Object Target, int ManaPoints, int SoulPoints,
throw ERROR;
}
- if(Actor != NULL){
+ if(Actor == NULL){
error("MassCombat: Übergebene Kreatur existiert nicht.\n");
throw ERROR;
}
@@ -4060,8 +4060,8 @@ void UseMagicItem(uint32 CreatureID, Object Obj, Object Dest){
if(Other.getObjectType().isCreatureContainer()){
uint32 OtherID = Other.getCreatureID();
if(Target == NULL
- || (Aggressive && OtherID != Actor->ID)
- || (!Aggressive && OtherID == Actor->ID)){
+ || (Aggressive && OtherID != Actor->ID && OtherID != Target->ID)
+ || (!Aggressive && OtherID == Actor->ID && OtherID != Target->ID)){
Target = GetCreature(OtherID);
Dest = Other;
}
@@ -4086,7 +4086,7 @@ void UseMagicItem(uint32 CreatureID, Object Obj, Object Dest){
throw PROTECTIONZONE;
}
- if(Dest.getContainer().getObjectType().isMapContainer()){
+ if(!Dest.getContainer().getObjectType().isMapContainer()){
throw NOROOM;
}
}
diff --git a/src/map.cc b/src/map.cc
index 78e54db..aad27c3 100644
--- a/src/map.cc
+++ b/src/map.cc
@@ -623,7 +623,7 @@ void SwapObject(TWriteBinaryFile *File, Object Obj, uintptr FileNumber){
File->writeBytes((const uint8*)Entry, sizeof(TObject));
if(Entry->Type.getFlag(CONTAINER) || Entry->Type.getFlag(CHEST)){
- Object Current = Obj.getAttribute(CONTENT);
+ Object Current = Object(Obj.getAttribute(CONTENT));
while(Current != NONE){
Object Next = Current.getNextObject();
SwapObject(File, Current, FileNumber);
@@ -1116,7 +1116,7 @@ void SaveObjects(Object Obj, TWriteStream *Stream, bool Stop){
Object First = NONE;
if(ObjType.getAttributeOffset(CONTENT) != -1){
- First = Obj.getAttribute(CONTENT);
+ First = Object(Obj.getAttribute(CONTENT));
}
if(First != NONE){
@@ -1330,7 +1330,7 @@ void RefreshSector(int SectorX, int SectorY, int SectorZ, TReadStream *Stream){
// TODO(fusion): This loop was done a bit differently but I suppose
// iterating it directly is clearer and as long as we don't access
// the object after `DeleteObject`, it should work the same.
- Object Obj = Con.getAttribute(CONTENT);
+ Object Obj = Object(Con.getAttribute(CONTENT));
while(Obj != NONE){
Object Next = Obj.getNextObject();
if(!Obj.getObjectType().isCreatureContainer()){
@@ -1419,7 +1419,7 @@ void PatchSector(int SectorX, int SectorY, int SectorZ, bool FullSector,
// NOTE(fusion): Similar to `RefreshSector`.
Object Con = Sec->MapCon[OffsetX][OffsetY];
- Object Obj = Con.getAttribute(CONTENT);
+ Object Obj = Object(Con.getAttribute(CONTENT));
while(Obj != NONE){
Object Next = Obj.getNextObject();
if(!Obj.getObjectType().isCreatureContainer()){
@@ -1511,7 +1511,7 @@ void PatchSector(int SectorX, int SectorY, int SectorZ, bool FullSector,
// NOTE(fusion): Same as in the parsing loop above.
Object Con = Sec->MapCon[OffsetX][OffsetY];
- Object Obj = Con.getAttribute(CONTENT);
+ Object Obj = Object(Con.getAttribute(CONTENT));
while(Obj != NONE){
Object Next = Obj.getNextObject();
if(!Obj.getObjectType().isCreatureContainer()){
@@ -1641,7 +1641,7 @@ void PatchSector(int SectorX, int SectorY, int SectorZ, bool FullSector,
}
Object Con = Sec->MapCon[OffsetX][OffsetY];
- Object First = Con.getAttribute(CONTENT);
+ Object First = Object(Con.getAttribute(CONTENT));
uint8 Flags = GetMapContainerFlags(Con);
if(First != NONE || Flags != 0){
OUT.writeNumber(OffsetX);
@@ -1853,7 +1853,7 @@ static void DestroyObject(Object Obj){
if(ObjType.getFlag(CONTAINER) || ObjType.getFlag(CHEST)){
while(true){
- Object Inner = Obj.getAttribute(CONTENT);
+ Object Inner = Object(Obj.getAttribute(CONTENT));
if(Inner == NONE){
break;
}
@@ -2020,7 +2020,7 @@ void PlaceObject(Object Obj, Object Con, bool Append){
}
Object Prev = NONE;
- Object Cur(Con.getAttribute(CONTENT));
+ Object Cur = Object(Con.getAttribute(CONTENT));
if(ConType.isMapContainer()){
// TODO(fusion): Review. The loop below was a bit rough but it seems that
// append is forced for non PRIORITY_CREATURE and PRIORITY_LOW.
@@ -2358,7 +2358,7 @@ Object GetFirstSpecObject(int x, int y, int z, ObjectType Type){
}
Obj = Obj.getNextObject();
}
- return NONE;
+ return Obj;
}
uint8 GetMapContainerFlags(Object Obj){
diff --git a/src/map.hh b/src/map.hh
index 571def0..bbd77fc 100644
--- a/src/map.hh
+++ b/src/map.hh
@@ -31,7 +31,7 @@ enum : int {
struct Object {
constexpr Object(void) : ObjectID(0) {}
- constexpr Object(uint32 ObjectID): ObjectID(ObjectID) {}
+ constexpr explicit Object(uint32 ObjectID): ObjectID(ObjectID) {}
bool exists(void);
ObjectType getObjectType(void);
diff --git a/src/moveuse.cc b/src/moveuse.cc
index 81fa948..e4d76db 100644
--- a/src/moveuse.cc
+++ b/src/moveuse.cc
@@ -1176,7 +1176,7 @@ void ExecuteAction(MoveUseEventType EventType, TMoveUseAction *Action,
}
// TODO(fusion): Some helper function to format text?
- char Text[256];
+ char Text[256] = {};
{
int ReadPos = 0;
int WritePos = 0;
@@ -1331,12 +1331,13 @@ void ExecuteAction(MoveUseEventType EventType, TMoveUseAction *Action,
}
case MOVEUSE_ACTION_MOVEREL:{
- int ObjX, ObjY, ObjZ, RelX, RelY, RelZ;
- Object Obj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
- UnpackRelativeCoordinate(Action->Parameters[1], &RelX, &RelY, &RelZ);
- GetObjectCoordinates(Obj, &ObjX, &ObjY, &ObjZ);
- Object Dest = GetMapContainer((ObjX + RelX), (ObjY + RelY), (ObjZ + RelZ));
- MoveOneObject(Obj, Dest);
+ int RefX, RefY, RefZ, RelX, RelY, RelZ;
+ Object MovObj = GetEventObject(Action->Parameters[0], User, Obj1, Obj2, *Temp);
+ Object RefObj = GetEventObject(Action->Parameters[1], User, Obj1, Obj2, *Temp);
+ UnpackRelativeCoordinate(Action->Parameters[2], &RelX, &RelY, &RelZ);
+ GetObjectCoordinates(RefObj, &RefX, &RefY, &RefZ);
+ Object Dest = GetMapContainer((RefX + RelX), (RefY + RelY), (RefZ + RelZ));
+ MoveOneObject(MovObj, Dest);
break;
}
@@ -1520,9 +1521,10 @@ bool HandleEvent(MoveUseEventType EventType, Object User, Object Obj1, Object Ob
ActionNr <= Rule->LastAction;
ActionNr += 1){
TMoveUseAction *Action = MoveUseActions.at(ActionNr);
- ExecuteAction(EventType, Action, User, Obj2, Obj2, &Temp);
+ ExecuteAction(EventType, Action, User, Obj1, Obj2, &Temp);
}
Result = true;
+ break;
}
}
RecursionDepth -= 1;
@@ -1842,7 +1844,7 @@ void UseFood(uint32 CreatureID, Object Obj){
}
Player->SetTimer(SKILL_FED, (CurFoodTime + ObjFoodTime), 0, 0, -1);
- Delete(Obj, -1);
+ Delete(Obj, 1);
}
void UseTextObject(uint32 CreatureID, Object Obj){
diff --git a/src/operate.cc b/src/operate.cc
index 14fab8a..92ba83e 100644
--- a/src/operate.cc
+++ b/src/operate.cc
@@ -145,7 +145,7 @@ void AnnounceChangedContainer(Object Obj, int Type){
}
for(int ContainerNr = 0;
- ContainerNr <= NARRAY(Player->OpenContainer);
+ ContainerNr < NARRAY(Player->OpenContainer);
ContainerNr += 1){
if(Player->GetOpenContainer(ContainerNr) != Con){
continue;
@@ -282,13 +282,13 @@ void AnnounceMissile(int OrigX, int OrigY, int OrigZ,
continue;
}
- if(!Player->Connection->IsVisible(OrigX, OrigY, OrigY)
+ if(!Player->Connection->IsVisible(OrigX, OrigY, OrigZ)
&& !Player->Connection->IsVisible(DestX, DestY, DestZ)){
continue;
}
SendMissileEffect(Player->Connection,
- OrigX, OrigY, OrigY,
+ OrigX, OrigY, OrigZ,
DestX, DestY, DestZ, Type);
}
}
@@ -449,10 +449,6 @@ void CheckMoveObject(uint32 CreatureID, Object Obj, bool Take){
// NOTE(fusion): This is a helper function for `CheckMapDestination` and `CheckMapPlace`
// and improves the readability of otherwise two convoluted functions.
static bool IsMapBlocked(int DestX, int DestY, int DestZ, ObjectType Type){
- if(Type.isCreatureContainer()){
- return false;
- }
-
bool HasBank = CoordinateFlag(DestX, DestY, DestZ, BANK);
if(HasBank && !CoordinateFlag(DestX, DestY, DestZ, UNPASS)){
return false;
@@ -480,16 +476,20 @@ void CheckMapDestination(uint32 CreatureID, Object Obj, Object MapCon){
return;
}
+ int OrigX, OrigY, OrigZ;
int DestX, DestY, DestZ;
ObjectType ObjType = Obj.getObjectType();
+ GetObjectCoordinates(Obj, &OrigX, &OrigY, &OrigZ);
GetObjectCoordinates(MapCon, &DestX, &DestY, &DestZ);
- if(IsMapBlocked(DestX, DestY, DestZ, ObjType)){
- throw NOROOM;
- }
+ if(!ObjType.isCreatureContainer()){
+ if(IsMapBlocked(DestX, DestY, DestZ, ObjType)){
+ throw NOROOM;
+ }
- int OrigX, OrigY, OrigZ;
- GetObjectCoordinates(Obj, &OrigX, &OrigY, &OrigZ);
- if(ObjType.isCreatureContainer()){
+ if(!ObjType.getFlag(TAKE) && !ObjectInRange(CreatureID, MapCon, 2)){
+ throw OUTOFRANGE;
+ }
+ }else{
if(std::abs(OrigX - DestX) > 1
|| std::abs(OrigY - DestY) > 1
|| std::abs(OrigZ - DestZ) > 1){
@@ -531,10 +531,6 @@ void CheckMapDestination(uint32 CreatureID, Object Obj, Object MapCon){
}
}
}
- }else{
- if(!ObjType.getFlag(TAKE) && !ObjectInRange(CreatureID, MapCon, 2)){
- throw OUTOFRANGE;
- }
}
// TODO(fusion): This looks awfully similar to `ObjectAccessible` outside
@@ -1169,19 +1165,19 @@ Object Create(Object Con, ObjectType Type, uint32 Value){
}
if(Type.getFlag(LIQUIDPOOL)){
- ChangeObject(POOLLIQUIDTYPE, Value);
+ ChangeObject(Obj, POOLLIQUIDTYPE, Value);
}
if(Type.getFlag(LIQUIDCONTAINER)){
- ChangeObject(CONTAINERLIQUIDTYPE, Value);
+ ChangeObject(Obj, CONTAINERLIQUIDTYPE, Value);
}
if(Type.getFlag(KEY)){
- ChangeObject(KEYNUMBER, Value);
+ ChangeObject(Obj, KEYNUMBER, Value);
}
if(Type.getFlag(RUNE)){
- ChangeObject(CHARGES, Value);
+ ChangeObject(Obj, CHARGES, Value);
}
if(Type.isCreatureContainer()){
@@ -1895,7 +1891,7 @@ void Look(uint32 CreatureID, Object Obj){
if(Yourself){
strcpy(Membership, "You are ");
}else{
- snprintf(Membership, sizeof(Membership), "%s id ", Pronoun);
+ snprintf(Membership, sizeof(Membership), "%s is ", Pronoun);
}
if(TargetPlayer->Rank[0] != 0){
@@ -2456,10 +2452,13 @@ void Talk(uint32 CreatureID, int Mode, const char *Addressee, const char *Text,
}
TCreature *Spectator = GetCreature(SpectatorID);
- if(Spectator != NULL){
- Spectator->TalkStimulus(CreatureID, Text);
- }else{
+ if(Spectator == NULL){
error("Talk: Kreatur existiert nicht.\n");
+ continue;
+ }
+
+ if(Spectator->posz == Creature->posz){
+ Spectator->TalkStimulus(CreatureID, Text);
}
}
}
diff --git a/src/query.cc b/src/query.cc
index 003892c..c9b47aa 100644
--- a/src/query.cc
+++ b/src/query.cc
@@ -711,6 +711,7 @@ int TQueryManagerConnection::loginGame(uint32 AccountID, char *PlayerName,
}
int NumberOfRights = this->getByte();
+ memset(Rights, 0, 12); // MAX_RIGHT_BYTES ?
for(int i = 0; i < NumberOfRights; i += 1){
char RightName[30];
this->getString(RightName, 30);
diff --git a/src/receiving.cc b/src/receiving.cc
index 6cf6609..ddaee44 100644
--- a/src/receiving.cc
+++ b/src/receiving.cc
@@ -646,7 +646,7 @@ void CEditText(TConnection *Connection, TReadBuffer *Buffer){
return;
}
- Object Obj = Buffer->readQuad();
+ Object Obj = Object(Buffer->readQuad());
if(!Obj.exists()){
SendResult(Connection, NOTACCESSIBLE);
return;
@@ -697,7 +697,7 @@ void CEditList(TConnection *Connection, TReadBuffer *Buffer){
}else if(Type == SUBOWNERLIST){
ChangeSubowners((uint16)ID, Player, Text);
}else if(Type == DOORLIST){
- Object Door = ID;
+ Object Door = Object(ID);
if(!Door.exists()){
SendResult(Connection, NOTACCESSIBLE);
return;
diff --git a/src/sending.cc b/src/sending.cc
index d1cca27..e6e5747 100644
--- a/src/sending.cc
+++ b/src/sending.cc
@@ -349,10 +349,10 @@ void SendResult(TConnection *Connection, RESULT r){
}
if(Message != NULL){
+ SendMessage(Connection, TALK_FAILURE_MESSAGE, Message);
if(r == ENTERPROTECTIONZONE || r == NOTINVITED || r == MOVENOTPOSSIBLE){
SendSnapback(Connection);
}
- SendMessage(Connection, TALK_FAILURE_MESSAGE, "Sorry, not possible.");
}
}