static const Pic *GetBodyPic( PicManager *pm, const direction_e dir, const int state, const bool isArmed) { const bool isIdle = state <= STATE_IDLERIGHT; const int row = (isArmed ? 5 : 0) + (isIdle ? 0 : state - STATE_IDLERIGHT); const int idx = row * DIRECTION_COUNT + dir; return CArrayGet( &PicManagerGetSprites(pm, "chars/body_arms_legs")->pics, idx); }
static const Pic *GetLegsPic( PicManager *pm, const CharSprites *cs, const direction_e dir, const ActorAnimation anim, const int frame) { const int stride = anim == ACTORANIMATION_IDLE ? 1 : 8; const int col = frame % stride; const int row = (int)dir; const int idx = col + row * stride; char buf[CDOGS_PATH_MAX]; sprintf( buf, "chars/bodies/%s/legs_%s", cs->Name, anim == ACTORANIMATION_IDLE ? "idle" : "run"); return CArrayGet(&PicManagerGetSprites(pm, buf)->pics, idx); }
static const Pic *GetBodyPic( PicManager *pm, const CharSprites *cs, const direction_e dir, const ActorAnimation anim, const int frame, const bool isArmed) { const int stride = anim == ACTORANIMATION_IDLE ? 1 : 8; const int col = frame % stride; const int row = (int)dir; const int idx = col + row * stride; char buf[CDOGS_PATH_MAX]; sprintf( buf, "chars/bodies/%s/upper_%s%s", cs->Name, anim == ACTORANIMATION_IDLE ? "idle" : "run", isArmed ? "_handgun" : ""); // TODO: other gun holding poses return CArrayGet(&PicManagerGetSprites(pm, buf)->pics, idx); }
static void LoadOldSprites( PicManager *pm, const char *name, const TOffsetPic *pics, const int count) { // Don't use old sprites if new ones are available if (PicManagerGetSprites(pm, name) != NULL) { return; } NamedSprites ns; NamedSpritesInit(&ns, name); const TOffsetPic *pic = pics; for (int i = 0; i < count; i++, pic++) { Pic p; const Pic *original = PicManagerGetFromOld(pm, pic->picIndex); PicCopy(&p, original); CArrayPushBack(&ns.pics, &p); } CArrayPushBack(&pm->sprites, &ns); }
static const Pic *GetDeathPic(PicManager *pm, const int frame) { return CArrayGet(&PicManagerGetSprites(pm, "chars/death")->pics, frame); }
static void LoadBullet( BulletClass *b, json_t *node, const BulletClass *defaultBullet) { memset(b, 0, sizeof *b); if (defaultBullet != NULL) { memcpy(b, defaultBullet, sizeof *b); if (defaultBullet->HitSound.Object != NULL) { CSTRDUP(b->HitSound.Object, defaultBullet->HitSound.Object); } if (defaultBullet->HitSound.Flesh != NULL) { CSTRDUP(b->HitSound.Flesh, defaultBullet->HitSound.Flesh); } if (defaultBullet->HitSound.Wall != NULL) { CSTRDUP(b->HitSound.Wall, defaultBullet->HitSound.Wall); } // TODO: enable default bullet guns? memset(&b->Falling.DropGuns, 0, sizeof b->Falling.DropGuns); memset(&b->OutOfRangeGuns, 0, sizeof b->OutOfRangeGuns); memset(&b->HitGuns, 0, sizeof b->HitGuns); memset(&b->ProximityGuns, 0, sizeof b->ProximityGuns); } char *tmp; LoadStr(&b->Name, node, "Name"); if (json_find_first_label(node, "Pic")) { json_t *pic = json_find_first_label(node, "Pic")->child; tmp = GetString(pic, "Type"); b->CPic.Type = StrPicType(tmp); CFREE(tmp); bool picLoaded = false; switch (b->CPic.Type) { case PICTYPE_NORMAL: tmp = GetString(pic, "Pic"); b->CPic.u.Pic = PicManagerGetPic(&gPicManager, tmp); CFREE(tmp); picLoaded = b->CPic.u.Pic != NULL; break; case PICTYPE_DIRECTIONAL: tmp = GetString(pic, "Sprites"); b->CPic.u.Sprites = &PicManagerGetSprites(&gPicManager, tmp)->pics; CFREE(tmp); picLoaded = b->CPic.u.Sprites != NULL; break; case PICTYPE_ANIMATED: // fallthrough case PICTYPE_ANIMATED_RANDOM: tmp = GetString(pic, "Sprites"); b->CPic.u.Animated.Sprites = &PicManagerGetSprites(&gPicManager, tmp)->pics; CFREE(tmp); LoadInt(&b->CPic.u.Animated.Count, pic, "Count"); LoadInt(&b->CPic.u.Animated.TicksPerFrame, pic, "TicksPerFrame"); // Set safe default ticks per frame 1; // if 0 then this leads to infinite loop when animating b->CPic.u.Animated.TicksPerFrame = MAX( b->CPic.u.Animated.TicksPerFrame, 1); picLoaded = b->CPic.u.Animated.Sprites != NULL; break; default: CASSERT(false, "unknown pic type"); break; } b->CPic.UseMask = true; b->CPic.u1.Mask = colorWhite; if (json_find_first_label(pic, "Mask")) { tmp = GetString(pic, "Mask"); b->CPic.u1.Mask = StrColor(tmp); CFREE(tmp); } else if (json_find_first_label(pic, "Tint")) { b->CPic.UseMask = false; json_t *tint = json_find_first_label(pic, "Tint")->child->child; b->CPic.u1.Tint.h = atof(tint->text); tint = tint->next; b->CPic.u1.Tint.s = atof(tint->text); tint = tint->next; b->CPic.u1.Tint.v = atof(tint->text); } if ((json_find_first_label(pic, "OldPic") && ConfigGetBool(&gConfig, "Graphics.OriginalPics")) || !picLoaded) { int oldPic = PIC_UZIBULLET; LoadInt(&oldPic, pic, "OldPic"); b->CPic.Type = PICTYPE_NORMAL; b->CPic.u.Pic = PicManagerGetFromOld(&gPicManager, oldPic); } } LoadVec2i(&b->ShadowSize, node, "ShadowSize"); LoadInt(&b->Delay, node, "Delay"); if (json_find_first_label(node, "Speed")) { LoadInt(&b->SpeedLow, node, "Speed"); b->SpeedHigh = b->SpeedLow; } if (json_find_first_label(node, "SpeedLow")) { LoadInt(&b->SpeedLow, node, "SpeedLow"); } if (json_find_first_label(node, "SpeedHigh")) { LoadInt(&b->SpeedHigh, node, "SpeedHigh"); } b->SpeedLow = MIN(b->SpeedLow, b->SpeedHigh); b->SpeedHigh = MAX(b->SpeedLow, b->SpeedHigh); LoadBool(&b->SpeedScale, node, "SpeedScale"); LoadInt(&b->Friction, node, "Friction"); if (json_find_first_label(node, "Range")) { LoadInt(&b->RangeLow, node, "Range"); b->RangeHigh = b->RangeLow; } if (json_find_first_label(node, "RangeLow")) { LoadInt(&b->RangeLow, node, "RangeLow"); } if (json_find_first_label(node, "RangeHigh")) { LoadInt(&b->RangeHigh, node, "RangeHigh"); } b->RangeLow = MIN(b->RangeLow, b->RangeHigh); b->RangeHigh = MAX(b->RangeLow, b->RangeHigh); LoadInt(&b->Power, node, "Power"); LoadVec2i(&b->Size, node, "Size"); if (json_find_first_label(node, "Special")) { tmp = GetString(node, "Special"); b->Special = StrSpecialDamage(tmp); CFREE(tmp); } LoadBool(&b->HurtAlways, node, "HurtAlways"); LoadBool(&b->Persists, node, "Persists"); if (json_find_first_label(node, "Spark")) { tmp = GetString(node, "Spark"); b->Spark = StrParticleClass(&gParticleClasses, tmp); CFREE(tmp); } if (json_find_first_label(node, "HitSounds")) { json_t *hitSounds = json_find_first_label(node, "HitSounds")->child; CFREE(b->HitSound.Object); b->HitSound.Object = NULL; LoadStr(&b->HitSound.Object, hitSounds, "Object"); CFREE(b->HitSound.Flesh); b->HitSound.Flesh = NULL; LoadStr(&b->HitSound.Flesh, hitSounds, "Flesh"); CFREE(b->HitSound.Wall); b->HitSound.Wall = NULL; LoadStr(&b->HitSound.Wall, hitSounds, "Wall"); } LoadBool(&b->WallBounces, node, "WallBounces"); LoadBool(&b->HitsObjects, node, "HitsObjects"); if (json_find_first_label(node, "Falling")) { json_t *falling = json_find_first_label(node, "Falling")->child; LoadInt(&b->Falling.GravityFactor, falling, "GravityFactor"); LoadBool(&b->Falling.FallsDown, falling, "FallsDown"); LoadBool(&b->Falling.DestroyOnDrop, falling, "DestroyOnDrop"); LoadBool(&b->Falling.Bounces, falling, "Bounces"); } LoadInt(&b->SeekFactor, node, "SeekFactor"); LoadBool(&b->Erratic, node, "Erratic"); b->node = node; }