Hello Guest, please login or register.
Did you miss your activation email?
Login with username, password and session length.

Pages: [1]   Go Down

Author Topic: Problems with collision  (Read 3788 times)

0 Members and 1 Guest are viewing this topic.

Miragos

ᚺᚨᛚᛁᚨ᛫ᚹᛁᛊᚨᛞᚨᚢ᛫ᛟᚱᛁᚾᛁᛋ᛫ᚷᚨᛊᛏᛋ
Problems with collision
« on: September 14, 2009, 10:39:47 pm »
  • 地獄に儚く惑った
  • *
  • Reputation: +0/-0
  • Offline Offline
  • Gender: Male
  • Posts: 106
I'm a GM newbie and I have a big problem with enemy collision.
Can someone make an example or explain how you can script it, please?
At the moment my enemys go through everything... XD

« Last Edit: September 14, 2009, 10:42:55 pm by Miragos »
Logged
Current project: Vortex of Height
Spriter of: Oracle of Mystery
               The Mask of Sheikah
  • Miragos Project Site
Re: Problems with collision
« Reply #1 on: September 15, 2009, 03:52:34 am »
  • *
  • Reputation: +0/-0
  • Offline Offline
  • Posts: 2245
It depends on how your enemies move.
Logged
Re: Problems with collision
« Reply #2 on: September 15, 2009, 05:51:07 am »
  • *
  • Reputation: +16/-0
  • Offline Offline
  • Gender: Male
  • Posts: 1633
If you are having problems than I am guessing you are using paths for the movements? I don't know of any solutions for that.

You could instead use timelines. Let's say you want an enemy to patrol along a line then you would need a timeline with two moments. One for walking left and one for walking right. When moving right you can add a condition to check if the end of the line has been reached (x => 100). If so then timeline_position += some value to set it up for moving left. Else timeline_position -= 1 so you will move right again during the next step.

Anyway. I use a script during each step with the speed (ex: 7) and direction of the character as input. The actual movement speed needs to be 0 beforehand. What the script does is create one big loop that repeat the following process equal to roof(speed). In this case 7. The distance between start and destination is cut up in pixels. You start at the beginning and check if moving one pixel has a collision with a solid object (I suggest grouping the solid objects together through a parent). If so then end the loop. If not then you let the loop continue and check for another pixel. If no objects are met you move.

This is the simplified concept. I've got an example on this site somewhere (of the collision script) but I don't want to be late for work so that's for another time.
Logged
Re: Problems with collision
« Reply #3 on: September 15, 2009, 08:37:13 am »
  • *
  • Reputation: +0/-0
  • Offline Offline
  • Posts: 2245
There is a GML function that allows you to navigate around objects in those sorts of circumstances.
Logged
Re: Problems with collision
« Reply #4 on: September 15, 2009, 04:17:03 pm »
  • Doesn't afraid of anything
  • *
  • Reputation: +42/-0
  • Offline Offline
  • Gender: Male
  • Posts: 7002
Can we see some of your code?
Logged



i love big weenies and i cannot lie
Re: Problems with collision
« Reply #5 on: September 15, 2009, 04:42:47 pm »
  • *
  • Reputation: +16/-0
  • Offline Offline
  • Gender: Male
  • Posts: 1633
Those ready made function(s) could also work. I wouldn't know though. Never tried them.

MC-Zero: you're talking to me or Miragos?
Logged

Miragos

ᚺᚨᛚᛁᚨ᛫ᚹᛁᛊᚨᛞᚨᚢ᛫ᛟᚱᛁᚾᛁᛋ᛫ᚷᚨᛊᛏᛋ
Re: Problems with collision
« Reply #6 on: September 15, 2009, 11:56:17 pm »
  • 地獄に儚く惑った
  • *
  • Reputation: +0/-0
  • Offline Offline
  • Gender: Male
  • Posts: 106
