Object clone bug. can i even do this??!

Started by Gijsdemik, September 03, 2021, 17:09:17

Previous topic - Next topic

Gijsdemik

Hi all,
I have a new question. last time you all helped me very well!.
I am wondering if what i am trying to do is correct.
my issue is that my object wont show its self using my draw routine.
what i am trying to do is clone an object in my game from my creature array.

As i am still learning blitz max i am not even sure if i should use this code.
i could just hard copy all data then create a new instance and a new object in the correct location
but i feel that could be done a lot cleaner.

Here is the code i use for the cloning. (.x and .y are used for the draw routine)


Function CloneCR(X:Int,Y:Int,ObjectRef:Int,Player:Int,NewX:Int,NewY:Int)
If Carr:Creature[ObjectRef,Player,X,Y].Is_wizzard=0
'Global MemArray:Creature[80,10,50,50]

Local oldx:Int
Local oldy:Int
oldx=Carr:Creature[ObjectRef,Player,X,Y].x
oldy=Carr:Creature[ObjectRef,Player,X,Y].y
Local OldAutoDmg:Int=Carr:Creature[ObjectRef,Player,X,Y].AutoDMG

PlayerGrid[newx,newy]=Player
GameP.PlayerObjects[NewX,NewY]=Player
ObjectGridRefRance[Player,NewX,NewY]=ObjectRef
Carr:Creature[ObjectRef,Player,NewX,NewY]=Carr:Creature[ObjectRef,Player,X,Y] ' is this even possible?!
Carr:Creature[ObjectRef,Player,NewX,NewY].PLayer=Player
Carr:Creature[ObjectRef,Player,NewX,NewY].x=NewX
Carr:Creature[ObjectRef,Player,NewX,NewY].y=NewY
Carr:Creature[ObjectRef,Player,NewX,NewY].AutoDMG=Rnd(3)+3+OldAutoDmg
Carr:Creature[ObjectRef,Player,NewX,NewY].Hp=Carr:Creature[ObjectRef,Player,NewX,NewY].hp-3
Carr:Creature[ObjectRef,Player,X,Y].x=oldx
Carr:Creature[ObjectRef,Player,X,Y].y=oldy

Grid[Newx,Newy]=1
'Notify Carr[ObjectRef,Player,NewX,NewY].AutoDMG

Else
Notify "cannot clone wizzard"
EndIf

EndFunction


Here is the draw routine.



Method Draw()

SetColor 256,256,256
DrawImage Mpic,X*50,Y*50 'Change in game code to 50 for Grid YX50
End Method


Function DrawPlayer(P:Int) 'drawplayer

For Local X:Creature=EachIn Carr:Creature
For Local Y= 0 To MaxCreatures
If X.Is_Wizzard=0
If X.Player = P:Int X.Draw()
EndIf
Next
Next
End Function
'Drawplayer is updated in game loop



What happens is that the creature is cloned perfectly but it will not show its picture until i have moved the unit.
the move function uses all the data creates a new instance of creature object then copies all data and removes the old
data in my creature array. i tried to create a new creature first in my new creature array location.
then copy the other data but that did nothing. a little reference here My creature array has 4 positions.
[a,b,c,d]. A is used to determine what kind of creature is in the array. b is used for the player owning the creature
and c / d are used for x / y positions on the map i have an  additional array keeping track of which creature number is where on the map so these two combined i can get the correct creature number,






Midimaster

For me your code looks like to be over-complicate....

So I first would ask some questions to find out, what exactly the game does....

Is it a multiplayer-game?

Is it a grid-based game?

What exactly do you want to clone? Only a single figur in the grid? Or a complete game-set? Or a new player?

normally a grid-array contains only a reference to a figur, which is on this grid-position. Therefore you need only a two-dimensional (f.e.10x10) array.

You could also store all figures in a list. The (grid-) coordinates of the figures are in this case only properties (fields) of the figures

The figurs are instances of the Creature-Type. The fields of this Creature-Type contain the properties of the figures.

In your code it looks like you work with 4dimensional arrays? Why?
...back from Egypt

markcwm

Hi G,

yes your code could be a lot tidier but that's up to you, I can follow it more or less.

I'm not sure why it doesn't draw until you move but maybe you're not calling Flip after it is cloned?

Derron

Quote

Carr:Creature[ObjectRef,Player,NewX,NewY]=Carr:Creature[ObjectRef,Player,X,Y] ' is this even possible?!
Carr:Creature[ObjectRef,Player,NewX,NewY].PLayer=Player
Carr:Creature[ObjectRef,Player,NewX,NewY].x=NewX
Carr:Creature[ObjectRef,Player,NewX,NewY].y=NewY


no need to append the "type" here each time
Code (Blitzmax) Select

