From 562b0ed67b1798eb959b23e7ef503605d073a74e Mon Sep 17 00:00:00 2001 From: br4e <br4e@protonmail.com> Date: Sat, 6 Aug 2022 11:26:42 -0700 Subject: [PATCH 01/20] beautify --- src/Items/Pickups.c | 159 +++++++++++++++++++++----------------------- 1 file changed, 76 insertions(+), 83 deletions(-) diff --git a/src/Items/Pickups.c b/src/Items/Pickups.c index f052a74..3002f7e 100644 --- a/src/Items/Pickups.c +++ b/src/Items/Pickups.c @@ -35,7 +35,7 @@ static void MoveNest(ObjNode *theNode); #define WhoHasPickUp SpecialRef[0] // objnode of object who has this pickup (nil == none) #define HoldingLimb Special[1] // which limb obj above object is doing holding #define OldCType Special[2] // keeps old collision info when an obj is being held -#define OldCBits Special[3] +#define OldCBits Special[3] #define EggIsInPortal Flag[0] // when egg is inside time portal and being transported @@ -57,8 +57,8 @@ ObjNode *newObj; /* MAKE THE EGG */ /****************/ - gNewObjectDefinition.group = LEVEL0_MGroupNum_Egg; - gNewObjectDefinition.type = LEVEL0_MObjType_Egg1 + itemPtr->parm[0]; + gNewObjectDefinition.group = LEVEL0_MGroupNum_Egg; + gNewObjectDefinition.type = LEVEL0_MObjType_Egg1 + itemPtr->parm[0]; gNewObjectDefinition.coord.x = x; gNewObjectDefinition.coord.y = GetTerrainHeightAtCoord_Planar(x,z)-5.0f; gNewObjectDefinition.coord.z = z; @@ -75,24 +75,24 @@ ObjNode *newObj; /* SET COLLISION INFO */ - + newObj->CType = CTYPE_MISC|CTYPE_PICKUP; newObj->CBits = CBITS_TOUCHABLE; - + SetObjectCollisionBounds(newObj,10,-7,-15,15,15,-15); - + newObj->PickUpCollisionRadius = newObj->Radius * 4.0f; // set pickup radius newObj->WhoHasPickUp = nil; // noone is holding this yet newObj->EggIsInPortal = false; // egg isn't in portal newObj->Kind = itemPtr->parm[0]; // remember species of egg - + /* MAKE NEST */ - + if (itemPtr->parm[3] & 1) MakeNest(x,z); - + return(true); // item was added } @@ -108,12 +108,12 @@ short species; /* SEE IF IT'S INSIDE THE ACTIVE TIME PORTAL */ - - + + if (DoSimplePointCollision(&gCoord,CTYPE_PORTAL)) - { + { ObjNode *whoHasMe; - + /* EGG HAS BEEN RECOVERED */ whoHasMe = (ObjNode *)theNode->WhoHasPickUp; // who has this? @@ -127,22 +127,22 @@ short species; } else AddToScore(EGG_POINTS2); // get smaller points - + theNode->TerrainItemPtr = nil; // aint never comin back - + theNode->EggIsInPortal = true; // it's being transported theNode->MoveCall = MoveEggInPortal; // change move routine theNode->Health = 1.0; theNode->Delta.y = 0; theNode->CType = 0; - + if (SeeIfAllEggSpeciesRecovered()) // get extra points for getting all eggs AddToScore(EGG_POINTS3); // get winning points - + PlayEffect(EFFECT_PORTAL); - - UpdateObjectTransforms(theNode); + + UpdateObjectTransforms(theNode); } } @@ -158,24 +158,24 @@ float fps = gFramesPerSecondFrac; theNode->Delta.y += 220.0f * fps; // climb up theNode->Coord.y += theNode->Delta.y * fps; - + theNode->Health -= fps * 0.4f; // decay it if (theNode->Health <= 0.0f) { DeleteObject(theNode); return; - } + } /* KEEP SPINNING */ - - theNode->Rot.x += theNode->RotDelta.x*fps; - theNode->Rot.y += theNode->RotDelta.y*fps; - theNode->Rot.z += theNode->RotDelta.z*fps; + + theNode->Rot.x += theNode->RotDelta.x*fps; + theNode->Rot.y += theNode->RotDelta.y*fps; + theNode->Rot.z += theNode->RotDelta.z*fps; /* UPDATE IT */ - - MakeObjectTransparent(theNode,theNode->Health); + + MakeObjectTransparent(theNode,theNode->Health); UpdateObjectTransforms(theNode); } @@ -187,8 +187,8 @@ static void MakeNest(long x, long z) { ObjNode *newObj; - gNewObjectDefinition.group = LEVEL0_MGroupNum_Nest; - gNewObjectDefinition.type = LEVEL0_MObjType_Nest; + gNewObjectDefinition.group = LEVEL0_MGroupNum_Nest; + gNewObjectDefinition.type = LEVEL0_MObjType_Nest; gNewObjectDefinition.coord.x = x; gNewObjectDefinition.coord.y = GetTerrainHeightAtCoord_Planar(x,z); gNewObjectDefinition.coord.z = z; @@ -203,10 +203,10 @@ ObjNode *newObj; /* SET COLLISION INFO */ - + newObj->CType = CTYPE_MISC; newObj->CBits = CBITS_ALLSOLID; - + CreateCollisionTrianglesForObject(newObj); // build triangle list } @@ -220,7 +220,7 @@ static void MoveNest(ObjNode *theNode) DeleteObject(theNode); return; } - + theNode->Coord.y = GetTerrainHeightAtCoord_Planar(theNode->Coord.x, theNode->Coord.z); UpdateObjectTransforms(theNode); } @@ -241,28 +241,28 @@ float iScale; /***********************/ /* SEE IF IS PICKED UP */ /***********************/ - + if (theNode->WhoHasPickUp) { holderObj = (ObjNode *)theNode->WhoHasPickUp; // get owner of pickup limbNum = theNode->HoldingLimb; // which limb of owner is holding this? - - + + if (holderObj->CType == INVALID_NODE_FLAG) // make sure holder is legal return; - - + + /* BUILD TRANSFORM MATRIX FOR PICKED UP OBJECT */ // // Since the limb's matrix may contain scaling info, we need // to cancel that out since we don't want our picked up // object to be scaled. // - + iScale = (1.0f/holderObj->Scale.x); // calc amount to reverse scaling by - + /* SET SCALE-TRANS MATRIX MANUALLY (FASTER) */ - + matrix.value[0][0] = iScale*theNode->Scale.x; // scale x matrix.value[1][1] = iScale*theNode->Scale.y; // scale y matrix.value[2][2] = iScale*theNode->Scale.z; // scale z @@ -283,39 +283,39 @@ float iScale; FindJointFullMatrix(holderObj,limbNum,&matrix2); // get full matrix for mouth Q3Matrix4x4_Multiply(&matrix,&matrix2,&theNode->BaseTransformMatrix); // concat final matrix } - + /*****************/ /* NOT PICKED UP */ /*****************/ - + else { float y,f; - + if (TrackTerrainItem(theNode)) // check to see if it's gone { DeleteObject(theNode); return; } - + GetObjectInfo(theNode); - + /* DO GRAVITY & FRICTION */ - - + + gDelta.y += -(GRAVITY_CONSTANT/2)*gFramesPerSecondFrac; // add gravity f = 200.0f * gFramesPerSecondFrac; // calc friction value - + ApplyFrictionToDeltas(f,&gDelta); - + /* MOVE IT */ - + gCoord.y += gDelta.y*gFramesPerSecondFrac; // move it gCoord.x += gDelta.x*gFramesPerSecondFrac; gCoord.z += gDelta.z*gFramesPerSecondFrac; - + y = GetTerrainHeightAtCoord_Planar(gCoord.x, gCoord.z); // get y here if ((gCoord.y+theNode->BottomOff) < y) // see if bottom below/on ground { @@ -325,27 +325,27 @@ float iScale; gDelta.y = 0; gDelta.x *= .9f; // strong friction on landing gDelta.z *= .9f; - + theNode->RotDelta.x *= .8f; theNode->RotDelta.y *= .8f; theNode->RotDelta.z *= .8f; } - + /* DEAL WITH SLOPES */ - + if (gRecentTerrainNormal.y < .95f) // if fairly flat, then no sliding effect - { + { gDelta.x += gRecentTerrainNormal.x * gFramesPerSecondFrac * 900.0f; gDelta.z += gRecentTerrainNormal.z * gFramesPerSecondFrac * 900.0f; - } - - + } + + /* SPIN IT */ - theNode->Rot.x += theNode->RotDelta.x*gFramesPerSecondFrac; - theNode->Rot.y += theNode->RotDelta.y*gFramesPerSecondFrac; - theNode->Rot.z += theNode->RotDelta.z*gFramesPerSecondFrac; - + theNode->Rot.x += theNode->RotDelta.x*gFramesPerSecondFrac; + theNode->Rot.y += theNode->RotDelta.y*gFramesPerSecondFrac; + theNode->Rot.z += theNode->RotDelta.z*gFramesPerSecondFrac; + UpdateObject(theNode); } } @@ -368,14 +368,14 @@ ObjNode *pickedObj; /* FIND COORDINATE OF MOUTH */ - + FindCoordOnJoint(theNode, limbNum, &inPoint, &testPt); - - + + /* DO COLLISION DETECT TO FIND OBJECT */ - + pickedObj = IsPointInPickupCollisionSphere(&testPt); // see if this coord is inside a pickup's collision sphere - + if (pickedObj) { theNode->StatusBits |= STATUS_BIT_ISCARRYING; @@ -383,11 +383,11 @@ ObjNode *pickedObj; pickedObj->WhoHasPickUp = theNode; pickedObj->HoldingLimb = limbNum; pickedObj->OldCBits = pickedObj->CBits; // keep collision settings - pickedObj->OldCType = pickedObj->CType; + pickedObj->OldCType = pickedObj->CType; pickedObj->CBits = 0; // clear collision stuff while being carried pickedObj->CType = 0; pickedObj->StatusBits |= STATUS_BIT_DONTCULL; // dont do custom culling while being carried - + } } @@ -418,9 +418,9 @@ static const TQ3Point3D inPoint = {0,0,0}; itemObj->Delta.y = 0; // start falling momentum @ 0 itemObj->Rot.y = theNode->Rot.y; // match y rotations - + /* GET CURRENT COORD OF ITEM */ - + Q3Point3D_Transform(&inPoint, &itemObj->BaseTransformMatrix, &itemObj->Coord); } @@ -430,9 +430,9 @@ static const TQ3Point3D inPoint = {0,0,0}; static Boolean SeeIfAllEggSpeciesRecovered(void) { int i,n; - + /* COUNT # SPECIES GOTTEN */ - + n = 0; for (i = 0; i < NUM_EGG_SPECIES; i++) if (gRecoveredEggs[i] > 0) @@ -440,15 +440,15 @@ int i,n; /* SEE IF ALL ACCOUNTED FOR */ - + if (n >= NUM_EGG_SPECIES) { MakeTimePortal(PORTAL_TYPE_EXIT, gMyCoord.x, gMyCoord.z); MorphToSkeletonAnim(gPlayerObj->Skeleton, PLAYER_ANIM_EXIT, 3); gPlayerObj->Flag[0] = false; gPlayerObj->ExitTimer = 0; - - PlayEffect_Parms(EFFECT_PORTAL,FULL_CHANNEL_VOLUME,kMiddleC-8); + + PlayEffect_Parms(EFFECT_PORTAL,FULL_CHANNEL_VOLUME,kMiddleC-8); return(true); } return(false); @@ -468,10 +468,3 @@ int i; SeeIfAllEggSpeciesRecovered(); } - - - - - - - From 24a1e62c623ca0fd74984c452c5c39d86eb4dda8 Mon Sep 17 00:00:00 2001 From: br4e <br4e@protonmail.com> Date: Sat, 6 Aug 2022 11:26:51 -0700 Subject: [PATCH 02/20] Increase pickup radius --- src/Items/Pickups.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Items/Pickups.c b/src/Items/Pickups.c index 3002f7e..651f6c6 100644 --- a/src/Items/Pickups.c +++ b/src/Items/Pickups.c @@ -81,7 +81,7 @@ ObjNode *newObj; SetObjectCollisionBounds(newObj,10,-7,-15,15,15,-15); - newObj->PickUpCollisionRadius = newObj->Radius * 4.0f; // set pickup radius + newObj->PickUpCollisionRadius = newObj->Radius * 10.0f; // set pickup radius newObj->WhoHasPickUp = nil; // noone is holding this yet newObj->EggIsInPortal = false; // egg isn't in portal newObj->Kind = itemPtr->parm[0]; // remember species of egg From 075d3b767f8ab1ba6605c5e362de7e9c98f63991 Mon Sep 17 00:00:00 2001 From: br4e <br4e@protonmail.com> Date: Sat, 6 Aug 2022 11:29:34 -0700 Subject: [PATCH 03/20] Balance enemies --- src/Enemies/Enemy_Ptera.c | 125 +++++++++++++++++------------------- src/Enemies/Enemy_Rex.c | 78 +++++++++++----------- src/Enemies/Enemy_Spitter.c | 105 ++++++++++++++---------------- src/Enemies/Enemy_Stego.c | 57 +++++++--------- src/Enemies/Enemy_TriCer.c | 59 ++++++++--------- 5 files changed, 194 insertions(+), 230 deletions(-) diff --git a/src/Enemies/Enemy_Ptera.c b/src/Enemies/Enemy_Ptera.c index 07f142a..cdeac35 100644 --- a/src/Enemies/Enemy_Ptera.c +++ b/src/Enemies/Enemy_Ptera.c @@ -35,8 +35,8 @@ static void MovePteraRock(ObjNode *theRock); #define PTERA_SCALE 1.0f -#define PTERA_HEALTH .5f -#define PTERA_DAMAGE 0.03f +#define PTERA_HEALTH .5f +#define PTERA_DAMAGE 0.04f #define ATTACK_DIST 300 @@ -77,14 +77,14 @@ ObjNode *newObj; if (gNumEnemies >= MAX_ENEMIES) // keep from getting absurd return(false); - if (!(itemPtr->parm[3] & 1)) // see if always add + if (!(itemPtr->parm[3] & 1)) // see if always add { if (gNumEnemyOfKind[ENEMY_KIND_PTERA] >= MAX_PTERA) return(false); } /* MAKE DEFAULT SKELETON ENEMY */ - + newObj = MakeEnemySkeleton(SKELETON_TYPE_PTERA,x,z); if (newObj == nil) return(false); @@ -93,40 +93,40 @@ ObjNode *newObj; /* SEE IF ROCK-DROPPER */ - + newObj->RockDropper = itemPtr->parm[3] & (1<<1); if (newObj->RockDropper) { AttachARock(newObj); - SetSkeletonAnim(newObj->Skeleton, PTERA_ANIM_CARRY); + SetSkeletonAnim(newObj->Skeleton, PTERA_ANIM_CARRY); } else SetSkeletonAnim(newObj->Skeleton, PTERA_ANIM_FLY); - - newObj->Skeleton->AnimSpeed = RandomFloat()*.5 + 1; + + newObj->Skeleton->AnimSpeed = RandomFloat()*.5 + 1; newObj->Scale.x = newObj->Scale.y = newObj->Scale.z = PTERA_SCALE; newObj->Radius *= PTERA_SCALE; - + /* SET BETTER INFO */ - + newObj->Coord.y += FLIGHT_HEIGHT; newObj->MoveCall = MovePtera; // set move call newObj->Health = PTERA_HEALTH; newObj->Damage = PTERA_DAMAGE; newObj->Kind = ENEMY_KIND_PTERA; newObj->Occillate = RandomFloat(); - - + + /* SET COLLISION INFO */ - + SetObjectCollisionBounds(newObj, 40,-40,-70,70,70,-70); CalcNewTargetOffsets(newObj,PTERA_TARGET_SCALE); newObj->TargetChangeTimer = RandomFloat()*5; /* MAKE SHADOW */ - + AttachShadowToObject(newObj, 4, 4.5); gNumEnemies++; @@ -141,8 +141,8 @@ static void AttachARock(ObjNode *theEnemy) { ObjNode *newObj; - gNewObjectDefinition.group = LEVEL0_MGroupNum_Boulder2; - gNewObjectDefinition.type = LEVEL0_MObjType_Boulder2; + gNewObjectDefinition.group = LEVEL0_MGroupNum_Boulder2; + gNewObjectDefinition.type = LEVEL0_MObjType_Boulder2; gNewObjectDefinition.scale = .4; gNewObjectDefinition.coord = gCoord; gNewObjectDefinition.flags = 0; @@ -154,10 +154,10 @@ ObjNode *newObj; { theEnemy->ChainNode = newObj; // setup chain links newObj->ChainHead = theEnemy; - - theEnemy->HasRock = true; + + theEnemy->HasRock = true; } -} +} /***************** MOVE PTERA ROCK ************************/ @@ -169,32 +169,32 @@ TQ3Point3D inPoint = {10,-10,80}; /* SEE IF STILL ATTACHED TO ENEMY */ - + theEnemy = theRock->ChainHead; if (theEnemy) { FindCoordOnJoint(theEnemy, 3, &inPoint, &theRock->Coord); UpdateObjectTransforms(theRock); } - + /* NOT ATTACHED ANYMORE */ else { GetObjectInfo(theRock); - - gDelta.y -= GRAVITY_CONSTANT * gFramesPerSecondFrac; + + gDelta.y -= GRAVITY_CONSTANT * gFramesPerSecondFrac; gCoord.x += gDelta.x * gFramesPerSecondFrac; gCoord.y += gDelta.y * gFramesPerSecondFrac; gCoord.z += gDelta.z * gFramesPerSecondFrac; - + if (gCoord.y <= GetTerrainHeightAtCoord_Planar(gCoord.x,gCoord.y)) - { + { QD3D_ExplodeGeometry(theRock, 400, 0, 2, .4); DeleteObject(theRock); return; } - + UpdateObject(theRock); } @@ -213,9 +213,9 @@ ObjNode *theRock; theEnemy->ChainNode = nil; theRock->ChainHead = nil; theRock->Delta = gDelta; - + theRock->CType = CTYPE_HURTME; - theRock->CBits = CBITS_TOUCHABLE; + theRock->CBits = CBITS_TOUCHABLE; theRock->Damage = .1; SetObjectCollisionBounds(theRock,30,-30,-30,30,30,-30); @@ -254,21 +254,21 @@ float r,aim,dist,fps = gFramesPerSecondFrac; float occ,y; /* AIM AT PLAYER */ - - aim = TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, PTERA_TURN_SPEED, true); - - + + aim = TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, PTERA_TURN_SPEED, true); + + /* MOVE IT */ - + occ = theNode->Occillate += fps * 2.0f; // inc occilation index - + r = theNode->Rot.y; - theNode->Speed = PTERA_WALK_SPEED; + theNode->Speed = PTERA_WALK_SPEED; gDelta.x = -sin(r) * PTERA_WALK_SPEED; gDelta.z = -cos(r) * PTERA_WALK_SPEED; y = gMyCoord.y + 200 + cos(occ)*150; // calc desired y offset gDelta.y = (y - gCoord.y); - + MoveEnemy(theNode,-FLIGHT_HEIGHT); @@ -282,7 +282,7 @@ float occ,y; /* SEE IF SHOULD ATTACK */ - + if (aim < 0.5f) { if ((gCoord.y - gMyCoord.y) > 100.0f) // must be above me a ways @@ -300,14 +300,14 @@ float occ,y; } } - + /* DO ENEMY COLLISION */ - + if (DoEnemyCollisionDetect(theNode,DEFAULT_ENEMY_COLLISION_CTYPES&(~CTYPE_BGROUND2))) // normal collision but no BG2 for flying things return; - UpdateEnemy(theNode); + UpdateEnemy(theNode); } @@ -320,16 +320,16 @@ float fps = gFramesPerSecondFrac; Boolean onGround; /* MOVE TOWARD PLAYER */ - - TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, PTERA_TURN_SPEED*1.5, false); - + TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, PTERA_TURN_SPEED*1.5, false); + + /* MOVE IT */ r = theNode->Rot.y; gDelta.x = -sin(r) * PTERA_WALK_SPEED; gDelta.z = -cos(r) * PTERA_WALK_SPEED; - + dy = (gMyCoord.y + 80 - gCoord.y) * 2.3f; gDelta.y += dy * fps; @@ -343,14 +343,14 @@ Boolean onGround; MorphToSkeletonAnim(theNode->Skeleton, PTERA_ANIM_FLY,2); } - + /* DO ENEMY COLLISION */ - + if (DoEnemyCollisionDetect(theNode,DEFAULT_ENEMY_COLLISION_CTYPES)) return; - UpdateEnemy(theNode); + UpdateEnemy(theNode); } @@ -363,21 +363,21 @@ float r,aim,dist,fps = gFramesPerSecondFrac; float occ,y; /* AIM AT PLAYER */ - - aim = TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, PTERA_TURN_SPEED, true); - - + + aim = TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, PTERA_TURN_SPEED, true); + + /* MOVE IT */ - + occ = theNode->Occillate += fps * 2.0f; // inc occilation index - + r = theNode->Rot.y; - theNode->Speed = PTERA_WALK_SPEED; + theNode->Speed = PTERA_WALK_SPEED; gDelta.x = -sin(r) * PTERA_WALK_SPEED; gDelta.z = -cos(r) * PTERA_WALK_SPEED; y = gMyCoord.y + 300 + cos(occ)*150; // calc desired y offset gDelta.y = (y - gCoord.y); - + MoveEnemy(theNode,-FLIGHT_HEIGHT); @@ -392,7 +392,7 @@ float occ,y; /***************************/ /* SEE IF SHOULD DROP ROCK */ /***************************/ - + if (aim < 0.5f) { if ((gCoord.y - gMyCoord.y) > 100.0f) // must be above me a ways @@ -410,19 +410,12 @@ float occ,y; } } - + /* DO ENEMY COLLISION */ - + if (DoEnemyCollisionDetect(theNode,DEFAULT_ENEMY_COLLISION_CTYPES&(~CTYPE_BGROUND2))) // normal collision but no BG2 for flying things return; - UpdateEnemy(theNode); + UpdateEnemy(theNode); } - - - - - - - diff --git a/src/Enemies/Enemy_Rex.c b/src/Enemies/Enemy_Rex.c index 0440a64..d665dff 100644 --- a/src/Enemies/Enemy_Rex.c +++ b/src/Enemies/Enemy_Rex.c @@ -41,8 +41,8 @@ static void MoveRex_Pounce(ObjNode *theNode); #define MAX_WALK_SPEED 200.0f -#define REX_HEALTH 1.0f -#define REX_DAMAGE 0.04f +#define REX_HEALTH 2.0f +#define REX_DAMAGE 0.08f #define REX_SCALE 1.2f @@ -78,33 +78,33 @@ ObjNode *newObj; if (gNumEnemies >= MAX_ENEMIES) // keep from getting absurd return(false); - if (!(itemPtr->parm[3] & 1)) // see if always add + if (!(itemPtr->parm[3] & 1)) // see if always add { if (gNumEnemyOfKind[ENEMY_KIND_REX] >= MAX_REX) return(false); } /* MAKE DEFAULT SKELETON ENEMY */ - + newObj = MakeEnemySkeleton(SKELETON_TYPE_REX,x,z); if (newObj == nil) return(false); newObj->TerrainItemPtr = itemPtr; SetSkeletonAnim(newObj->Skeleton, REX_ANIM_WALK); - + /* SET BETTER INFO */ - - newObj->Coord.y -= FOOT_OFFSET; + + newObj->Coord.y -= FOOT_OFFSET; newObj->MoveCall = MoveRex; // set move call newObj->Health = REX_HEALTH; newObj->Damage = REX_DAMAGE; newObj->Kind = ENEMY_KIND_REX; newObj->Scale.x = newObj->Scale.y = newObj->Scale.z = REX_SCALE; // set scale newObj->Radius *= REX_SCALE; - + /* SET COLLISION INFO */ - + SetObjectCollisionBounds(newObj, 120,FOOT_OFFSET,-120,120,120,-120); @@ -113,7 +113,7 @@ ObjNode *newObj; /* MAKE SHADOW */ - + AttachShadowToObject(newObj, 2.6, 2.6*2.5); gNumEnemies++; @@ -142,7 +142,7 @@ static void(*myMoveTable[])(ObjNode *) = } GetObjectInfo(theNode); - + myMoveTable[theNode->Skeleton->AnimNum](theNode); } @@ -153,12 +153,12 @@ static void MoveRex_Standing(ObjNode *theNode) MorphToSkeletonAnim(theNode->Skeleton, REX_ANIM_WALK,5); /* DO ENEMY COLLISION */ - + if (DoEnemyCollisionDetect(theNode,DEFAULT_ENEMY_COLLISION_CTYPES)) return; - UpdateEnemy(theNode); - + UpdateEnemy(theNode); + } @@ -171,11 +171,11 @@ float r,speed,dist,fps,aim; fps = gFramesPerSecondFrac; /* MOVE TOWARD PLAYER */ - - aim = TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, REX_TURN_SPEED, true); + + aim = TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, REX_TURN_SPEED, true); r = theNode->Rot.y; - speed = theNode->Speed = MAX_WALK_SPEED; + speed = theNode->Speed = MAX_WALK_SPEED; gDelta.x = -sin(r) * speed; gDelta.z = -cos(r) * speed; gDelta.y -= GRAVITY_CONSTANT*fps; // add gravity @@ -183,13 +183,13 @@ float r,speed,dist,fps,aim; MoveEnemy(theNode, theNode->BottomOff); /* SEE IF RETURN TO STANDING */ - + dist = CalcQuickDistance(gCoord.x+theNode->TargetOff.x, gCoord.z+theNode->TargetOff.y, gMyCoord.x, gMyCoord.z); if (dist > (REX_MAX_ATTACK_RANGE*1.3f)) MorphToSkeletonAnim(theNode->Skeleton, REX_ANIM_STAND,3); /* SEE IF CLOSE ENOUGH TO POUNCE */ - else + else if (dist < REX_MIN_ATTACK_RANGE) { if (aim < 0.5f) // must be aimed mostly at me @@ -209,10 +209,10 @@ float r,speed,dist,fps,aim; { CalcNewTargetOffsets(theNode,REX_TARGET_SCALE); theNode->TargetChangeTimer = 0; - - + + /* MAKE ROAR */ - + if ((MyRandomLong()&3) < 2) // see if roar { long volume = FULL_CHANNEL_VOLUME - (long)(dist * .15f); @@ -221,18 +221,18 @@ float r,speed,dist,fps,aim; } } - + /* UPDATE ANIM SPEED */ theNode->Skeleton->AnimSpeed = speed * .005f; - + /* DO ENEMY COLLISION */ - + if (DoEnemyCollisionDetect(theNode,DEFAULT_ENEMY_COLLISION_CTYPES)) return; - - UpdateEnemy(theNode); + + UpdateEnemy(theNode); } @@ -249,18 +249,18 @@ Boolean onGround; fps = gFramesPerSecondFrac; /* MOVE HIM */ - + r = theNode->Rot.y; - speed = theNode->Speed; + speed = theNode->Speed; gDelta.x = -sin(r) * speed; gDelta.z = -cos(r) * speed; gDelta.y -= GRAVITY_CONSTANT*fps; // add gravity onGround = MoveEnemy(theNode, theNode->BottomOff); - + /* SEE IF RETURN TO STANDING */ - + if (theNode->IsPouncingFlag && onGround) // see if landed on something solid { theNode->IsPouncingFlag = false; @@ -273,7 +273,7 @@ Boolean onGround; PlayEffect_Parms(EFFECT_FOOTSTEP,FULL_CHANNEL_VOLUME,kMiddleC-5); // play sound } /* SEE IF DONE WITH LANDING */ - + else if (theNode->Skeleton->AnimNum) { @@ -282,11 +282,11 @@ Boolean onGround; } /* SEE IF START POUNCE NOW */ - + if (theNode->PounceFlag) { dist = CalcQuickDistance(gCoord.x, gCoord.z, gMyCoord.x, gMyCoord.z); - theNode->PounceFlag = false; + theNode->PounceFlag = false; theNode->IsPouncingFlag = true; theNode->Speed = (POUNCE_SPEED * dist) + 50; gDelta.y = POUNCE_YACC; @@ -295,16 +295,12 @@ Boolean onGround; } /* DO ENEMY COLLISION */ - + if (DoEnemyCollisionDetect(theNode,DEFAULT_ENEMY_COLLISION_CTYPES)) return; - - UpdateEnemy(theNode); -} - - - + UpdateEnemy(theNode); +} diff --git a/src/Enemies/Enemy_Spitter.c b/src/Enemies/Enemy_Spitter.c index d9a6485..b79fd3a 100644 --- a/src/Enemies/Enemy_Spitter.c +++ b/src/Enemies/Enemy_Spitter.c @@ -32,13 +32,13 @@ static void MoveDinoSpit(ObjNode *theNode); #define SPITTER_MIN_ATTACK_RANGE 300.0f #define SPITTER_TURN_SPEED 3.5f -#define SPITTER_WALK_SPEED 380.0f +#define SPITTER_WALK_SPEED 400.0f #define SPITTER_TARGET_SCALE 200.0f -#define SPITTER_HEALTH 0.8f -#define SPITTER_DAMAGE 0.01f +#define SPITTER_HEALTH 2f +#define SPITTER_DAMAGE 0.02f #define SPITTER_SCALE .8f @@ -75,34 +75,34 @@ ObjNode *newObj; if (gNumEnemies >= MAX_ENEMIES) // keep from getting absurd return(false); - if (!(itemPtr->parm[3] & 1)) // see if always add + if (!(itemPtr->parm[3] & 1)) // see if always add { if (gNumEnemyOfKind[ENEMY_KIND_SPITTER] >= MAX_SPITTER) return(false); } /* MAKE DEFAULT SKELETON ENEMY */ - + newObj = MakeEnemySkeleton(SKELETON_TYPE_SPITTER,x,z); if (newObj == nil) return(false); newObj->TerrainItemPtr = itemPtr; SetSkeletonAnim(newObj->Skeleton, SPITTER_ANIM_WALK); - + /* SET BETTER INFO */ - - newObj->Coord.y -= FOOT_OFFSET; + + newObj->Coord.y -= FOOT_OFFSET; newObj->MoveCall = MoveSpitter; // set move call newObj->Health = SPITTER_HEALTH; newObj->Damage = SPITTER_DAMAGE; newObj->Kind = ENEMY_KIND_SPITTER; newObj->Scale.x = newObj->Scale.y = newObj->Scale.z = SPITTER_SCALE; // set scale newObj->Radius *= SPITTER_SCALE; - + /* SET COLLISION INFO */ - + SetObjectCollisionBounds(newObj, 80,FOOT_OFFSET,-90,90,90,-90); @@ -112,7 +112,7 @@ ObjNode *newObj; /* MAKE SHADOW */ - + AttachShadowToObject(newObj, 1.6, 1.6*2.5); gNumEnemies++; @@ -152,13 +152,13 @@ float d; /* SEE IF IN WALK RANGE */ - + d = CalcQuickDistance(gCoord.x+theNode->TargetOff.x, gCoord.z+theNode->TargetOff.y, gMyCoord.x, gMyCoord.z); if ((d < SPITTER_MAX_ATTACK_RANGE) && (d > SPITTER_MIN_ATTACK_RANGE)) MorphToSkeletonAnim(theNode->Skeleton, SPITTER_ANIM_WALK,7); /* SEE IF SHOULD SPIT */ - + else { theNode->SpitTimer -= gFramesPerSecondFrac; // dec timer @@ -171,19 +171,19 @@ float d; } /* IF CLOSE, KEEP AIMED AT ME */ - + if (d < (SPITTER_MIN_ATTACK_RANGE * 2.0f)) { - TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, SPITTER_TURN_SPEED/3, false); + TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, SPITTER_TURN_SPEED/3, false); } /* DO ENEMY COLLISION */ - + if (DoEnemyCollisionDetect(theNode,DEFAULT_ENEMY_COLLISION_CTYPES)) return; - UpdateEnemy(theNode); - + UpdateEnemy(theNode); + } @@ -194,11 +194,11 @@ static void MoveSpitter_Walking(ObjNode *theNode) float r,speed,dist; /* MOVE TOWARD PLAYER */ - - TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, SPITTER_TURN_SPEED, true); + + TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, SPITTER_TURN_SPEED, true); r = theNode->Rot.y; - speed = theNode->Speed = SPITTER_WALK_SPEED; + speed = theNode->Speed = SPITTER_WALK_SPEED; gDelta.x = -sin(r) * speed; gDelta.z = -cos(r) * speed; gDelta.y -= GRAVITY_CONSTANT*gFramesPerSecondFrac; // add gravity @@ -207,7 +207,7 @@ float r,speed,dist; /* SEE IF OUT OF WALK-RANGE */ - + dist = CalcQuickDistance(gCoord.x+theNode->TargetOff.x, gCoord.z+theNode->TargetOff.y, gMyCoord.x, gMyCoord.z); if (dist > (SPITTER_MAX_ATTACK_RANGE*1.3f)) { @@ -237,18 +237,18 @@ float r,speed,dist; CalcNewTargetOffsets(theNode,SPITTER_TARGET_SCALE); theNode->TargetChangeTimer = 0; } - + /* UPDATE ANIM SPEED */ theNode->Skeleton->AnimSpeed = speed * .008f; - + /* DO ENEMY COLLISION */ - + if (DoEnemyCollisionDetect(theNode,DEFAULT_ENEMY_COLLISION_CTYPES)) return; - - UpdateEnemy(theNode); + + UpdateEnemy(theNode); } /********************** MOVE SPITTER: SPITTING ******************************/ @@ -257,21 +257,21 @@ static void MoveSpitter_Spitting(ObjNode *theNode) { /* SEE IF CAN SHOOT SPIT NOW */ - + if (theNode->ShootSpitFlag) { ShootSpit(theNode); - + } - + /* SEE IF DONE WITH ANIM */ - + if (theNode->Skeleton->AnimHasStopped) - { + { float d; /* FIGURE OUT WHICH ANIM TO GO TO */ - + d = CalcQuickDistance(gCoord.x+theNode->TargetOff.x, gCoord.z+theNode->TargetOff.y, gMyCoord.x, gMyCoord.z); if ((d < SPITTER_MAX_ATTACK_RANGE) && (d > SPITTER_MIN_ATTACK_RANGE)) MorphToSkeletonAnim(theNode->Skeleton, SPITTER_ANIM_WALK,7); @@ -283,12 +283,12 @@ static void MoveSpitter_Spitting(ObjNode *theNode) } /* DO ENEMY COLLISION */ - + if (DoEnemyCollisionDetect(theNode,DEFAULT_ENEMY_COLLISION_CTYPES)) return; - UpdateEnemy(theNode); - + UpdateEnemy(theNode); + } @@ -303,29 +303,29 @@ TQ3Vector3D vector; ObjNode *newObj; /* SEE IF TIME TO SPIT */ - + theNode->SpitRegulator += gFramesPerSecondFrac; if (theNode->SpitRegulator < .08f) return; - - theNode->SpitRegulator = 0; - + + theNode->SpitRegulator = 0; + /* CALCULATE COORD OF MOUTH */ - + FindJointFullMatrix(theNode, 2, &matrix); Q3Point3D_Transform(&originOff, &matrix, &gNewObjectDefinition.coord); /* CALC DIRECTIONAL VECTOR FOR SPEW */ - + Q3Vector3D_Transform(&inVector, &matrix, &vector); /* MAKE SPIT WAD */ - gNewObjectDefinition.group = GLOBAL_MGroupNum_DinoSpit; - gNewObjectDefinition.type = GLOBAL_MObjType_DinoSpit; + gNewObjectDefinition.group = GLOBAL_MGroupNum_DinoSpit; + gNewObjectDefinition.type = GLOBAL_MObjType_DinoSpit; gNewObjectDefinition.flags = 0; gNewObjectDefinition.slot = 100; gNewObjectDefinition.moveCall = MoveDinoSpit; @@ -341,8 +341,8 @@ ObjNode *newObj; newObj->CType = CTYPE_HURTME; newObj->CBits = CBITS_TOUCHABLE; newObj->Damage = .1; - - + + SetObjectCollisionBounds(newObj,20,-20,-20,20,20,-20); } } @@ -358,11 +358,11 @@ float y,fps; /* APPLY GRAVITY */ - fps = gFramesPerSecondFrac; + fps = gFramesPerSecondFrac; gDelta.y -= fps * (GRAVITY_CONSTANT/6); /* MOVE IT */ - + gCoord.x += gDelta.x * fps; gCoord.y += gDelta.y * fps; gCoord.z += gDelta.z * fps; @@ -372,7 +372,7 @@ float y,fps; y = GetTerrainHeightAtCoord_Quick(gCoord.x,gCoord.z); if (gCoord.y <= y) { -del: +del: DeleteObject(theNode); return; } @@ -385,10 +385,3 @@ float y,fps; UpdateObject(theNode); } - - - - - - - diff --git a/src/Enemies/Enemy_Stego.c b/src/Enemies/Enemy_Stego.c index ec6c4f6..194c587 100644 --- a/src/Enemies/Enemy_Stego.c +++ b/src/Enemies/Enemy_Stego.c @@ -26,15 +26,15 @@ static void MoveStego_Standing(ObjNode *theNode); /****************************/ #define STEGO_ATTACK_RANGE 700 -#define STEGO_TURN_SPEED .45 -#define MAX_WALK_SPEED 80 +#define STEGO_TURN_SPEED 1 +#define MAX_WALK_SPEED 100 #define STEGO_TARGET_SCALE 350 -#define STEGO_HEALTH 5.0 -#define STEGO_DAMAGE .2 +#define STEGO_HEALTH 6.0 +#define STEGO_DAMAGE .3 #define STEGO_SCALE 1.4 @@ -67,14 +67,14 @@ ObjNode *newObj; if (gNumEnemies >= MAX_ENEMIES) // keep from getting absurd return(false); - if (!(itemPtr->parm[3] & 1)) // see if always add + if (!(itemPtr->parm[3] & 1)) // see if always add { if (gNumEnemyOfKind[ENEMY_KIND_STEGO] >= MAX_STEGO) return(false); } /* MAKE DEFAULT SKELETON ENEMY */ - + newObj = MakeEnemySkeleton(SKELETON_TYPE_STEGO,x,z); if (newObj == nil) return(false); @@ -82,11 +82,11 @@ ObjNode *newObj; newObj->TerrainItemPtr = itemPtr; SetSkeletonAnim(newObj->Skeleton, STEGO_ANIM_STAND); - + newObj->Coord.y -= FOOT_OFFSET; // adjust y - + /* SET BETTER INFO */ - + newObj->MoveCall = MoveStego; // set move call newObj->Health = STEGO_HEALTH; @@ -95,19 +95,19 @@ ObjNode *newObj; newObj->Scale.x = newObj->Scale.y = newObj->Scale.z = STEGO_SCALE; // set scale newObj->Radius *= STEGO_SCALE; - + newObj->Rot.y = RandomFloat()*PI2; // random rotation - - + + /* SET COLLISION INFO */ - + SetObjectCollisionBounds(newObj, 90,FOOT_OFFSET,-130,130,130,-130); CalcNewTargetOffsets(newObj,STEGO_TARGET_SCALE); newObj->TargetChangeTimer = 0; /* MAKE SHADOW */ - + AttachShadowToObject(newObj, 5, 5*2); @@ -149,13 +149,13 @@ static void MoveStego_Standing(ObjNode *theNode) /* DO ENEMY COLLISION */ - + if (DoEnemyCollisionDetect(theNode,DEFAULT_ENEMY_COLLISION_CTYPES)) return; - UpdateEnemy(theNode); - + UpdateEnemy(theNode); + } @@ -168,11 +168,11 @@ float r; theNode->Skeleton->AnimSpeed = .5; // tweak speed to avoid moonwalking /* MOVE TOWARD PLAYER */ - - TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, STEGO_TURN_SPEED, true); + + TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, STEGO_TURN_SPEED, true); r = theNode->Rot.y; - theNode->Speed = MAX_WALK_SPEED; + theNode->Speed = MAX_WALK_SPEED; gDelta.x = -sin(r) * MAX_WALK_SPEED; gDelta.z = -cos(r) * MAX_WALK_SPEED; gDelta.y -= GRAVITY_CONSTANT*gFramesPerSecondFrac; // add gravity @@ -190,20 +190,11 @@ float r; CalcNewTargetOffsets(theNode,STEGO_TARGET_SCALE); theNode->TargetChangeTimer = 0; } - + /* DO ENEMY COLLISION */ - + if (DoEnemyCollisionDetect(theNode,DEFAULT_ENEMY_COLLISION_CTYPES)) return; - - UpdateEnemy(theNode); -} - - - - - - - - + UpdateEnemy(theNode); +} diff --git a/src/Enemies/Enemy_TriCer.c b/src/Enemies/Enemy_TriCer.c index 66ba13c..62bef00 100644 --- a/src/Enemies/Enemy_TriCer.c +++ b/src/Enemies/Enemy_TriCer.c @@ -27,14 +27,14 @@ static void MoveTricer_Standing(ObjNode *theNode); #define TRICER_ATTACK_RANGE 600 #define TRICER_ATTACK_RANGE_IN_BUSH 550 -#define TRICER_TURN_SPEED 1.5 +#define TRICER_TURN_SPEED 2.5 #define MAX_WALK_SPEED 240 #define TRICER_TARGET_SCALE 40 -#define TRICER_HEALTH 4.0 +#define TRICER_HEALTH 3.0 #define TRICER_DAMAGE .1 #define TRICER_SCALE 2.2 @@ -90,16 +90,16 @@ ObjNode *newObj; if (itemPtr) // (itemptr == nil if in bush) { - if (!(itemPtr->parm[3] & 1)) // see if always add + if (!(itemPtr->parm[3] & 1)) // see if always add { if (gNumEnemyOfKind[ENEMY_KIND_TRICER] >= MAX_TRICER) - return(false); + return(false); } } /* MAKE DEFAULT SKELETON ENEMY */ - + newObj = MakeEnemySkeleton(SKELETON_TYPE_TRICER,x,z); if (newObj == nil) return(false); @@ -109,11 +109,11 @@ ObjNode *newObj; newObj->TerrainItemPtr = itemPtr; SetSkeletonAnim(newObj->Skeleton, TRICER_ANIM_STAND); - + newObj->Coord.y -= FOOT_OFFSET; // adjust y - + /* SET BETTER INFO */ - + newObj->MoveCall = MoveTricer; // set move call newObj->Health = TRICER_HEALTH; @@ -122,18 +122,18 @@ ObjNode *newObj; newObj->Scale.x = newObj->Scale.y = newObj->Scale.z = TRICER_SCALE; // set scale newObj->Radius *= TRICER_SCALE; - + newObj->Rot.y = RandomFloat()*PI2; // random rotation - + /* SET COLLISION INFO */ - + SetObjectCollisionBounds(newObj, 90,FOOT_OFFSET,-120,120,120,-120); CalcNewTargetOffsets(newObj,TRICER_TARGET_SCALE); newObj->TargetChangeTimer = 0; /* MAKE SHADOW */ - + AttachShadowToObject(newObj, 2.7, 2.7*1.5); @@ -182,7 +182,7 @@ ObjNode *bushObj; if (CalcQuickDistance(gCoord.x+theNode->TargetOff.x, gCoord.z+theNode->TargetOff.y, gMyCoord.x, gMyCoord.z) < dist) { MorphToSkeletonAnim(theNode->Skeleton, TRICER_ANIM_WALK,5); - + if (theNode->InBush) { theNode->InBush = false; @@ -194,20 +194,20 @@ ObjNode *bushObj; } /* IF INSIDE BUSH, KEEP AIMED */ - + if (theNode->InBush) { - TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, TRICER_TURN_SPEED*10, false); + TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, TRICER_TURN_SPEED*10, false); } /* DO ENEMY COLLISION */ - + if (DoEnemyCollisionDetect(theNode,DEFAULT_ENEMY_COLLISION_CTYPES)) return; - UpdateEnemy(theNode); - + UpdateEnemy(theNode); + } @@ -220,11 +220,11 @@ float r; theNode->Skeleton->AnimSpeed = MAX_WALK_SPEED / 63.3; // tweak speed to sync /* MOVE TOWARD PLAYER */ - - TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, TRICER_TURN_SPEED, true); + + TurnObjectTowardTarget(theNode, gMyCoord.x, gMyCoord.z, TRICER_TURN_SPEED, true); r = theNode->Rot.y; - theNode->Speed = MAX_WALK_SPEED; + theNode->Speed = MAX_WALK_SPEED; gDelta.x = -sin(r) * MAX_WALK_SPEED; gDelta.z = -cos(r) * MAX_WALK_SPEED; gDelta.y -= GRAVITY_CONSTANT*gFramesPerSecondFrac; // add gravity @@ -234,20 +234,11 @@ float r; if (CalcQuickDistance(gCoord.x+theNode->TargetOff.x, gCoord.z+theNode->TargetOff.y, gMyCoord.x, gMyCoord.z) > (TRICER_ATTACK_RANGE*4)) MorphToSkeletonAnim(theNode->Skeleton, TRICER_ANIM_STAND,3); - + /* DO ENEMY COLLISION */ - + if (DoEnemyCollisionDetect(theNode,DEFAULT_ENEMY_COLLISION_CTYPES)) return; - - UpdateEnemy(theNode); -} - - - - - - - - + UpdateEnemy(theNode); +} From d30855572aae69a419b5f2e1cf6529e8c08be5a2 Mon Sep 17 00:00:00 2001 From: br4e <br4e@protonmail.com> Date: Sat, 6 Aug 2022 11:30:04 -0700 Subject: [PATCH 04/20] 1 hour game --- src/Headers/infobar.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Headers/infobar.h b/src/Headers/infobar.h index a1364a4..ede815f 100644 --- a/src/Headers/infobar.h +++ b/src/Headers/infobar.h @@ -4,7 +4,7 @@ #define MAX_FUEL_CAPACITY (29-1) #define NUM_EGG_SPECIES 5 -#define LEVEL_DURATION (60*20) // n seconds +#define LEVEL_DURATION 3599 // 1 hour enum { @@ -30,4 +30,3 @@ extern void AddToScore(long points); extern void DoPaused(void); extern void DecAsteroidTimer(void); extern void GetHealth(float amount); - From 476ab43d59f6716136bdb6dbdf4913432de0d4fa Mon Sep 17 00:00:00 2001 From: br4e <br4e@protonmail.com> Date: Sat, 6 Aug 2022 12:18:23 -0700 Subject: [PATCH 05/20] Better heatseaker --- src/Player/Weapons.c | 423 +++++++++++++++++++++---------------------- 1 file changed, 208 insertions(+), 215 deletions(-) diff --git a/src/Player/Weapons.c b/src/Player/Weapons.c index e7a3a3e..911b5bc 100644 --- a/src/Player/Weapons.c +++ b/src/Player/Weapons.c @@ -51,7 +51,7 @@ extern const float NUKE_RATE; #define BLASTER_SPEED 1100 #define BLASTER_DAMAGE .4 -#define HEATSEEK_SPEED 700 +#define HEATSEEK_SPEED 900 #define HEATSEEK_DAMAGE .8 #define TRIBLAST_SPEED 1100 @@ -88,9 +88,9 @@ short i; gCurrentAttackMode = ATTACK_MODE_BLASTER; gAutoFireCounter = 0; gSonicScreamWave = 0; - + /* INIT ATTACK MODE POWERUPS */ - + for (i=0; i < NUM_ATTACK_MODES; i++) gPossibleAttackModes[i] = false; @@ -98,17 +98,17 @@ short i; gWeaponInventory[ATTACK_MODE_BLASTER] = 50; gPossibleAttackModes[ATTACK_MODE_HEATSEEK] = false; - gWeaponInventory[ATTACK_MODE_HEATSEEK] = 0; + gWeaponInventory[ATTACK_MODE_HEATSEEK] = 10; gPossibleAttackModes[ATTACK_MODE_SONICSCREAM] = false; - gWeaponInventory[ATTACK_MODE_SONICSCREAM] = 0; + gWeaponInventory[ATTACK_MODE_SONICSCREAM] = 10; gPossibleAttackModes[ATTACK_MODE_TRIBLAST] = false; - gWeaponInventory[ATTACK_MODE_TRIBLAST] = 0; + gWeaponInventory[ATTACK_MODE_TRIBLAST] = 25; gPossibleAttackModes[ATTACK_MODE_NUKE] = false; - gWeaponInventory[ATTACK_MODE_NUKE] = 0; - + gWeaponInventory[ATTACK_MODE_NUKE] = 1; + gInfobarUpdateBits |= UPDATE_WEAPONICON; } @@ -124,17 +124,17 @@ void GetCheatWeapons(void) gWeaponInventory[ATTACK_MODE_BLASTER] = 999; gPossibleAttackModes[ATTACK_MODE_HEATSEEK] = true; - gWeaponInventory[ATTACK_MODE_HEATSEEK] = 999; + gWeaponInventory[ATTACK_MODE_HEATSEEK] = 999; gPossibleAttackModes[ATTACK_MODE_SONICSCREAM] = true; - gWeaponInventory[ATTACK_MODE_SONICSCREAM] = 999; + gWeaponInventory[ATTACK_MODE_SONICSCREAM] = 999; gPossibleAttackModes[ATTACK_MODE_TRIBLAST] = true; - gWeaponInventory[ATTACK_MODE_TRIBLAST] = 999; + gWeaponInventory[ATTACK_MODE_TRIBLAST] = 999; gPossibleAttackModes[ATTACK_MODE_NUKE] = true; - gWeaponInventory[ATTACK_MODE_NUKE] = 999; - + gWeaponInventory[ATTACK_MODE_NUKE] = 999; + gInfobarUpdateBits |= UPDATE_WEAPONICON; } @@ -147,7 +147,7 @@ static const short quans[] = { 25, // blaster 10, // heat seek - 50, // sonic scream + 25, // sonic scream 30, // triblast 1, // Nuke 25, @@ -155,13 +155,13 @@ static const short quans[] = 25 }; /* SEE IF USE DEFAULT QUANTITY */ - + if (quantity == 0) quantity = quans[kind]; - - + + /* ADD TO INVENTORY */ - + gPossibleAttackModes[kind] = true; // we now have this weapon gWeaponInventory[kind] += quantity; // inc inventory count if (gWeaponInventory[kind] > 999) @@ -179,21 +179,21 @@ void CheckIfMeAttack(ObjNode *theNode) /*****************/ /* SEE IF ATTACK */ /*****************/ - + if ((gMyControlBits & KEYCONTROL_ATTACK) && (gWeaponInventory[gCurrentAttackMode] > 0)) - { + { /* SEE WHICH ATTACK */ - + switch(gCurrentAttackMode) { case ATTACK_MODE_BLASTER: ShootBlaster(theNode); - break; + break; case ATTACK_MODE_HEATSEEK: ShootHeatSeek(theNode); break; - + case ATTACK_MODE_SONICSCREAM: ShootSonicScream(theNode); break; @@ -201,7 +201,7 @@ void CheckIfMeAttack(ObjNode *theNode) case ATTACK_MODE_NUKE: ShootNuke(theNode); break; - + case ATTACK_MODE_TRIBLAST: ShootTriBlast(theNode); break; @@ -209,9 +209,9 @@ void CheckIfMeAttack(ObjNode *theNode) } else gAutoFireCounter = 1.0; // not shooting now, so ready to shoot immediately -} - - +} + + /************************** DO BULLET COLLISION DETECT ************************/ // // OUTPUT: true = hit something @@ -225,35 +225,35 @@ ObjNode *hitObj; /*************************/ /* CREATE COLLISION LIST */ /*************************/ - + /* FIRST DO SIMPLE POINT COLLISION */ - + numCollisions = DoSimplePointCollision(&gCoord, CTYPE_ENEMY|CTYPE_PLAYER|CTYPE_MISC|CTYPE_CRYSTAL); if (numCollisions == 0) { - DoTriangleCollision(theBullet, CTYPE_MISC); + DoTriangleCollision(theBullet, CTYPE_MISC); if (gNumCollisions == 0) return(false); - + } /* SEE WHAT WE HIT */ - + for (i = 0; i < numCollisions; i++) { hitObj = gCollisionList[i].objectPtr; // get objnode of collision if (hitObj) { /* BULLET HIT AN ENEMY */ - + if (hitObj->CType & CTYPE_ENEMY) { EnemyGotHurt(hitObj, theBullet, theBullet->Damage); // hurt the enemy } - + /* BULLET HIT A CRYSTAL */ - + else if (hitObj->CType & CTYPE_CRYSTAL) { @@ -262,14 +262,14 @@ ObjNode *hitObj; break; } } - - + + /* EXPLODE THE BULLET */ - + ExplodeBullet(theBullet); return(true); } - + /****************** EXPLODE BULLET *********************/ static void ExplodeBullet(ObjNode *theNode) @@ -278,15 +278,15 @@ float d; long volume; /* SPECIAL IF NUKE */ - + if (theNode->Kind == ATTACK_MODE_NUKE) { DetonateNuke(theNode); return; } - + /* SPECIAL IF SONIC SCREAM */ - + else if (theNode->Kind == ATTACK_MODE_SONICSCREAM) { @@ -296,7 +296,7 @@ long volume; /* GENERIC */ - + DeleteObject(theNode); MakeExplosion(&theNode->Coord); @@ -305,7 +305,7 @@ long volume; if (volume > 0) PlayEffect_Parms(EFFECT_EXPLODE,volume,kMiddleC); // play sound -} +} /********************** MAKE EXPLOSION *****************************/ @@ -315,10 +315,10 @@ static void MakeExplosion(TQ3Point3D *coord) ObjNode *newObj; gNewObjectDefinition.coord = *coord; - gNewObjectDefinition.group = GLOBAL_MGroupNum_Explosion; - gNewObjectDefinition.type = GLOBAL_MObjType_Explosion; + gNewObjectDefinition.group = GLOBAL_MGroupNum_Explosion; + gNewObjectDefinition.type = GLOBAL_MObjType_Explosion; gNewObjectDefinition.flags = 0; - gNewObjectDefinition.slot = SLOT_OF_DUMB; + gNewObjectDefinition.slot = SLOT_OF_DUMB; gNewObjectDefinition.moveCall = MoveExplosion; gNewObjectDefinition.rot = 0; gNewObjectDefinition.scale = 1; @@ -327,7 +327,7 @@ ObjNode *newObj; { newObj->Health = .9; MakeObjectTransparent(newObj, newObj->Health); // make transparent - } + } } @@ -343,15 +343,15 @@ float fps = gFramesPerSecondFrac; DeleteObject(theNode); return; } - + MakeObjectTransparent(theNode, theNode->Health); theNode->Scale.x = theNode->Scale.y = theNode->Scale.z += fps * 20; UpdateObjectTransforms(theNode); } - - + + /****************** SHOOT SONIC SCREAM ***********************/ static void ShootSonicScream(ObjNode *theNode) @@ -367,15 +367,15 @@ float r,fps; if (gAutoFireCounter >= 1.0) { gAutoFireCounter -= 1.0; - + /* CALC START COORD */ - + FindCoordOnJoint(theNode, MYGUY_LIMB_GUN, &gGunTipOffset, &gNewObjectDefinition.coord); - + /* MAKE MODEL */ - - gNewObjectDefinition.group = GLOBAL_MGroupNum_SonicScream; - gNewObjectDefinition.type = GLOBAL_MObjType_SonicScream; + + gNewObjectDefinition.group = GLOBAL_MGroupNum_SonicScream; + gNewObjectDefinition.type = GLOBAL_MObjType_SonicScream; gNewObjectDefinition.flags = STATUS_BIT_KEEPBACKFACES | STATUS_BIT_NULLSHADER; gNewObjectDefinition.slot = PLAYER_SLOT-1; // dont update till next loop gNewObjectDefinition.moveCall = MoveSonicScream; @@ -387,25 +387,25 @@ float r,fps; gSonicScreamWave += fps*25; - newObj->Kind = ATTACK_MODE_SONICSCREAM; + newObj->Kind = ATTACK_MODE_SONICSCREAM; newObj->Health = .7; // transparency value - + newObj->Delta.x = (-sin(r) * SONIC_SCREAM_SPEED) + gDelta.x; // calc deltas newObj->Delta.z = (-cos(r) * SONIC_SCREAM_SPEED) + gDelta.z; MakeObjectTransparent(newObj, newObj->Health); - - + + /* MAKE COLLISION BOX */ - + newObj->CType = CTYPE_MYBULLET; // note: don't set as CTYPE_HURTENEMY since bullets do their own collision check newObj->CBits = CBITS_TOUCHABLE; // .. which also means I don't need a collision box since bullets use point collision checks - + newObj->Damage = SONIC_SCREAM_DAMAGE; /* UPDATE INFOBAR */ - + if (--gWeaponInventory[gCurrentAttackMode] == 0) // dec inventory & if run out, select next weapon NextAttackMode(); gInfobarUpdateBits |= UPDATE_WEAPONICON; // tell system to update this at end of frame @@ -430,14 +430,14 @@ float x,y,z; DeleteObject(theNode); return; } - + GetObjectInfo(theNode); - + MakeObjectTransparent(theNode, theNode->Health); /* MOVE IT */ - + theNode->Scale.x += fps * 1.0; theNode->Scale.y += fps * 1.0; theNode->Scale.z += fps * 1.0; @@ -448,7 +448,7 @@ float x,y,z; /* SEE IF HIT TERRAIN */ - + if (y <= GetTerrainHeightAtCoord_Planar(x,z)) { ExplodeBullet(theNode); @@ -456,7 +456,7 @@ float x,y,z; } /* DO BULLET COLLISION */ - + if (DoBulletCollisionDetect(theNode)) return; @@ -474,20 +474,20 @@ static void ShootBlaster(ObjNode *theNode) ObjNode *newObj; float r; - gAutoFireCounter += gFramesPerSecondFrac * BLASTER_RATE; // check auto fire timer + gAutoFireCounter += gFramesPerSecondFrac * BLASTER_RATE; // check auto fire timer if (gAutoFireCounter >= 1.0) { gAutoFireCounter -= 1.0; - + /* CALC START COORD */ - + FindCoordOnJoint(theNode, MYGUY_LIMB_GUN, &gGunTipOffset, &gNewObjectDefinition.coord); - - + + /* MAKE MODEL */ - - gNewObjectDefinition.group = GLOBAL_MGroupNum_Blaster; - gNewObjectDefinition.type = GLOBAL_MObjType_Blaster; + + gNewObjectDefinition.group = GLOBAL_MGroupNum_Blaster; + gNewObjectDefinition.type = GLOBAL_MObjType_Blaster; gNewObjectDefinition.flags = 0; gNewObjectDefinition.slot = PLAYER_SLOT-1; // dont update till next loop gNewObjectDefinition.moveCall = MoveBlaster; @@ -497,22 +497,22 @@ float r; if (newObj == nil) return; - newObj->Health = 1.0; - - newObj->Kind = ATTACK_MODE_BLASTER; + newObj->Health = 1.0; + + newObj->Kind = ATTACK_MODE_BLASTER; newObj->Delta.x = (-sin(r) * BLASTER_SPEED) + gDelta.x; // calc deltas newObj->Delta.z = (-cos(r) * BLASTER_SPEED) + gDelta.z; - + newObj->CType = CTYPE_MYBULLET; // note: don't set as CTYPE_HURTENEMY since bullets do their own collision check newObj->CBits = CBITS_TOUCHABLE; // .. which also means I don't need a collision box since bullets use point collision checks - + newObj->Damage = BLASTER_DAMAGE; - + PlayEffect(EFFECT_BLASTER); // play sound - + /* UPDATE INFOBAR */ - + if (--gWeaponInventory[gCurrentAttackMode] == 0) // dec inventory & if run out, select next weapon { gPossibleAttackModes[gCurrentAttackMode] = false; @@ -535,23 +535,23 @@ float x,y,z,fps; fps = gFramesPerSecondFrac; /* DECAY IT */ - + theNode->Health -= .9 * fps; if (theNode->Health < 0) { DeleteObject(theNode); return; } - + /* MOVE IT */ - + x = gCoord.x += gDelta.x * fps; y = gCoord.y += gDelta.y * fps; z = gCoord.z += gDelta.z * fps; /* SEE IF HIT TERRAIN */ - + if (y <= GetTerrainHeightAtCoord_Planar(x,z)) { ExplodeBullet(theNode); @@ -559,7 +559,7 @@ float x,y,z,fps; } /* DO BULLET COLLISION */ - + if (DoBulletCollisionDetect(theNode)) return; @@ -584,16 +584,16 @@ float r; if (gAutoFireCounter >= 1.0) { gAutoFireCounter -= 1.0; - + /* CALC START COORD */ - + FindCoordOnJoint(theNode, MYGUY_LIMB_GUN, &gGunTipOffset, &gNewObjectDefinition.coord); - - + + /* MAKE MODEL */ - - gNewObjectDefinition.group = GLOBAL_MGroupNum_HeatSeek; - gNewObjectDefinition.type = GLOBAL_MObjType_HeatSeek; + + gNewObjectDefinition.group = GLOBAL_MGroupNum_HeatSeek; + gNewObjectDefinition.type = GLOBAL_MObjType_HeatSeek; gNewObjectDefinition.flags = 0; gNewObjectDefinition.slot = PLAYER_SLOT-1; // dont update till next loop gNewObjectDefinition.moveCall = MoveHeatSeek; @@ -603,27 +603,27 @@ float r; if (newObj == nil) return; - newObj->Health = 1.0; - - newObj->Kind = ATTACK_MODE_HEATSEEK; + newObj->Health = 1.0; + + newObj->Kind = ATTACK_MODE_HEATSEEK; newObj->Delta.x = (-sin(r) * HEATSEEK_SPEED) + gDelta.x; // calc deltas newObj->Delta.z = (-cos(r) * HEATSEEK_SPEED) + gDelta.z; - - + + /* MAKE COLLISION BOX */ - + newObj->CType = CTYPE_MYBULLET; // note: don't set as CTYPE_HURTENEMY since bullets do their own collision check newObj->CBits = CBITS_TOUCHABLE; // .. which also means I don't need a collision box since bullets use point collision checks - - newObj->Damage = HEATSEEK_DAMAGE; + + newObj->Damage = HEATSEEK_DAMAGE; newObj->SpecialF[0] = 0; // init auto-target delay PlayEffect(EFFECT_HEATSEEK); // play sound /* UPDATE INFOBAR */ - + if (--gWeaponInventory[gCurrentAttackMode] == 0) // dec inventory & if run out, select next weapon { gPossibleAttackModes[gCurrentAttackMode] = false; @@ -649,85 +649,86 @@ short num,i; /* DECAY LIFE */ - theNode->Health -= .5 * fps; + theNode->Health -= .25 * fps; if (theNode->Health < 0) { DeleteObject(theNode); return; } - + GetObjectInfo(theNode); - - + + /* FIND CLOSEST ENEMY & ACCEL TO IT */ - theNode->SpecialF[0] += fps * 4; + theNode->SpecialF[0] += fps * 6; enemyObj = FindClosestEnemy(&gCoord, &dist); // get closest if (enemyObj) { y = enemyObj->Coord.y + ((enemyObj->BottomOff + enemyObj->TopOff)>>1); // calc center y of enemy as target y gDelta.y += (y - gCoord.y) * fps; - + + turnSp = theNode->SpecialF[0]; // calc turn speed - if (turnSp > 7) - turnSp = 7; + if (turnSp > 40) + turnSp = 40; TurnObjectTowardTarget(theNode, enemyObj->Coord.x, // rotate toward target - enemyObj->Coord.z, turnSp, false); - + enemyObj->Coord.z, turnSp, false); + r = theNode->Rot.y; // calc deltas based on aiming gDelta.x = -sin(r) * HEATSEEK_SPEED; - gDelta.z = -cos(r) * HEATSEEK_SPEED; + gDelta.z = -cos(r) * HEATSEEK_SPEED; } - - + + /* MOVE IT */ - + x = gCoord.x += gDelta.x * fps; y = gCoord.y += gDelta.y * fps; z = gCoord.z += gDelta.z * fps; /* CALC YAW/PITCH ROTATION */ - + theNode->Rot.x = gDelta.y * .001; if (theNode->Rot.x > PI/2) theNode->Rot.x = PI/2; else if (theNode->Rot.x < -PI/2) theNode->Rot.x = -PI/2; - + /* SEE IF HIT TERRAIN */ - + if (y <= GetTerrainHeightAtCoord_Planar(x,z)) { ExplodeBullet(theNode); return; } - + /* DO BULLET COLLISION */ - + if (DoBulletCollisionDetect(theNode)) return; - + /* LEAVE TRAIL */ - + num = (CalcQuickDistance(gCoord.x, gCoord.z, theNode->OldCoord.x, theNode->OldCoord.z) * (1.0/15.0)) + 1.0; r = -1.0/(float)num; xi = (gCoord.x - theNode->OldCoord.x) * r; yi = (gCoord.y - theNode->OldCoord.y) * r; zi = (gCoord.z - theNode->OldCoord.z) * r; - + for (i = 0; i <= num; i++) - { + { gNewObjectDefinition.coord.x = x; gNewObjectDefinition.coord.y = y; gNewObjectDefinition.coord.z = z; - gNewObjectDefinition.group = GLOBAL_MGroupNum_HeatSeekEcho; - gNewObjectDefinition.type = GLOBAL_MObjType_HeatSeekEcho; + gNewObjectDefinition.group = GLOBAL_MGroupNum_HeatSeekEcho; + gNewObjectDefinition.type = GLOBAL_MObjType_HeatSeekEcho; gNewObjectDefinition.flags = 0; - gNewObjectDefinition.slot = SLOT_OF_DUMB; + gNewObjectDefinition.slot = SLOT_OF_DUMB; gNewObjectDefinition.moveCall = MoveHeatSeekEcho; gNewObjectDefinition.rot = 0; gNewObjectDefinition.scale = .7 + RandomFloat()*.5; @@ -736,11 +737,11 @@ short num,i; { newObj->Health = .7 + RandomFloat()*.3; // transparency value MakeObjectTransparent(newObj, newObj->Health); // make transparent - } - + } + x += xi; y += yi; - z += zi; + z += zi; }; @@ -758,7 +759,7 @@ static void MoveHeatSeekEcho(ObjNode *theNode) DeleteObject(theNode); return; } - + MakeObjectTransparent(theNode, theNode->Health); } @@ -774,23 +775,23 @@ static void ShootTriBlast(ObjNode *theNode) ObjNode *newObj; float r; - gAutoFireCounter += gFramesPerSecondFrac * TRIBLAST_RATE; // check auto fire timer + gAutoFireCounter += gFramesPerSecondFrac * TRIBLAST_RATE; // check auto fire timer if (gAutoFireCounter >= 1.0) { gAutoFireCounter -= 1.0; - + /* CALC START COORD */ - + FindCoordOnJoint(theNode, MYGUY_LIMB_GUN, &gGunTipOffset, &gNewObjectDefinition.coord); - + /***************/ /* MAKE MODELS */ /***************/ - + /* MAKE TOP TRI */ - - gNewObjectDefinition.group = GLOBAL_MGroupNum_TriBlast; - gNewObjectDefinition.type = GLOBAL_MObjType_TriBlast; + + gNewObjectDefinition.group = GLOBAL_MGroupNum_TriBlast; + gNewObjectDefinition.type = GLOBAL_MObjType_TriBlast; gNewObjectDefinition.flags = 0; gNewObjectDefinition.slot = PLAYER_SLOT-1; // dont update till next loop gNewObjectDefinition.moveCall = MoveTriBlast; @@ -800,64 +801,64 @@ float r; if (newObj == nil) return; - newObj->Health = 1.0; - + newObj->Health = 1.0; + newObj->Delta.x = (-sin(r) * TRIBLAST_SPEED) + gDelta.x; // calc deltas newObj->Delta.z = (-cos(r) * TRIBLAST_SPEED) + gDelta.z; newObj->Delta.y = newObj->Delta.y + 200; - + newObj->CType = CTYPE_MYBULLET; // note: don't set as CTYPE_HURTENEMY since bullets do their own collision check newObj->CBits = CBITS_TOUCHABLE; // .. which also means I don't need a collision box since bullets use point collision checks - + newObj->Damage = TRIBLAST_DAMAGE; newObj->Kind = ATTACK_MODE_TRIBLAST; - + UpdateObjectTransforms(newObj); - - + + /* MAKE LEFT TRI */ - + gNewObjectDefinition.rot = r = theNode->Rot.y-.2; newObj = MakeNewDisplayGroupObject(&gNewObjectDefinition); if (newObj == nil) return; - newObj->Health = 1.0; + newObj->Health = 1.0; newObj->Delta.x = (-sin(r) * TRIBLAST_SPEED) + gDelta.x; // calc deltas newObj->Delta.z = (-cos(r) * TRIBLAST_SPEED) + gDelta.z; newObj->Delta.y = newObj->Delta.y - 20; - + newObj->CType = CTYPE_MYBULLET; // note: don't set as CTYPE_HURTENEMY since bullets do their own collision check - newObj->CBits = CBITS_TOUCHABLE; // .. which also means I don't need a collision box since bullets use point collision checks + newObj->CBits = CBITS_TOUCHABLE; // .. which also means I don't need a collision box since bullets use point collision checks newObj->Damage = TRIBLAST_DAMAGE; newObj->Kind = ATTACK_MODE_TRIBLAST; - + UpdateObjectTransforms(newObj); - + /* MAKE RIGHT TRI */ - + gNewObjectDefinition.rot = r = theNode->Rot.y + .2; newObj = MakeNewDisplayGroupObject(&gNewObjectDefinition); if (newObj == nil) return; - newObj->Health = 1.0; + newObj->Health = 1.0; newObj->Delta.x = (-sin(r) * TRIBLAST_SPEED) + gDelta.x; // calc deltas newObj->Delta.z = (-cos(r) * TRIBLAST_SPEED) + gDelta.z; newObj->Delta.y = newObj->Delta.y - 20; newObj->CType = CTYPE_MYBULLET; // note: don't set as CTYPE_HURTENEMY since bullets do their own collision check - newObj->CBits = CBITS_TOUCHABLE; // .. which also means I don't need a collision box since bullets use point collision checks + newObj->CBits = CBITS_TOUCHABLE; // .. which also means I don't need a collision box since bullets use point collision checks newObj->Damage = TRIBLAST_DAMAGE; newObj->Kind = ATTACK_MODE_TRIBLAST; - + UpdateObjectTransforms(newObj); - - + + PlayEffect(EFFECT_BLASTER); // play sound - + /* UPDATE INFOBAR */ - + if (--gWeaponInventory[gCurrentAttackMode] == 0) // dec inventory & if run out, select next weapon { gPossibleAttackModes[gCurrentAttackMode] = false; @@ -880,23 +881,23 @@ float x,y,z,fps; fps = gFramesPerSecondFrac; /* DECAY IT */ - + theNode->Health -= 1.1f * fps; if (theNode->Health < 0) { DeleteObject(theNode); return; } - + /* MOVE IT */ - + x = gCoord.x += gDelta.x * fps; y = gCoord.y += gDelta.y * fps; z = gCoord.z += gDelta.z * fps; /* SEE IF HIT TERRAIN */ - + if (y <= GetTerrainHeightAtCoord_Planar(x,z)) { ExplodeBullet(theNode); @@ -904,13 +905,13 @@ float x,y,z,fps; } /* DO BULLET COLLISION */ - + if (DoBulletCollisionDetect(theNode)) return; /* RANDOM SPIN */ - + theNode->Rot.x = RandomFloat()*PI2; theNode->Rot.y = RandomFloat()*PI2; @@ -928,20 +929,20 @@ static void ShootNuke(ObjNode *theNode) ObjNode *newObj; float r; - gAutoFireCounter += gFramesPerSecondFrac * NUKE_RATE; // check auto fire timer + gAutoFireCounter += gFramesPerSecondFrac * NUKE_RATE; // check auto fire timer if (gAutoFireCounter >= 1.0) { gAutoFireCounter -= 1.0; - + /* CALC START COORD */ - + FindCoordOnJoint(theNode, MYGUY_LIMB_GUN, &gGunTipOffset, &gNewObjectDefinition.coord); - - + + /* MAKE MODEL */ - - gNewObjectDefinition.group = GLOBAL_MGroupNum_Nuke; - gNewObjectDefinition.type = GLOBAL_MObjType_Nuke; + + gNewObjectDefinition.group = GLOBAL_MGroupNum_Nuke; + gNewObjectDefinition.type = GLOBAL_MObjType_Nuke; gNewObjectDefinition.flags = 0; gNewObjectDefinition.slot = PLAYER_SLOT-1; // dont update till next loop gNewObjectDefinition.moveCall = MoveNuke; @@ -951,22 +952,22 @@ float r; if (newObj == nil) return; - newObj->Health = 1.0; - + newObj->Health = 1.0; + r = theNode->Rot.y; newObj->Delta.x = (-sin(r) * NUKE_SPEED) + gDelta.x; // calc deltas newObj->Delta.z = (-cos(r) * NUKE_SPEED) + gDelta.z; - + newObj->CType = CTYPE_MYBULLET; // note: don't set as CTYPE_HURTENEMY since bullets do their own collision check newObj->CBits = CBITS_TOUCHABLE; // .. which also means I don't need a collision box since bullets use point collision checks - + newObj->Kind = ATTACK_MODE_NUKE; newObj->Damage = NUKE_DAMAGE; - + // PlayEffect(EFFECT_BLASTER); // play sound - + /* UPDATE INFOBAR */ - + if (--gWeaponInventory[gCurrentAttackMode] == 0) // dec inventory & if run out, select next weapon { gPossibleAttackModes[gCurrentAttackMode] = false; @@ -989,16 +990,16 @@ float x,y,z,fps; fps = gFramesPerSecondFrac; /* SEE IF READY TO EXPLODE */ - + theNode->Health -= .8 * fps; if (theNode->Health < 0) { ExplodeBullet(theNode); return; } - + /* MOVE IT */ - + x = gCoord.x += gDelta.x * fps; y = gCoord.y += gDelta.y * fps; z = gCoord.z += gDelta.z * fps; @@ -1007,7 +1008,7 @@ float x,y,z,fps; theNode->Rot.z += fps * 8; /* SEE IF HIT TERRAIN */ - + if (y <= GetTerrainHeightAtCoord_Planar(x,z)) { ExplodeBullet(theNode); @@ -1015,7 +1016,7 @@ float x,y,z,fps; } /* DO BULLET COLLISION */ - + if (DoBulletCollisionDetect(theNode)) return; @@ -1030,7 +1031,7 @@ static void DetonateNuke(ObjNode *theNode) ObjNode *newObj; /* DELETE NUKE */ - + DeleteObject(theNode); PlayEffect_Parms(EFFECT_EXPLODE,FULL_CHANNEL_VOLUME,kMiddleC-6); // play sound @@ -1039,10 +1040,10 @@ ObjNode *newObj; /* CREATE SHOCKWAVE */ gNewObjectDefinition.coord = theNode->Coord; - gNewObjectDefinition.group = GLOBAL_MGroupNum_Explosion; - gNewObjectDefinition.type = GLOBAL_MObjType_Explosion; + gNewObjectDefinition.group = GLOBAL_MGroupNum_Explosion; + gNewObjectDefinition.type = GLOBAL_MObjType_Explosion; gNewObjectDefinition.flags = 0; - gNewObjectDefinition.slot = 200; + gNewObjectDefinition.slot = 200; gNewObjectDefinition.moveCall = MoveNukeShockwave; gNewObjectDefinition.rot = 0; gNewObjectDefinition.scale = 1; @@ -1052,12 +1053,12 @@ ObjNode *newObj; newObj->Health = .9; newObj->Damage = newObj->Health * 3; MakeObjectTransparent(newObj, newObj->Health); // make transparent - newObj->CType = CTYPE_HURTENEMY|CTYPE_HURTME; - newObj->CBits = CBITS_TOUCHABLE; + newObj->CType = CTYPE_HURTENEMY|CTYPE_HURTME; + newObj->CBits = CBITS_TOUCHABLE; SetObjectCollisionBounds(newObj,10,-10,-10,10,10,-10); - } + } } - + /*********************** MOVE NUKE SHOCKWAVE **************************/ @@ -1067,7 +1068,7 @@ float fps = gFramesPerSecondFrac; float s; /* DECAY IT */ - + theNode->Health -= fps * .6; // decay it if (theNode->Health <= 0) { @@ -1076,24 +1077,16 @@ float s; } MakeObjectTransparent(theNode, theNode->Health); theNode->Damage = theNode->Health * .5; // update damage - - + + /* ENLARGE */ - - s = theNode->Scale.x = theNode->Scale.y = theNode->Scale.z += fps * 80; + + s = theNode->Scale.x = theNode->Scale.y = theNode->Scale.z += fps * 80; SetObjectCollisionBounds(theNode,s*10,s*-10,s*-10,s*10,s*10,s*-10); - - - /* UPATE */ - - UpdateObjectTransforms(theNode); -} + /* UPATE */ + UpdateObjectTransforms(theNode); - - - - - \ No newline at end of file +} From 2af9180802627d4925635dbe6a1af5a4d420b143 Mon Sep 17 00:00:00 2001 From: br4e <br4e@protonmail.com> Date: Sat, 6 Aug 2022 12:18:44 -0700 Subject: [PATCH 06/20] start with a little fuel --- src/Screens/Infobar.c | 143 +++++++++++++++++++++--------------------- 1 file changed, 71 insertions(+), 72 deletions(-) diff --git a/src/Screens/Infobar.c b/src/Screens/Infobar.c index 6368123..de8a851 100644 --- a/src/Screens/Infobar.c +++ b/src/Screens/Infobar.c @@ -98,10 +98,10 @@ short i; gNumLives = 2; gScore = 0; - gFuel = 0; //MAX_FUEL_CAPACITY/6; + gFuel = MAX_FUEL_CAPACITY/6; gTimeRemaining = LEVEL_DURATION; gOldTime = 1000000000; - + for (i=0; i < NUM_EGG_SPECIES; i++) gRecoveredEggs[i] = 0; } @@ -169,7 +169,7 @@ unsigned long bits; bits = gInfobarUpdateBits; /* SHOW ATTACK MODE */ - + if (bits & UPDATE_WEAPONICON) { DrawSpriteFrameToScreen(SPRITE_GROUP_INFOBAR, gCurrentAttackMode, WEAPON_ICON_X, WEAPON_ICON_Y); @@ -177,7 +177,7 @@ unsigned long bits; } /* SHOW SCORE */ - + if (bits & UPDATE_SCORE) PrintNumber(gScore,8, SCORE_X,SCORE_Y); @@ -189,25 +189,25 @@ unsigned long bits; FUEL_X, FUEL_Y); /* UPDATE TIMERS */ - + if (bits & UPDATE_IMPACTTIME) ShowTimeRemaining(); /* UPDATE HEALTH */ - + if (bits & UPDATE_HEALTH) ShowHealth(); /* UPDATE EGGS */ - + if (bits & UPDATE_EGGS) ShowEggs(); - - + + /* UPDATE LIVES */ - + if (bits & UPDATE_LIVES) PrintNumber(gNumLives,1, LIVES_X,LIVES_Y); @@ -222,22 +222,22 @@ void NextAttackMode(void) short i; /* SCAN FOR NEXT AVAILABLE ATTACK MODE */ - + i = gCurrentAttackMode; - + do { if (++i >= NUM_ATTACK_MODES) // see if wrap around i = 0; - + if (gPossibleAttackModes[i]) // can I do this one? break; - + }while(i != gCurrentAttackMode); /* SEE IF IT CHANGED */ - + if (i != gCurrentAttackMode) { gCurrentAttackMode = i; @@ -287,7 +287,7 @@ short minutes,seconds; minutes = (int)gTimeRemaining / 60; // calc # minutes seconds = (int)gTimeRemaining - (minutes * 60); // calc # seconds - + PrintNumber(seconds, 2, TIME_REM_X+38, TIME_REM_Y); PrintNumber(minutes, 2, TIME_REM_X, TIME_REM_Y); } @@ -302,7 +302,7 @@ Rect r; static const RGBColor color = {0x9000,0,0x0800}; /* GET MY HEALTH */ - + health = gMyHealth; if (health < 0) health = 0; @@ -322,12 +322,12 @@ static const RGBColor color = {0x9000,0,0x0800}; PaintRect(&r); /* ERASE TAIL */ - + ForeColor(blackColor); r.left = r.right; r.right = HEALTH_METER_X+HEALTH_METER_WIDTH; PaintRect(&r); - + } @@ -335,16 +335,16 @@ static const RGBColor color = {0x9000,0,0x0800}; static void UpdateInfobarIcon(ObjNode *theNode) { -TQ3Matrix4x4 matrix,matrix2,matrix3; +TQ3Matrix4x4 matrix,matrix2,matrix3; /* APPLY SCALE TO OBJECT */ - + Q3Matrix4x4_SetScale(&matrix, theNode->Scale.x, // make scale matrix - theNode->Scale.y, + theNode->Scale.y, theNode->Scale.z); /* APPLY LOCAL ROTATION TO OBJECT */ - + Q3Matrix4x4_SetRotate_XYZ(&matrix2,theNode->Rot.x,theNode->Rot.y,theNode->Rot.z); Q3Matrix4x4_Multiply(&matrix,&matrix2,&matrix3); @@ -353,8 +353,8 @@ TQ3Matrix4x4 matrix,matrix2,matrix3; Q3Matrix4x4_SetTranslate(&matrix2,theNode->Coord.x,theNode->Coord.y,theNode->Coord.z); Q3Matrix4x4_Multiply(&matrix3,&matrix2,&matrix); - - + + /* TRANSFORM TO WORLD COORDINATES */ Q3Matrix4x4_Multiply(&matrix,&gCameraAdjustMatrix,&theNode->BaseTransformMatrix); @@ -378,7 +378,7 @@ Boolean toggleMusic = !gMuteMusicFlag; /***************/ /* MAKE RESUME */ /***************/ - + gNewObjectDefinition.group = MODEL_GROUP_INFOBAR; gNewObjectDefinition.type = INFOBAR_ObjType_Resume; gNewObjectDefinition.coord.x = 0; @@ -394,7 +394,7 @@ Boolean toggleMusic = !gMuteMusicFlag; /***************/ /* MAKE QUIT */ /***************/ - + gNewObjectDefinition.type = INFOBAR_ObjType_Quit; gNewObjectDefinition.coord.y = -3.0; quit = MakeNewDisplayGroupObject(&gNewObjectDefinition); @@ -402,13 +402,13 @@ Boolean toggleMusic = !gMuteMusicFlag; /*************/ /* MAIN LOOP */ /*************/ - + do { - QD3D_CalcFramesPerSecond(); // calc frame rate - + QD3D_CalcFramesPerSecond(); // calc frame rate + /* SEE IF CHANGE SELECT */ - + UpdateInput(); if (GetNewNeedState(kNeed_UIUp) && (selected > 0)) { @@ -427,9 +427,9 @@ Boolean toggleMusic = !gMuteMusicFlag; selected = 0; break; } - + /* FLUCTUATE SELECTED */ - + fluc += gFramesPerSecondFrac * 8; if (selected == 0) { @@ -449,15 +449,15 @@ Boolean toggleMusic = !gMuteMusicFlag; while (!GetNewNeedState(kNeed_UIConfirm)); // see if select /* CLEANUP */ - + DeleteObject(quit); DeleteObject(resume); - + if (toggleMusic) ToggleMusic(); // restart music Pomme_PauseAllChannels(false); // Source port addition: unpause looping channels - + if (selected == 1) // see if want out { gGameOverFlag = true; @@ -476,16 +476,16 @@ short n; if (n >= 0) { /* ANGLE TO CURRENT ACTIVE TIME PORTAL */ - + x = gPlayerObj->Coord.x; z = gPlayerObj->Coord.z; - + rot = CalcYAngleFromPointToPoint(x,z, gTimePortalList[n].coord.x, gTimePortalList[n].coord.y); // calc angle directly at target rot -= gPlayerObj->Rot.y; theNode->Rot.y = rot; theNode->StatusBits &= ~STATUS_BIT_HIDDEN; - + UpdateInfobarIcon(theNode); } else @@ -493,7 +493,7 @@ short n; theNode->StatusBits |= STATUS_BIT_HIDDEN; // make invisible } - + } @@ -533,7 +533,7 @@ static TQ3Point3D points[4] = { { -GPS_DISPLAY_SIZE, GPS_DISPLAY_SIZE, 0 }, if (gGPSFullImage) { - DisposeGWorld(gGPSFullImage); + DisposeGWorld(gGPSFullImage); gGPSFullImage = nil; } if (gGPSGWorld) @@ -551,7 +551,7 @@ static TQ3Point3D points[4] = { { -GPS_DISPLAY_SIZE, GPS_DISPLAY_SIZE, 0 }, /* DRAW FULL-SIZE IMAGE INTO GWORLD */ - + myErr = FSMakeFSSpec(gDataSpec.vRefNum, gDataSpec.parID, ":Images:Map.tga", &spec); GAME_ASSERT(!myErr); @@ -563,8 +563,8 @@ static TQ3Point3D points[4] = { { -GPS_DISPLAY_SIZE, GPS_DISPLAY_SIZE, 0 }, GAME_ASSERT(!myErr); - GetGWorld(&oldGW, &oldGD); - SetGWorld(gGPSFullImage, nil); + GetGWorld(&oldGW, &oldGD); + SetGWorld(gGPSFullImage, nil); DrawPicture(pict,&gGPSFullImage->portRect); // draw PICT into GWorld SetGWorld (oldGW, oldGD); ReleaseResource((Handle)pict); // free the PICT rez @@ -576,7 +576,7 @@ static TQ3Point3D points[4] = { { -GPS_DISPLAY_SIZE, GPS_DISPLAY_SIZE, 0 }, myErr = NewGWorld(&gGPSGWorld, 16, &r, 0, 0, 0L); // make gworld GAME_ASSERT(!myErr); - SetGWorld(gGPSGWorld, nil); + SetGWorld(gGPSGWorld, nil); ForeColor(blackColor); FrameRect(&r); SetGWorld (oldGW, oldGD); @@ -660,30 +660,30 @@ Boolean forceUpdate = false; /* SEE IF NEED TO UPDATE POSITION */ - + x = gMyCoord.x * .005f; y = gMyCoord.z * .005f; - + if ((x != gOldGPSCoordX) || (y != gOldGPSCoordY) || forceUpdate) { long w,h; /* COPY VISIBLE SECTION OF GWORLD */ - + dRect = gGPSGWorld->portRect; // get dest rect dRect.left++; dRect.right--; dRect.top++; dRect.bottom--; w = dRect.right - dRect.left; h = dRect.bottom - dRect.top; - + sRect.left = (gMyCoord.x * TERRAIN_POLYGON_SIZE_Frac) - (GPS_MAP_SIZE/2); // get src rect sRect.top = (gMyCoord.z * TERRAIN_POLYGON_SIZE_Frac) - (GPS_MAP_SIZE/2); sRect.right = sRect.left + w; sRect.bottom = sRect.top + h; - - + + /* CHECK EDGE CLIP */ - + left = right = top = bottom = 0; // assume no edge clipping if (sRect.left < 0) @@ -713,41 +713,41 @@ Boolean forceUpdate = false; /* DRAW IT */ - + DumpGWorldToGWorld(gGPSFullImage, gGPSGWorld, &sRect, &dRect); /* ERASE EDGES */ - GetGWorld(&oldGW, &oldGD); - SetGWorld(gGPSGWorld, nil); - + GetGWorld(&oldGW, &oldGD); + SetGWorld(gGPSGWorld, nil); + BackColor(blackColor); if (left > 0) { SetRect(&dRect,1,1,left+1,gGPSGWorld->portRect.bottom-1); - EraseRect(&dRect); + EraseRect(&dRect); } if (right > 0) { SetRect(&dRect,gGPSGWorld->portRect.right-1-right,1,gGPSGWorld->portRect.right-1,gGPSGWorld->portRect.bottom-1); - EraseRect(&dRect); + EraseRect(&dRect); } if (top > 0) { SetRect(&dRect,1,1,gGPSGWorld->portRect.right-1,top+1); - EraseRect(&dRect); + EraseRect(&dRect); } if (bottom > 0) { SetRect(&dRect,1,gGPSGWorld->portRect.bottom-1-bottom,gGPSGWorld->portRect.right-1,gGPSGWorld->portRect.bottom-1); - EraseRect(&dRect); + EraseRect(&dRect); } /* DRAW CROSSHAIRS */ - + ForeColor(yellowColor); MoveTo(GPS_MAP_SIZE/2, 0); LineTo(GPS_MAP_SIZE/2, GPS_MAP_SIZE); @@ -779,12 +779,12 @@ Boolean forceUpdate = false; gOldGPSCoordX = x; gOldGPSCoordY = y; } - - + + /* UPDATE IT IN THE INFOBAR */ - + theNode->Rot.z = -gPlayerObj->Rot.y; - + UpdateInfobarIcon(theNode); } @@ -794,26 +794,26 @@ Boolean forceUpdate = false; void DecAsteroidTimer(void) { /* DEC TIMER & SEE IF DONE */ - + if (gTimeRemaining <= 0.0f) // see if done { - gGameOverFlag = true; + gGameOverFlag = true; } - + if ((gTimeRemaining -= gFramesPerSecondFrac) <= 0.0f) // dec timer gTimeRemaining = 0; - + if (fabs(gOldTime - gTimeRemaining) >= 1.0f) { gInfobarUpdateBits |= UPDATE_IMPACTTIME; gOldTime = gTimeRemaining; /* DO 30 SECOND WARNING BEEP */ - + if (gTimeRemaining < 30.0f) PlayEffect_Parms(EFFECT_ALARM,FULL_CHANNEL_VOLUME,kMiddleC-5); - } + } } @@ -826,4 +826,3 @@ void GetHealth(float amount) gMyHealth = 1.0f; gInfobarUpdateBits |= UPDATE_HEALTH; } - From cc5e624cf3550ff0d8f6d90e48b5b627d55c208d Mon Sep 17 00:00:00 2001 From: br4e <br4e@protonmail.com> Date: Sat, 6 Aug 2022 12:18:57 -0700 Subject: [PATCH 07/20] balance enemeies --- src/Enemies/Enemy_Rex.c | 4 ++-- src/Enemies/Enemy_Spitter.c | 2 +- src/Enemies/Enemy_Stego.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Enemies/Enemy_Rex.c b/src/Enemies/Enemy_Rex.c index d665dff..d19c056 100644 --- a/src/Enemies/Enemy_Rex.c +++ b/src/Enemies/Enemy_Rex.c @@ -38,10 +38,10 @@ static void MoveRex_Pounce(ObjNode *theNode); #define REX_TARGET_SCALE 200.0f -#define MAX_WALK_SPEED 200.0f +#define MAX_WALK_SPEED 250.0f -#define REX_HEALTH 2.0f +#define REX_HEALTH 3.0f #define REX_DAMAGE 0.08f #define REX_SCALE 1.2f diff --git a/src/Enemies/Enemy_Spitter.c b/src/Enemies/Enemy_Spitter.c index b79fd3a..ffb3d35 100644 --- a/src/Enemies/Enemy_Spitter.c +++ b/src/Enemies/Enemy_Spitter.c @@ -37,7 +37,7 @@ static void MoveDinoSpit(ObjNode *theNode); #define SPITTER_TARGET_SCALE 200.0f -#define SPITTER_HEALTH 2f +#define SPITTER_HEALTH 2.0f #define SPITTER_DAMAGE 0.02f #define SPITTER_SCALE .8f diff --git a/src/Enemies/Enemy_Stego.c b/src/Enemies/Enemy_Stego.c index 194c587..cf5cc12 100644 --- a/src/Enemies/Enemy_Stego.c +++ b/src/Enemies/Enemy_Stego.c @@ -27,14 +27,14 @@ static void MoveStego_Standing(ObjNode *theNode); #define STEGO_ATTACK_RANGE 700 #define STEGO_TURN_SPEED 1 -#define MAX_WALK_SPEED 100 +#define MAX_WALK_SPEED 70 #define STEGO_TARGET_SCALE 350 #define STEGO_HEALTH 6.0 -#define STEGO_DAMAGE .3 +#define STEGO_DAMAGE .2 #define STEGO_SCALE 1.4 From ea830359abe26098bffcef26d095391a3288a11b Mon Sep 17 00:00:00 2001 From: br4e <br4e@protonmail.com> Date: Sat, 6 Aug 2022 12:48:53 -0700 Subject: [PATCH 08/20] all initial weapons --- src/Player/Weapons.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/Player/Weapons.c b/src/Player/Weapons.c index 911b5bc..525515f 100644 --- a/src/Player/Weapons.c +++ b/src/Player/Weapons.c @@ -97,16 +97,16 @@ short i; gPossibleAttackModes[ATTACK_MODE_BLASTER] = true; gWeaponInventory[ATTACK_MODE_BLASTER] = 50; - gPossibleAttackModes[ATTACK_MODE_HEATSEEK] = false; + gPossibleAttackModes[ATTACK_MODE_HEATSEEK] = true; gWeaponInventory[ATTACK_MODE_HEATSEEK] = 10; - gPossibleAttackModes[ATTACK_MODE_SONICSCREAM] = false; + gPossibleAttackModes[ATTACK_MODE_SONICSCREAM] = true; gWeaponInventory[ATTACK_MODE_SONICSCREAM] = 10; - gPossibleAttackModes[ATTACK_MODE_TRIBLAST] = false; + gPossibleAttackModes[ATTACK_MODE_TRIBLAST] = true; gWeaponInventory[ATTACK_MODE_TRIBLAST] = 25; - gPossibleAttackModes[ATTACK_MODE_NUKE] = false; + gPossibleAttackModes[ATTACK_MODE_NUKE] = true; gWeaponInventory[ATTACK_MODE_NUKE] = 1; gInfobarUpdateBits |= UPDATE_WEAPONICON; @@ -147,7 +147,7 @@ static const short quans[] = { 25, // blaster 10, // heat seek - 25, // sonic scream + 15, // sonic scream 30, // triblast 1, // Nuke 25, @@ -407,7 +407,11 @@ float r,fps; /* UPDATE INFOBAR */ if (--gWeaponInventory[gCurrentAttackMode] == 0) // dec inventory & if run out, select next weapon + { + gPossibleAttackModes[gCurrentAttackMode] = false; NextAttackMode(); + } + gInfobarUpdateBits |= UPDATE_WEAPONICON; // tell system to update this at end of frame From 48df7a533b127a57bdf59c758c584e21af10cb3f Mon Sep 17 00:00:00 2001 From: br4e <br4e@protonmail.com> Date: Sat, 6 Aug 2022 13:14:03 -0700 Subject: [PATCH 09/20] beautify --- src/Player/MyGuy.c | 335 ++++++++++++++++++++++----------------------- 1 file changed, 165 insertions(+), 170 deletions(-) diff --git a/src/Player/MyGuy.c b/src/Player/MyGuy.c index 72c34ea..a880147 100644 --- a/src/Player/MyGuy.c +++ b/src/Player/MyGuy.c @@ -43,7 +43,7 @@ static void MoveShield(ObjNode *theNode); /****************************/ -#define MY_SCALE .5f +#define MY_SCALE .5f #define MY_FOOT_JOINT_NUM 7 @@ -86,22 +86,22 @@ void InitMyGuy(void) { ObjNode *newObj; float y; - - gMyLatestPathTileNum = gMyLatestTileAttribs = 0; - gLavaSmokeCounter = gMySpeedPuffCounter = 0; - gShieldTimer = 0; + + gMyLatestPathTileNum = gMyLatestTileAttribs = 0; + gLavaSmokeCounter = gMySpeedPuffCounter = 0; + gShieldTimer = 0; gMyShield = nil; gMyHealth = 1.0; gShieldChannel = -1; - + y = GetTerrainHeightAtCoord_Quick(gMyStartX,gMyStartZ)-DIST_FROM_ORIGIN_TO_FEET; - + gMyCoord.x = gMyStartX; gMyCoord.z = gMyStartZ; gMyCoord.y = y+50; - - /* CREATE MY CHARACTER */ - + + /* CREATE MY CHARACTER */ + gNewObjectDefinition.type = SKELETON_TYPE_DEINON; gNewObjectDefinition.animNum = PLAYER_ANIM_FALLING; gNewObjectDefinition.coord.x = gMyStartX; @@ -112,32 +112,32 @@ float y; gNewObjectDefinition.moveCall = MoveMe; gNewObjectDefinition.rot = (float)gMyStartAim * (PI2/8); gNewObjectDefinition.scale = MY_SCALE; - newObj = gPlayerObj = MakeNewSkeletonObject(&gNewObjectDefinition); - + newObj = gPlayerObj = MakeNewSkeletonObject(&gNewObjectDefinition); + newObj->CType = CTYPE_SKELETON|CTYPE_PLAYER; newObj->CBits = CBITS_TOUCHABLE; - - + + /* INIT COLLISION BOX */ - + SetObjectCollisionBounds(newObj,60*MY_SCALE,-DIST_FROM_ORIGIN_TO_FEET,-50*MY_SCALE, 50*MY_SCALE,50*MY_SCALE,-50*MY_SCALE); newObj->Damage = .5; - + newObj->InvincibleTimer = 0; - - + + /* MAKE SHADOW */ - + AttachShadowToObject(newObj, .9, .9*2.5); - + /* MAKE APPEARANCE TIME PORTAL */ gMyTimePortal = MakeTimePortal(PORTAL_TYPE_ENTER, gMyStartX, gMyStartZ); gMyTimePortalTimer = 2.5; - PlayEffect_Parms(EFFECT_PORTAL,FULL_CHANNEL_VOLUME,kMiddleC-8); + PlayEffect_Parms(EFFECT_PORTAL,FULL_CHANNEL_VOLUME,kMiddleC-8); } @@ -156,11 +156,11 @@ ObjNode *theNode = gPlayerObj; gGameOverFlag = true; return; } - + gPlayerGotKilledFlag = false; gMyHealth = 1.0; - gFuel = 0; + gFuel = 0; gInfobarUpdateBits |= UPDATE_HEALTH|UPDATE_FUEL|UPDATE_SCORE|UPDATE_LIVES; theNode->HurtTimer = 0; @@ -168,7 +168,7 @@ ObjNode *theNode = gPlayerObj; /* EXPLODE "OLD" ONE */ - + QD3D_ExplodeGeometry(theNode, 500.0f, 0, 3, .4); // note: this doesnt delete anything @@ -180,22 +180,22 @@ ObjNode *theNode = gPlayerObj; /* RESET PLAYER INTO POSITION */ - + SetSkeletonAnim(theNode->Skeleton, PLAYER_ANIM_FALLING); // start falling theNode->Coord.y += 400; theNode->StatusBits |= STATUS_BIT_HIDDEN; UpdateObjectTransforms(theNode); - - + + /* ALSO RESET CAMERA */ - + ResetCameraSettings(); - - - + + + /* AND RESET WEAPONS INVENTORY */ - + InitWeaponManager(); } @@ -207,7 +207,7 @@ static void MoveMe(ObjNode *theNode) static void(*myMoveTable[])(ObjNode *) = { MovePlayer_Standing, - MovePlayer_Walking, + MovePlayer_Walking, MovePlayer_Jumping2, MovePlayer_Landing, MovePlayer_Biting, @@ -222,39 +222,39 @@ static void(*myMoveTable[])(ObjNode *) = MovePlayer_Death, MovePlayer_Exit }; - + GetObjectInfo(theNode); - + /* DON'T DO ANYTHING UNTIL ENTRY TIME PORTAL TIMES OUT */ - + if (gMyTimePortalTimer > 0.0f) { gMyTimePortalTimer -= gFramesPerSecondFrac; if (gMyTimePortalTimer <= 0.0f) { theNode->StatusBits &= ~STATUS_BIT_HIDDEN; // un-hide me - PlayEffect_Parms(EFFECT_PORTAL,FULL_CHANNEL_VOLUME,kMiddleC+2); + PlayEffect_Parms(EFFECT_PORTAL,FULL_CHANNEL_VOLUME,kMiddleC+2); } - UpdatePlayer(theNode); + UpdatePlayer(theNode); return; } - + /* UPDATE INVINCIBILITY */ - + if (theNode->InvincibleTimer > 0) { theNode->InvincibleTimer -= gFramesPerSecondFrac; if (theNode->InvincibleTimer < 0) theNode->InvincibleTimer = 0; } - + /* FORCE ME DEAD IF THAT'S THE CASE */ - + if (gPlayerGotKilledFlag) if (theNode->Skeleton->AnimNum != PLAYER_ANIM_DEATH) SetSkeletonAnim(theNode->Skeleton,PLAYER_ANIM_DEATH); - + myMoveTable[theNode->Skeleton->AnimNum](theNode); } @@ -271,32 +271,32 @@ static void MovePlayer_Standing(ObjNode *theNode) CheckJetThrustControl(theNode); /* MOVE PLAYER */ - + DoFrictionAndGravity(theNode,PLAYER_FRICTION_ACCEL); DoPlayerMovement(theNode); - + /* CHECK ANIM */ - + if ((gDelta.z != 0.0f) || (gDelta.x != 0.0f)) // see if go/run if (!theNode->JetThrust) // make sure jet didnt just now get activated MorphToSkeletonAnim(theNode->Skeleton,PLAYER_ANIM_WALK,15.0); - + /* DO COLLISION DETECT */ - + if (DoPlayerCollisionDetect(theNode)) goto update; - + /* SEE IF ATTACK */ - + CheckIfMeAttack(theNode); /* UPDATE IT */ - -update: + +update: UpdatePlayer(theNode); } @@ -315,8 +315,8 @@ static void MovePlayer_Walking(ObjNode *theNode) DoFrictionAndGravity(theNode,PLAYER_FRICTION_ACCEL); DoPlayerMovement(theNode); - - + + /* UPDATE ANIM SPEED */ if (theNode->Skeleton->AnimNum == PLAYER_ANIM_WALK) @@ -324,26 +324,26 @@ static void MovePlayer_Walking(ObjNode *theNode) /* CHECK ANIM */ - + if ((gDelta.z == 0.0f) && (gDelta.x == 0.0f)) // see if stop/stand { MorphToSkeletonAnim(theNode->Skeleton,PLAYER_ANIM_STAND,3.0); } - + /* DO COLLISION DETECT */ - + if (DoPlayerCollisionDetect(theNode)) goto update; - + /* SEE IF ATTACK */ - + CheckIfMeAttack(theNode); - + /* UPDATE IT */ - -update: + +update: UpdatePlayer(theNode); } @@ -368,23 +368,23 @@ static void MovePlayer_Jumping1(ObjNode *theNode) /* MOVE PLAYER */ DoFrictionAndGravity(theNode,PLAYER_FRICTION_ACCEL/10); // do friction - + DoPlayerMovement(theNode); // returns true if on terrain /* SEE IF SWITCH TO FALLING */ - + if (theNode->Skeleton->AnimNum != PLAYER_ANIM_FALLING) { if (gDelta.y <= 0) MorphToSkeletonAnim(theNode->Skeleton,PLAYER_ANIM_FALLING,2.0); // start falling - } - + } + /* DO COLLISION DETECT */ - + if (DoPlayerCollisionDetect(theNode)) goto update; - + if (theNode->StatusBits & STATUS_BIT_ONGROUND) // see if landed on something solid { DoFrictionAndGravity(theNode,PLAYER_FRICTION_ACCEL*5); // do momentary friction upon landing @@ -393,14 +393,14 @@ static void MovePlayer_Jumping1(ObjNode *theNode) MakeDustPuff(gCoord.x, gCoord.y-DIST_FROM_ORIGIN_TO_FEET, gCoord.z, .2); MakeDustPuff(gCoord.x, gCoord.y-DIST_FROM_ORIGIN_TO_FEET, gCoord.z, .25); } - + /* SEE IF ATTACK */ - + CheckIfMeAttack(theNode); - - + + /* UPDATE IT */ -update: +update: UpdatePlayer(theNode); } @@ -416,16 +416,16 @@ static void MovePlayer_Landing(ObjNode *theNode) DoFrictionAndGravity(theNode,PLAYER_FRICTION_ACCEL/10); // do friction DoPlayerMovement(theNode); - + if (theNode->Skeleton->AnimHasStopped) // returns true if on terrain MorphToSkeletonAnim(theNode->Skeleton,PLAYER_ANIM_STAND,4); - - + + if (DoPlayerCollisionDetect(theNode)) goto update; - + /* UPDATE IT */ -update: +update: UpdatePlayer(theNode); } @@ -447,7 +447,7 @@ static void MovePlayer_Jumping2(ObjNode *theNode) /* MOVE PLAYER */ DoFrictionAndGravity(theNode,PLAYER_FRICTION_ACCEL/10.0f); // do friction - + DoPlayerMovement(theNode); // returns true if on terrain theNode->Rot.x -= 6.0f * gFramesPerSecondFrac; // spin when jump @@ -456,13 +456,13 @@ static void MovePlayer_Jumping2(ObjNode *theNode) theNode->Rot.x = 0; MorphToSkeletonAnim(theNode->Skeleton, PLAYER_ANIM_FALLING, 3.0); } - - + + /* DO COLLISION DETECT */ - + if (DoPlayerCollisionDetect(theNode)) goto update; - + if (theNode->StatusBits & STATUS_BIT_ONGROUND) // see if landed on something solid { DoFrictionAndGravity(theNode,PLAYER_FRICTION_ACCEL*5); // do momentary friction upon landing @@ -472,9 +472,9 @@ static void MovePlayer_Jumping2(ObjNode *theNode) MakeDustPuff(gCoord.x, gCoord.y-DIST_FROM_ORIGIN_TO_FEET, gCoord.z, .2); MakeDustPuff(gCoord.x, gCoord.y-DIST_FROM_ORIGIN_TO_FEET, gCoord.z, .25); } - + /* UPDATE IT */ -update: +update: if (theNode->Skeleton->AnimNum != PLAYER_ANIM_JUMP2) // fix x-rot if anim has changed theNode->Rot.x = 0; @@ -493,7 +493,7 @@ static void MovePlayer_Biting(ObjNode *theNode) DoFrictionAndGravity(theNode,PLAYER_FRICTION_ACCEL); // do friction DoPlayerMovement(theNode); - + if (theNode->Skeleton->AnimHasStopped) // returns true if on terrain MorphToSkeletonAnim(theNode->Skeleton,PLAYER_ANIM_STAND,4); @@ -534,25 +534,25 @@ static void MovePlayer_Turning(ObjNode *theNode) DoFrictionAndGravity(theNode,PLAYER_FRICTION_ACCEL); DoPlayerMovement(theNode); - - + + /* DO COLLISION DETECT */ - + if (DoPlayerCollisionDetect(theNode)) goto update; /* UPDATE ANIM SPEED */ - + theNode->Skeleton->AnimSpeed = .7f + theNode->Speed * .006f; - + /* SEE IF ATTACK */ - + CheckIfMeAttack(theNode); /* UPDATE IT */ -update: +update: UpdatePlayer(theNode); } @@ -569,7 +569,7 @@ static void MovePlayer_PickUp(ObjNode *theNode) DoFrictionAndGravity(theNode,PLAYER_FRICTION_ACCEL); // do friction DoPlayerMovement(theNode); - + if (theNode->Skeleton->AnimHasStopped) // returns true if on terrain SetSkeletonAnim(theNode->Skeleton,PLAYER_ANIM_STAND); @@ -582,9 +582,9 @@ static void MovePlayer_PickUp(ObjNode *theNode) if (theNode->PickUpNow) { theNode->PickUpNow = false; - + if (theNode->StatusBits & STATUS_BIT_ISCARRYING) - DropItem(theNode); + DropItem(theNode); else TryToDoPickUp(theNode,MYGUY_LIMB_HEAD); } @@ -610,7 +610,7 @@ float r; DoFrictionAndGravity(theNode,PLAYER_FRICTION_ACCEL); // do friction DoPlayerMovement(theNode); - + if (theNode->Skeleton->AnimHasStopped) SetSkeletonAnim(theNode->Skeleton,PLAYER_ANIM_STAND); @@ -623,26 +623,26 @@ float r; if (theNode->ThrowNow) { theNode->ThrowNow = false; // clear flag - + if (theNode->StatusBits & STATUS_BIT_ISCARRYING) // verify this is still valid { itemObj = theNode->CarriedObj; // remember what obj is being thrown if (itemObj->CType == INVALID_NODE_FLAG) // make sure object is valid return; - + DropItem(theNode); // cause it to be dropped, but CarriedObj still pts to it - + /* CALC THROW VECTOR */ - + r = theNode->Rot.y; // get player y rot - itemObj->Delta.x = gDelta.x + sin(r) * -THROW_FORCE; - itemObj->Delta.z = gDelta.z + cos(r) * -THROW_FORCE; + itemObj->Delta.x = gDelta.x + sin(r) * -THROW_FORCE; + itemObj->Delta.z = gDelta.z + cos(r) * -THROW_FORCE; itemObj->Delta.y = 80; - + itemObj->RotDelta.x = (RandomFloat()-.5f)*30.0f; // put random spin on it itemObj->RotDelta.y = (RandomFloat()-.5f)*30.0f; itemObj->RotDelta.z = (RandomFloat()-.5f)*30.0f; - } + } } @@ -660,16 +660,16 @@ static void MovePlayer_GetHurt(ObjNode *theNode) DoFrictionAndGravity(theNode,PLAYER_FRICTION_ACCEL/10); // do friction DoPlayerMovement(theNode); - + if (DoPlayerCollisionDetect(theNode)) goto update; - + if ((theNode->HurtTimer -= gFramesPerSecondFrac) < 0.0f) // see if done being hurt MorphToSkeletonAnim(theNode->Skeleton,PLAYER_ANIM_STAND,4); - - + + /* UPDATE IT */ -update: +update: UpdatePlayer(theNode); } @@ -688,36 +688,36 @@ int oldFuel; /* MOVE IT */ - + DoPlayerJetMovement(theNode); - + /* SEE IF ATTACK */ - + CheckIfMeAttack(theNode); /* LOSE FUEL */ - + oldFuel = gFuel; - gFuel -= gFramesPerSecondFrac * FUEL_LOSS_RATE; + gFuel -= gFramesPerSecondFrac * FUEL_LOSS_RATE; if (gFuel <= 0.0f) { gFuel = 0; gInfobarUpdateBits |= UPDATE_FUEL; StopJetPack(theNode); } - if ((int)gFuel != oldFuel) // only update infobar if changed by integer value + if ((int)gFuel != oldFuel) // only update infobar if changed by integer value gInfobarUpdateBits |= UPDATE_FUEL; /* COLLISION */ - + if (DoPlayerCollisionDetect(theNode)) goto update; - + /* UPDATE IT */ -update: +update: UpdatePlayer(theNode); } @@ -734,12 +734,12 @@ static void MovePlayer_Death(ObjNode *theNode) DoFrictionAndGravity(theNode,PLAYER_FRICTION_ACCEL); // do friction DoPlayerMovement(theNode); - + if (DoPlayerCollisionDetect(theNode)) goto update; - + /* UPDATE IT */ -update: +update: if (theNode->Skeleton->AnimNum != PLAYER_ANIM_DEATH) // make sure stays dead! SetSkeletonAnim(theNode->Skeleton,PLAYER_ANIM_DEATH); @@ -755,7 +755,7 @@ TQ3Point3D oldMyCoord; /* MOVE UP PORTAL */ - if (theNode->Flag[0]) + if (theNode->Flag[0]) { gDelta.y += gFramesPerSecondFrac * 100; gCoord.y += gDelta.y * gFramesPerSecondFrac; @@ -768,9 +768,9 @@ TQ3Point3D oldMyCoord; } else { - gDelta.x = gDelta.y = gDelta.z; - } - + gDelta.x = gDelta.y = gDelta.z; + } + if (theNode->Skeleton->AnimNum != PLAYER_ANIM_EXIT) // make sure stays exited SetSkeletonAnim(theNode->Skeleton,PLAYER_ANIM_EXIT); @@ -788,7 +788,7 @@ static void UpdatePlayer(ObjNode *theNode) { /* SEE IF ENTRY PORTAL SHOULD STOP */ - + if (gMyTimePortal) { if (!(theNode->StatusBits & STATUS_BIT_HIDDEN)) @@ -802,11 +802,11 @@ static void UpdatePlayer(ObjNode *theNode) } else gMyCoord = gCoord; // only if no portal so camera wont track me - + UpdateObject(theNode); - + /* CHECK FOR EASTER EGG */ - + if (gMyCoord.y > 1500) // while riding birdie does this { GetCheatWeapons(); @@ -835,21 +835,21 @@ float y; UInt8 sides; /* AUTOMATICALLY HANDLE THE GOOD STUFF */ - + if (gPlayerGotKilledFlag) - sides = HandleCollisions(theNode, CTYPE_MISC|CTYPE_BGROUND); + sides = HandleCollisions(theNode, CTYPE_MISC|CTYPE_BGROUND); else sides = HandleCollisions(theNode, PLAYER_COLLISION_CTYPE); /* SEE IF NEED TO SET GROUND FLAG */ - + if (sides & SIDE_BITS_BOTTOM) - theNode->StatusBits |= STATUS_BIT_ONGROUND; + theNode->StatusBits |= STATUS_BIT_ONGROUND; /* MAKE SURE I DIDN'T GET PUSHED UNDERGROUND */ - + y = GetTerrainHeightAtCoord_Planar(gCoord.x, gCoord.z) + DIST_FROM_ORIGIN_TO_FEET; if (gCoord.y < y) gCoord.y = y; @@ -858,56 +858,56 @@ UInt8 sides; /******************************/ /* SCAN FOR INTERESTING STUFF */ /******************************/ - - for (i=0; i < gNumCollisions; i++) + + for (i=0; i < gNumCollisions; i++) { if (gCollisionList[i].type == COLLISION_TYPE_OBJ) { hitObj = gCollisionList[i].objectPtr; // get ObjNode of this collision ctype = hitObj->CType; // get collision ctype from hit obj - + /*******************/ /* CHECK FOR ENEMY */ /*******************/ - + if (ctype & CTYPE_ENEMY) { hitObj->Delta.x = hitObj->Delta.z = 0; if (hitObj->CType & CTYPE_HURTIFTOUCH) // see if enemy is deadly to touch PlayerGotHurt(theNode,hitObj->Damage,true,false); } - + /**********************/ /* SEE IF HURTME ITEM */ /**********************/ - + else if (ctype & CTYPE_HURTME) { PlayerGotHurt(theNode,hitObj->Damage,true,false); - + /* SEE IF WAS DINO SPIT */ - + if ((hitObj->Group == GLOBAL_MGroupNum_DinoSpit) && (hitObj->Type == GLOBAL_MObjType_DinoSpit)) { QD3D_ExplodeGeometry(hitObj, 100, 0, 10, .5); DeleteObject(hitObj); } - } + } } } - + /********************************/ /* CHECK FOR SPECIAL PATH TILES */ /********************************/ - gMyLatestPathTileNum = GetPathTileNum(gCoord.x, gCoord.z); // get path tile under there + gMyLatestPathTileNum = GetPathTileNum(gCoord.x, gCoord.z); // get path tile under there gMyLatestTileAttribs = GetTileAttribs(gCoord.x, gCoord.z); // get tile attributes here (before move) - + if (gMyHeightOffGround < 1.0f) // must be on terrain for these checks { /* SEE IF ON LAVA */ - + if (gMyLatestTileAttribs & TILE_ATTRIB_LAVA) { float x,z; @@ -919,7 +919,7 @@ UInt8 sides; gLavaSmokeCounter = 0; x = (RandomFloat() - .5f) * 40.0f + gCoord.x; z = (RandomFloat() - .5f) * 40.0f + gCoord.z; - MakeSmokePuff(x, gCoord.y, z, .1); + MakeSmokePuff(x, gCoord.y, z, .1); } } } @@ -949,15 +949,15 @@ UInt32 ctype; { hitObj = gCollisionList[i].objectPtr; // get ptr to hit obj ctype = hitObj->CType; // get collision ctype - + /* HIT AN ENEMY */ - - if (ctype & CTYPE_ENEMY) + + if (ctype & CTYPE_ENEMY) { EnemyGotHurt(gCollisionList[i].objectPtr, theNode, MY_KICK_DAMAGE); } } - + return(n); } @@ -968,16 +968,16 @@ void PlayerGotHurt(ObjNode *theNode, float damage, Boolean doHurtAnim, Boolean o { if (damage == 0.0f) return; - + if (!overrideShield) if (gMyShield) // see if shielded return; - + StopJetPack(theNode); // make sure this is stopped when get hit if (gPlayerGotKilledFlag) // cant get hurt if already dead return; - + if (theNode->InvincibleTimer > 0) // cant be harmed if invincible return; @@ -996,8 +996,8 @@ void PlayerGotHurt(ObjNode *theNode, float damage, Boolean doHurtAnim, Boolean o else if (theNode->InvincibleTimer < INVINCIBILITY_DURATION_SHORT) theNode->InvincibleTimer = INVINCIBILITY_DURATION_SHORT; // make me invincible for a shorter while - - + + gMyHealth -= damage; // take damage gInfobarUpdateBits |= UPDATE_HEALTH; // tell system to update this at end of frame if (gMyHealth <= 0) // see if was killed @@ -1027,11 +1027,11 @@ void StartMyShield(ObjNode *theNode) gShieldTimer = SHIELD_TIME; /* MAKE SHIELD GEOMETRY */ - + if (gMyShield == nil) { - gNewObjectDefinition.group = GLOBAL_MGroupNum_Shield; - gNewObjectDefinition.type = GLOBAL_MObjType_Shield; + gNewObjectDefinition.group = GLOBAL_MGroupNum_Shield; + gNewObjectDefinition.type = GLOBAL_MObjType_Shield; gNewObjectDefinition.coord = gMyCoord; gNewObjectDefinition.flags = STATUS_BIT_KEEPBACKFACES; gNewObjectDefinition.slot = SLOT_OF_DUMB; @@ -1044,7 +1044,7 @@ void StartMyShield(ObjNode *theNode) MakeObjectTransparent(gMyShield,.3); } } - + if (gShieldChannel == -1) gShieldChannel = PlayEffect_Parms(EFFECT_SHIELD,150,kMiddleC); @@ -1058,7 +1058,7 @@ static void MoveShield(ObjNode *theNode) float fps = gFramesPerSecondFrac; /* SEE IF TIMED OUT */ - + gShieldTimer -= fps; if (gShieldTimer <= 0.0f) { @@ -1073,15 +1073,10 @@ float fps = gFramesPerSecondFrac; /* UPDATE POSITION */ - + theNode->Coord = gMyCoord; theNode->Rot.y += fps * 6.0f; theNode->Rot.z += fps * 9.0f; - + UpdateObjectTransforms(theNode); } - - - - - From a6cf58cc3e05463391e8c4a89bf9c31f8b0d415a Mon Sep 17 00:00:00 2001 From: br4e <br4e@protonmail.com> Date: Sat, 6 Aug 2022 13:20:24 -0700 Subject: [PATCH 10/20] update start location --- src/Terrain/Terrain2.c | 48 +++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/Terrain/Terrain2.c b/src/Terrain/Terrain2.c index 1abb5c0..6b09cf5 100644 --- a/src/Terrain/Terrain2.c +++ b/src/Terrain/Terrain2.c @@ -131,29 +131,29 @@ TerrainItemEntryType *lastPtr; { gTerrainItemLookupTableX[col] = lastPtr; } - - + + /*********************/ /* BUILD LINKED LIST */ /*********************/ - + /* MANUALLY BUILD 1ST & LAST NODES */ - + gMasterItemList[0].prevItemIdx = -1; // 1st has no prev gMasterItemList[0].nextItemIdx = 1; // link to next gMasterItemList[gNumTerrainItems-1].prevItemIdx = gNumTerrainItems-2; // 1st has no prev gMasterItemList[gNumTerrainItems-1].nextItemIdx = -1; // last has no next - - + + /* LINK ALL THE OTHERS */ - + for (itemNum = 1; itemNum < (gNumTerrainItems-1); itemNum++) { gMasterItemList[itemNum].prevItemIdx = itemNum - 1; gMasterItemList[itemNum].nextItemIdx = itemNum + 1; - } - + } + } @@ -173,8 +173,8 @@ long i; for (i= 0; i < gNumTerrainItems; i++) if (gMasterItemList[i].type == MAP_ITEM_MYSTARTCOORD) // see if it's a MyStartCoord item { - gMyCoord.x = gMyStartX = (gMasterItemList[i].x * MAP2UNIT_VALUE); // convert to world coords - gMyCoord.z = gMyStartZ = gMasterItemList[i].y * MAP2UNIT_VALUE; + gMyCoord.x = gMyStartX = 28500; // (gMasterItemList[i].x * MAP2UNIT_VALUE); // convert to world coords + gMyCoord.z = gMyStartZ = 42500; // gMasterItemList[i].y * MAP2UNIT_VALUE; gMyStartAim = gMasterItemList[i].parm[0]; // get aim 0..7 return; } @@ -231,7 +231,7 @@ long realX,realZ; { realX = itemPtr->x * MAP2UNIT_VALUE; // calc & pass 3-space coords realZ = itemPtr->y * MAP2UNIT_VALUE; - + flag = gTerrainItemAddRoutines[type](itemPtr,realX, realZ); // call item's ADD routine if (flag) itemPtr->flags |= ITEM_FLAGS_INUSE; // set in-use flag @@ -353,7 +353,7 @@ UInt16 GetPathTileNumAtRowCol(long row, long col) UInt16 tile; tile = gTerrainPathLayer[row][col]; // get path data from map - tile = tile&TILENUM_MASK; // filter out tile # + tile = tile&TILENUM_MASK; // filter out tile # return(tile); } @@ -376,10 +376,10 @@ TQ3Matrix4x4 *matrix = &theNode->BaseTransformMatrix; TQ3Vector3D lookAt,upVector,theXAxis; Q3Matrix4x4_SetIdentity(matrix); // init the matrix - + rotY = theNode->Rot.y; - - + + /* CALC TERRAIN HEIGHT IN FRONT,BACK,LEFT & RIGHT */ sinRot = sin(rotY)*endOff; @@ -421,14 +421,14 @@ TQ3Vector3D lookAt,upVector,theXAxis; matrix->value[2][0] = lookAt.x; matrix->value[2][1] = lookAt.y; matrix->value[2][2] = lookAt.z; - + /* CALC UP VECTOR */ { theXAxis.x = right.x - left.x; // first calc left->right vector - theXAxis.y = right.y - left.y; - theXAxis.z = right.z - left.z; + theXAxis.y = right.y - left.y; + theXAxis.z = right.z - left.z; Q3Vector3D_Normalize(&theXAxis,&theXAxis); } @@ -440,26 +440,26 @@ TQ3Vector3D lookAt,upVector,theXAxis; /* CALC THE X-AXIS VECTOR */ - + matrix->value[0][0] = theXAxis.x; matrix->value[0][1] = theXAxis.y; matrix->value[0][2] = theXAxis.z; /* POP IN THE TRANSLATE INTO THE MATRIX */ - + matrix->value[3][0] = theNode->Coord.x; matrix->value[3][1] = theNode->Coord.y; matrix->value[3][2] = theNode->Coord.z; /* SET SCALE IF ANY */ - + if ((theNode->Scale.x != 1) || (theNode->Scale.y != 1) || (theNode->Scale.z != 1)) // see if ignore scale { TQ3Matrix4x4 matrix2; - + Q3Matrix4x4_SetScale(&matrix2, theNode->Scale.x, // make scale matrix - theNode->Scale.y, + theNode->Scale.y, theNode->Scale.z); Q3Matrix4x4_Multiply(&matrix2, matrix, matrix); From bf8b49f1bb059c5a5f11719a3747dadf399e7bf3 Mon Sep 17 00:00:00 2001 From: br4e <br4e@protonmail.com> Date: Sat, 6 Aug 2022 13:20:31 -0700 Subject: [PATCH 11/20] Revert "1 hour game" This reverts commit d30855572aae69a419b5f2e1cf6529e8c08be5a2. --- src/Headers/infobar.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Headers/infobar.h b/src/Headers/infobar.h index ede815f..a1364a4 100644 --- a/src/Headers/infobar.h +++ b/src/Headers/infobar.h @@ -4,7 +4,7 @@ #define MAX_FUEL_CAPACITY (29-1) #define NUM_EGG_SPECIES 5 -#define LEVEL_DURATION 3599 // 1 hour +#define LEVEL_DURATION (60*20) // n seconds enum { @@ -30,3 +30,4 @@ extern void AddToScore(long points); extern void DoPaused(void); extern void DecAsteroidTimer(void); extern void GetHealth(float amount); + From b21932912f8ea2f9869f52f168c25dd8aad229f1 Mon Sep 17 00:00:00 2001 From: br4e <br4e@protonmail.com> Date: Sat, 6 Aug 2022 14:00:37 -0700 Subject: [PATCH 12/20] make spitters weaker --- src/Enemies/Enemy_Spitter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Enemies/Enemy_Spitter.c b/src/Enemies/Enemy_Spitter.c index ffb3d35..b8619dc 100644 --- a/src/Enemies/Enemy_Spitter.c +++ b/src/Enemies/Enemy_Spitter.c @@ -37,7 +37,7 @@ static void MoveDinoSpit(ObjNode *theNode); #define SPITTER_TARGET_SCALE 200.0f -#define SPITTER_HEALTH 2.0f +#define SPITTER_HEALTH 1.0f #define SPITTER_DAMAGE 0.02f #define SPITTER_SCALE .8f From 34d871edbab76a2f6a12b88a2d67af5ef9396a71 Mon Sep 17 00:00:00 2001 From: br4e <br4e@protonmail.com> Date: Sat, 6 Aug 2022 14:02:44 -0700 Subject: [PATCH 13/20] update to lava start --- src/Terrain/Terrain2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Terrain/Terrain2.c b/src/Terrain/Terrain2.c index 6b09cf5..36d8040 100644 --- a/src/Terrain/Terrain2.c +++ b/src/Terrain/Terrain2.c @@ -173,8 +173,8 @@ long i; for (i= 0; i < gNumTerrainItems; i++) if (gMasterItemList[i].type == MAP_ITEM_MYSTARTCOORD) // see if it's a MyStartCoord item { - gMyCoord.x = gMyStartX = 28500; // (gMasterItemList[i].x * MAP2UNIT_VALUE); // convert to world coords - gMyCoord.z = gMyStartZ = 42500; // gMasterItemList[i].y * MAP2UNIT_VALUE; + gMyCoord.x = gMyStartX = 26000; // (gMasterItemList[i].x * MAP2UNIT_VALUE); // convert to world coords + gMyCoord.z = gMyStartZ = 13000; // gMasterItemList[i].y * MAP2UNIT_VALUE; gMyStartAim = gMasterItemList[i].parm[0]; // get aim 0..7 return; } From d699132f99b59df3ae57dd1e7e0125e15c282f33 Mon Sep 17 00:00:00 2001 From: br4e <br4e@protonmail.com> Date: Sat, 6 Aug 2022 14:17:19 -0700 Subject: [PATCH 14/20] lava hurts enemies --- src/Enemies/Enemy.c | 86 ++++++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 41 deletions(-) diff --git a/src/Enemies/Enemy.c b/src/Enemies/Enemy.c index 62180ed..3e3866f 100644 --- a/src/Enemies/Enemy.c +++ b/src/Enemies/Enemy.c @@ -75,11 +75,11 @@ static const int enemyPoints[]= 500, 500 }; - + AddToScore(enemyPoints[theEnemy->Kind]); // get points - + QD3D_ExplodeGeometry(theEnemy, 570.0f, 0, EXPLODEGEOMETRY_DENOMINATOR, .4); - + DeleteEnemy(theEnemy); PlayEffect(EFFECT_ENEMYDIE); } @@ -99,24 +99,30 @@ Boolean DoEnemyCollisionDetect(ObjNode *theEnemy, unsigned long ctype) short i; ObjNode *hitObj; + /* AUTOMATICALLY HANDLE THE BORING STUFF */ + + HandleCollisions(theEnemy, ctype); + + + /* HANDLE LAVA */ + - /* AUTOMATICALLY HANDLE THE BORING STUFF */ - - HandleCollisions(theEnemy, ctype); /******************************/ /* SCAN FOR INTERESTING STUFF */ /******************************/ - - for (i=0; i < gNumCollisions; i++) + + for (i=0; i < gNumCollisions; i++) { if (gCollisionList[i].type == COLLISION_TYPE_OBJ) { hitObj = gCollisionList[i].objectPtr; // get ObjNode of this collision ctype = hitObj->CType; - + + + if (ctype & CTYPE_HURTENEMY) { if (EnemyGotHurt(theEnemy,hitObj,hitObj->Damage)) // handle hit (returns true if was deleted) @@ -129,8 +135,20 @@ ObjNode *hitObj; PlayerGotHurt(hitObj,theEnemy->Damage, true, false); } } + } - + + UInt16 enemyTile = GetTileAttribs(theEnemy->Coord.x, theEnemy->Coord.z); + if (enemyTile & TILE_ATTRIB_LAVA) { + MakeSmokePuff(theEnemy->Coord.x, theEnemy->Coord.y, theEnemy->Coord.z, .1); + + if (EnemyGotHurt(theEnemy,hitObj,.01)) { + // handle hit (returns true if was deleted) + return(true); + } + } + + return(false); } @@ -150,20 +168,20 @@ Boolean EnemyGotHurt(ObjNode *theEnemy, ObjNode *theHurter, float damage) /* LOSE HEALTH */ - + theEnemy->Health -= damage; - - + + /* HANDLE DEATH OF ENEMY */ - + if (theEnemy->Health <= 0) { KillEnemy(theEnemy); return(true); } - - - + + + return(false); } @@ -188,14 +206,14 @@ ObjNode *FindClosestEnemy(TQ3Point3D *pt, float *dist) ObjNode *thisNodePtr,*best = nil; float d,minDist = 100000; - + thisNodePtr = gFirstNodePtr; - + do { if (thisNodePtr->Slot >= SLOT_OF_DUMB) // see if reach end of usable list break; - + if (thisNodePtr->CType & CTYPE_ENEMY) { d = CalcQuickDistance(pt->x,pt->z,thisNodePtr->Coord.x, thisNodePtr->Coord.z); @@ -204,7 +222,7 @@ float d,minDist = 100000; minDist = d; best = thisNodePtr; } - } + } thisNodePtr = (ObjNode *)thisNodePtr->NextNode; // next node } while (thisNodePtr != nil); @@ -226,7 +244,7 @@ float d,minDist = 100000; ObjNode *MakeEnemySkeleton(Byte skeletonType, float x, float z) { ObjNode *newObj; - + /****************************/ /* MAKE NEW SKELETON OBJECT */ /****************************/ @@ -245,13 +263,13 @@ ObjNode *newObj; newObj = MakeNewSkeletonObject(&gNewObjectDefinition); if (newObj == nil) DoFatalAlert("MakeEnemySkeleton: MakeNewSkeletonObject failed!"); - - + + /* SET DEFAULT COLLISION INFO */ - + newObj->CType = CTYPE_ENEMY | CTYPE_HURTIFTOUCH; newObj->CBits = CBITS_ALLSOLID; - + // SIDE_BITS_LEFT | SIDE_BITS_RIGHT | SIDE_BITS_FRONT | // not solid on bottom or top // SIDE_BITS_BACK; return(newObj); @@ -275,7 +293,7 @@ float y; /* SEE IF ON GROUND */ - + y = GetTerrainHeightAtCoord_Planar(gCoord.x, gCoord.z); // get center Y if ((gCoord.y + flightHeight) < y) { @@ -287,17 +305,3 @@ float y; theNode->StatusBits &= ~STATUS_BIT_ONGROUND; return(false); } - - - - - - - - - - - - - - From 7da7a219cf0f2095e8f8f8ba9d9fd9c8d32b1e0c Mon Sep 17 00:00:00 2001 From: br4e <br4e@protonmail.com> Date: Sat, 6 Aug 2022 14:24:04 -0700 Subject: [PATCH 15/20] Fix enemy smoke --- src/Enemies/Enemy.c | 12 ++++++++++- src/Headers/structs.h | 48 +++++++++++++++++++++---------------------- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/Enemies/Enemy.c b/src/Enemies/Enemy.c index 3e3866f..e4b4b58 100644 --- a/src/Enemies/Enemy.c +++ b/src/Enemies/Enemy.c @@ -140,12 +140,22 @@ ObjNode *hitObj; UInt16 enemyTile = GetTileAttribs(theEnemy->Coord.x, theEnemy->Coord.z); if (enemyTile & TILE_ATTRIB_LAVA) { - MakeSmokePuff(theEnemy->Coord.x, theEnemy->Coord.y, theEnemy->Coord.z, .1); if (EnemyGotHurt(theEnemy,hitObj,.01)) { // handle hit (returns true if was deleted) return(true); } + + theEnemy->LavaSmokeCounter += gFramesPerSecondFrac; + if (theEnemy->LavaSmokeCounter > .08f) + { + theEnemy->LavaSmokeCounter = 0.0f; + MakeSmokePuff( + (RandomFloat() - .5f) * 40.0f + gCoord.x, + gCoord.y, + (RandomFloat() - .5f) * 40.0f + gCoord.z, + .1); + } } diff --git a/src/Headers/structs.h b/src/Headers/structs.h index 37f52ce..aa440ae 100644 --- a/src/Headers/structs.h +++ b/src/Headers/structs.h @@ -27,7 +27,7 @@ /* COLLISION BOX */ - + typedef struct { long left,right,front,back,top,bottom; @@ -38,7 +38,7 @@ typedef struct /****************************/ /* POLYGONAL COLLISION INFO */ /****************************/ - + typedef struct { TQ3Point3D verts[3]; // coords of each vertex @@ -60,11 +60,11 @@ typedef struct // // NOTE: Similar to joint definition but lacks animation, rot/scale info. // - + typedef struct { long parentBone; // index to previous bone - TQ3Point3D coord; // absolute coord (not relative to parent!) + TQ3Point3D coord; // absolute coord (not relative to parent!) UInt16 numPointsAttachedToBone; // # vertices/points that this bone has UInt16 *pointList; // indecies into gDecomposedPointList UInt16 numNormalsAttachedToBone; // # vertex normals this bone has @@ -73,12 +73,12 @@ typedef struct /* DECOMPOSED POINT INFO */ - + typedef struct { TQ3Point3D realPoint; // point coords as imported in 3DMF model TQ3Point3D boneRelPoint; // point relative to bone coords (offset from bone) - + Byte numRefs; // # of places this point is used in the geometry data Byte whichTriMesh[MAX_POINT_REFS]; // index to trimeshes short whichPoint[MAX_POINT_REFS]; // index into pointlist of triMesh above @@ -88,7 +88,7 @@ typedef struct /* CURRENT JOINT STATE */ - + typedef struct { SInt32 tick; // time at which this state exists @@ -100,7 +100,7 @@ typedef struct /* JOINT DEFINITIONS */ - + typedef struct { signed char numKeyFrames[MAX_ANIMS]; // # keyframes @@ -108,7 +108,7 @@ typedef struct }JointKeyFrameHeader; /* ANIM EVENT TYPE */ - + typedef struct { short time; @@ -118,7 +118,7 @@ typedef struct /* SKELETON INFO */ - + typedef struct { Byte NumBones; // # joints in this skeleton object @@ -166,12 +166,12 @@ typedef struct JointKeyframeType MorphStart[MAX_JOINTS]; // morph start & end keyframes for each joint JointKeyframeType MorphEnd[MAX_JOINTS]; - float CurrentAnimTime; // current time index for animation + float CurrentAnimTime; // current time index for animation float LoopBackTime; // time to loop or zigzag back to (default = 0 unless set by a setmarker) float MaxAnimTime; // duration of current anim float AnimSpeed; // time factor for speed of executing current anim (1.0 = normal time) Byte AnimEventIndex; // current index into anim event list - Byte AnimDirection; // if going forward in timeline or backward + Byte AnimDirection; // if going forward in timeline or backward Byte EndMode; // what to do when reach end of animation Boolean AnimHasStopped; // flag gets set when anim has reached end of sequence (looping anims don't set this!) @@ -188,8 +188,8 @@ struct TerrainItemEntryType UInt16 x,y; UInt16 type; Byte parm[4]; - - UInt16 flags; + + UInt16 flags; // Source port fix: changed from pointers to 32-bit longs for 64-bit compatibility. // These "pointers" were loaded from Level1.ter -- they're actually just stored as zeores @@ -237,21 +237,22 @@ struct ObjNode struct ObjNode *SpecialRef[6]; // source port addition for 64-bit compat float Health; // health 0..1 float Damage; // damage - + float LavaSmokeCounter; + unsigned long StatusBits; // various status bits - + struct ObjNode *ShadowNode; // ptr to node's shadow (if any) struct ObjNode *PlatformNode; // ptr to object which it on top of. struct ObjNode *CarriedObj; // ptr to object being carried/pickedup - + Byte NumCollisionBoxes; CollisionBoxType *CollisionBoxes;// Ptr to array of collision rectangles short LeftOff,RightOff,FrontOff,BackOff,TopOff,BottomOff; // box offsets (only used by simple objects with 1 collision box) - + TriangleCollisionList *CollisionTriangles; // ptr to triangle collision data - + short StreamingEffect; // streaming effect (-1 = none) - + TQ3Matrix4x4 BaseTransformMatrix; // matrix which contains all of the transforms for the object as a whole int NumMeshes; @@ -271,7 +272,7 @@ typedef struct ObjNode ObjNode; /* NEW OBJECT DEFINITION TYPE */ - + typedef struct { Byte genre,group,type,animNum; @@ -284,7 +285,7 @@ typedef struct /* TIME PORTAL STRUCT */ - + typedef struct { TQ3Point2D coord; @@ -292,7 +293,7 @@ typedef struct /* PREFERENCES */ - + typedef struct { char magic[32]; @@ -313,4 +314,3 @@ typedef struct }PrefsType; #define PREFS_MAGIC "Nanosaur Prefs v4" - From c0f0d558f9ba425fb30f8892e4c5daa02f3740dd Mon Sep 17 00:00:00 2001 From: br4e <br4e@protonmail.com> Date: Sat, 6 Aug 2022 14:35:02 -0700 Subject: [PATCH 16/20] Fix smoke puff etc --- src/Enemies/Enemy.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/Enemies/Enemy.c b/src/Enemies/Enemy.c index e4b4b58..930f922 100644 --- a/src/Enemies/Enemy.c +++ b/src/Enemies/Enemy.c @@ -135,26 +135,31 @@ ObjNode *hitObj; PlayerGotHurt(hitObj,theEnemy->Damage, true, false); } } - } UInt16 enemyTile = GetTileAttribs(theEnemy->Coord.x, theEnemy->Coord.z); if (enemyTile & TILE_ATTRIB_LAVA) { - if (EnemyGotHurt(theEnemy,hitObj,.01)) { - // handle hit (returns true if was deleted) - return(true); - } + float groundY = GetTerrainHeightAtCoord(theEnemy->Coord.x, theEnemy->Coord.z); + float enemyY = theEnemy->Coord.y; - theEnemy->LavaSmokeCounter += gFramesPerSecondFrac; - if (theEnemy->LavaSmokeCounter > .08f) - { - theEnemy->LavaSmokeCounter = 0.0f; - MakeSmokePuff( - (RandomFloat() - .5f) * 40.0f + gCoord.x, - gCoord.y, - (RandomFloat() - .5f) * 40.0f + gCoord.z, - .1); + if (enemyY >= groundY && enemyY - groundY < 100) { + if (EnemyGotHurt(theEnemy,hitObj,.01)) { + // handle hit (returns true if was deleted) + return(true); + } + + theEnemy->LavaSmokeCounter += gFramesPerSecondFrac; + if (theEnemy->LavaSmokeCounter > .08f) + { + theEnemy->LavaSmokeCounter = 0.0f; + MakeSmokePuff( + (RandomFloat() - .5f) * 40.0f + theEnemy->Coord.x, + theEnemy->Coord.y, + (RandomFloat() - .5f) * 40.0f + theEnemy->Coord.z, + .1); + + } } } From faaa54b09fad010dadb991bd46addc6f520a79e2 Mon Sep 17 00:00:00 2001 From: br4e <br4e@protonmail.com> Date: Sat, 6 Aug 2022 14:39:02 -0700 Subject: [PATCH 17/20] reset start point --- src/Terrain/Terrain2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Terrain/Terrain2.c b/src/Terrain/Terrain2.c index 36d8040..9e9fd06 100644 --- a/src/Terrain/Terrain2.c +++ b/src/Terrain/Terrain2.c @@ -173,8 +173,8 @@ long i; for (i= 0; i < gNumTerrainItems; i++) if (gMasterItemList[i].type == MAP_ITEM_MYSTARTCOORD) // see if it's a MyStartCoord item { - gMyCoord.x = gMyStartX = 26000; // (gMasterItemList[i].x * MAP2UNIT_VALUE); // convert to world coords - gMyCoord.z = gMyStartZ = 13000; // gMasterItemList[i].y * MAP2UNIT_VALUE; + gMyCoord.x = gMyStartX = (gMasterItemList[i].x * MAP2UNIT_VALUE); // convert to world coords + gMyCoord.z = gMyStartZ = gMasterItemList[i].y * MAP2UNIT_VALUE; gMyStartAim = gMasterItemList[i].parm[0]; // get aim 0..7 return; } From 68dc54aed18282c826061e0861598ad7512c5fc9 Mon Sep 17 00:00:00 2001 From: br4e <milesminton@gmail.com> Date: Sat, 27 Apr 2024 17:20:17 -0700 Subject: [PATCH 18/20] Get everything cheat is higher --- src/Player/MyGuy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Player/MyGuy.c b/src/Player/MyGuy.c index a880147..20dee9a 100644 --- a/src/Player/MyGuy.c +++ b/src/Player/MyGuy.c @@ -807,7 +807,7 @@ static void UpdatePlayer(ObjNode *theNode) /* CHECK FOR EASTER EGG */ - if (gMyCoord.y > 1500) // while riding birdie does this + if (gMyCoord.y > 2000) // while riding birdie does this { GetCheatWeapons(); GetHealth(1); From c76339fc2eb20ec820ea2f56cf12d5c942b0f1f4 Mon Sep 17 00:00:00 2001 From: br4e <milesminton@gmail.com> Date: Sat, 27 Apr 2024 17:38:15 -0700 Subject: [PATCH 19/20] pomme --- extern/Pomme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/Pomme b/extern/Pomme index 1acfd09..0581b24 160000 --- a/extern/Pomme +++ b/extern/Pomme @@ -1 +1 @@ -Subproject commit 1acfd097047d75065d8eefc37f9fea2cc09577f6 +Subproject commit 0581b241624d16c453e0afab57a379b443229260 From cdb2872481f61116a9d5112320155b233f023c2f Mon Sep 17 00:00:00 2001 From: br4e <milesminton@gmail.com> Date: Thu, 25 Jul 2024 08:49:58 -0700 Subject: [PATCH 20/20] Revert "pomme" This reverts commit c76339fc2eb20ec820ea2f56cf12d5c942b0f1f4. --- extern/Pomme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/Pomme b/extern/Pomme index 0581b24..1acfd09 160000 --- a/extern/Pomme +++ b/extern/Pomme @@ -1 +1 @@ -Subproject commit 0581b241624d16c453e0afab57a379b443229260 +Subproject commit 1acfd097047d75065d8eefc37f9fea2cc09577f6