I just want to create an octorok first and I have no collision code. So it's unnecassary
to post my  enemy code (it's just a collection of a few enemy codes posted here and I edited it a little bit ).

If you are having problems than I am guessing you are using paths for the movements? I don't know of any solutions for that.

You could instead use timelines. Let's say you want an enemy to patrol along a line then you would need a timeline with two moments. One for walking left and one for walking right. When moving right you can add a condition to check if the end of the line has been reached (x => 100). If so then timeline_position += some value to set it up for moving left. Else timeline_position -= 1 so you will move right again during the next step.

Anyway. I use a script during each step with the speed (ex: 7) and direction of the character as input. The actual movement speed needs to be 0 beforehand. What the script does is create one big loop that repeat the following process equal to roof(speed). In this case 7. The distance between start and destination is cut up in pixels. You start at the beginning and check if moving one pixel has a collision with a solid object (I suggest grouping the solid objects together through a parent). If so then end the loop. If not then you let the loop continue and check for another pixel. If no objects are met you move.

This is the simplified concept. I've got an example on this site somewhere (of the collision script) but I don't want to be late for work so that's for another time.

Thanks. That's very useful, but I'm a GML noob and don't know for example how to insert timelines in your GML enemy script...   :-[

Logged
Current project: Vortex of Height
Spriter of: Oracle of Mystery
               The Mask of Sheikah
  • Miragos Project Site
Re: Problems with collision
« Reply #7 on: September 16, 2009, 02:38:05 am »
  • Doesn't afraid of anything
  • *
  • Reputation: +42/-0
  • Offline Offline
  • Gender: Male
  • Posts: 7002
Those ready made function(s) could also work. I wouldn't know though. Never tried them.

MC-Zero: you're talking to me or Miragos?

No, I was talking to Miragos.
Logged



i love big weenies and i cannot lie

Miragos

ᚺᚨᛚᛁᚨ᛫ᚹᛁᛊᚨᛞᚨᚢ᛫ᛟᚱᛁᚾᛁᛋ᛫ᚷᚨᛊᛏᛋ
Re: Problems with collision
« Reply #8 on: October 19, 2009, 11:06:28 pm »
  • 地獄に儚く惑った
  • *
  • Reputation: +0/-0
  • Offline Offline
  • Gender: Male
  • Posts: 106
(Sorry for not replying, but I was on vacation... :-[)

object: objOkt


CREATE

Code: [Select]

alarm[0]=60
alarm[1]=40
alarm[2]=30
OKTOH=2
image_speed=0.5


ALARM 0

Code: [Select]
switch floor(random(6)){ //Pick a random number, make it an integer, and see what it is
case 0:
 direction=0 //Right
 sprite_index=OktR
 image_speed=0.1
 speed=floor(2)
 break;
case 1:
 direction=90 //Up
 sprite_index=OktU
 image_speed=0.1
 speed=floor(2)
break;
case 2:
 direction=180 //Left
 sprite_index=OktL
 image_speed=0.1
 speed=floor(2)
break;
case 3:
 direction=270 //Down
 sprite_index=OktD
 image_speed=0.1
 speed=floor(2)
break;
case 4:
 a=instance_create(x,y,objOKTE);
a.direction=direction
a.speed=4
if direction = 0 //Right
{
sprite_index=OktER
}
if direction = 90 //Up
{
sprite_index=OktEU
}
if direction = 180 //Left
{
sprite_index=OktEL
}
if direction = 270 //Down
{
sprite_index=OktED
}
image_speed=0.05
speed=floor(0)
speed=0
 break;
case 5:
 a=instance_create(x,y,objOKTE);
a.direction=direction
a.speed=4
if direction = 0 //Right
{
sprite_index=OktER
}
if direction = 90 //Up
{
sprite_index=OktEU
}
if direction = 180 //Left
{
sprite_index=OktEL
}
if direction = 270 //Down
{
sprite_index=OktED
}
image_speed=0.05
speed=floor(0)
break;
}
  
//Set the speed
speed=floor(random(2)) //Could also be zero, as sometimes the octorocs stop.
//Reset the alarm
alarm[0]=30+random(30)


ALARM 1
Code: [Select]
dif = abs(direction-point_direction(self.x,self.y,objLink.x,objLink.y))
if dif<5 {
a=instance_create(x,y,objOKTE);
a.direction=direction
a.speed=4
speed=0
if direction = 0 //Right
{
sprite_index=OktER
}
if direction = 90 //Up
{
sprite_index=OktEU
}
if direction = 180 //Left
{
sprite_index=OktEL
}
if direction = 270 //Down
{
sprite_index=OktED
}
image_speed=0.05
}
alarm[1]=45+random(45)


ALARM 2

Code: [Select]
if not instance_exists(self)
{
instance_destroy()
instance_create(x,y,objonerupee)
}
(^I know that this is awful and does not work  XD)


STEP

Code: [Select]
if position_meeting(x,y,InvisibleWall or objBush or objRock or objPot or objInvisibleWall or NoEnemy or NoEnemyKlein or objTree or objPalmTree or objHouse or objFountin or objLink ) {speed=0}
if OKTOH <= 0
{ instance_destroy()}
if position_meeting(x,y,objLinkSword) {OKTOH -= 1}

-the movement of the Octorok does not work perfect
-the HP of the Octorok (OKTOH) don't work
-the collision does not work  :-\

« Last Edit: October 20, 2009, 10:19:30 pm by Miragos »
Logged
Current project: Vortex of Height
Spriter of: Oracle of Mystery
               The Mask of Sheikah
  • Miragos Project Site

Miragos

ᚺᚨᛚᛁᚨ᛫ᚹᛁᛊᚨᛞᚨᚢ᛫ᛟᚱᛁᚾᛁᛋ᛫ᚷᚨᛊᛏᛋ
Re: Problems with collision
« Reply #9 on: October 24, 2009, 02:32:59 am »
  • 地獄に儚く惑った
  • *
  • Reputation: +0/-0
  • Offline Offline
  • Gender: Male
  • Posts: 106
Can anybody help, please?
Logged
Current project: Vortex of Height
Spriter of: Oracle of Mystery
               The Mask of Sheikah
  • Miragos Project Site
Re: Problems with collision
« Reply #10 on: October 24, 2009, 05:49:53 am »
  • *
  • Reputation: +16/-0
  • Offline Offline
  • Gender: Male
  • Posts: 1633
It´s a little hard to read, with it´s layot and small number of comments.

You seems to be resetting the character´s speed twice in alarm[0]. Intentional?

Alarm[2] will indeed not work. When the object is no longer existing I believe the coding is stopped after the current step. It will not continue during further steps and thus no alarms like that will not get activated. A little tip for if you want to check if coding is actually used. Add in something like:
Code: [Select]
show_message('If you can read this ingame then the code is being used')
Either way. The if statement in alarm[2] does not appear usefull.
Logged
Re: Problems with collision
« Reply #11 on: October 24, 2009, 09:46:13 am »
  • *
  • Reputation: +9/-0
  • Offline Offline
  • Gender: Male
  • Posts: 3725
ALARM 2
Code: [Select]
if not instance_exists(self)
{
instance_destroy()
instance_create(x,y,objonerupee)
}
(^I know that this is awful and does not work  XD)
Okay this won't work. As Martijn said it won't be executed, because he does not exist anymore. If you want to place a ruppee instance, where octorok instance was, you should do this in the DESTROY event, of the octorok.


CREATE
Code: [Select]

alarm[0]=60
alarm[1]=40
alarm[2]=30
OKTOH=2
image_speed=0.5
I don't see anything wrong with this besides the useless "alarm[2]=30" code. But it does not do anything with the object.

ALARM 0
Code: [Select]
switch floor(random(6)){ //Pick a random number, make it an integer, and see what it is
case 0:
   direction=0 //Right
   sprite_index=OktR
   image_speed=0.1
   speed=floor(2)
   break;
case 1:
   direction=90 //Up
   sprite_index=OktU
   image_speed=0.1
   speed=floor(2)
   break;
case 2:
   direction=180 //Left
   sprite_index=OktL
   image_speed=0.1
   speed=floor(2)
   break;
case 3:
   direction=270 //Down
   sprite_index=OktD
   image_speed=0.1
   speed=floor(2)
   break;
case 4:
   a=instance_create(x,y,objOKTE);
   a.direction=direction
   a.speed=4
   if direction = 0 //Right
   {
       sprite_index=OktER
   }
   if direction = 90 //Up
   {
       sprite_index=OktEU
   }
   if direction = 180 //Left
   {
       sprite_index=OktEL
   }
   if direction = 270 //Down
   {
       sprite_index=OktED
   }
   image_speed=0.05
   speed=floor(0)
   speed=0
   break;
case 5:
   a=instance_create(x,y,objOKTE);
   a.direction=direction
   a.speed=4
   if direction = 0 //Right
   {
       sprite_index=OktER
   }
   if direction = 90 //Up
   {
       sprite_index=OktEU
   }
   if direction = 180 //Left
   {
       sprite_index=OktEL
   }
   if direction = 270 //Down
   {
       sprite_index=OktED
   }
   image_speed=0.05
   speed=floor(0)
   break;
}
 
//Set the speed
speed=floor(random(2)) //Could also be zero, as sometimes the octorocs stop.
//Reset the alarm
alarm[0]=30+random(30)
There are somethings wrong with this, but nothing that causes your problems.
1) speed=floor(2) is the same as speed=2. Taking the floor of a constant numeral value returns the same numeral value. The call to floor() is additional overhead which isn't doing anything. I know GML only uses real value numbers, but it isn't going to add a fraction to it when you don't give it.
2) In case 4 you do this: 
  speed=floor(0)
  speed=0
