MCPcopy Create free account
hub / github.com/OpenDUNE/OpenDUNE / Script_Unit_Fire

Function Script_Unit_Fire

src/script/unit.c:577–697  ·  view source on GitHub ↗

* Makes the current unit fire a bullet (or eat its target). * * Stack: *none*. * * @param script The script engine to operate on. * @return The value 1 if the current unit fired/eat, 0 otherwise. */

Source from the content-addressed store, hash-verified

575 * @return The value 1 if the current unit fired/eat, 0 otherwise.
576 */
577uint16 Script_Unit_Fire(ScriptEngine *script)
578{
579 const UnitInfo *ui;
580 Unit *u;
581 uint16 target;
582 UnitType typeID;
583 uint16 distance;
584 bool fireTwice;
585 uint16 damage;
586
587 u = g_scriptCurrentUnit;
588
589 target = u->targetAttack;
590 if (target == 0 || !Tools_Index_IsValid(target)) return 0;
591
592 if (u->o.type != UNIT_SANDWORM && target == Tools_Index_Encode(Tile_PackTile(u->o.position), IT_TILE)) u->targetAttack = 0;
593
594 if (u->targetAttack != target) {
595 Unit_SetTarget(u, target);
596 return 0;
597 }
598
599 ui = &g_table_unitInfo[u->o.type];
600
601 if (u->o.type != UNIT_SANDWORM && u->orientation[ui->o.flags.hasTurret ? 1 : 0].speed != 0) return 0;
602
603 if (Tools_Index_GetType(target) == IT_TILE && Object_GetByPackedTile(Tools_Index_GetPackedTile(target)) != NULL) Unit_SetTarget(u, target);
604
605 if (u->fireDelay != 0) return 0;
606
607 distance = Object_GetDistanceToEncoded(&u->o, target);
608
609 if ((int16)(ui->fireDistance << 8) < (int16)distance) return 0;
610
611 if (u->o.type != UNIT_SANDWORM && (Tools_Index_GetType(target) != IT_UNIT || g_table_unitInfo[Tools_Index_GetUnit(target)->o.type].movementType != MOVEMENT_WINGER)) {
612 int16 diff = 0;
613 int8 orientation;
614
615 orientation = Tile_GetDirection(u->o.position, Tools_Index_GetTile(target));
616
617 diff = abs(u->orientation[ui->o.flags.hasTurret ? 1 : 0].current - orientation);
618 if (ui->movementType == MOVEMENT_WINGER) diff /= 8;
619
620 if (diff >= 8) return 0;
621 }
622
623 damage = ui->damage;
624 typeID = ui->bulletType;
625
626 fireTwice = ui->flags.firesTwice && u->o.hitpoints > ui->o.hitpoints / 2;
627
628 if ((u->o.type == UNIT_TROOPERS || u->o.type == UNIT_TROOPER) && (int16)distance > 512) typeID = UNIT_MISSILE_TROOPER;
629
630 switch (typeID) {
631 case UNIT_SANDWORM: {
632 Unit *u2;
633
634 Unit_UpdateMap(0, u);

Callers

nothing calls this directly

Calls 15

Tools_Index_IsValidFunction · 0.85
Tools_Index_EncodeFunction · 0.85
Unit_SetTargetFunction · 0.85
Tools_Index_GetTypeFunction · 0.85
Object_GetByPackedTileFunction · 0.85
Tools_Index_GetUnitFunction · 0.85
Tile_GetDirectionFunction · 0.85
Tools_Index_GetTileFunction · 0.85
Unit_UpdateMapFunction · 0.85
Unit_RemovePlayerFunction · 0.85

Tested by

no test coverage detected