Carr[ObjectRef,Player,NewX,NewY]=Carr[ObjectRef,Player,X,Y] ' is this even possible?!
Carr[ObjectRef,Player,NewX,NewY].PLayer=Player
Carr[ObjectRef,Player,NewX,NewY].x=NewX
Carr[ObjectRef,Player,NewX,NewY].y=NewY


Yet it does not create a COPY but ...  simply stores the same object in a new position - and afterwards even alters the properties of this object (which is now referenced from two cells of your array).

In vanilla you were able to do this:
Carr[ObjectRef,Player,NewX,NewY]= new Carr[ObjectRef,Player,X,Y]
it then created a "new object" for the same type as the given one

in NG you can do it this way:

local T:TTypeID = TTypeID.ForObject(Carr[ObjectRef,Player,X,Y])
if T then Carr[ObjectRef,Player,NewX,NewY] = T.NewObject()


It utilizes the reflection module to create a new object instance for the given object.


OK ... as reflection might sound complicated, this might help you a bit more (also for other purposes):
Code (Blitzmax) Select

Type TTest
  Field speed:Int
  Field live:Int

  Method Copy:TTest()
    Local c:TTest = new TTest
    c.speed = self.speed
    c.live = self.live
  End Method
End Type

local t1:TTest = new TTest
t1.live = 100
t1.speed = 50

local t2:TTest = t1.Copy()
print t2.speed

t2.speed = 250
print t1.speed
print t2.speed





Quote

Function DrawPlayer(P:Int) 'drawplayer

For Local X:Creature=EachIn Carr:Creature
For Local Y= 0 To MaxCreatures
If X.Is_Wizzard=0
If X.Player = P:Int X.Draw()
EndIf
Next
Next
End Function


These for loops are ... overcomplicated and not doing what you think they do (seems code is missing)

- for every creature in "carr" do "MaxCreatures" times:
- - if "creature.Is_wizzard = 0" and "creature.player = desired player number" then draw it

I somehow think your plan is to only draw up to "maxCreatures"?
Then loop over all creatures (outer for loop is correct) and for each drawn one, you "increase" a number - once it reaches the limit, exit the loop (if maxCreatures is bigger than CArr-entries, then all are drawn)

Code (BlitzMax) Select

Local creaturesDrawn:int = 0
For Local X:Creature=EachIn Carr:Creature
  X.Draw()
  creaturesDrawn :+ 1
  if creaturesDrawn >= maxCreatures then exit
Next


But ... this wont fit into your "DrawPlayer" ... if you want to draw a specific "number/id" character, then iterate through the container (here the "Carr") and once you spotted the player draw and done.


Code (BlitzMax) Select

For Local X:Creature=EachIn Carr:Creature
'skip creatures of other players     
If X.Player <> P then continue

        'whatever this means - if wizzard is set, char wont be drawn - no matter if player or not!
If X.Is_Wizzard <> 0 Then continue
       
X.Draw()
'exit earlier if only one char per player exists (saves iterating over other characters which wont be "player's chars" then
'comment out if multiple creatures of a player can exist
exit
Next



bye
Ron

Gijsdemik

Thanks guys for helping me out,
I wil try all this the next time i am going to program again. sorry for my late response i have had some busy weeks.

For markcwm, the flip is in the loop where i try to use my clone code. it clones but the image will flash and disappears.
I tried forcing a flip in the clone function same result.

For Midimaster, i have a grid based strategy game. in which the wizard cast units to kill other wizards.
The reason i use multi dimension arrays is that they store al information on a square.

The carr[Obj,Player,x,y] object is linked back to an object array which then stores al information about a creature.
The information is read from a different array [Creature,properties] which holds all the creatures properties
how far it can walk can it do spells how much dmg.
This is done because at some point i need to game to be mod able. and external file wil be read and fill this array whit information.
Then Carr gets filled whit a new instance of a creature which has all the fields then i read the array to fill those fields
like. Carr[1,2,15,15].Move = crarry[1,1] , Carr[1,2,15,15].dmg = crarry[1,2]
in game you can buff your creatures or make enemies weaker.
units can level up if they have enough exp all this info is then changed in there position.

I have and additional array [player,x,y] which links back to which object is where on the map and who it belongs to
why my draw routine stopts at the max creature count. so the wizzards can have different selectable skins.
wizzards is simply Maxcreatures+player , Max creatures is the maximum count of different creatures in the game. currently 80.

i could also just copy and edit my movement code. and read the array and not remove the old one .
but i wanted to do it cleaner and in a new way to push my self to learn blitz max better.

for Derron
I wil try all the code and see what i can do whit that. it seems my draw routine can be speed up using your code.
Thank you for the extended explanations,
this is the first time i am making a game whit blitz i have been at it for a few years so my older code is a bit more strange.
I am probably over complicating things, but i still have a long way to go before i understand blitzmax better.
I don't know what the difference is between vanilla blitz and NG. but i use version 1.5 i got it like 5 years ago

thanks for all the insights here.