You are repeating the exact same thing in twice after each other.
3) case 5 and case 4 are exactly the same.
4) After the switch statement you have "speed=floor(random(2))" this invalidates any code that sets the speed inside the switch statements. Therefore you have a bunch of useless statements. Also the speed will always be 0 or 1, resulting that the octorok never gets the speed of 2 what you are trying to do in the switch.

ALARM 1
Code: [Select]
dif = abs(direction-point_direction(self.x,self.y,objLink.x,objLink.y))
if dif<5 {
a=instance_create(x,y,objOKTE);
a.direction=direction
a.speed=4
speed=0
if direction = 0 //Right
{
sprite_index=OktER
}
if direction = 90 //Up
{
sprite_index=OktEU
}
if direction = 180 //Left
{
sprite_index=OktEL
}
if direction = 270 //Down
{
sprite_index=OktED
}
image_speed=0.05
}
alarm[1]=45+random(45)
Nothing wrong with this, but I wonder if it is necessary and it isn't better paced in the step event.

STEP
Code: [Select]
if position_meeting(x,y,InvisibleWall or objBush or objRock or objPot or objInvisibleWall or NoEnemy or NoEnemyKlein or objTree or objPalmTree or objHouse or objFountin or objLink ) {speed=0}
if OKTOH <= 0
{ instance_destroy()}
if position_meeting(x,y,objLinkSword) {OKTOH -= 1}

-the movement of the Octorok does not work perfect
-the HP of the Octorok (OKTOH) don't work
-the collision does not work  :-\
The movement imperfections are probably due to your code in ALARM 0 event. I saw there that you did "image_speed=0.1". This means that for every 10 gamecycles you change the frame.
The other two errors are due to faulty code in the STEP event.

The collision doesn't work because of the line "if position_meeting(x,y,InvisibleWall or objBush or objRock or objPot or objInvisibleWall or NoEnemy or NoEnemyKlein or objTree or objPalmTree or objHouse or objFountin or objLink )" There are probably two errors in there.
1) I guess in syntax it is okay, but I don't think the boolean expression can't be used as the 3rd argument for position meeting. The boolean expression returns true or false and because there is no object with the objectID (read: not instanceID) of 1 and 0 the if statement is always seen as false and therefore does not execute the things within the if statement.
2) The second problem has to do with the use of position_meeting() instead of place_meeting(). But you probably need to change this to how you want the movement to behave.
3) Well the third problem has more to do with what happens when you solve the collision problem. In your current code you only check the current position and not where the octorok is going. So once it collides with a object it gets stuck. Because its speed is always set to 0 no matter where the object is and in which direction the octorok is going.

The problem with HP has to do with this "if position_meeting(x,y,objLinkSword) {OKTOH -= 1}" Once more the position_meeting() evaluates as false. This has to do with the nature of position_meeting. You should use place_meeting(). Position_meeting only takes the bounding box of objLinkSword into account. To put it simple:Position_meeting evaluates true when the point given by x and y is inside the bounding box of one instance of the requested object.
Place_meeting takes into account the bounding box of both obj and self. To put this simple: Place_Meeting evaluates true, when the origin of self is placed at position given by x and y and the bounding boxes of both the obj and self intersect.
So use place_meeting instead of position_meeting and you should be closer to the solution. I say closer, because I can forsee another behavioral error. You code isn't complete yet. As a hint I'll give you this: Take the position from Link and the octorok towards each other into account and look at the direction Link is facing.


PS: I find it interesting that you use "NoEnemyKlein" as one of the object indicators.
Logged

Miragos

ᚺᚨᛚᛁᚨ᛫ᚹᛁᛊᚨᛞᚨᚢ᛫ᛟᚱᛁᚾᛁᛋ᛫ᚷᚨᛊᛏᛋ
Re: Problems with collision
« Reply #12 on: October 24, 2009, 11:15:01 pm »
  • 地獄に儚く惑った
  • *
  • Reputation: +0/-0
  • Offline Offline
  • Gender: Male
  • Posts: 106
Thank you. This helped me a lot.

But I don't understand how to  get the collision to work.
At the moment my code looks like this:
Code: [Select]
with(objOkt) if place_meeting(objOkt.x,objOkt.y,InvisibleWall || objBush || objRock || objPot || objInvisibleWall || NoEnemy || NoEnemyKlein || objTree || objPalmTree || objHouse || objFountin || objLink )==true {speed=0}
with(objOkt) if place_meeting(objOkt.x,objOkt.y,objLinkSword)==true {OKTOH -= 1}

I think nothing I added was necessary, but I wanted to try these things...

PS: NoEnemyKlein means NoEnemySmall, but "klein" is german  XD.


« Last Edit: October 24, 2009, 11:18:33 pm by Miragos »
Logged
Current project: Vortex of Height
Spriter of: Oracle of Mystery
               The Mask of Sheikah
  • Miragos Project Site
Re: Problems with collision
« Reply #13 on: October 25, 2009, 08:19:24 am »
  • *
  • Reputation: +9/-0
  • Offline Offline
  • Gender: Male
  • Posts: 3725
Thank you. This helped me a lot.

But I don't understand how to  get the collision to work.
At the moment my code looks like this:
Code: [Select]
with(objOkt) if place_meeting(objOkt.x,objOkt.y,InvisibleWall || objBush || objRock || objPot || objInvisibleWall || NoEnemy || NoEnemyKlein || objTree || objPalmTree || objHouse || objFountin || objLink )==true {speed=0}
with(objOkt) if place_meeting(objOkt.x,objOkt.y,objLinkSword)==true {OKTOH -= 1}

I think nothing I added was necessary, but I wanted to try these things...

Okay,  now I'm a bit confused. I thought the code was in the Octorok object. If so you don't need to do with(objOkt) and objOkt.x like that. One of my advices was not to use an boolean expresion as the third argument for postion/place_meeting(). You need an objectID. Thus the code has to be:
Code: [Select]
if( place_meeting( x, y, InvisibleWall)
         || place_meeting( x, y, objBush)
         || place_meeting( x, y, objRock)
         || place_meeting( x, y, objPot)
         || place_meeting( x, y, objInvisibleWall)
         || place_meeting( x, y, NoEnemy)
         || place_meeting( x, y, NoEnemyKlein)
         || place_meeting( x, y, objTree)
         || place_meeting( x, y, objPalmTree)
         || place_meeting( x, y, objHouse)
         || place_meeting( x, y, objFountin)
         || place_meeting( x, y, objLink) )
{speed=0}

if ( place_meeting( x, y, objLinkSword) ) {OKTOH -= 1}

If this piece of code is not in an Octorok object but in another the you need to add the following in front of it:
Code: [Select]
var instOkt;
instOkt = instance_position(x,y,objOkt);
And then replace "place_meeting( x, y, obj)", with "instOkt.place_meeting( instOkt.x, instOkt.y, obj)". What you tried to do was to call that function on an object instead of an instance.

GML only has one basic type and that are real values. It does not differentiate between boolean, class, integer, float and chars. They are easily switched. Thus it will not give an compile error when you try to call a function on an object instead of an instance. You need to be very carefull with what you do, because it results in unwanted and erroneous behavior.

PS: NoEnemyKlein means NoEnemySmall, but "klein" is german  XD.

I know what it means, because it is a word used in German and in Dutch with the same meaning. I just found it funny to see a non-English word between all those English words. And I was wondering if you had Dutch or German ancestry.
Logged

Miragos

ᚺᚨᛚᛁᚨ᛫ᚹᛁᛊᚨᛞᚨᚢ᛫ᛟᚱᛁᚾᛁᛋ᛫ᚷᚨᛊᛏᛋ
Re: Problems with collision
« Reply #14 on: January 13, 2010, 11:49:36 pm »
  • 地獄に儚く惑った
  • *
  • Reputation: +0/-0
  • Offline Offline
  • Gender: Male
  • Posts: 106
(I know the topic is a few months old, but since I started the topic and the problem isn't solved yet, I will continue using it...)


Code: [Select]
if( place_meeting( x, y, InvisibleWall)
         || place_meeting( x, y, objBush)
         || place_meeting( x, y, objRock)
         || place_meeting( x, y, objPot)
         || place_meeting( x, y, objInvisibleWall)
         || place_meeting( x, y, NoEnemy)
         || place_meeting( x, y, NoEnemyKlein)
         || place_meeting( x, y, objTree)
         || place_meeting( x, y, objPalmTree)
         || place_meeting( x, y, objHouse)
         || place_meeting( x, y, objFountin)
         || place_meeting( x, y, objLink) )
{speed=0}

if ( place_meeting( x, y, objLinkSword) ) {OKTOH -= 1}

If this piece of code is not in an Octorok object but in another the you need to add the following in front of it:
Code: [Select]
var instOkt;
instOkt = instance_position(x,y,objOkt);
And then replace "place_meeting( x, y, obj)", with "instOkt.place_meeting( instOkt.x, instOkt.y, obj)". What you tried to do was to call that function on an object instead of an instance.

GML only has one basic type and that are real values. It does not differentiate between boolean, class, integer, float and chars. They are easily switched. Thus it will not give an compile error when you try to call a function on an object instead of an instance. You need to be very carefull with what you do, because it results in unwanted and erroneous behavior.


This didn't work too. So I gave up in solving this problem, but in the last week I decided to to try to find a solution for my collision problem again.
Could anybody help me, please?

(I didn't start a new topic, because the information in this one could be important for finding a solution.)

« Last Edit: January 13, 2010, 11:57:16 pm by Miragos »
Logged
Current project: Vortex of Height
Spriter of: Oracle of Mystery
               The Mask of Sheikah
  • Miragos Project Site
Re: Problems with collision
« Reply #15 on: January 14, 2010, 07:51:54 am »
  • *
  • Reputation: +9/-0
  • Offline Offline
  • Gender: Male
  • Posts: 3725
Okay, I have a few questions first.

1) Is the code for the octorok collision placed in the octorok object or in a different object.

2) did you just simply copy paste the inside the [ code ] bracket to your step event.

3) Is the problem still that the octorok walks through everything. Or is it now that it gets stuck in objects.

Also in case of a collision, setting just the speed to 0 is not enough. You need to do more like, x = xprevious; y = yprevious;
« Last Edit: January 14, 2010, 09:13:49 am by Niek »
Logged

Miragos

ᚺᚨᛚᛁᚨ᛫ᚹᛁᛊᚨᛞᚨᚢ᛫ᛟᚱᛁᚾᛁᛋ᛫ᚷᚨᛊᛏᛋ
Re: Problems with collision
« Reply #16 on: January 14, 2010, 11:28:45 pm »
  • 地獄に儚く惑った
  • *
  • Reputation: +0/-0
  • Offline Offline
  • Gender: Male
  • Posts: 106
1) The code is placed in the octorok object.

2) Yes, I pasted your last improvement of the code in my step event.

3) It walks through everything.

So, what do you have to do with x = xprevious; y = yprevious etc. ?
Logged
Current project: Vortex of Height
Spriter of: Oracle of Mystery
               The Mask of Sheikah
  • Miragos Project Site
Re: Problems with collision
« Reply #17 on: January 15, 2010, 09:51:54 am »
  • *
  • Reputation: +9/-0
  • Offline Offline
  • Gender: Male
  • Posts: 3725
Hmmm, there could be that something else is wrong, that has an effect on your octorok. Could you send me your gmk so I could browse around and experiment a bit. It might be that the collision masks/settings are wrong

So, what do you have to do with x = xprevious; y = yprevious etc. ?
Well, in case that a collision occurs and you only set the speed on 0, the octorok will get stuck and go nowhere. Because it has a collision and in every next cycle this collision occurs again and again and again and again.... Thus each cycle the speed gets set to 0. If you don't place the octorok back to a position without a collision he won't be able to move in a different direction either.
Logged
Pages: [1]   Go Up

 


Contact Us | Legal | Advertise Here
2013 © ZFGC, All Rights Reserved



Page created in 0.049 seconds with 71 queries.